User:Tezamen/scripts/TabbedLanguages.js

var tabbedLanguages = []; var tabLangSectionNums = {}; var tabLangTOC = {};

/* * Modelled after function described at http://robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/ */

if (document.getElementsByClassName == undefined) { function homeBrewElementsByClassName(className) { var child; var results = []; var allChildren = this.getElementsByTagName('*'); for (var a=0; a<allChildren.length; a++) { child = allChildren[a]; childClass = child.className; regexTest = new RegExp('(^|\\s)' + className + '(\\s|$)'); if (regexTest.test(childClass)) { results.push(child); }     }    return results; }   Document.prototype.getElementsByClassName = homeBrewElementsByClassName; Element.prototype.getElementsByClassName = homeBrewElementsByClassName; }

/* *Taken from https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/indexOf */

if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(elt /*, from*/) {   var len = this.length >>> 0;

var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) from += len;

for (from < len; from++) {     if (from in this &&          this[from] === elt) return from; }   return -1; }; } function makeLanguageTabs { if (wgNamespaceNumber == 0) { // Start by looking at all the L2 headers, which, in the main namespace, should all be languages. // Generate containers, placed immediately before the headers, // and create a list of all the languages the page contains. // Also, remember the section numbers of the edit links, so we can recreate them after they're nuked. var languageContainer, languageContainers, li, languageLinks, toc; var EditSectionNumber = false; var language = false; var headerLanguageSection = false; var tabbedTOCPrefs = 'sectioned'; //Gotta find a way to institute a pref about that. var bodyContent = document.getElementById('bodyContent'); for (var child = bodyContent.firstChild; child != null; child = child.nextSibling) { if (child.nodeName.toUpperCase == 'H2') { EditSectionNumber = false; language = false; headerLanguageSection = false; var spans = child.getElementsByTagName('span'); if (spans[1] && spans[1].className == 'mw-headline') { headerLanguageSection = spans[1]; EditSectionNumber = spans[0].getElementsByTagName('a')[0].href.split('section=')[1]; }       else if (spans[0] && spans[0].className == 'mw-headline') { headerLanguageSection = spans[0]; }       if (headerLanguageSection) { if (headerLanguageSection.getElementsByTagName('a').length > 0) { language = headerLanguageSection.getElementsByTagName('a')[0].innerHTML; headerLanguageSection.innerHTML = ''; }         else { language = headerLanguageSection.innerHTML; headerLanguageSection.innerHTML = ''; }         }        if (language) { tabbedLanguages.push(language); languageContainer = newNode('div', {'class' : 'languageContainer', 'id' : language + 'container'}); bodyContent.insertBefore(languageContainer, child); if (EditSectionNumber) { tabLangSectionNums[language] = EditSectionNumber; }         }        }      if (document.getElementById('toc')) { toc = document.getElementById('toc'); tocLangSections = toc.getElementsByClassName('toclevel-1'); for (var c = 0; c < tocLangSections.length; c++) { if (tocLangSections[c].className.split('tocsection-')[1] == tabLangSectionNums[language]) { tabLangTOC[language] = tocLangSections[c]; tocLangSections[c].parentNode.removeChild(tocLangSections[c]); }         }        }      }    if (document.getElementById('toc')) { var throwAway = VisibilityToggles.register('TOC',       function show {          addCSSRule('#toc', 'display:table');          },        function hide {          addCSSRule('#toc', 'display:none');          }); }   // Make the toggle. languageLinks = newNode('div', {'id' : 'languageLinks'}); for (var b = 0; b < tabbedLanguages.length; b++) { language = tabbedLanguages[b]; languageLink = newNode('a', language, {'href' : '#' + language}); languageLinks.appendChild(newNode('span', languageLink, {'class' : 'unselectedTab'})); languageLinks.appendChild(newNode('wbr')); }   // If there are section edit links, reproduce them, within a non-float container to make room. if (EditSectionNumber) { var LLEditSection = newNode('span', '[', newNode('a', 'edit', {'href' : 'emptyURL'}), ']', {'class' : 'editsection'}); languageLinks.appendChild(newNode('span', LLEditSection, {'class' : 'LLeditContainer'})); }   //Make the toggle so pretty that you want to walk over and buy it a drink. if (skin == 'vector') { addCSSRule('#languageLinks .unselectedTab', 'height:2.5em; padding:1.25em 0 .5em;\     background-image:url("http://bits.wikimedia.org/skins-1.5/vector/images/tab-normal-fade.png?1"); \      background-position:left bottom; background-repeat:repeat-x;'); addCSSRule('#languageLinks .selectedTab', 'height:2.5em; padding:1.25em 0 .5em;'); addCSSRule('#languageLinks .selectedTab a', 'cursor:pointer; color:#333333; height:2.5em; padding-left:0.4em; \     padding-right:0.4em; line-height:3.1em; white-space:nowrap; padding-top:1.25em; padding-bottom:.5em; \      background-image:url("http://bits.wikimedia.org/skins-1.5/vector/images/tab-break.png?1"); \      background-position:right bottom; background-repeat:no-repeat;'); addCSSRule('#languageLinks .unselectedTab a', 'cursor:pointer; color:#0645AD; height:2.5em; padding-left:0.4em; \     padding-right:0.4em; line-height:3.1em; white-space:nowrap;  padding-top:1.25em; padding-bottom:.5em; \      background-image:url("http://bits.wikimedia.org/skins-1.5/vector/images/tab-break.png?1"); \      background-position:right bottom; background-repeat:no-repeat;'); addCSSRule('.LLEditContainer', 'width : 3em;'); }   else { addCSSRule('#languageLinks .unselectedTab', 'line-height : 1.5em; display : inline; padding : 0 0.5em; \     border : 1px solid #AAAAAA; background : #E8E8E8; white-space:nowrap;'); addCSSRule('#languageLinks .selectedTab', 'line-height : 1.5em; display : inline; padding : 0 0.5em; \     border : 1px solid #AAAAAA; border-bottom : none; background : white; white-space:nowrap'); addCSSRule('#languageLinks a', 'color : #0645AD'); }   // Finally, stuff all the content into the appropriate language container. languageContainers = document.getElementsByClassName('languageContainer'); var neighbor; for (var a = 0; a < languageContainers.length; a++) { languageContainer = languageContainers[a]; if (a == 0) { bodyContent.insertBefore(languageLinks, languageContainer); }     else { languageContainer.style.display = 'none'; }     while (true) { neighbor = languageContainer.nextSibling; if (!neighbor) { break; }       else if (neighbor.className == 'languageContainer') { break; }       else if (neighbor.className == 'printfooter' || neighbor.className == 'catlinks') { break; }       else if (neighbor.nodeName.toUpperCase == 'HR') { neighbor.parentNode.removeChild(neighbor); }       else if (neighbor.nodeName.toUpperCase == 'H2') { neighbor.parentNode.removeChild(neighbor); }       else { languageContainer.appendChild(neighbor); }            }      // Put a container in each for categories. These will be populated later. languageContainer.appendChild(newNode('div', newNode('text', languageContainer.id.split('container')[0] + ' categories: '), {'class' : 'catlinks'})); }   // Now for category sorting, courtesy of Yair rand. var catDiv = document.getElementById('catlinks'); var cats, catname; var catSections = catDiv.getElementsByTagName('div'); for (var d=0; d 0) { z=0; catname = cats[z].getElementsByTagName('a')[0].innerHTML; while(catname.match(/derivations/)) { z+=1; catname = cats[z].getElementsByTagName('a')[0].innerHTML; }       if(catname.match(new RegExp("^"+tabbedLanguages[langcurrent+1]))&&!catname.match(/letter\snames$/)&&!catname.match(/script\scharacters$/)) {langcurrent+=1} var currentCatDiv = languageContainers[langcurrent].getElementsByClassName('catlinks')[0] if (currentCatDiv.lastChild.nodeName.toUpperCase == 'SPAN') { currentCatDiv.appendChild(newNode('text', ' | ')) }       languageContainers[langcurrent].getElementsByClassName('catlinks')[0].appendChild(cats[0]); }     }    catDiv.parentNode.removeChild(catDiv); // If there's a location hash, the window may have scrolled down before we got a chance to reorganize everything. // If the destination was a sense id, switch to the right tab, and rescroll. // If it was simply a language, switch to the appropriate tab, and scroll back up. // If it was anything else (e.g. #Noun, #Etymology 1), switch to the first tab, and try scrolling to it. // Note that the above method is not reliable, as the link author may have intended the "noun" of a different language. // However, it's unreliable anyway, even if tabbed languages does make it less reliable. if (window.location.hash != '') { var hash = decodeURI(window.location.hash).substr(1); if (hash.indexOf('-') > -1) { var destination = hash.split('-')[0].replace('_', ' '); toggleLanguageTabs(destination); window.location.hash = window.location.hash; }     else if (tabbedLanguages.indexOf(hash.replace('_', ' ')) > -1) { var destination = hash.replace('_', ' '); toggleLanguageTabs(destination); if (window.scrollY) { window.scroll(0,0); }       }      else { toggleLanguageTabs(tabbedLanguages[0]); window.location.hash = window.location.hash; }     }    else { toggleLanguageTabs(tabbedLanguages[0]); }   window.onhashchange = hashToggleLT; } }

function hashToggleLT { var destination = decodeURI(window.location.hash.substr(1)).replace('_', ' '); toggleLanguageTabs(destination); }

function toggleLanguageTabs(language) { if (tabbedLanguages.indexOf(language) != -1) { var languageButtons = document.getElementById('languageLinks').getElementsByTagName('span'); for (var b = 0; b < languageButtons.length; b++) { if (languageButtons[b].firstChild.innerHTML == language) { languageButtons[b].className = 'selectedTab'; }     else if (languageButtons[b].className == 'selectedTab') { languageButtons[b].className = 'unselectedTab'; }     }    var languageContainers = document.getElementsByClassName('languageContainer'); for (var a = 0; a < languageContainers.length; a++) { if (languageContainers[a].id.indexOf(language) != 0) { languageContainers[a].style.display = 'none'; }     else { languageContainers[a].style.display = 'block'; }     }    if (document.getElementById('languageLinks').getElementsByClassName('editsection')[0] != undefined) { var editSection = document.getElementById('languageLinks').getElementsByClassName('editsection')[0]; var editSectionHref = '/w/index.php?title=' + wgPageName + '&action=edit&section=' + tabLangSectionNums[language]; editSection.getElementsByTagName('a')[0].href = editSectionHref; }   if (document.getElementById('toc')) { var emptyTOC = document.getElementById('toc').getElementsByTagName('ul')[0]; emptyTOC.innerHTML = ''; emptyTOC.appendChild(tabLangTOC[language].cloneNode(true)); }   }    }

$( makeLanguageTabs );