Jump to content

User:Khanson/dabfixer.js

From Wikipedia, the free encyclopedia
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.
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">↓&nbsp;</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>&nbsp;<s>]]</s></button>\
 <button class="x"/>\
 <span class=info>&nbsp;</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,'&gt;').replace(/</g,'&lt;') }

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')
}



}