User:Alex Smotrov/iwiki.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Alex Smotrov/iwiki. |
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)