Rosetta Code:Language comparison script: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added script from Tyrok1/monobook.js)
 
(Typo)
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
//<lang javascript>
<pre>
/*========================================
/*========================================
This comparison script was written by
This comparison script was written by
Tyrok1, and has been tested on IE 5.5,
Tyrok1. Tested in:
- Fe 7.0.520.0
IE 6, IE 7, IE 8, Fx 3.6.2, and
Fe 4.0.280.
- Fx 3.6.11
- IE 6, 7, 8
========================================*/
========================================*/
function GetElWidth(el)
function GetElWidth(el)
Line 20: Line 21:
if(tocEl && ulElsNodeList.length > 0)
if(tocEl && ulElsNodeList.length > 0)
{
{
//limit what we're looking at to only what's directly in the main list, and move from NodeList objects to Arrays
//limit what we're looking at to only what's directly in
//the main list, and move from NodeList objects to Arrays
var ulEls = [ulElsNodeList[0]];
var ulEls = [ulElsNodeList[0]];
for(var u = 1; u < ulElsNodeList.length; ++u)
for(var u = 1; u < ulElsNodeList.length; ++u)
Line 44: Line 46:
//show all of the <ul> tags so we can get their items' ideal widths
//show all of the <ul> tags so we can get their items' ideal widths
ulEls[0].oldDisplay = (ulEls[0].style.display && ulEls[0].style.display == "none" ? "none" : "inline-block");
if(ulEls[0].style.display && ulEls[0].style.display == "none")
{
ulEls[0].oldDisplay = "none";
}
else
{
ulEls[0].oldDisplay = "inline-block";
}
for(u = 0; u < ulEls.length; ++u)
for(u = 0; u < ulEls.length; ++u)
{
{
Line 59: Line 68:
}
}
maxWidth = Math.max(liEls[l].initialWidth, maxWidth);
maxWidth = Math.max(liEls[l].initialWidth, maxWidth);
if(navigator.appVersion.indexOf("MSIE 5.") >= 0 || navigator.appVersion.indexOf("MSIE 6.") >= 0 || navigator.appVersion.indexOf("MSIE 7.") >= 0)
if(navigator.appVersion.indexOf("MSIE 5.") >= 0 ||
navigator.appVersion.indexOf("MSIE 6.") >= 0 ||
navigator.appVersion.indexOf("MSIE 7.") >= 0)
{
{
liEls[l].style.display = "inline";
liEls[l].style.display = "inline";
Line 70: Line 81:
//figure out the ideal number of columns
//figure out the ideal number of columns
tocEl.style.width = "100%";
tocEl.style.width = "100%";
var idealColumns = Math.floor(GetElWidth(tocEl) / maxWidth);
var idealColumns = Math.min(
Math.floor(GetElWidth(tocEl) / maxWidth),
if(navigator.appVersion.indexOf("MSIE 5.") >= 0 || navigator.appVersion.indexOf("MSIE 6.") >= 0 || navigator.appVersion.indexOf("MSIE 7.") >= 0)
Math.floor(liEls.length / 3) + 1);
if(navigator.appVersion.indexOf("MSIE 5.") >= 0 ||
navigator.appVersion.indexOf("MSIE 6.") >= 0 ||
navigator.appVersion.indexOf("MSIE 7.") >= 0)
{
{
idealColumns = 1;
idealColumns = 1;
Line 84: Line 99:
while(ulEls.length < idealColumns)
while(ulEls.length < idealColumns)
{
{
ulEls[ulEls.length] =
ulEls[ulEls.length] = ulEls[ulEls.length - 1].parentNode.insertBefore(document.createElement("ul"), ulEls[ulEls.length - 1].nextSibling);
ulEls[ulEls.length - 1].parentNode.insertBefore(
document.createElement("ul"),
ulEls[ulEls.length - 1].nextSibling);
}
}
Line 99: Line 117:
for(l = 0; l < liEls.length; ++l)
for(l = 0; l < liEls.length; ++l)
{
{
liEls[l] = ulEls[
liEls[l] = ulEls[Math.floor(l / liEls.length * idealColumns)].appendChild(liEls[l].parentNode.removeChild(liEls[l]));
Math.floor(l / liEls.length * idealColumns)
].appendChild(liEls[l].parentNode.removeChild(liEls[l]));
}
}
Line 113: Line 133:
if(insEl)
if(insEl)
{
{
insEl.style.display = (ulEls[0].oldDisplay.toLowerCase() == "none" ? "none" : "block");
insEl.style.display =
(ulEls[0].oldDisplay.toLowerCase() == "none" ? "none" : "block");
}
}
for(u = 0; u < ulEls.length; ++u)
for(u = 0; u < ulEls.length; ++u)
Line 130: Line 151:
for(var u = 0; u < ulEls.length; ++u)
for(var u = 0; u < ulEls.length; ++u)
{
{
ulEls[u].style.display = (ulEls[0].style.display && ulEls[0].style.display == "none" ? "none" : "inline-block");
if(ulEls[0].style.display &&
ulEls[0].style.display == "none")
{
ulEls[u].style.display = "none"
}
else
{
ulEls[u].style.display = "inline-block"
}
}
}
var el = document.getElementById("tocinstructions");
var el = document.getElementById("tocinstructions");
if(el)
if(el)
{
{
el.style.display = (ulEls[0].style.display && ulEls[0].style.display.toLowerCase() == "none" ? "none" : "block");
if(ulEls[0].style.display &&
ulEls[0].style.display.toLowerCase() == "none")
{
el.style.display = "none";
}
else
{
el.style.display = "block";
}
}
}
};
};
Line 143: Line 180:
};
};
//add an event handler so if the window's resized the number of columns can change
//add an event handler so if the window's
//resized the number of columns can change
if(window.addEventListener)
if(window.addEventListener)
{
{
Line 195: Line 233:
for(var s = 0; s < spanEls.length; ++s)
for(var s = 0; s < spanEls.length; ++s)
{
{
if(spanEls[s].className && spanEls[s].className.toLowerCase() == "toctoggle")
if(spanEls[s].className &&
spanEls[s].className.toLowerCase() == "toctoggle")
{
{
if(foundToggle)
if(foundToggle)
Line 210: Line 249:
for(var l = 0; l < liEls.length; ++l)
for(var l = 0; l < liEls.length; ++l)
{
{
//add a checkbox with the language section's <a> name attribute as its value for easier lookup in the refresh function
//add a checkbox with the language section's anchor name attribute
//as its value for easier lookup in the refresh function
var checkboxEl = document.createElement("input");
var checkboxEl = document.createElement("input");
checkboxEl.setAttribute("type", "checkbox");
checkboxEl.setAttribute("type", "checkbox");
Line 216: Line 256:
checkboxEl.setAttribute("id", "CompareLanguage" + l);
checkboxEl.setAttribute("id", "CompareLanguage" + l);
var href = liEls[l].getElementsByTagName("a")[0].getAttribute("href");
var href = liEls[l].getElementsByTagName("a")[0].getAttribute("href");
checkboxEl.setAttribute("value", href.substring(href.indexOf("#") + 1, href.length));
checkboxEl.setAttribute("value",
href.substring(href.indexOf("#") + 1, href.length));
checkboxEl.onclick = CompareRefresh;
checkboxEl.onclick = CompareRefresh;
liEls[l].insertBefore(checkboxEl, liEls[l].firstChild);
liEls[l].insertBefore(checkboxEl, liEls[l].firstChild);
Line 225: Line 266:
var instructionsEl = toctitleEl.appendChild(document.createElement("p"));
var instructionsEl = toctitleEl.appendChild(document.createElement("p"));
instructionsEl.setAttribute("id", "tocinstructions");
instructionsEl.setAttribute("id", "tocinstructions");
instructionsEl.appendChild(document.createTextNode("Check the boxes next to languages to compare them."));
instructionsEl.appendChild(
document.createTextNode("Check the boxes next to languages to compare them."));
instructionsEl.appendChild(document.createElement("br"));
instructionsEl.appendChild(document.createElement("br"));
instructionsEl.appendChild(document.createTextNode("Uncheck all boxes to show all languages."));
instructionsEl.appendChild(
document.createTextNode("Uncheck all boxes to show all languages."));
//switch the ToC to multi-column mode
//switch the ToC to multi-column mode
Line 233: Line 276:
//put all language sections inside of a <div>
//put all language sections inside of a <div>
var aEls = document.getElementsByTagName("a");
var spanEls = document.getElementsByTagName("span");
var languages = CompareGetLanguages();
var languages = CompareGetLanguages();
var divEl = null;
var divEl = null;
for(var a = 0; a < aEls.length; ++a)
for(var s = 0; s < spanEls.length; ++s)
{
{
if(aEls[a].name && typeof languages[aEls[a].name] != "undefined")
if(typeof spanEls[s].id != "undefined" &&
typeof languages[spanEls[s].id] != "undefined")
{
{
//we can assume that this is a language section
//we can assume that this is a language section
//make a list of all of the elements between this <a> tag and the next one that has a name attribute
//make a list of all of the elements between this <span>
//tag and the next one that has a name attribute
divEl = aEls[a].parentNode.insertBefore(document.createElement("div"), aEls[a]);
divEl = spanEls[s].parentNode.parentNode.insertBefore(
var curEl = aEls[a].nextSibling;
divEl.appendChild(aEls[a].parentNode.removeChild(aEls[a]));
document.createElement("div"), spanEls[s].parentNode);
var curEl = spanEls[s].parentNode.nextSibling;
while(curEl && (!curEl.tagName || curEl.tagName.toLowerCase() != "a" || !curEl.name || typeof languages[curEl.name] == "undefined"))
divEl.appendChild(spanEls[s].parentNode.parentNode.removeChild(
spanEls[s].parentNode));
while(curEl && (!curEl.tagName || curEl.tagName.toLowerCase() != "h2"))
{
{
var newCurEl = curEl.nextSibling;
var newCurEl = curEl.nextSibling;
Line 256: Line 303:
{
{
//add a float clearing div
//add a float clearing div
var clearEl = divEl.parentNode.insertBefore(document.createElement("div"), divEl.nextSibling);
var clearEl = divEl.parentNode.insertBefore(
document.createElement("div"), divEl.nextSibling);
clearEl.style.clear = "both";
clearEl.style.clear = "both";
}
}
//and refresh the display for good measure (sometimes browsers like to save <input> states between reloads)
//and refresh the display for good measure (sometimes
//browsers like to save <input> states between reloads)
CompareRefresh();
CompareRefresh();
//add an event listener for window resizing
if(window.addEventListener)
{
window.addEventListener("resize", CompareRefresh, false);
}
else if(document.addEventListener)
{
document.addEventListener("resize", CompareRefresh, false);
}
else if(window.attachEvent)
{
window.attachEvent("onresize", CompareRefresh);
}
}
}
}
}
Line 275: Line 338:
for(var i = 0; i < inputEls.length; ++i)
for(var i = 0; i < inputEls.length; ++i)
{
{
//if it's one of the ones we added earlier, log the checked status to the languages array for later use
//if it's one of the ones we added earlier, log the
//checked status to the languages array for later use
if(inputEls[i].getAttribute("name").substring(0, ("CompareLanguage").length) == "CompareLanguage")
if(inputEls[i].getAttribute("name").substring(0,
("CompareLanguage").length) == "CompareLanguage")
{
{
languages[inputEls[i].value] = inputEls[i].checked;
languages[inputEls[i].value] = inputEls[i].checked;
Line 306: Line 371:
//now, find all <a> tags with name attributes
//now, find all <a> tags with name attributes
var aEls = document.getElementsByTagName("a");
var spanEls = document.getElementsByTagName("span");
for(var a = 0; a < aEls.length; ++a)
for(var s = 0; s < spanEls.length; ++s)
{
{
if(aEls[a].name && typeof languages[aEls[a].name] != "undefined")
if(typeof spanEls[s].className != "undefined" &&
spanEls[s].className.indexOf("mw-headline") >= 0 &&
typeof spanEls[s].id != "undefined" &&
typeof languages[spanEls[s].id] != "undefined")
{
{
var anchorName = spanEls[s].id;
var parentDiv = spanEls[s].parentNode.parentNode;
//we can assume that this is a language section
//we can assume that this is a language section
//check to see if we're displaying in side-by-side mode, regular mode, or not at all
//check to see if we're displaying in side-by-side mode,
//regular mode, or not at all
if(numChecked < 1 || (languages[aEls[a].name] && (navigator.appVersion.indexOf("MSIE 5.") >= 0 || navigator.appVersion.indexOf("MSIE 6.") >= 0 || navigator.appVersion.indexOf("MSIE 7.") >= 0)))
if(numChecked < 1 || (languages[anchorName] &&
(navigator.appVersion.indexOf("MSIE 5.") >= 0 ||
navigator.appVersion.indexOf("MSIE 6.") >= 0 ||
navigator.appVersion.indexOf("MSIE 7.") >= 0)))
{
{
//enable full-width mode
//enable full-width mode
aEls[a].parentNode.style.display = "block";
parentDiv.style.display = "block";
aEls[a].parentNode.style.cssFloat = "none";
parentDiv.style.cssFloat = "none";
aEls[a].parentNode.style.width = "auto";
parentDiv.style.width = "auto";
aEls[a].parentNode.style.marginRight = 0;
parentDiv.style.marginRight = 0;
}
}
else if(languages[aEls[a].name])
else if(languages[anchorName])
{
{
//enable side-by-side mode
//enable side-by-side mode
aEls[a].parentNode.style.display = "inline-block";
parentDiv.style.display = "inline-block";
aEls[a].parentNode.style.verticalAlign = "top";
parentDiv.style.verticalAlign = "top";
aEls[a].parentNode.style.marginRight = "20px";
parentDiv.style.marginRight = "20px";
//find the width for this language
//find the width for this language
var preEls = aEls[a].parentNode.getElementsByTagName("pre");
var preEls = parentDiv.getElementsByTagName("pre");
var maxWidth = 0;
var maxWidth = 0;
for(var p = 0; p < preEls.length; ++p)
for(var p = 0; p < preEls.length; ++p)
Line 337: Line 412:
if(GetElWidth(preEls[p]) == oldWidth)
if(GetElWidth(preEls[p]) == oldWidth)
{
{
//assume it's either wider than the window or IE where they don't shrink
//assume it's either wider than the
//window or IE where they don't shrink
//arbitrarily set to 45% width
//arbitrarily set to 45% width
maxWidth = Math.max(GetElWidth(aEls[a].parentNode.parentNode) * 0.45, maxWidth);
maxWidth = Math.max(
GetElWidth(parentDiv.parentNode) * 0.45,
maxWidth);
}
}
else
else
{
{
maxWidth = Math.max(GetElWidth(preEls[p]), maxWidth);
maxWidth = Math.max(GetElWidth(preEls[p]),
maxWidth);
}
}
preEls[p].style.cssFloat = "none";
preEls[p].style.cssFloat = "none";
Line 351: Line 430:
if(!maxWidth)
if(!maxWidth)
{
{
var h2Els = aEls[a].parentNode.getElementsByTagName("h2");
var h2Els = parentDiv.getElementsByTagName("h2");
if(h2Els.length > 0)
if(h2Els.length > 0)
{
{
Line 360: Line 439:
if(GetElWidth(h2Els[p]) == oldWidth)
if(GetElWidth(h2Els[p]) == oldWidth)
{
{
//assume it's either wider than the window or IE where they don't shrink
//assume it's either wider than the
//window or IE where they don't shrink
//arbitrarily set to 45% width
//arbitrarily set to 45% width
maxWidth = Math.max(GetElWidth(aEls[a].parentNode.parentNode) * 0.45, maxWidth);
maxWidth = Math.max(
GetElWidth(parentDiv.parentNode) * 0.45,
maxWidth);
}
}
else
else
Line 379: Line 461:
//set the container <div> to a size just a little bit larger
//set the container <div> to a size just a little bit larger
aEls[a].parentNode.style.width = (maxWidth + codeMargin) + "px";
parentDiv.style.width = (maxWidth + codeMargin) + "px";
}
}
else
else
{
{
//hide it entirely
//hide it entirely
aEls[a].parentNode.style.display = "none";
parentDiv.style.display = "none";
}
}
}
}
Line 408: Line 490:
window.onload = CompareActivate;
window.onload = CompareActivate;
}
}
</pre>
//</lang>

Latest revision as of 21:34, 2 July 2011

//<lang javascript> /*======================================== This comparison script was written by Tyrok1. Tested in: - Fe 7.0.520.0 - Fx 3.6.11 - IE 6, 7, 8 ========================================*/ function GetElWidth(el) { return (el.clientWidth ? el.clientWidth : el.offsetWidth); }

function ToCMulticolumn() { var gutter = 10;

//split the ToC into multiple columns var tocEl = document.getElementById("toc"); var ulElsNodeList = tocEl.getElementsByTagName("ul"); if(tocEl && ulElsNodeList.length > 0) { //limit what we're looking at to only what's directly in //the main list, and move from NodeList objects to Arrays var ulEls = [ulElsNodeList[0]]; for(var u = 1; u < ulElsNodeList.length; ++u) { if(ulElsNodeList[u].parentNode == ulElsNodeList[0].parentNode) { ulEls[ulEls.length] = ulElsNodeList[u]; } } var liElsNodeList = tocEl.getElementsByTagName("li"); var liEls = new Array(); for(var l = 0; l < liElsNodeList.length; ++l) { for(u = 0; u < ulEls.length; ++u) { if(liElsNodeList[l].parentNode == ulEls[u]) { liEls[liEls.length] = liElsNodeList[l]; break; } } }

//show all of the

    tags so we can get their items' ideal widths if(ulEls[0].style.display && ulEls[0].style.display == "none") { ulEls[0].oldDisplay = "none"; } else { ulEls[0].oldDisplay = "inline-block"; } for(u = 0; u < ulEls.length; ++u) { ulEls[u].style.display = "inline-block"; } //find the widest item and use that to set up an ideal number of columns var maxWidth = 0; for(l = 0; l < liEls.length; ++l) { if(!liEls[l].initialWidth) { liEls[l].initialWidth = GetElWidth(liEls[l]); } maxWidth = Math.max(liEls[l].initialWidth, maxWidth); if(navigator.appVersion.indexOf("MSIE 5.") >= 0 || navigator.appVersion.indexOf("MSIE 6.") >= 0 || navigator.appVersion.indexOf("MSIE 7.") >= 0) { liEls[l].style.display = "inline"; } } //add in the gutter maxWidth += gutter; //figure out the ideal number of columns tocEl.style.width = "100%"; var idealColumns = Math.min( Math.floor(GetElWidth(tocEl) / maxWidth), Math.floor(liEls.length / 3) + 1); if(navigator.appVersion.indexOf("MSIE 5.") >= 0 || navigator.appVersion.indexOf("MSIE 6.") >= 0 || navigator.appVersion.indexOf("MSIE 7.") >= 0) { idealColumns = 1; } //see if we've already got the ideal number of columns //if so, we don't need to change anything if(ulEls.length != idealColumns) { //split the list into multiple columns of width (95 / idealColumns)% //first, make sure we have enough lists to split into while(ulEls.length < idealColumns) { ulEls[ulEls.length] = ulEls[ulEls.length - 1].parentNode.insertBefore( document.createElement("ul"), ulEls[ulEls.length - 1].nextSibling); } //style the lists for(var c = 0; c < ulEls.length; ++c) { ulEls[c].style.display = "inline-block"; ulEls[c].style.cssFloat = "left"; ulEls[c].style.verticalAlign = "top"; ulEls[c].style.width = (95 / idealColumns) + "%"; } //sort the items into the lists for(l = 0; l < liEls.length; ++l) { liEls[l] = ulEls[ Math.floor(l / liEls.length * idealColumns) ].appendChild(liEls[l].parentNode.removeChild(liEls[l])); } //get rid of any unnecessary lists for(l = idealColumns; l < ulEls.length; ++l) { ulEls[l].parentNode.removeChild(ulEls[l]); } } //hide the instructions/lists if they're supposed to be hidden var insEl = document.getElementById("tocinstructions"); if(insEl) { insEl.style.display = (ulEls[0].oldDisplay.toLowerCase() == "none" ? "none" : "block"); } for(u = 0; u < ulEls.length; ++u) { ulEls[u].style.display = ulEls[0].oldDisplay; } //if we're setting this up for the first time... if(!window.toggleTocOld) { //change out the toggling function so it toggles all of the lists window.toggleTocOld = window.toggleToc; window.toggleUpdateVisibility = function() { var tocEl = document.getElementById("toc"); var ulEls = tocEl.getElementsByTagName("ul"); for(var u = 0; u < ulEls.length; ++u) { if(ulEls[0].style.display && ulEls[0].style.display == "none") { ulEls[u].style.display = "none" } else { ulEls[u].style.display = "inline-block" } } var el = document.getElementById("tocinstructions"); if(el) { if(ulEls[0].style.display && ulEls[0].style.display.toLowerCase() == "none") { el.style.display = "none"; } else { el.style.display = "block"; } } }; window.toggleToc = function() { toggleTocOld(); toggleUpdateVisibility(); }; //add an event handler so if the window's //resized the number of columns can change if(window.addEventListener) { window.addEventListener("resize", ToCMulticolumn, false); } else if(document.addEventListener) { document.addEventListener("resize", ToCMulticolumn, false); } else if(window.attachEvent) { window.attachEvent("onresize", ToCMulticolumn); } } } } function CompareActivate() { //check to see if we're looking at a task page var catLinksEl = document.getElementById("catlinks"); var isTask = false; if(catLinksEl) { var aEls = catLinksEl.getElementsByTagName("a"); for(var a = 0; a < aEls.length; ++a) { if(aEls[a].getAttribute("title") == "Category:Programming Tasks") { //it's a task isTask = true; break; } } } if(!isTask) { return; } //check to make sure we have a table of contents var tocEl = document.getElementById("toc"); if(tocEl) { //remove the extra show/hide button from the Contents area var tocTitleEl = document.getElementById("toctitle"); if(tocTitleEl) { var spanEls = tocTitleEl.getElementsByTagName("span"); var foundToggle = false; for(var s = 0; s < spanEls.length; ++s) { if(spanEls[s].className && spanEls[s].className.toLowerCase() == "toctoggle") { if(foundToggle) { spanEls[s].parentNode.removeChild(spanEls[s]); } foundToggle = true; } } } //find all of the links to language sections and add checkboxes var liEls = tocEl.getElementsByTagName("li"); for(var l = 0; l < liEls.length; ++l) { //add a checkbox with the language section's anchor name attribute //as its value for easier lookup in the refresh function var checkboxEl = document.createElement("input"); checkboxEl.setAttribute("type", "checkbox"); checkboxEl.setAttribute("name", "CompareLanguage" + l); checkboxEl.setAttribute("id", "CompareLanguage" + l); var href = liEls[l].getElementsByTagName("a")[0].getAttribute("href"); checkboxEl.setAttribute("value", href.substring(href.indexOf("#") + 1, href.length)); checkboxEl.onclick = CompareRefresh; liEls[l].insertBefore(checkboxEl, liEls[l].firstChild); } //add some instructions var toctitleEl = document.getElementById("toctitle"); var instructionsEl = toctitleEl.appendChild(document.createElement("p")); instructionsEl.setAttribute("id", "tocinstructions"); instructionsEl.appendChild( document.createTextNode("Check the boxes next to languages to compare them.")); instructionsEl.appendChild(document.createElement("br")); instructionsEl.appendChild( document.createTextNode("Uncheck all boxes to show all languages.")); //switch the ToC to multi-column mode ToCMulticolumn(); //put all language sections inside of a

    var spanEls = document.getElementsByTagName("span"); var languages = CompareGetLanguages(); var divEl = null; for(var s = 0; s < spanEls.length; ++s) { if(typeof spanEls[s].id != "undefined" && typeof languages[spanEls[s].id] != "undefined") { //we can assume that this is a language section //make a list of all of the elements between this //tag and the next one that has a name attribute divEl = spanEls[s].parentNode.parentNode.insertBefore( document.createElement("div"), spanEls[s].parentNode); var curEl = spanEls[s].parentNode.nextSibling; divEl.appendChild(spanEls[s].parentNode.parentNode.removeChild( spanEls[s].parentNode)); while(curEl && (!curEl.tagName || curEl.tagName.toLowerCase() != "h2")) { var newCurEl = curEl.nextSibling; divEl.appendChild(curEl.parentNode.removeChild(curEl)); curEl = newCurEl; }; } } if(divEl) { //add a float clearing div var clearEl = divEl.parentNode.insertBefore( document.createElement("div"), divEl.nextSibling); clearEl.style.clear = "both"; }

    //and refresh the display for good measure (sometimes //browsers like to save <input> states between reloads) CompareRefresh();

    //add an event listener for window resizing if(window.addEventListener) { window.addEventListener("resize", CompareRefresh, false); } else if(document.addEventListener) { document.addEventListener("resize", CompareRefresh, false); } else if(window.attachEvent) { window.attachEvent("onresize", CompareRefresh); } } }

    function CompareGetLanguages() { var tocEl = document.getElementById("toc"); var languages = new Array(); if(tocEl) { //find all of the checkboxes within the ToC var inputEls = tocEl.getElementsByTagName("input"); for(var i = 0; i < inputEls.length; ++i) { //if it's one of the ones we added earlier, log the //checked status to the languages array for later use if(inputEls[i].getAttribute("name").substring(0, ("CompareLanguage").length) == "CompareLanguage") { languages[inputEls[i].value] = inputEls[i].checked; } } } return languages; }

    function CompareRefresh() { //refresh the display of the language sections displayed under the ToC //first, check to see if we're looking at a task page var codeMargin = 20; var tocEl = document.getElementById("toc"); var languages = new Array(); var numChecked = 0; if(tocEl) { //count how many languages are checked languages = CompareGetLanguages(); for(var l in languages) { if(languages[l]) { ++numChecked; } }

    //now, find all <a> tags with name attributes var spanEls = document.getElementsByTagName("span"); for(var s = 0; s < spanEls.length; ++s) { if(typeof spanEls[s].className != "undefined" && spanEls[s].className.indexOf("mw-headline") >= 0 && typeof spanEls[s].id != "undefined" && typeof languages[spanEls[s].id] != "undefined") { var anchorName = spanEls[s].id; var parentDiv = spanEls[s].parentNode.parentNode;

    //we can assume that this is a language section //check to see if we're displaying in side-by-side mode, //regular mode, or not at all if(numChecked < 1 || (languages[anchorName] && (navigator.appVersion.indexOf("MSIE 5.") >= 0 || navigator.appVersion.indexOf("MSIE 6.") >= 0 || navigator.appVersion.indexOf("MSIE 7.") >= 0))) { //enable full-width mode parentDiv.style.display = "block"; parentDiv.style.cssFloat = "none"; parentDiv.style.width = "auto"; parentDiv.style.marginRight = 0; } else if(languages[anchorName]) { //enable side-by-side mode parentDiv.style.display = "inline-block"; parentDiv.style.verticalAlign = "top"; parentDiv.style.marginRight = "20px";

    //find the width for this language var preEls = parentDiv.getElementsByTagName("pre"); var maxWidth = 0; for(var p = 0; p < preEls.length; ++p) { var oldWidth = GetElWidth(preEls[p]); preEls[p].style.cssFloat = "left"; if(GetElWidth(preEls[p]) == oldWidth) { //assume it's either wider than the //window or IE where they don't shrink //arbitrarily set to 45% width maxWidth = Math.max( GetElWidth(parentDiv.parentNode) * 0.45, maxWidth); } else { maxWidth = Math.max(GetElWidth(preEls[p]), maxWidth); } preEls[p].style.cssFloat = "none"; }

    //if there are no code blocks, base it off of the

    if(!maxWidth) { var h2Els = parentDiv.getElementsByTagName("h2"); if(h2Els.length > 0) { //we have at least one h2 //use its width var oldWidth = GetElWidth(h2Els[p]); h2Els[0].style.cssFloat = "left"; if(GetElWidth(h2Els[p]) == oldWidth) { //assume it's either wider than the //window or IE where they don't shrink //arbitrarily set to 45% width maxWidth = Math.max( GetElWidth(parentDiv.parentNode) * 0.45, maxWidth); } else { maxWidth = GetElWidth(h2Els[0]); } h2Els[0].style.cssFloat = "none"; } else { //no clue what it should be //arbitrarily set it to 200 maxWidth = 200; } } //set the container
    to a size just a little bit larger

    parentDiv.style.width = (maxWidth + codeMargin) + "px"; } else { //hide it entirely parentDiv.style.display = "none"; } } } } }

    //register the comparison script with the window's load event if(window.addEventListener) { window.addEventListener("load", CompareActivate, false); } else if(window.attachEvent) { window.attachEvent("onload", CompareActivate); } else if(document.addEventListener) { document.addEventListener("load", CompareActivate, false); } else { window.onload = CompareActivate; } //</lang>