Wikipedia:WikiProject User scripts/Scripts/TwoColumns.js

/* TwoColumns, version [0.0.5]

Documentation: Wikipedia:WikiProject User scripts/Scripts/TwoColumns

  • /

if (mw.config.get('wgAction') == 'view' && mw.config.get('wgCanonicalNamespace')=='') addOnloadHook(fr_format)

var fr_columns;

var imgRegExp= /(thumb|frame)/i;

var trashNodes;

function fr_format() {

fr_addButton();

fr_columns=fr_getCookie ('fr_columns'); if (! (0<1*fr_columns)) fr_columns=1;

trashNodes=new Array;

if (fr_columns==1) return;

var bodyContent= document.getElementById('bodyContent');

if (! bodyContent || ! bodyContent.innerHTML || bodyContent.innerHTML=='') return;

var allNodes=bodyContent.childNodes;

var group=new Array, node, groupArea=0;

for (var i = allNodes.length-1; 0 <= i; i--) {

node=allNodes[i];

var pre= node.tagName=="PRE" || (node.tagName=="DIV" && node.childNodes[1] && node.childNodes[1].tagName=='PRE')

if (node.nodeValue && node.nodeValue.substr(0,1)=="\n") {

// } else if (node.tagName=="p" || node.tagName=="P" || node.tagName=="ul" || node.tagName=="UL" ) {

} else if (node.tagName && node.tagName.substr(0,1) !="H" && node.tagName.substr(0,5) !="TABLE" && node.tagName.substr(0,5) !="SCRIPT" && node.style.MozColumnCount<=0 && ! pre) { //everything but H

group.push(node);

groupArea += node.clientHeight * node.clientWidth;

} else {

if (node.tagName && node.tagName.substr(0,1) =="H") {

var prevNode=node;

var count=0;

do {

do {

prevNode=prevNode.previousSibling;count++;

} while (prevNode && (prevNode.clientHeight==0 || prevNode.clientHeight=== undefined));

if (prevNode && prevNode.className && imgRegExp.test(prevNode.className)) {

group.push(prevNode); i=i-count;count=0;

groupArea += prevNode.clientHeight * prevNode.clientWidth;

}

} while (prevNode && prevNode.className && imgRegExp.test(prevNode.className))

}

if (0

group=new Array; groupArea=0;

}

}

for (var i=trashNodes.length-1; 0<=i;i--) {

trashNodes[i].parentNode.removeChild(trashNodes[i]);

}

}

function fr_layoutDiv (aGroup, groupArea) {

var contentWidth=aGroup[0].parentNode.clientWidth;

if (groupArea < 100 * contentWidth) return;

var start=0, stop=aGroup.length-1;

var pieces=Math.round(groupArea / (window.innerHeight * contentWidth)+0.5);

var targetArea=groupArea/ pieces;

var targetHeight= (pieces==1) ? window.innerHeight : targetArea / contentWidth;

var divArea=0, first=true, imgHeight=0;

for (var i = stop; 0 <= i; i--) {

if (aGroup[i].className && imgRegExp.test(aGroup[i].className)) {

imgHeight +=aGroup[i].clientHeight;

}

divArea += aGroup[i].clientHeight * aGroup[i].clientWidth;

if (targetArea < divArea || targetHeight < imgHeight) {

fr_createDiv(aGroup, i+1,stop,fr_columns,first);

first=false;

stop=i;

if (aGroup[i].className && imgRegExp.test(aGroup[i].className)) {

imgHeight =aGroup[i].clientHeight;

} else {

imgHeight =0;

}

divArea = aGroup[i].clientHeight * aGroup[i].clientWidth;

}

}

if (0<=stop) {

divArea=0;

for (i=stop; 0<=i;i--) {

divArea += aGroup[i].clientHeight * aGroup[i].clientWidth;

}

if (100 * contentWidth < divArea) fr_createDiv(aGroup,0,stop,fr_columns,first);

}

}

function fr_createDiv(aGroup, start, stop, columns, noHR) { // start, stop: inclusive, (counting in the Group !), e.g. 0..3

if (stop

var newDiv = document.createElement('div');

newDiv.style.MozColumnCount=columns;

newDiv.style.MozColumnGap='2em';

newDiv.style.textAlign='justify';

var tooBig=false;

for (var i = stop; start <= i; i--) { // first append the thumb

if (imgRegExp.test(aGroup[i].className)) {

newNode=aGroup[i].cloneNode(true);

newDiv.appendChild(newNode);

if (imgRegExp.test(aGroup[i].className) && aGroup[i].parentNode.clientWidth / columns < newNode.clientWidth) {

tooBig=true;

}

}

}

for (var i = stop; start <= i; i--) {

if (!imgRegExp.test(aGroup[i].className)) {

newNode=aGroup[i].cloneNode(true);

newDiv.appendChild(newNode)

}

}

if (window.innerHeight < newDiv.clientHeight || tooBig /* window.innerHeight-10 < imgHeight */) { // safety valve: too big

return;

}

aGroup[start].parentNode.insertBefore(newDiv,aGroup[start]);

if (!noHR) {

var HR=document.createElement('HR');

newDiv.parentNode.insertBefore(HR,newDiv);

}

for (var i = stop; start <= i; i--) {

trashNodes.push(aGroup[i]); //newDiv.parentNode.removeChild(aGroup[i])

}

}

// Button to increment the number of columns

function fr_addButton () {

var node = document.getElementById('p-personal');

if ( !node ) return null;

node = node.getElementsByTagName( "ul" )[0];

if ( !node ) return null;

var link = document.createElement( "img" );

link.src= 'http://upload.wikimedia.org/wikipedia/commons/f/f5/FastReader_logo.PNG';

link.appendChild( document.createTextNode( "FastReader" ) );

link.onclick = function() {fr_next()};

var item = document.createElement( "li" );

item.appendChild( link );

link.setAttribute( "title", 'FastReader' );

node.appendChild( item ); // IE compatibility (?)

}

function fr_next() {

fr_columns= fr_columns % 2 +1;

fr_setCookie('fr_columns', fr_columns);

document.location.reload();

};

// Cookie routines to save the number of columns

function fr_getCookie (cookieName) {

var cookie = ' ' + document.cookie;

var search = ' ' + cookieName + '=';

var cookieValue = '';

var offset = 0;

var end = 0;

offset = cookie.indexOf(search);

if (offset != -1) {

offset += search.length;

end = cookie.indexOf(';', offset)

if (end == -1) {

end = cookie.length;

}

cookieValue = cookie.substring(offset, end);

cookieValue = cookieValue.replace(/\\+/g, ' ');

cookieValue = decodeURIComponent(cookieValue);

}

return(cookieValue);

}

function fr_setCookie (name, value) {

var cookie = name + '=' + encodeURIComponent(value);

var cookieExpire = new Date();

expires = cookieExpire.setTime(cookieExpire.getTime() + 30 * 24 * 60 * 60 * 1000);

expires = cookieExpire.toUTCString();

cookie += '; expires=' + expires;

document.cookie = cookie;

return;

}