User:Tyrok1/monobook.js: Difference between revisions
Content added Content deleted
m (Changed capitalization of ToC) |
No edit summary |
||
Line 5: | Line 5: | ||
Fe 4.0.280. |
Fe 4.0.280. |
||
========================================*/ |
========================================*/ |
||
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 <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"); |
|||
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.floor(GetElWidth(tocEl) / maxWidth); |
|||
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) |
|||
{ |
|||
ulEls[u].style.display = (ulEls[0].style.display && ulEls[0].style.display == "none" ? "none" : "inline-block"); |
|||
} |
|||
var el = document.getElementById("tocinstructions"); |
|||
if(el) |
|||
{ |
|||
el.style.display = (ulEls[0].style.display && ulEls[0].style.display.toLowerCase() == "none" ? "none" : "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() |
function CompareActivate() |
||
{ |
{ |
||
//check to see if we're looking at a task page |
//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"); |
var tocEl = document.getElementById("toc"); |
||
if(tocEl) |
if(tocEl) |
||
{ |
{ |
||
//remove the extra show/hide button from the Contents area |
|||
//add some instructions |
|||
var |
var tocTitleEl = document.getElementById("toctitle"); |
||
if(tocTitleEl) |
|||
var instructionsEl = toctitleEl.appendChild(document.createElement("p")); |
|||
{ |
|||
instructionsEl.appendChild(document.createTextNode("Check the boxes next to languages to compare them.")); |
|||
var spanEls = tocTitleEl.getElementsByTagName("span"); |
|||
instructionsEl.appendChild(document.createElement("br")); |
|||
var foundToggle = false; |
|||
instructionsEl.appendChild(document.createTextNode("Uncheck all boxes to show all languages.")); |
|||
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 |
//find all of the links to language sections and add checkboxes |
||
var liEls = tocEl.getElementsByTagName("li"); |
var liEls = tocEl.getElementsByTagName("li"); |
||
for(var l = 0; l < liEls.length; ++l) |
for(var l = 0; l < liEls.length; ++l) |
||
Line 31: | Line 218: | ||
checkboxEl.onclick = CompareRefresh; |
checkboxEl.onclick = CompareRefresh; |
||
liEls[l].insertBefore(checkboxEl, liEls[l].firstChild); |
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 <div> |
|||
var aEls = document.getElementsByTagName("a"); |
|||
var languages = CompareGetLanguages(); |
|||
var divEl = null; |
|||
for(var a = 0; a < aEls.length; ++a) |
|||
{ |
|||
if(aEls[a].name && typeof languages[aEls[a].name] != "undefined") |
|||
{ |
|||
//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 |
|||
divEl = aEls[a].parentNode.insertBefore(document.createElement("div"), aEls[a]); |
|||
var curEl = aEls[a].nextSibling; |
|||
divEl.appendChild(aEls[a].parentNode.removeChild(aEls[a])); |
|||
while(curEl && (!curEl.tagName || curEl.tagName.toLowerCase() != "a" || !curEl.name || typeof languages[curEl.name] == "undefined")) |
|||
{ |
|||
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"; |
|||
} |
} |
||
Line 38: | Line 264: | ||
} |
} |
||
function |
function CompareGetLanguages() |
||
{ |
{ |
||
//refresh the display of the language sections displayed under the ToC |
|||
//first, check to see if we're looking at a task page |
|||
var tocEl = document.getElementById("toc"); |
var tocEl = document.getElementById("toc"); |
||
var languages = new Array(); |
var languages = new Array(); |
||
var numChecked = 0; |
|||
if(tocEl) |
if(tocEl) |
||
{ |
{ |
||
Line 55: | Line 278: | ||
{ |
{ |
||
languages[inputEls[i].value] = inputEls[i].checked; |
languages[inputEls[i].value] = inputEls[i].checked; |
||
numChecked += (inputEls[i].checked ? 1 : 0); |
|||
} |
} |
||
} |
} |
||
} |
|||
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 |
//now, find all <a> tags with name attributes |
||
var aEls = document.getElementsByTagName("a"); |
var aEls = document.getElementsByTagName("a"); |
||
Line 65: | Line 311: | ||
{ |
{ |
||
//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 |
|||
//make a list of all of the elements between this <a> tag and the next one that has a name attribute |
|||
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))) |
|||
var topicEls = new Array(); |
|||
var curEl = aEls[a].nextSibling; |
|||
while(curEl && (!curEl.tagName || curEl.tagName.toLowerCase() != "a" || !curEl.name || typeof languages[curEl.name] == "undefined")) |
|||
{ |
{ |
||
//enable full-width mode |
|||
topicEls[topicEls.length] = curEl; |
|||
aEls[a].parentNode.style.display = "block"; |
|||
curEl = curEl.nextSibling; |
|||
aEls[a].parentNode.style.cssFloat = "none"; |
|||
}; |
|||
aEls[a].parentNode.style.width = "auto"; |
|||
aEls[a].parentNode.style.marginRight = 0; |
|||
//either show or hide them depending on the language's checked status (of if none are checked, display all) |
|||
} |
|||
for(var e = 0; e < topicEls.length; ++e) |
|||
else if(languages[aEls[a].name]) |
|||
{ |
{ |
||
//enable side-by-side mode |
|||
if(topicEls[e].tagName && topicEls[e].style) |
|||
aEls[a].parentNode.style.display = "inline-block"; |
|||
aEls[a].parentNode.style.verticalAlign = "top"; |
|||
aEls[a].parentNode.style.marginRight = "20px"; |
|||
//find the width for this language |
|||
var preEls = aEls[a].parentNode.getElementsByTagName("pre"); |
|||
var maxWidth = 0; |
|||
for(var p = 0; p < preEls.length; ++p) |
|||
{ |
{ |
||
var oldWidth = GetElWidth(preEls[p]); |
|||
topicEls[e].style.display = (numChecked < 1 || languages[aEls[a].name] ? "" : "none"); |
|||
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(aEls[a].parentNode.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 <h2> |
|||
if(!maxWidth) |
|||
{ |
|||
var h2Els = aEls[a].parentNode.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(aEls[a].parentNode.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 <div> to a size just a little bit larger |
|||
aEls[a].parentNode.style.width = (maxWidth + codeMargin) + "px"; |
|||
} |
|||
else |
|||
{ |
|||
//hide it entirely |
|||
aEls[a].parentNode.style.display = "none"; |
|||
} |
} |
||
} |
} |