User:Yair rand/TabbedLanguages.js

// This is a modified version of User:Atelaes/TabbedLanguages.js var tabbedLanguages = []; var languageContainers=[]; var currentLanguageTab = 0; var languageHeaderEditButtons=[]; var tocLangSections; var languageLinks; var loadremovecatbuttons = true;

function makeLanguageTabs { if ((mw.config.get('wgNamespaceNumber') == 0 || mw.config.get('wgPageName') == "Wiktionary:Sandbox") && mw.config.get('wgAction') != 'edit') { importStylesheet("User:Yair_rand/TabbedLanguages.css") var languageContainer, li, language, toc = document.getElementById('toc'), catDiv = document.getElementById('catlinks'), isIE9; var bodyContent_ = document.getElementById('wikiPreview') || mw.util.$content[0]; // Dump everything into a documentfragment, to be put back at the end (this is somehow faster, I don't know why) var bodyContent=document.createDocumentFragment; while(bodyContent_.firstChild)bodyContent.appendChild(bodyContent_.firstChild); window.toggleLanguageTabs = function(language) {     // Find the destination language. for (var destinationLanguageTab = tabbedLanguages.length - 1; destinationLanguageTab >= 0; destinationLanguageTab--) { if(language.indexOf(tabbedLanguages[destinationLanguageTab]) == 0){ break; }       }      // Style the right toggle button, hide the old language section and show the new one, rm the old toc and add the new one. var languageButtons = document.getElementById('languageLinks').getElementsByTagName('span'); if(destinationLanguageTab >= 0){ languageButtons[currentLanguageTab].className = 'unselectedTab'; languageContainers[currentLanguageTab].style.display = 'none'; if (document.getElementById('toc')) { tocLangSections[currentLanguageTab].style.display='none'; tocLangSections[destinationLanguageTab].style.display='list-item'; }       currentLanguageTab = destinationLanguageTab languageButtons[destinationLanguageTab].className = 'selectedTab' languageContainers[currentLanguageTab].style.display = 'block' if(languageHeaderEditButtons.length){ languageLinks.removeChild(languageLinks.lastChild) languageLinks.appendChild(languageHeaderEditButtons[currentLanguageTab]) }       if(isIE9){ for(var ols = languageContainers[currentLanguageTab].getElementsByTagName('ol'), i = 0; i < ols.length; i++){ (function(i){setTimeout(function{ols[i].removeChild(ols[i].insertBefore(document.createElement('li'), ols[i].firstChild))},0)})(i) }         }        }      else if((language = language.replace(/\ /g, '_')) && document.getElementById(language) && document.getElementById(language).parentNode.parentNode.className == 'languageContainer'){ toggleLanguageTabs(document.getElementById(language).parentNode.parentNode.id.split('container')[0]) }     }    // Look through all the nodes in bodyContent, placing them in the correct language containers. for (var child = bodyContent.firstChild; child && (child.nodeName != "H2" || child.getElementsByTagName('span').length==0); child = child.nextSibling); for (child && child.className != 'printfooter' && child.className != 'catlinks'; child = child.nextSibling) { if (child.nodeName == 'H2') { var spans = child.getElementsByTagName('span'); if (spans.length != 0 && (language = (language = spans[1] && spans[1].className == 'mw-headline' && languageHeaderEditButtons.push(spans[0]) && spans[1]||spans[0]).innerText || language.textContent)) { tabbedLanguages.push(language); languageContainers.push(languageContainer = bodyContent.insertBefore(newNode('div', {'class' : 'languageContainer', 'id' : language + 'container'}), child)); bodyContent.removeChild(child); child = languageContainer }       }      else{ child.nodeName != "HR"?languageContainer.appendChild(child):bodyContent.removeChild(child); child = languageContainer }     }    if (toc) { VisibilityToggles.register('TOC',       function  {          toc.style.display='table';          },        function  {          toc.style.display='none';          }); }   if(tabbedLanguages.length > 0) { if (toc) { if(toc.getElementsByClassName){ tocLangSections = toc.getElementsByClassName('toclevel-1'); for (var c = 1; c < tocLangSections.length; c++) { tocLangSections[c].style.display='none' }         }        else{ tocLangSections = [] for (var c = 0, temptocbox = toc.getElementsByTagName('ul')[0]; c < temptocbox.childNodes.length; c++) { if(temptocbox.childNodes[c].nodeName == "LI") { if(tocLangSections.length) temptocbox.childNodes[c].style.display='none'; tocLangSections.push(temptocbox.childNodes[c]) }           }          }        }      // Make the toggle. languageLinks = newNode('div', {'id' : 'languageLinks'}); for (var b = 0; b < tabbedLanguages.length; b++) { language = tabbedLanguages[b]; languageLinks.appendChild(newNode('span', {'class' : (b?'un':'')+'selectedTab'}, newNode('a', language, {'href' : location.pathname + location.search + '#' + language}), ' ')); }     // If there are section edit links, add edit link, and a new language button. if (languageHeaderEditButtons.length) { if(window.addPOSHeader && window.setUpBoxToBeAdded) // this functionality requires adddefinition.js, editor.js, and TabbedLanguages.js at the same time languageLinks.appendChild(newNode('span', {'class': 'unselectedTab'}, newNode('a', '+', {'click':newLanguageTab,'title':'Add new language section'}))); languageLinks.appendChild(languageHeaderEditButtons[0]); }     for (var a = 0; a < languageContainers.length; a++) { languageContainer = languageContainers[a]; if (a == 0) { bodyContent.insertBefore(languageLinks, toc && toc.parentNode == bodyContent && toc || languageContainer); }       else { languageContainer.style.display = 'none'; }       // Put a container in each for categories. languageContainer.appendChild(newNode('div', languageContainer.id.split('container')[0] + ' categories: ', {'class' : 'catlinks'})); }     // Now for category sorting if(catDiv.firstChild) { var cats = catDiv.firstChild.getElementsByTagName('span'), catname; var langcurrent=0; while (cats.length > 0) { var z=0; catname = cats[z].getElementsByTagName('a')[0].innerHTML; while(catname.indexOf("derivations") > 0 && cats.length > z+1) { catname = cats[++z].getElementsByTagName('a')[0].innerHTML; }         if(catname.indexOf(tabbedLanguages[langcurrent+1])==0&&!/letter\snames$|script\scharacters$|mythology$/.test(catname)) {langcurrent+=1} while(z--+1){ var currentCatDiv = languageContainers[langcurrent].lastChild if (currentCatDiv.lastChild.nodeName == 'SPAN') { currentCatDiv.appendChild(document.createTextNode(' | ')) }           currentCatDiv.appendChild(cats[0]) }         }        }      if(mw.config.get('wgAction') == "view" && !/&printable=yes|&diff=|&oldid=/.test(location.search)) { for(z=0;z<languageContainers.length;z++) { addTabbedLanguageNewCatButton(z) }       if(loadremovecatbuttons == true){ window.Editor && (new Editor).withCurrentText(addRemoveCatButtons) }       }      catDiv.parentNode.removeChild(catDiv); bodyContent_.appendChild(bodyContent);bodyContent=bodyContent_; if(isIE9 = $.client.profile.name == "msie" && $.client.profile.versionNumber == 9){ // IE9 is EVIL tocLangSections = toc.getElementsByClassName('toclevel-1'); toggleLanguageTabs(tabbedLanguages[currentLanguageTab]) }     // 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 subsection or 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 (location.hash != '') { var hash = decodeURI(location.hash).substr(1); var destination = hash.replace(/_/g, ' '); toggleLanguageTabs(destination); if (document.getElementById(hash)) { resetHash }       else{ window.scrollY && window.scroll(0,0); }       }      else{ if(tabbedLanguages[0]!='Translingual' && tabbedLanguages[0]!='English' && 'localStorage' in window){ if($.inArray(localStorage.langTabPref, tabbedLanguages) != -1){ toggleLanguageTabs(tabbedLanguages[$.inArray(localStorage.langTabPref, tabbedLanguages)]) }         else if(localStorage.TargetedTranslations){ for(var tt = localStorage.TargetedTranslations.split("|")[0].split(";").concat($.grep(localStorage.TargetedTranslations.split("|")[1].replace(/[^;\/]+\//g,).split(";"),function(z){return z && z!="Latin" && z!="Hebrew" && z!="Arabic"})).concat(localStorage.TargetedTranslations.split("|")[1].replace(/\/[^;]+/g,).split(";")), i = 0; i < tt.length; i++){ if($.inArray(tt[i], tabbedLanguages) != -1){ toggleLanguageTabs(tabbedLanguages[$.inArray(tt[i], tabbedLanguages)]); break; }             }            }          }        }      if("onhashchange" in window){ window.onhashchange = hashToggleLT; }     else{ jQuery('#bodyContent a[href^='+location.pathname+location.search+'#]').click(function{setTimeout(hashToggleLT,10)}) }     if('localStorage' in window){ window.onunload=function{ if(tabbedLanguages[currentLanguageTab] && tabbedLanguages[currentLanguageTab] != 'English' && tabbedLanguages[currentLanguageTab] != 'Translingual'){ localStorage.langTabPref = tabbedLanguages[currentLanguageTab] }         }        }      }    else{ bodyContent_.appendChild(bodyContent);bodyContent=bodyContent_; }   }  }

function addTabbedLanguageNewCatButton(z) { function addTabbedLanguageCatForm { editor=new Editor; var addCatForm; new AdderWrapper(     editor,       {        'createForm':function{          return addCatForm = newNode('form',{'style':'display:inline;'}, newNode('input',{'name':'category'}), newNode('input',{'type':'submit', 'value':'Add'}), newNode('input',{'type':'button', 'value':'Cancel', 'click': function{addCatForm.style.display='none'}}), ' | '           )          },        'fields':{'category':function(txt,error){if(txt.indexOf('derivations') > -1){return error("Please add derivations categories via the etymology section.")};if(tabbedLanguages.length > z && txt.indexOf(tabbedLanguages[z+1]) ==0){return error("Please add categories to their proper sections.")};return util.validateNoWikisyntax('category', true)(txt, error)}},        'onsubmit':function(values,render){          render( + values.category + , function(res){ var newCat=newNode('span'); newCat.innerHTML=res + " | "; editor.addEdit({             'edit':function(wikitext){                return ccc=wikitext.replace(new RegExp("(((^|\n)==[^=][\\s\\S]*?){"+(z+1)+"}[\\s\\S]*?)(?=(\n|$))"),"$1\n["+"[Category:" + values.category + "]]")                },              'redo':function{addCatForm.parentNode.insertBefore(newCat,addCatForm);addCatForm.style.display='none'},              'undo':function{addCatForm.parentNode.removeChild(newCat);addCatForm.style.display='inline'},              'summary':'+['+'[Category:' + values.category + ']]'              }, newCat.firstChild) })         }      },      languageContainers[z].lastChild,      languageContainers[z].lastChild.lastChild      ) addCatForm.firstChild.focus } if(languageContainers[z].lastChild.lastChild.nodeName=="SPAN") languageContainers[z].lastChild.appendChild(document.createTextNode(' | ')); languageContainers[z].lastChild.appendChild(   newNode('a','(+)',{'click':addTabbedLanguageCatForm,'style':'cursor:pointer;','title':'Add a new category'})) }

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

function resetHash { location.hash = [location.hash, location.hash = ''][0] }

function newLanguageTab { languageLinks.lastChild.previousSibling.style.display='none' var newLanguageButton = languageLinks.insertBefore(newNode('form',{'style':'display:inline;','class':'unselectedTab'},newNode('input',{style:'color:#AAA;font-size:150%;'}),newNode('input',{type:'submit',value:'Add'}),newNode('input',{type:'button',click:function{languageLinks.removeChild(newLanguageButton);languageLinks.lastChild.previousSibling.style.display='inline'},value:'Cancel'})),languageLinks.lastChild.previousSibling) newLanguageButton.onsubmit = function{ newLanguageTab2(languageLinks.removeChild(newLanguageButton).firstChild.value); return false} newLanguageButton.firstChild.focus var langsuggestlist = "\nEnglish" + ('localStorage' in window && localStorage.langTabPref?'\n'+localStorage.langTabPref:''), TTlangs = ('localStorage' in window?localStorage.TargetedTranslations:getCookie('TargetedTranslations')); if(TTlangs){ langsuggestlist += "\n" + TTlangs.split("|")[0].replace(/;/g, "\n") + "\n" + TTlangs.split("|")[1].replace(/[^;\/]+\//g,'').replace(/;/g,'\n') } // note: find or build some autocomplete function so that I don't have to rewrite it for every script newLanguageButton.firstChild.onkeyup = function(e){ if(this.value.charAt(0)!=this.value.charAt(0).toUpperCase) this.value = this.value.charAt(0).toUpperCase + this.value.substr(1); e=(e||event).keyCode; if(!(e>=33&&e<=40)&&e!=8&&e!=46&&e!=27&&e!=16&&this.value){ if(langsuggestlist.indexOf('\n'+this.value) > -1){ if(this.setSelectionRange) this.setSelectionRange([this.value.length, this.value = langsuggestlist.match(RegExp(this.value+"[^\n]*"))][0], this.value.length); else if(this.createTextRange){ var z = this.createTextRange; z.moveEnd('character', 0-z.move('character', [this.value.length, this.value = langsuggestlist.match(RegExp(this.value+"[^\n]*"))][0]) + this.value.length); z.select }       }      }    }  function newLanguageTab2(languageName) {   editor=new Editor; for(var tosearchfrom = languageContainers[languageContainers.length - 1].lastChild; tosearchfrom && !/h\d/i.test(tosearchfrom.nodeName); ) {tosearchfrom = tosearchfrom.previousSibling} var findnumberofheaders = Number(tosearchfrom.firstChild.getElementsByTagName('a')[0].href.split("&section=")[1]) var newbutton = newNode('span',newNode('a', languageName, {'href': '#' + languageName, 'click':function{if(!"onhashchange" in window){setTimeout(hashToggleLT,10)}}})) var newsection = newNode('div', {'class':'languageContainer', 'id':languageName+"container"},newNode('h3',{'style':'display:none;'},newNode('span',{'class':'editsection'},newNode('a',{'href':'&section='+(findnumberofheaders+1)})),'...'),newNode('div', languageName+' categories: ', {'class':'catlinks'})) var toc=document.getElementById('toc')?document.getElementById('toc').getElementsByTagName('ul')[0]:null editor.addEdit({     edit:function(wikitext){return ccc=wikitext+"\n{\{rfc-auto}}\n\n\n=="+languageName+"==\n"},      redo:function{        languageContainers.push(bodyContent.insertBefore(newsection, languageContainers[languageContainers.length-1].nextSibling))        if(languageLinks==newLanguageButton.parentNode)languageLinks.removeChild(newLanguageButton);        tabbedLanguages.push(languageName);        languageLinks.insertBefore(newbutton, languageLinks.lastChild.previousSibling)        languageHeaderEditButtons.push(newNode('span',{'class':'editsection'},newNode('a',{href:'&section='+(findnumberofheaders+1)})))        toc && toc.appendChild(newNode('li',{'class':'toclevel-1'}));        if(toc && tocLangSections.push)tocLangSections.push(toc.lastChild);        location.hash = '';        toggleLanguageTabs(languageName);        languageLinks.lastChild.previousSibling.style.display='inline' },     undo:function{ toggleLanguageTabs(tabbedLanguages[tabbedLanguages.length-2]) bodyContent.removeChild(languageContainers.pop) tabbedLanguages.pop languageLinks.removeChild(newbutton) languageHeaderEditButtons.pop if(toc && tocLangSections.push)tocLangSections.pop; toc && toc.removeChild(toc.lastChild); languageLinks.lastChild.previousSibling.style.display='none' languageLinks.insertBefore(newLanguageButton, languageLinks.lastChild.previousSibling) },     summary:"+section "+languageName },newsection)   editor.withCurrentText(function{ addPOSHeader(true) currentBoxToBeAdded.style.display='none'; newsection.insertBefore(currentBoxToBeAdded.firstChild, newsection.lastChild).firstChild.focus addTabbedLanguageNewCatButton(languageContainers.length-1) }) } }

function addRemoveCatButtons(res) { function addRemoveCatButton(qq) { qq.appendChild(newNode('a', '(−)', {style:'padding-left:4px; cursor: pointer;',title:'Remove this category',click:function{ editor=new Editor; editor.addEdit({     edit:function(wikitext){return ccc=wikitext.replace(RegExp("\\[\\\\|[^\\+\\]\\])"),"").replace(/\n\n\n/g,"\n\n")},      redo:function{qq.lastChild.style.display=qq.lastChild.previousSibling.style.display='none';qq.style.border="2px #F00 dashed";qq.style.opacity="0.6";qq.style.backgroundColor="#FEE"}, // not going to bother with opacity for IE bc it breaks everything else      undo:function{qq.lastChild.style.display=qq.lastChild.previousSibling.style.display='inline';qq.style.border="";qq.style.opacity="";qq.style.backgroundColor=""},      summary:"-["+"[Category:"+qq.firstChild.innerHTML+"]]",      after_save:function{        qq.style.backgroundColor="#F00";        setTimeout(function{qq.parentNode.removeChild(qq.nextSibling);qq.parentNode.removeChild(qq)}, 400)        }      }) }})) qq.appendChild(newNode('a', '(±)', {style:'padding-left:4px; cursor: pointer;',title:'Modify',click:function{ qq.firstChild.style.display=qq.lastChild.style.display=qq.lastChild.previousSibling.style.display='none'; editor=new Editor; var addCatForm; new AdderWrapper(     editor,       {        'createForm':function{          return addCatForm = newNode('form',{'style':'display:inline;'}, newNode('input',{'name':'category',value:qq.firstChild.innerHTML}), newNode('input',{'type':'submit', 'value':'Change'}), newNode('input',{'type':'button', 'value':'Cancel', 'click': function{qq.removeChild(addCatForm);qq.firstChild.style.display='inline';qq.lastChild.style.display=qq.lastChild.previousSibling.style.display='inline';}}) )         },        'fields':{'category':function(txt,error){if(txt.indexOf('derivations') > -1){return error("Please add derivations categories via the etymology section.")};return util.validateNoWikisyntax('category', true)(txt, error)}},        'onsubmit':function(values,render){          render( + values.category + , function(res){ var newCat=newNode('span'); newCat.innerHTML=res; editor.addEdit({             'edit':function(wikitext){                return ccc=wikitext.replace(new RegExp("\\[\\\\)"),"["+"[Category:" + values.category+"$1")                },              'redo':function{qq.insertBefore(newCat,addCatForm);addCatForm.style.display='none'},              'undo':function{qq.removeChild(newCat);addCatForm.style.display='inline'},              'summary':'['+'[Category:' + qq.firstChild.innerHTML + ']] > ['+'[Category:' + values.category + ']]'              }, newCat) })         }      },      qq) addCatForm.firstChild.focus }})) } for(var i = 0; i < languageContainers.length; i++){ for(var ii = 0, q = languageContainers[i].lastChild.getElementsByTagName('span'); ii < q.length; ii++){ if(RegExp("\\[\\[[Cc]ategory:"+q[ii].firstChild.innerHTML+"[\\]\\|]").test(res)){     addRemoveCatButton(q[ii])      }    }  } }

jQuery(document).ready( makeLanguageTabs );