User:Splarka/dabfinder.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.
/* Disambiguation lookup script, version [0.2.8]
Originally from: https://en.wikipedia.org/wiki/User:Splarka/dabfinder.js
Notes:
* Uses the API using head/appendchild(script) and callback to avoid ajax.
* Alt command finds and hilights redirects with simple CSS append (class="mw-redirect").
* Per http://svn.wikimedia.org/viewvc/mediawiki?view=rev&revision=37270 we are limited to 500 subtemplates
** The query-continue seems to work fine even as a generator. Built a re-query system to do this automatically.
Operation:
* Adds portlet button (or works with URI parameter &finddab=true)
** Makes call to MediaWiki:Disambiguationspage links, generates array of these.
*** Makes call to generator=links / prop=templates on page title.
**** Builds array of registered links that link to disambiguation pages (that contain a disambiguation template).
***** Iterates over all <a> link objects on page, matching any that link to disambiguation, and applies green border.
***** .dablink descendant links are given a dashed border, all other found links are given a solid border.
*** Repeats call with tlcontinue if more than 500 templates have been returned in previous query.
This is a bit messy but at the time was the easiest and most thorough way to do it I could think of.
Of course, a bot might be much more efficient, but this is handy for quick on-the-fly live checking.
To do:
* test it
* centralized link list in contentSub?
* test unicode support
*/
var dabnames = [];
var dabfound = 0;
if(mw.config.get('wgNamespaceNumber') !== -1) {
$.when( $.ready, mw.loader.using('mediawiki.util') ).then(findDABsButton);
}
function findDABsButton() {
var el;
var action = mw.config.get('wgAction');
if(!mw.util.getParamValue('oldid') && !mw.util.getParamValue('diff') && (action === 'view' || action === 'purge')) {
el = mw.util.addPortletLink('p-tb','','Find disambiguations','t-dab');
$(el).on('click', findDABs );
if(mw.util.getParamValue('finddab')==='true') {
findDABs();
}
}
el = mw.util.addPortletLink('p-tb','','Find redirects','t-rdr');
$(el).on( 'click', findRDRs );
if(mw.util.getParamValue('findrdr')==='true') {
findRDRs();
}
}
function findRDRs(event) {
event.preventDefault();
mw.util.addCSS('.mw-redirect {background-color: #ffff00;}\n#t-rdr {background-color:#ffff00;}');
document.getElementById('t-rdr').appendChild(document.createTextNode('\nRedirects highlighted, but don\'t '));
if(mw.config.get('wgServer') != 'https://en.wikipedia.org' && mw.config.get('wgScriptPath') != '/wikipedia/en/w') { return; //en.wp policy
}
var a = document.createElement('a');
a.setAttribute('href','https://en.wikipedia.org/wiki/Wikipedia:Redirect#Do_not_.22fix.22_links_to_redirects_that_are_not_broken');
a.appendChild(document.createTextNode('fix them.'));
document.getElementById('t-rdr').appendChild(a);
}
function findDABs(event) {
event.preventDefault();
var dab = document.getElementById('t-dab');
//if(dab) injectSpinner(dab,'dab');
var url = mw.config.get('wgScriptPath') + '/api.php?maxage=86400&smaxage=86400&action=query&prop=links&pllimit=500&indexpageids&format=json&rawcontinue=&callback=findDABsCB&titles=MediaWiki:Disambiguationspage';
$.getScript(url);
}
function findDABsCB(obj) {
if(!obj['query'] || !obj['query']['pages'] || !obj['query']['pageids']) return
var links = obj['query']['pages'][obj['query']['pageids'][0]]['links']
if(!links) return
for(var i=0;i<links.length;i++) {
dabnames.push(links[i]['title']);
}
findDABsQuery();
}
function findDABsQuery(qcont) {
var url = mw.config.get('wgScriptPath') + '/api.php?maxage=300&smaxage=300&action=query&redirects&generator=links&gpllimit=500&prop=templates&tllimit=500&indexpageids&format=json&rawcontinue=&callback=findDABlinksCB&titles=' + encodeURIComponent(mw.config.get('wgPageName'));
if(qcont) url += '&tlcontinue=' + encodeURIComponent(qcont);
$.getScript(url);
}
function findDABlinksCB(obj) {
var dablinks = [];
if(!obj['query'] || !obj['query']['pages'] || !obj['query']['pageids']) return
mw.util.addCSS('.dablink-found {border: 2px solid #00ff00}\n .dablink .dablink-found {border:2px dashed #00ff00}');
var ids = obj['query']['pageids'];
var links = [];
for(var i=0;i<ids.length;i++) {
var templates = obj['query']['pages'][ids[i]]['templates'];
if(!templates) continue;
for(var j=0;j<templates.length;j++) {
var tpl = templates[j]['title'];
for(var k=0;k<dabnames.length;k++) {
if(tpl == dabnames[k]) {
dablinks.push(obj['query']['pages'][ids[i]]['title']);
continue;
}
}
}
}
if(obj['query']['redirects']) {
var dablen = dablinks.length; //don't iterate over additions.
var redirects = obj['query']['redirects'];
if(redirects) {
for(var i=0;i<redirects.length;i++) {
for(var j=0;j<dablen;j++) {
if(obj['query']['redirects'][i]['to'] == dablinks[j]) {
dablinks.push(obj['query']['redirects'][i]['from']);
continue;
}
}
}
}
}
var docobj = document.getElementById('bodyContent') || document.getElementById('content') || document.body;
var links = docobj.getElementsByTagName('a')
for(var i=0;i<links.length;i++) {
for(var j=0;j<dablinks.length;j++) {
//to match API: "Foo (bar)" with href: "/wiki/Foo_%28bar%29", have to do some hacky string manipulation
//should now work with parenthesis, unicode?
var dablink = dablinks[j].replace(/ /g,'_');
var chklink = (links[i].hasAttribute('href')) ? links[i].getAttribute('href', 2).replace(/\#.*/,'') : ''
chklink = chklink.replace(mw.config.get('wgArticlePath').replace(/\$1/,''),'');
chklink = decodeURIComponent(chklink);
if(chklink == dablink && links[i].className.indexOf('dablink-found') == -1) {
links[i].className += ' dablink-found';
dabfound++;
}
}
}
var dab = document.getElementById('t-dab');
if(obj['query-continue'] && obj['query-continue']['templates']) {
if(dab) {
dab.appendChild(document.createElement('br'));
dab.appendChild(document.createTextNode('more...'));
}
findDABsQuery(obj['query-continue']['templates']['tlcontinue']);
} else {
if(dab) {
removeSpinner('dab');
dab.appendChild(document.createElement('br'));
if(dabfound > 0) {
var span = document.createElement('span');
span.appendChild(document.createTextNode(dabfound + ' links to disambiguation pages found.'));
span.className = 'dablink-found';
dab.appendChild(span);
} else {
dab.appendChild(document.createTextNode('No disambiguation links found.'));
}
} else {
alert(dabfound + ' links to disambiguation pages found.');
}
}
}