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.length) fr_layoutDiv (group, groupArea); 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<start) return; 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; }