User:Khanson/dabfixer.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:Khanson/dabfixer. |
if (!window.$j) mw.loader.load('http://bits.wikimedia.org/skins-1.5/common/jquery.min.js')
if ((wgNamespaceNumber == 0 || wgNamespaceNumber == 2 || wgNamespaceNumber == 10 || wgNamespaceNumber == 14 || wgNamespaceNumber == 100) &&
/edit|submit/.test(wgAction) &&
wgServer.indexOf('wikipedia') != -1)
$(function () {
addPortletLink('p-cactions','javascript:dabLinksStart()', 'DAB')
var tlb = $('#toolbar')
if (tlb.length==0) return
$('<input type=button\ style="height:22px;width:24px;vertical-align:top;padding:0;\
background:url(http://upload.wikimedia.org/wikipedia/commons/6/62/Button_desambig.png)"\
title="Уточнить ссылки на неоднозначности" />')
.click(dabLinksStart).appendTo(tlb)
})
function dabLinksStart(){
var dis=null, disIdx = -1, changes=[], dabMsgTimeout
var dabPgTitle, lnkRegExp, wikiLink, wikiLinkOrig, wikiLinkPos, snippetBefore, snippetAfter
var $i = {
requesting:'Ждём ответа от тулсервера...',
unlink_tip:'Убрать ссылку',
undo_tip:'Отменить сделанное исправление',
choose_tip:'Уточните ссылку, кликнув на более точном значении ниже',
x_tip:'отменить изменение',
cancel:'отменить',
cancel_tip:'отменить все сделанные изменения и закрыть диалог',
next_tip:'перейти к следующей ссылке на неоднозначность',
linksback:'есть <b>обратная ссылка</b>, вероятно исправления не нужно',
nolinks:'В тексте не найдено ссылок на $1',
cancelled:'Все изменения отменены',
finished:'Исправлено ссылок:'
}
var tBox = $('#wpTextbox1')
var wikiText = tBox.val()
appendCSS('#dabMsg {background:#cec; border:1px solid; padding:0 10px}')
showMsg($i.requesting||'Making request to toolserver...', 8000)
window.dabLinksProcess = dabLinksProcess
mw.loader.load('http://toolserver.org/~dispenser/cgi-bin/dablinks.py?\
format=json&callback=dabLinksProcess\
&titles='+wgContentLanguage+':'+encodeURIComponent(mw.config.get('wgPageName'))
+'&nocache='+Math.random())
return
function dabLinksProcess(data){
try { dis=data.query.pages[0].disambiguationlinks } catch(e){}
if (!dis) return showMsg('В статье не найдено ссылок на неоднозначности')
$('#bodyContent').hide().parent().append('<div id=dabFrame>\
<pre id=dabText style="padding-left:2px;font-family:monospace, sans-serif" />\
<div id=dabTitle style="float:left; border:2px outset; border-bottom:none; padding:0 5px; margin-right:1em">\
<span class=title />\
<span class=choose style="cursor:help">↓ </span></div>\
<div id=dabMenu>\
<div style="float:right">\
<span class=dabCount />\
<button class="next">→</button>\
<button class="cancel" /></div>\
<button class="unlink" style="opacity:0.6"><s>[\[</s> <s>]]</s></button>\
<button class="x"/>\
<span class=info> </span> <span class=linksback /></div>\
<div id=dabPage/>\
</div>')
appendCSS('\
#dabFrame {padding:2px; border:1px solid gray}\
#dabFrame button {background:#cce; padding:0 5px; opacity:0.8; margin-left:0.5em;\
font-size:85%; line-height:1.5em; vertical-align:top; cursor:pointer;}\
#dabText.text {word-wrap: break-word; white-space:pre-wrap; border:2px inset}\
#dabText .highlighted {background:#FFFF00}\
#dabText .changed {background:#A0E0A0}\
#dabPage {width:100%; border:2px outset; padding:10px 0;\
max-height:230px; overflow-y:auto}\
#dabPage #disambig {font-size:75%; margin-bottom:0 !important; line-height:1em; padding:0}\
#dabPage span.editsection {display:none}\
#dabPage li.highlight {background-color:#F0F5F0; border:1px dotted gray}\
#dabPage a:hover {border-top:1px dotted green; border-top:1px dotted green}\
')
$('#dabFrame button').click(buttonClicked)
$('#dabPage').click(linkClicked)
$('#dabFrame span').add('#dabFrame button').each(function(){
var el = $(this), cl = el.attr('class').split(' ')[0], txt
if (!cl) return
if (txt=$i[cl]) el.html(txt)
if (txt=$i[cl+'_tip']) el.attr('title', txt)
if (!el.text()) el.text(cl)
})
$('#dabText')[0].scrollIntoView(true)
nextLink()
return false
}
function buttonClicked(){
switch(this.className.split(' ')[0]){
case 'next':
nextLink()
break
case 'cancel':
close($i.cancelled || 'All changes cancelled')
break
case 'unlink':
wikiLink = wikiLinkOrig.replace(/^\[\[|\]\]|.+\|/g,'')
showText()
break
case 'x':
wikiLink = wikiLinkOrig
showText()
break
}
return false
}
function close(msg){
$('#dabFrame').remove()
$('#bodyContent').show()
if (msg) showMsg(msg)
}
function showMsg(msg, time){
if (dabMsgTimeout) { clearTimeout(dabMsgTimeout); $('#dabMsg').remove() }
$('<div id=dabMsg />').append(msg).prependTo('#editform')[0].scrollIntoView()
dabMsgTimeout = setTimeout("$('#dabMsg').remove()",time||3000)
}
function nextLink(){
//save previous change
if (wikiLink && (wikiLink != wikiLinkOrig)){
wikiText = wikiText.substring(0,wikiLinkPos) + wikiLink
+ wikiText.substr(wikiLinkPos+wikiLinkOrig.length)
changes.push([wikiLinkOrig, wikiLink])
}
if (findNextLink()) return showText()
if (++disIdx >= dis.length) return finish()
$('#dabFrame .dabCount').empty().append((disIdx+1)+'/'+dis.length)
//show current disambig page
var item = dis[disIdx]
dabPgTitle = item.target || item.title
$('#dabTitle .title').empty()
.append(outputWikiLink(dabPgTitle).attr('target','_blank'))
$('#dabMenu .linksback').toggle(item.linksback==1)
$("#dabPage").empty()
lnkRegExp = createLinkRegexp(item.title)
if (!findNextLink()){
$('#dabText').removeClass('text')
.html('<i><center>'+
($i.nolinks||'No links found in wikitext for $1')
.replace(/\$1/,'<b>[\['+item.title+']]</b>') + '</center></i>')
return
}
showText()
$("#dabPage").html('<img src=/skins-1.5/common/images/spinner.gif />')
.load(wgScript+'?action=render&title='+encodeURIComponent(item.title), guessDab)
}
function findNextLink(){
if (!lnkRegExp || !(wikiLink=lnkRegExp.exec(wikiText))) return false
wikiLink = wikiLinkOrig = wikiLink[0]
wikiLinkPos = lnkRegExp.lastIndex - wikiLink.length
var p = wikiText.lastIndexOf('\n', wikiLinkPos-100)+1
if (wikiLinkPos-p > 500) p = wikiText.lastIndexOf('. ', wikiLinkPos-150)+2
if (wikiLinkPos-p > 500) p = wikiText.lastIndexOf(' ', wikiLinkPos-200)+1
if (wikiLinkPos-p > 500) p = wikiLinkPos-200
snippetBefore = safe(wikiText.substring(p,wikiLinkPos))
p = wikiText.indexOf('\n', wikiLinkPos + 100)
if (p-wikiLinkPos > 500) p = wikiText.indexOf('. ', wikiLinkPos+150)
if (p-wikiLinkPos > 500) p = wikiText.indexOf(' ', wikiLinkPos+200)
if (p-wikiLinkPos > 500) p = wikiLinkPos+200
snippetAfter = safe(wikiText.substring(wikiLinkPos+wikiLink.length, p))
return true
}
function showText(){
var isChanged = wikiLink != wikiLinkOrig
$('#dabText').empty().addClass('text').append(snippetBefore
+'<span class=highlighted>'+safe(wikiLink)+'</span>'+snippetAfter)
$('#dabText .highlighted').toggleClass('changed', isChanged)
$('#dabMenu button.x').css('visibility', isChanged?'visible':'hidden')
$('#dabMenu button.unlink').css('visibility', /^\[/.test(wikiLink)?'visible':'hidden')
}
function finish(){
tBox.val(wikiText)
appendSummary()
close(($i.finished || 'Changed links:') + ' ' + changes.length)
}
function safe(s){ return s.replace(/>/g,'>').replace(/</g,'<') }
function outputWikiLink(name){
return $('<a>').append(name).attr('title',name)
.attr('href', wgArticlePath.replace(/\$1/,'')+encodeURI(name).replace(/\?/g,'%3F'))
}
function linkClicked(e){
e.preventDefault()
var targ = $(e.target)
if (targ.attr('nodeName') != 'A') return
// !!! check for parent metadata
if (targ.hasClass('new')) targ = targ.attr('href').match(/\?title=([^&]+)/)
else targ = targ.attr('href').match(/\/wiki\/([^\?]+)/)
if (!targ) return
targ = decodeURIComponent(targ[1]).replace(/_/g,' ')
wikiLink = wikiLinkOrig.replace(/\[\[(.+\|)?(.+)\]\](.+)?/, function(str, lnk, name, trail){return '[\['+targ+'|'+name+(trail||'')+']]'})
showText()
return false
}
function appendSummary(){
var sm = $('#wpSummary')
if (sm.val().indexOf('disambiguation') == -1)
sm.val(sm.val()+'[[Wikipedia:Disambiguation]]')
}
function createLinkRegexp(title){
var i, ch, re = ''
for (i=0; ch=title.charAt(i), i<title.length; i++)
re += ('(){}^$.+*|/\\'.indexOf(ch) != -1 ? '\\' :'') + ch
ch = re.charAt(0)
if (/^[\wА-Я]/.test(ch)) re = '('+ch+'|'+ch.toLowerCase()+')'+re.substring(1)
re = new RegExp('\\[\\[\\s*'+re+'\\s*(\\|[^\\[\\]]+)?\\]\\][a-zа-яё]*', 'g')
return re
}
function guessDab(){
$('#floating_object').remove()
var words, word, score, count, ma, lis = $("#dabPage li")
for (var l=0; l<lis.length;l++){
score = 0; count = 0
words = lis.eq(l).text().replace(/[^\wа-яё]+/gi,' ').split(' ')
for (var i=0; i<words.length; i++){
word = words[i]
if (/^[а-яё]+$/i.test(word)) word = word.substr(0, word.length-2) //rus suffix
if (word.length < 4) continue //too short
if (dis[disIdx].title.match(RegExp('^'+word,'i'))) continue //disambig title
count++
ma = wikiText.match(RegExp(word, 'ig'))
if (!ma) continue
score += ma.length
}
lis[l].score = score / count
}
lis.sort(function(a,b){return b.score-a.score})
lis.eq(0).addClass('highlight')
}
}