User:Alex Smotrov/iwiki.js
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
var iwiki = new function (){
// View interwiki
var pLang, ul, lis, count, ww, displayMode = window.iwDisplayMode || 0
this.onLoad = function(){
pLang = document.getElementById('p-lang')
if (!pLang) return
var h3 = pLang.getElementsByTagName('h3')[0]
if (!h3) return
h3.addEventListener('click', iwiki.display)
h3.style.cursor = 'pointer'
h3.title = 'Change how interwiki displayed'
if (displayMode) iwiki.display()
if (mw.config.get('wgAction')=='edit' || mw.config.get('wgAction')=='submit')
iwiki.loadSync()
}
this.display = function(){
displayMode++
if (displayMode > 3) displayMode = 1
var aa, page
if (!ww) getDisplayedList()
switch (displayMode){
case 1: //no change
ww.sort(function(a,b){return a.i > b.i ? 1 : -1})
for(i=0; i < count; i++){
aa = ww[i].li.firstChild
aa.title = ''
aa.innerHTML = ww[i].local
}
break
case 2: //English names
ww.sort(function(a,b){return a.name > b.name ? 1 : -1})
for(i=0; i < count; i++){
aa = ww[i].li.firstChild
aa.title = ww[i].local
aa.innerHTML = ww[i].name
}
break
case 3: //actual interwiki links
ww.sort(function(a,b){return a.lang > b.lang ? 1 : -1})
for(i=0; i < count; i++){
aa = ww[i].li.firstChild
page = aa.href.match(/org\/wiki\/(.*)$/)[1]
page = decodeURIComponent(page)
aa.title = ww[i].name + ': ' + page
aa.innerHTML = ww[i].lang + ':' + page
}
break
}
for(i=1; i < count; i++)
ul.appendChild(ww[i].li)
}
function getDisplayedList(){
ul = pLang.getElementsByTagName('ul')[0]
lis = ul.getElementsByTagName('li')
count = lis.length
ww = new Array(count)
var aa, lang
for (var i=0; i < count; i++){
aa = lis[i].firstChild
lang = aa.href.substring(7, aa.href.indexOf('.'))
ww[i] = {
lang: lang,
local: aa.innerHTML,
name: iwNames[lang] || '- ' + aa.innerHTML,
li: lis[i],
i: i
}
}
}
// Sync interwiki
var wpTextbox1, iw, iwdiv, iwtable, queriedLink, siteLang, wasRedirect
this.loadSync = function(){
mw.util.addPortletLink('p-lang', 'javascript:iwiki.sync()', '(sync)')
}
this.sync = function(){
iw = []
queriedLink = ''
wasRedirect = false
siteLang = mw.config.get('wgServer').substring(7, mw.config.get('wgServer').indexOf('.'))
wpTextbox1 = document.getElementById('wpTextbox1')
var i, m, ma, re, txt = wpTextbox1.value
//find local interwikis
for (i in iwNames){
re = new RegExp('\\[\\['+i+':'+'[^\\]]+\\]\\]', 'gi');
if (ma = txt.match(re)){
if (ma.length==0) continue
for (var m=0; m < ma.length; m++)
addIW(ma[m].substring(2,ma[m].length-2), false) //drop brackets
}
}
//add self
addIW(siteLang + ':' + mw.config.get('wgPageName').replace(/_/g, ' '))
//show
showDiv()
}
function showDiv(){
if (iwdiv) iwdiv.style.display = 'block'
else createDiv()
//scroll to it
var yy = iwdiv.offsetTop, obj = iwdiv
while (obj = obj.offsetParent) yy += obj.offsetTop
scrollTo(0, yy)
drawTable()
}
function createDiv(){
var div = document.createElement('div')
div.innerHTML = '<div id=iwdiv style="padding:10px; margin:5px; border:1px solid gray; min-height:150px">\
<div style="float:left; margin-right:20px">\
<br><input type=button value=Query id=iwNext onclick=iwiki.queryNext()\
style="background-color:#EEEEEE">\
<br><br><input type=button value="Add All" id=appendAll onclick=iwiki.appendAll()\
style="background-color:#EEEEEE">\
<br><br><br><input type=button value=Apply id=iwApply onclick=iwiki.apply()\
style="background-color:#E5EFE5">\
<br><br><input type=button value=Cancel id=iwCancel onclick=iwiki.cancel()\
style="background-color:#F5E5E5">\
</div></div>'
wpTextbox1.parentNode.insertBefore(div, wpTextbox1.nextSibling)
iwdiv = div.firstChild
//document.getElementById('iwNext').onclick = iwiki.queryNext
//document.getElementById('iwApply').onclick = iwiki.apply
//document.getElementById('iwCancel').onclick = iwiki.cancel
}
function drawTable(){
iw.sort(function(a,b){ return (a.lnk>b.lnk)?1:-1})
var tb = document.createElement('tbody')
//draw
var tr, td, nocell, needAddAllButton = false, lang, prev = ''
for (var i=0; i<iw.length; i++){
tr = document.createElement('tr')
lang = getLang(iw[i].lnk)
isself = (siteLang == lang)
//«x» link to delete cell
if (iw[i].local && !isself)
putCell('<a title=remove href="javascript:iwiki.remove(\'' + i + '\')">x</a>',' ')
else
putCell('', ' ')
td.style.paddingRight = '5px'
//local cell
if (iw[i].local) {
if (isself) {
putCell (iw[i].lnk)
td.style.color = 'gray'
td.style.fontSize = 'smaller'
}else{
putCell(getFullLink(iw[i].lnk))
if (iw[i].isnew) td.style.backgroundColor = '#DFFFEF'
if (queriedLink == iw[i].lnk) { //was just queried
td.style.backgroundColor = '#EFEFEF'
td.style.fontWeight = 'bold'
}
}
if (lang == prev) td.style.border = '2px solid red'
prev = lang
}else //local missing
putCell('', '#FFEADF')
//status cell
if (isself){
putCell('', ' ')
}else if (!iw[i].local && iw[i].remote) {
putCell('<a title=append href="javascript:iwiki.append(\'' + i + '\')">←</a>', ' ')
needAddAllButton = true
}else{
htm = '<a title=query href="javascript:iwiki.query(\'' + i + '\')"'
htm += (iw[i].queried) ? '>v' : '>?'
putCell(htm+'</a>', ' ')
}
td.style.textAlign = 'center'
td.style.width = '50px'
//remote cell
if (iw[i].remote){
if (iw[i].local) putCell('', '#F5F5F5');
else putCell (getFullLink(iw[i].lnk))
}else if (!queriedLink || queriedLink == iw[i].lnk){ //remote not needed
if (wasRedirect) putCell('(redirect)', ' ')
else putCell('', ' ')
}else{ //remote is absent
putCell('', '#FFEADF')
}
//add row
tb.appendChild(tr)
}//for
if (iwtable)
iwtable.replaceChild(tb, iwtable.firstChild)
else{
iwtable = document.createElement('table')
iwtable.id = 'iwtable'
iwtable.appendChild(tb)
iwdiv.appendChild(iwtable)
}
document.getElementById('appendAll').style.visibility = needAddAllButton ? 'visible' : 'hidden'
//iwdiv.focus()
function putCell(htm, style){
td = document.createElement('td')
td.style.padding = '0 10px 0 10px '
td.innerHTML = htm
if (!style)
td.style.border = '1px dotted gray'
else if (style != ' ')
td.style.backgroundColor = style
tr.appendChild(td)
return
}
}
function addIW(iwlink, isRemote){
if (!isRemote){ //local
var iwnew = {}
iwnew.lnk = iwlink
iwnew.local = true
//iwnew.remote = false
//iwnew.queried = false
iw[iw.length] = iwnew
}else{ //remote
//if (siteLang == getLang(iwlink)) return
var isFound = false
for (var i=0; i<iw.length; i++)
if (iw[i].lnk == iwlink) { isFound = true; break }
if (isFound){
iw[i].remote = true
}else{
var iwnew = {}
iwnew.lnk = iwlink
iwnew.local = false
iwnew.remote = true
iw[iw.length] = iwnew
}
}
}
function getLang(iwlink){ //en:Page -> en
return iwlink.substring(0, iwlink.indexOf(':'))
}
function getPage(iwlink){ // //en:Page -> Page
return iwlink.substring(iwlink.indexOf(':')+1)
}
function getFullLink(iwlink){ ////en:Page -> <a href=…
return '<a href="' + 'http://' + getLang(iwlink)
+ mw.config.get('wgServer').substring(mw.config.get('wgServer').indexOf('.')) + '/wiki/'
+ encodeURIComponent(getPage(iwlink)) + '">' + iwlink + '</a>'
}
this.append = function(i){
iw[i].local = true
iw[i].isnew = true
drawTable()
}
this.appendAll = function(){
for (var i=0; i<iw.length; i++)
if (!iw[i].local && iw[i].remote){
iw[i].local = true
iw[i].isnew = true
}
drawTable()
}
this.remove = function(i){
iw[i].local = false
//iw.splice(i,1)
drawTable()
}
this.apply = function(){
var i, re, txt = wpTextbox1.value
//remove old
for (i in iwNames){
re = new RegExp('\\[\\['+i+':'+'[^\\]]+\\]\\]\n?', 'gi')
txt = txt.replace(re, '\x01')
}
//create new
var iwtxt = ''
for (i=0; i<iw.length; i++)
if (iw[i].local && getLang(iw[i].lnk) != siteLang)
iwtxt += '[' + '[' + iw[i].lnk + ']]\n'
//append new
txt = txt.replace('\x01', iwtxt).replace(/\x01/g,'')
wpTextbox1.value = txt
iwdiv.style.display = 'none'
}
this.cancel = function(){
iwdiv.style.display = 'none'
}
this.queryNext = function(){
for (var i=0; i<iw.length; i++)
if (iw[i].local && !iw[i].queried && getLang(iw[i].lnk) != siteLang) {
iwiki.query(i)
break
}
}
this.query = function(idx){
document.getElementById('iwNext').style.textDecoration = 'blink'
queriedLink = iw[idx].lnk //remember
queryGo('langlinks&titles='+encodeURIComponent(getPage(queriedLink))
+ '&proxylang='+getLang(queriedLink), iwiki.process )
}
this.process = function(q){
document.getElementById('iwNext').style.textDecoration = 'none'
//mark queried link
for (var i=0; i<iw.length; i++)
if (queriedLink == iw[i].lnk){ iw[i].queried = true; break }
//clear last results
for (var i=0; i<iw.length; i++) {
iw[i].remote = false
if (!iw[i].local) { iw.splice(i,1); i-- } //remove item
}
//add new iwikis
links = anyChild(q.pages).langlinks
if (links){
for (var n=0; n<links.length; n++){
iwlink = links[n].lang + ':' + links[n]['*']
addIW(iwlink, true)
}
wasRedirect = false
}else if (typeof anyChild(q.pages).redirect == 'string')
wasRedirect = true
drawTable()
}
function queryGo(params, func){
var aj = sajax_init_object()
aj.onreadystatechange = function() {
if (aj.readyState != 4) return
//if (aj.status == 200) {
eval('q='+aj.responseText)
func(q)
//} else jsMsg('Empty query result') //else func(null)
}
var url='/w/query.php?format=json&noprofile&what=' + params
aj.open("GET",url,true)
//aj.setRequestHeader('Accept','text/*')
aj.send(null)
}
//interwiki codes and names, extracted from http://meta.wikimedia.org/wiki/List_of_Wikipedias
var iwNames = {
'en':'English',
'de':'German',
'fr':'French',
'pl':'Polish',
'ja':'Japanese',
'nl':'Dutch',
'it':'Italian',
'pt':'Portuguese',
'es':'Spanish',
'sv':'Swedish',
'ru':'Russian',
'zh':'Chinese',
'fi':'Finnish',
'no':'Norwegian (Bokmål)',
'vo':'Volapük',
'ro':'Romanian',
'tr':'Turkish',
'eo':'Esperanto',
'ca':'Catalan',
'sk':'Slovak',
'cs':'Czech',
'uk':'Ukrainian',
'hu':'Hungarian',
'da':'Danish',
'id':'Indonesian',
'he':'Hebrew',
'lt':'Lithuanian',
'sr':'Serbian',
'sl':'Slovenian',
'lmo':'Lombard',
'bg':'Bulgarian',
'ko':'Korean',
'ar':'Arabic',
'et':'Estonian',
'te':'Telugu',
'hr':'Croatian',
'new':'Newar / Nepal Bhasa',
'ceb':'Cebuano',
'gl':'Galician',
'th':'Thai',
'el':'Greek',
'nn':'Norwegian (Nynorsk)',
'fa':'Persian',
'vi':'Vietnamese',
'ms':'Malay',
'bpy':'Bishnupriya Manipuri',
'eu':'Basque',
'bs':'Bosnian',
'simple':'Simple English',
'lb':'Luxembourgish',
'is':'Icelandic',
'sq':'Albanian',
'ka':'Georgian',
'az':'Azeri',
'br':'Breton',
'bn':'Bengali',
'la':'Latin',
'io':'Ido',
'hi':'Hindi',
'sh':'Serbo-Croatian',
'mr':'Marathi',
'su':'Sundanese',
'mk':'Macedonian',
'nap':'Neapolitan',
'cy':'Welsh',
'ta':'Tamil',
'lv':'Latvian',
'scn':'Sicilian',
'nds':'Low Saxon',
'oc':'Occitan',
'pms':'Piedmontese',
'jv':'Javanese',
'tl':'Tagalog',
'ku':'Kurdish',
'ast':'Asturian',
'wa':'Walloon',
'af':'Afrikaans',
'tg':'Tajik',
'be-x-old':'Belarusian (Tarashkevitsa)',
'roa-tara':'Tarantino',
'an':'Aragonese',
'be':'Belarusian',
'ru-sib':'Siberian/North Russian',
'ksh':'Ripuarian',
'ht':'Haitian',
'cv':'Chuvash',
'ur':'Urdu',
'mi':'Maori',
'sw':'Swahili',
'vec':'Venetian',
'uz':'Uzbek',
'fy':'West Frisian',
'zh-yue':'Cantonese',
'ga':'Irish',
'co':'Corsican',
'qu':'Quechua',
'kn':'Kannada',
'gd':'Scottish Gaelic',
'ml':'Malayalam',
'yi':'Yiddish',
'yo':'Yoruba',
'nah':'Nahuatl',
'bat-smg':'Samogitian',
'pam':'Kapampangan',
'tt':'Tatar',
'ia':'Interlingua',
'sa':'Sanskrit',
'hsb':'Upper Sorbian',
'hy':'Armenian',
'li':'Limburgian',
'als':'Alemannic',
'map-bms':'Banyumasan',
'am':'Amharic',
'pag':'Pangasinan',
'zh-min-nan':'Min Nan',
'nrm':'Norman',
'fo':'Faroese',
'se':'Northern Sami',
'nds-nl':'Dutch Low Saxon',
'fur':'Friulian',
'bh':'Bihari',
'nov':'Novial',
'war':'Waray-Waray',
'pi':'Pali',
'vls':'West Flemish',
'ilo':'Ilokano',
'sco':'Scots',
'frp':'Franco-Provençal/Arpitan',
'lij':'Ligurian',
'ne':'Nepali',
'dv':'Divehi',
'os':'Ossetian',
'zh-classical':'Classical Chinese',
'diq':'Zazaki',
'mt':'Maltese',
'kk':'Kazakh',
'csb':'Kashubian',
'pdc':'Pennsylvania German',
'lad':'Ladino',
'fiu-vro':'Võro',
'kw':'Cornish',
'to':'Tongan',
'bar':'Bavarian',
'ps':'Pashto',
'rm':'Romansh',
'tk':'Turkmen',
'ang':'Anglo-Saxon',
'ln':'Lingala',
'mn':'Mongolian',
'jbo':'Lojban',
'tpi':'Tok Pisin',
'or':'Oriya',
'wo':'Wolof',
'ty':'Tahitian',
'eml':'Emilian-Romagnol',
'ky':'Kirghiz',
'arc':'Assyrian Neo-Aramaic',
'ig':'Igbo',
'roa-rup':'Aromanian',
'mo':'Moldovan',
'gu':'Gujarati',
'km':'Khmer',
'ie':'Interlingue',
'kab':'Kabyle',
'ks':'Kashmiri',
'wuu':'Wu',
'glk':'Gilaki',
'zea':'Zealandic',
'mg':'Malagasy',
'tet':'Tetum',
'cu':'Old Church Slavonic',
'sc':'Sardinian',
'so':'Somali',
'gv':'Manx',
'kg':'Kongo',
'udm':'Udmurt',
'si':'Sinhalese',
'iu':'Inuktitut',
'pa':'Punjabi',
'rmy':'Romani',
'cbk-zam':'Zamboanga Chavacano',
'na':'Nauruan',
'haw':'Hawaiian',
'lo':'Lao',
'bo':'Tibetan',
'sd':'Sindhi',
'chr':'Cherokee',
'ba':'Bashkir',
'got':'Gothic',
'om':'Oromo',
'ee':'Ewe',
'ti':'Tigrinya',
'as':'Assamese',
'sm':'Samoan',
'ay':'Aymara',
'ug':'Uyghur',
'hak':'Hakka',
'av':'Avar',
'cdo':'Min Dong',
'mzn':'Mazandarani',
'ce':'Chechen',
'bm':'Bambara',
'nv':'Navajo',
'pap':'Papiamentu',
'cr':'Cree',
'zu':'Zulu',
'rw':'Kinyarwanda',
'my':'Burmese',
'tlh':'Klingon',
'xh':'Xhosa',
've':'Venda',
'ik':'Inupiak',
'dz':'Dzongkha',
'pih':'Norfolk',
'gn':'Guarani',
'ss':'Swati',
'ab':'Abkhazian',
'kl':'Greenlandic',
'kv':'Komi',
'bug':'Buginese',
'ak':'Akan',
'bi':'Bislama',
'st':'Sesotho',
'bxr':'Buryat (Russia)',
'tn':'Tswana',
'xal':'Kalmyk',
'tw':'Twi',
'ny':'Chichewa',
'fj':'Fijian',
'ff':'Fula',
'ha':'Hausa',
'tum':'Tumbuka',
'sn':'Shona',
'za':'Zhuang',
'ki':'Kikuyu',
'sg':'Sango',
'ii':'Sichuan Yi',
'lg':'Luganda',
'cho':'Choctaw',
'lbe':'Lak',
'rn':'Kirundi',
'chy':'Cheyenne',
'ts':'Tsonga',
'mh':'Marshallese',
'ch':'Chamorro',
'ng':'Ndonga',
'aa':'Afar',
'kj':'Kuanyama',
'ho':'Hiri Motu',
'mus':'Muscogee',
'kr':'Kanuri',
'hz':'Herero',
'tokipona':'Tokipona'
}
} //obj
function anyChild(obj) { for(var key in obj) return obj[key]; return null }
$(iwiki.onLoad)