User:Yair rand/TabbedLanguages.js
Jump to navigation
Jump to search
Note: You may have to bypass your browser’s cache to see the changes. In addition, after saving a sitewide CSS file such as MediaWiki:Common.css, it will take 5-10 minutes before the changes take effect, even if you clear your cache.
- Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
- Konqueror and Chrome: click Reload or press F5;
- Opera: clear the cache in Tools → Preferences;
- Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.
- This script lacks a documentation subpage. Please create it.
- Useful links: root page • root page’s subpages • links • redirects • your own
// 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('[[:Category:' + values.category + '|' + 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("§ion=")[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':'§ion='+(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:'§ion='+(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("\\[\\[[Cc]ategory:"+qq.firstChild.innerHTML+"(\\]\\]|\\|[^\\]]+\\]\\])"),"").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('[[:Category:' + values.category + '|' + values.category + ']]', function(res){
var newCat=newNode('span'); newCat.innerHTML=res;
editor.addEdit({
'edit':function(wikitext){
return ccc=wikitext.replace(new RegExp("\\[\\[[Cc]ategory:"+qq.firstChild.innerHTML+"([\\|\\]])"),"["+"[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 );