function findHeading( $el ) {
while( !$el.is( '#bodyContent' ) ) {
var $prev = $el.prevAll( 'h1,h2,h3,h4,h5,h6' );
if ( $prev.length ) {
return $prev.first();
}
$el = $el.parent();
}
return $();
}
function getSectionNumber( $el ) {
var editLink = findHeading( $el ).find( '.mw-editsection a' ).attr( 'href' ),
matches = editLink ? editLink.match( /§ion=([^&]+)/ ) : null;
return $.isArray( matches ) ? parseInt( matches[1] ) : 0;
}
function ucfirst( s ) {
var ch = s.charAt( 0 ).toUpperCase();
return ch + s.substr( 1 );
}
function normalizeTitle( title ) {
return ucfirst( decodeURIComponent( title )
.replace( '_', ' ' )
.replace( / +/, ' ' )
.trim()
);
}
function findDabLink( text, faceText, dest ) {
var matches,
match,
i,
template,
link,
linkFace,
result = {};
dest = dest.trim();
matches = text.match( /\[\[[^\[\]]*?\]\][^\[\]]{0,20}\s*\{\{.*?\}\}/g );
if ( !matches ) {
return false;
}
for ( i = 0; i < matches.length; i++ ) {
match = matches[i];
var linkMatches = match.match( /\[\[\s*(.+?)\s*(?:|\|\s*(.+?))\s*\]\]/ );
var templateMatches = match.match( /\s*\{\{\s*(.+?)\s*(?:|\|\s*(.+?))\s*\}\}/ );
if ( linkMatches && templateMatches ) {
link = normalizeTitle( linkMatches[1] );
template = normalizeTitle( templateMatches[1] );
linkFace = linkMatches[2] === undefined ? linkMatches[1] : linkMatches[2];
if ( link == dest
&& linkFace == faceText
&& template.match( /Dn|Disambiguation needed/ )
) {
return {
match: match,
linkText: linkMatches[0],
link: link,
rawLink: linkMatches[1],
face: faceText,
template: templateMatches[0]
};
}
}
}
return false;
}
function getDabVariants( title ) {
var api = new mw.Api();
return api.get( {
action: 'query',
prop: 'links',
plnamespace: 0,
pllimit: 'max',
titles: title,
redirects: 1
} ).then(
function( data ) {
var links = [];
$.each( data.query.pages, function( i, page ) {
$.each( page.links, function( i, link ) {
links.push( link.title );
} );
} );
return links.sort();
}
);
}
function getWikiText( page, section ) {
var api = new mw.Api();
return api.get( {
action: 'parse',
page: page,
prop: 'wikitext',
section: section
} ).then( function( data ) {
return data.parse.wikitext['*'];
} );
}
function doDabDialog( section, faceText, dest ) {
var disambiguationResult,
buttons = {
Cancel: function() {
$( this ).dialog( 'close' );
},
},
saveButton = function() {
var api = new mw.Api();
api.postWithToken( 'edit', {
action: 'edit',
title: mw.config.get( 'wgPageName' ),
section: section,
text: $( '#dabtext' ).val(),
summary: 'Disambiguated [[' + dest + ']] to [[' + disambiguationResult + ']]'
} ).done( function() {
location.reload();
} );
$( this )
.text( 'Saving...' )
.dialog( { buttons: {} } );
},
$content = $( '<div>' )
.append( $( '<div id="dab-dialog">' ).append(
$.createSpinner().after( $( '<span>Loading...</span>' ) )
) )
.dialog( {
modal: true,
buttons: buttons,
width: '80%',
height: 400
} );
$.when(
getWikiText( mw.config.get( 'wgPageName' ), section ),
getDabVariants( dest )
).done( function( wikitext, links ) {
var $select,
dab = findDabLink( wikitext, faceText, dest ),
newWikitext;
if ( !dab ) {
$content.text( 'Could not find a link to correct. Edit manually?' );
return;
}
$select = $( '<select>' )
.append(
$( '<option>' )
.attr( 'value', '' )
.text( 'Select a destination article...' )
)
.on( 'change', function() {
var val = $select.val(),
newLink;
if ( val === '' ) {
return;
}
disambiguationResult = val;
newLink = dab.match
.replace( dab.linkText, '[[' + val + '|' + dab.face + ']]' )
.replace( dab.template, '' );
newWikitext = wikitext.replace( dab.match, newLink );
$( '#dabtext' )
.val( newWikitext )
.show();
if ( !window.find( newLink, false, true ) ) {
window.find( newLink, false, false );
}
} );
$.each( links, function( i, link ) {
$select.append(
$( '<option>' )
.attr( 'value', link )
.text( link )
);
} );
buttons.Save = saveButton;
$content.html( '' )
.append(
$( '<div>' )
.append( $( '<textarea rows="20" id="dabtext" style="display: none">' )
.val( wikitext )
)
.append( $select )
).dialog( { buttons: buttons } );
} )
.fail( function() {
$content.text( 'zomgfailed' );
} );
}
$( 'sup.Inline-Template a' ).each( function() {
var href = this.getAttribute( 'href' ) || '',
$link = $( this );
if ( !href.indexOf( 'editintro=Template:Disambiguation_needed/editintro' ) ) {
return;
}
$link.on( 'click.dab', function( e ) {
e.preventDefault();
mw.loader.using( [ 'jquery.ui', 'jquery.spinner' ], function() {
var section = getSectionNumber( $link ),
$dabLink = $link.parents( 'sup' ).prev( 'a' ),
faceText = $dabLink.text(),
dest = $dabLink.attr( 'href' );
if ( $dabLink.length != 1
|| $dabLink.is( '.external' )
|| !dest.match( /^\/wiki\// ) )
{
return;
}
dest = normalizeTitle( dest.replace( /^\/wiki\//, '' ) );
doDabDialog( section, faceText, dest );
} );
} );
} );