MediaWiki:Gadget-interwiki.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
/**
* The interwiki gadget
*
* This gadget does three separate but interrelated things related to interwiki
* links:
* * On Wiktionary entries, it automatically adds interwiki links to pages in
* existing Wiktionaries that have the same spelling, in the same way that
* the Cognate extension does on actual Wiktionaries.
* * On all other pages (including pages outside test wikis), it changes the
* non-functional "add interlanguage link" links so that when you click them,
* a dialog to add interwiki links appears. This will then add the module-
* based {{INTERWIKI}} template to the page, adding interwiki links from
* Wikidata.
* * On pages that already have the {{INTERWIKI}} template, it will add a link
* to Wikidata to the sidebar, and add a toolbar section "In other projects"
* like what pages on existing wikis have.
*
* The gadget should work on both desktop and mobile, in all supported skins.
*
* @author Jon Harald Søby
* @author Nikki
* @version 1.7.2 (2024-02-15)
*/
( function() {
var conf = mw.config.get( [
'skin',
'wgAction',
'wgArticleId',
'wgCurRevisionId',
'wgIsProbablyEditable',
'wgNamespaceNumber',
'wgPageContentLanguage',
'wgPageName',
'wgRevisionId',
'wgULSBabelLanguages',
'wgUserId',
'wgUserLanguage',
'wgWmincRealPagename',
'wgWmincTestwikiProject'
] ),
babel = conf.wgULSBabelLanguages || [],
fallbackLanguageChain = mw.language.getFallbackLanguageChain(),
langPriList = babel.concat( fallbackLanguageChain );
function capitalize( text ) {
var userlang = conf.wgUserLanguage,
lowercaseLangs = mw.config.get( 'wgWmincLowercaseLanguages' ) || []; // Not in conf because it loads later
if ( lowercaseLangs && lowercaseLangs.includes( userlang ) ) {
return text;
} else {
return text.charAt( 0 ).toUpperCase() + text.substring( 1 );
}
}
function sort_languages( a, b ) {
// Put Wiktionary links for languages in the user's Babel box first
if ( babel.includes( a.lang ) && !babel.includes( b.lang ) )
return -1;
if ( babel.includes( b.lang ) && !babel.includes( a.lang ) )
return 1;
// Then sort alphabetically by language code
return a.lang.toLocaleLowerCase().localeCompare( b.lang.toLocaleLowerCase() );
}
function analyzeInput( input ) {
var langcode, dbsuffix, pagename;
if ( /(.*wikidata.org\/.*[Qq][1-9]\d*.*|^[Qq][1-9]\d*$)/.test( input ) ) {
// If the input is a Wikidata item ID or Wikidata item URL
return {
qid: input.match( /[Qq][1-9]\d*/ )[ 0 ]
};
} else if ( /^https?:\/\/(commons\.(m\.)?wikimedia|[a-z\-]+\.(m\.)?wik(ibooks|inews|ipedia|iquote|isource|iversity|ivoyage|tionary))\.org\//.test( input ) ) {
// If the input is a URL to a sister project
var domain = input.split( '/' )[ 2 ].replace( '.m.', '.' ).split( '.' );
langcode = domain[ 0 ];
dbsuffix = domain[ 1 ];
if ( langcode === 'commons' ) {
dbsuffix = 'wiki';
}
if ( /\.org\/wiki\/.+/.test( input ) ) {
pagename = input.split( '/' )[ 4 ].split( '?' )[ 0 ].split( '#' )[ 0 ];
} else if ( /\.org\/w\/index\.php/.test( input ) ) {
pagename = mw.util.getParamValue( 'title', input );
} else {
return false;
}
if ( /^(b|wikibooks|n|wikinews|q|wikiquote|s|wikisource|v|wikiversity|voy|wikivoyage|wikt|wiktionary):/i.test( pagename ) ) {
var iwProjectMapping = {
'b': 'wikibooks',
'n': 'wikinews',
'q': 'wikiquote',
's': 'wikisource',
'v': 'wikiversity',
'voy': 'wikivoyage',
'wikt': 'wiktionary'
};
var iwPrefix = pagename.substring( 0, pagename.indexOf( ':' ) ).toLowerCase();
dbsuffix = iwProjectMapping[ iwPrefix ] || iwPrefix;
pagename = pagename.substring( pagename.indexOf( ':' ) );
}
dbsuffix = dbsuffix.replace( 'wikipedia', 'wiki' );
} else if ( /^([a-z]{2,3}|simple)([\-_][a-z]+){0,2}:.+$/.test( input ) ) {
// If the input is "old interwiki style" (like "en:Something")
var incProjectMapping = {
'b': 'wikibooks',
'n': 'wikinews',
'p': 'wiki',
'q': 'wikiquote',
's': 'wikisource',
't': 'wiktionary',
'v': 'wikiversity',
'y': 'wikivoyage'
};
langcode = input.substring( 0, input.indexOf( ':' ) );
if ( langcode === 'commons' ) {
dbsuffix = 'wiki';
} else {
dbsuffix = incProjectMapping[ conf.wgWmincTestwikiProject ];
}
pagename = input.substring( input.indexOf( ':' ) + 1 );
} else {
return false;
}
pagename = mw.util.percentDecodeFragment( pagename );
langcode = langcode.replace( /-/g, '_' ).replace( 'be_tarask', 'be_x_old' );
return {
dbname: langcode + dbsuffix,
pagename: pagename
};
}
if ( $( '#wminc-interwiki' ).length && /^Q\d+$/.test( $( '#wminc-interwiki' ).attr( 'data-wikidata-id' ) ) ) {
// If there is an {{INTERWIKI}} template present, do this
new mw.Api().loadMessagesIfMissing( [
'accesskey-t-wikibase', // g
'tooltip-t-wikibase', // Link to connected data repository item
'wikibase-dataitem',
'wikibase-otherprojects',
'wikibase-otherprojects-commons',
'wikibase-otherprojects-mediawiki',
'wikibase-otherprojects-meta',
'wikibase-otherprojects-sources',
'wikibase-otherprojects-species',
'wikibase-otherprojects-wikibooks',
'wikibase-otherprojects-wikidata',
'wikibase-otherprojects-wikimania',
'wikibase-otherprojects-wikinews',
'wikibase-otherprojects-wikipedia',
'wikibase-otherprojects-wikiquote',
'wikibase-otherprojects-wikisource',
'wikibase-otherprojects-wikiversity',
'wikibase-otherprojects-wikivoyage',
'wikibase-otherprojects-wiktionary'
] ).then( function() {
var qid = $( '#wminc-interwiki' ).attr( 'data-wikidata-id' );
mw.config.set( 'wgWikibaseItemId', qid );
mw.hook( 'incubator.wikidata' ).fire( qid );
mw.util.addPortletLink(
'p-tb',
'https://www.wikidata.org/wiki/Special:EntityPage/' + qid,
mw.msg( 'wikibase-dataitem' ),
't-wikibase',
mw.msg( 'tooltip-t-wikibase' ),
mw.msg( 'accesskey-t-wikibase' ),
$( '.menu__item--page-actions-overflow-cite' ).closest( 'li' ) // Minerva specific, does nothing in other skins
);
if ( $( '.wminc-otherprojects' ).length ) {
var $opportlet = $( '#p-coll-print_export' ).clone().attr( 'id', 'p-wikibase-otherprojects' );
var $opportletheader = $opportlet.find( '.vector-menu-heading, h3' );
$opportletheader.attr( 'id', 'p-wikibase-otherprojects-label' );
if ( $opportletheader.find( '.vector-menu-heading-label' ).length ) {
$opportletheader = $opportletheader.find( '.vector-menu-heading-label' );
}
$opportletheader.text( mw.msg( 'wikibase-otherprojects' ) );
$opportlet.find( 'ul' ).empty();
var insertportletafter = conf.skin === 'timeless' ? '#p-lang' : '#p-coll-print_export';
$opportlet.insertAfter( insertportletafter );
$( '.wminc-otherprojects' ).each( function() {
var project = $( this ).attr( 'data-project' ),
url = $( this ).attr( 'data-url' );
mw.util.addPortletLink( 'p-wikibase-otherprojects', url, mw.msg( 'wikibase-otherprojects-' + project ) ).classList.add( 'wb-otherproject-link', 'wb-otherproject-' + project );
});
}
mw.hook( 'mobileFrontend.languageSearcher.onOpen' ).add( function( langoverlay ) {
$( langoverlay.$el ).find( 'span.title' ).each( function() {
var title = $( this ).text();
title = title.replace( /^(b|wikibooks|n|wikinews|q|wikiquote|s|wikisource|v|wikiversity|voy|wikivoyage|wikt|wiktionary):/i, '' );
$( this ).text( title );
});
});
});
} else if (
// We are on a Wiktionary project
conf.wgWmincTestwikiProject === 't' &&
// We are in the main namespace
conf.wgNamespaceNumber === 0 &&
// We are on an actual page (not a project's info page)
conf.wgWmincRealPagename &&
// We are viewing the page (not editing, deliting, etc.)
conf.wgAction === 'view'
) {
// The API query only includes pages on other domains.
// To avoid having to do a second query to find out whether
// the page exists on the API's domain, we can instead take
// advantage of aa.wiktionary.org being a closed wiki with no pages.
var aaapi = new mw.ForeignApi( 'https://aa.wiktionary.org/w/api.php' ),
lemma = conf.wgWmincRealPagename;
// Add OOUI's pending class as a visual hint that the element will change
$( '#p-lang, #p-lang-btn, #language-selector' ).addClass( 'oo-ui-pendingElement-pending' );
aaapi.get( {
'action': 'parse',
'prop': 'langlinks',
'text': '',
'title': lemma,
} ).then( function ( data ) {
if ( !data.parse.langlinks.length ) {
$( '#p-lang, #p-lang-btn, #language-selector' ).removeClass( 'oo-ui-pendingElement-pending' );
return;
}
if ( conf.skin === 'vector-2022' ) {
new mw.Api().loadMessagesIfMissing( [
'vector-language-button-label',
'vector-language-button-aria-label',
'interlanguage-link-title'
] ).then( function() {
$( '#p-lang-btn' )
.removeClass( [ 'mw-portlet-empty', 'oo-ui-pendingElement-pending' ] )
.addClass( [ 'mw-portlet', 'mw-portlet-lang' ] );
$( '#p-lang-btn-checkbox' )
.attr( 'aria-label', mw.msg( 'vector-language-button-aria-label', mw.language.convertNumber( data.parse.langlinks.length ) ) );
$( '#p-lang-btn-label .vector-menu-heading-label, #p-lang-btn-sticky-header span:last-of-type' )
.text( mw.msg( 'vector-language-button-label', mw.language.convertNumber( data.parse.langlinks.length ) ) );
$.each( data.parse.langlinks.sort( sort_languages ), function( i, v ) {
var $li = $( '<li>' )
.addClass( 'interlanguage-link interwiki-' + v.lang + ' mw-list-item' );
var $langlink = $( '<a>' )
.addClass( 'interlanguage-link-target' )
.attr( 'href', v.url )
.attr( 'title', mw.msg( 'interlanguage-link-title', v[ '*' ], v.langname ) )
.attr( 'hreflang', v.lang )
.attr( 'lang', v.lang )
.html( '<span>' + v.autonym + '</span>' )
.appendTo( $li );
$( '#p-lang-btn ul.vector-menu-content-list' ).append( $li );
} );
} );
} else if ( conf.skin === 'minerva' ) {
new mw.Api().loadMessagesIfMissing( [
'parentheses',
'mobile-frontend-languages-structured-overlay-all-languages-header',
'mobile-frontend-languages-structured-overlay-suggested-languages-header'
] ).then( function() {
$( '#language-selector' ).removeClass( 'oo-ui-pendingElement-pending' );
var $langselector = $( '#language-selector a' );
$langselector.removeClass( 'disabled' );
$langselector.attr( 'href', '#' ); // so that it goes to the language page instead of showing an error
mw.hook( 'mobileFrontend.languageSearcher.onOpen' ).add( function( langoverlay ) {
$( langoverlay.$el ).find( '.panel' ).remove();
var $overlay = $( langoverlay.$el ).find( '.overlay-content-body' );
var $suggestedLangHeader = $( '<h3>' )
.addClass( 'list-header' )
.text( mw.msg( 'mobile-frontend-languages-structured-overlay-suggested-languages-header' ) );
var $suggestedLangList = $( '<ol>' ).addClass( 'site-link-list suggested-languages' );
var suggestedLangCount = 0;
var $otherLangHeader = $( '<h3>' )
.addClass( 'list-header' )
.text( mw.msg( 'mobile-frontend-languages-structured-overlay-all-languages-header' ) );
var $otherLangList = $( '<ol>' ).addClass( 'site-link-list all-languages' );
var otherLangCount = 0;
$.each( data.parse.langlinks.sort( sort_languages ), function( i, v ) {
var $li = $( '<li>' );
var $langlink = $( '<a>' )
.attr( 'lang', v.lang )
.attr( 'hreflang', v.lang )
.attr( 'href', v.url )
.attr( 'dir', $.uls.data.getDir( v.lang ) )
.append( $( '<span class="autonym">').text( v.autonym ) )
.append( $( '<span class="title">').text( lemma ) );
$li.append( $langlink );
if ( babel.includes( v.lang ) ) {
$suggestedLangList.append( $li );
++suggestedLangCount;
} else {
$otherLangList.append( $li );
++otherLangCount;
}
} );
if ( suggestedLangCount ) {
$suggestedLangHeader.append( ' ' + mw.msg( 'parentheses', mw.language.convertNumber( suggestedLangCount ) ) );
$overlay.append( $suggestedLangHeader, $suggestedLangList );
}
if ( otherLangCount ) {
$otherLangHeader.append( ' ' + mw.msg( 'parentheses', mw.language.convertNumber( otherLangCount ) ) );
$overlay.append( $otherLangHeader, $otherLangList );
}
});
});
} else {
$( '#p-lang' ).removeClass( 'oo-ui-pendingElement-pending' );
$( '#p-lang ul.vector-menu-content-list' ).empty();
$.each( data.parse.langlinks.sort( sort_languages ), function ( i, v ) {
var autonym = v.autonym;
if ( v.lang !== 'ka' ) {
autonym = autonym.charAt( 0 ).toUpperCase() + autonym.slice( 1 );
}
mw.util.addPortletLink( 'p-lang', v.url, autonym );
} );
}
} );
} else {
if (
// Not in a test wiki
!conf.wgWmincRealPagename ||
// On a talk page
conf.wgNamespaceNumber % 2 !== 0 ||
// In the Module namespace
( conf.wgNamespaceNumber === 828 && !/\/doc$/.test( conf.wgWmincRealPagename ) ) ||
// In a test Wiktionary entry (interwikis there are handled by another part of this gadget)
( conf.wgWmincTestwikiProject === 't' && conf.wgNamespaceNumber === 0 ) ||
// The page doesn't exist
conf.wgArticleId === 0 ||
// You're editing the page, not simply viewing it
conf.wgAction !== 'view' ||
// The user is not logged in
!conf.wgUserId ||
// You are viewing an old revision of the page
( conf.wgRevisionId !== conf.wgCurRevisionId ) ||
// You can edit the page
!conf.wgIsProbablyEditable
) {
// Do nothing
return;
} else {
// If the following has a match, that means that there are old-style
// interwiki links on the page. If that is the case, we will attempt
// to switch them out with the {{INTERWIKI}} template instead.
var replaceOldIw = !!$( '.mw-portlet-lang, #p-lang' ).find( '.interlanguage-link-target' ).length || !!$( '#language-selector a' ).attr( 'href' ),
triggerSelector = '#wminc-addinterwiki a, #p-lang-btn, #p-lang-btn-sticky-header',
oldIwHref;
new mw.Api().getMessages(
// This message is loaded in a special way because it should
// preferrably be in the page's content language and not in the
// user interface language.
[
'wminc-gadget-iw-editsummary'
],
{ amlang: conf.wgPageContentLanguage }
).then( function( msgs ) {
mw.messages.set( msgs );
});
new mw.Api().loadMessagesIfMissing( [
'accesskey-publish',
'accesskey-t-wikibase',
'pipe-separator',
'wikibase-addlinkstitle',
'wikibase-linkitem-addlinks',
'wminc-gadget-iw-add-wikidata',
'wminc-gadget-iw-dialog-cancel',
'wminc-gadget-iw-dialog-editpage',
'wminc-gadget-iw-dialog-learn-more',
'wminc-gadget-iw-dialog-publish',
'wminc-gadget-iw-dialog-qid-placeholder',
'wminc-gadget-iw-dialog-replace-editinstead',
'wminc-gadget-iw-dialog-replace-text',
'wminc-gadget-iw-dialog-title',
'wminc-gadget-iw-dialog-text',
'wminc-gadget-iw-dialog-wikidata-search',
'wminc-gadget-iw-error-invalid',
'wminc-gadget-iw-error-reload',
'wminc-gadget-iw-error-title'
] ).then( function() {
var portlet = 'p-lang',
addlinkmsg = 'wikibase-linkitem-addlinks';
if ( conf.skin === 'vector-2022' ) {
portlet = 'p-tb';
addlinkmsg = 'wikibase-addlinkstitle';
}
if ( replaceOldIw ) {
addlinkmsg = 'wminc-gadget-iw-add-wikidata';
if ( conf.skin !== 'minerva' ) {
triggerSelector = '#wminc-addinterwiki a';
var oldIwSelector = $( '.mw-portlet-lang, #p-lang ' ).find( '.interlanguage-link-target' ),
random = Math.floor( Math.random() * oldIwSelector.length ),
chosenIw = oldIwSelector[ random ];
for ( var i = 0; i < langPriList.length; i++ ) {
var lang = langPriList.reverse()[ i ];
if ( $( '.interlanguage-link-target[lang=' + lang + ']' ).length ) {
chosenIw = $( '.interlanguage-link-target[lang=' + lang + ']' )[ 0 ];
}
}
oldIwHref = chosenIw.href;
} else {
if ( $( '#language-selector a' ).hasClass( 'disabled' ) ) {
triggerSelector = '#language-selector a';
$( triggerSelector )
.removeClass( [ 'mw-ui-icon-wikimedia-language-base20', 'disabled' ] )
.addClass( 'gadget-iw-icon-addlang' );
} else {
$( 'body' ).append( '<a id="wminc-dummylink" style="display:none;"></a>' );
triggerSelector = '#wminc-dummylink';
mw.hook( 'mobileFrontend.languageSearcher.onOpen' ).add( function( langoverlay ) {
var oldIws = langoverlay.$languageItems,
random = Math.floor( Math.random() * oldIws.length ),
chosenIw = oldIws[ random ];
for ( var i = 0; i < langPriList.length; i++ ) {
var lang = langPriList.reverse()[ i ];
if ( $( langoverlay.$el ).find( 'a.' + lang ).length ) {
chosenIw = $( langoverlay.$el ).find( 'a.' + lang )[ 0 ];
}
}
oldIwHref = chosenIw.href;
var $addwdlink = $( '<ol>' ).addClass( 'site-link-list' )
.append( $( '<li id="wminc-addinterwiki">' )
.append( $( '<a>' )
.append( '<span class="mw-ui-icon gadget-iw-icon-addlang"></span>' )
.append( '<span>' + mw.msg( addlinkmsg ) + '</span>' )
.on( 'click', function() {
$( '#wminc-dummylink' ).click();
})
)
);
$( langoverlay.$el ).find( '.overlay-content-body' ).prepend( $addwdlink );
});
}
}
}
mw.util.addPortletLink(
portlet,
mw.util.getUrl( null, { action: 'edit' } ),
mw.msg( addlinkmsg ),
'wminc-addinterwiki',
null,
mw.msg( 'accesskey-t-wikibase' )
);
// Minerva specific
if ( $( '#language-selector a' ).hasClass( 'disabled' ) ) {
triggerSelector = '#language-selector a';
$( triggerSelector )
.removeClass( [ 'mw-ui-icon-wikimedia-language-base20', 'disabled' ] )
.addClass( 'gadget-iw-icon-addlang' );
}
$( triggerSelector ).on( 'click', function( e ) {
e.preventDefault();
e.stopPropagation();
function AddInterwikiDialog( config ) {
AddInterwikiDialog.super.call( this, config );
}
OO.inheritClass( AddInterwikiDialog, OO.ui.ProcessDialog );
AddInterwikiDialog.static.name = 'addInterwikiDialog';
AddInterwikiDialog.static.title = mw.msg( 'wminc-gadget-iw-dialog-title' );
var saveButton = new OO.ui.ActionWidget( {
action: 'save',
label: mw.msg( 'wminc-gadget-iw-dialog-publish' ),
flags: [ 'primary', 'progressive' ],
framed: true,
tabIndex: replaceOldIw ? 1 : 2,
accessKey: mw.msg( 'accesskey-publish' )
});
AddInterwikiDialog.static.actions = [
saveButton,
{
label: mw.msg( 'wminc-gadget-iw-dialog-cancel' ),
flags: 'safe',
tabIndex: 3,
icon: 'close',
invisibleLabel: true
}
];
var qidinput = new OO.ui.TextInputWidget( {
placeholder: mw.msg( 'wminc-gadget-iw-dialog-qid-placeholder', 'Q12345' ),
tabIndex: 1,
validate: analyzeInput,
spellcheck: false,
accessKey: ','
}).on( 'change', function( value ) {
qidinput.getValidity().then( function() {
saveButton.setDisabled( false );
}, function() {
saveButton.setDisabled( true );
});
}).on( 'enter', function() {
qidinput.getValidity().then( function() {
dialog.executeAction( 'save' );
}, function() {
saveButton.setDisabled( true );
});
});
var editButton = new OO.ui.ButtonWidget( {
label: capitalize( mw.msg( 'wminc-gadget-iw-dialog-editpage' ) ),
title: capitalize( mw.msg( 'wminc-gadget-iw-dialog-editpage' ) ),
flags: [ 'progressive', 'primary' ],
href: mw.util.getUrl( null, { action: 'edit' } )
});
AddInterwikiDialog.prototype.initialize = function() {
AddInterwikiDialog.super.prototype.initialize.apply( this, arguments );
this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
if ( replaceOldIw ) {
this.content.$element
.append( $( '<p>' )
.text( mw.msg( 'wminc-gadget-iw-dialog-replace-text' ) )
).append( $( '<p>' )
.append( $( '<a>' )
.attr( 'href', oldIwHref )
.attr( 'target', '_blank' )
.text( mw.util.percentDecodeFragment( oldIwHref ) ) )
).append( $( '<p>' )
.text( mw.msg( 'wminc-gadget-iw-dialog-replace-editinstead' ) )
).append( editButton.$element );
} else {
this.content.$element
.append( $( '<p>' ).text( mw.message( 'wminc-gadget-iw-dialog-text' ).parse() ) )
.append( $( '<p>' ).css( 'text-align', 'end' )
.append( $( '<a>' )
.attr( 'href', mw.util.getUrl( 'Special:MyLanguage/Incubator:Wikidata' ) )
.attr( 'target', '_blank' )
.text( mw.msg( 'wminc-gadget-iw-dialog-learn-more' ) ) )
.append( mw.msg( 'pipe-separator' ) )
.append( $ ( '<a>' )
.attr( 'href', 'https://www.wikidata.org/wiki/Special:Search/' + conf.wgWmincRealPagename )
.attr( 'target', '_blank' )
.text( mw.msg( 'wminc-gadget-iw-dialog-wikidata-search' ) )
))
.append( qidinput.$element );
}
this.$body.append( this.content.$element );
};
AddInterwikiDialog.prototype.getActionProcess = function( action ) {
var dialog = this;
if ( action && action === 'save' && ( replaceOldIw || qidinput.getValue().length ) ) {
dialog.pushPending();
var input;
if ( replaceOldIw ) {
input = analyzeInput( oldIwHref );
if ( !input ) {
dialog.close();
mw.notify( mw.msg( 'wminc-gadget-iw-error-invalid' ), {
title: mw.msg( 'wminc-gadget-iw-error-title' ),
type: 'error',
autoHide: false
} );
return;
}
} else {
input = analyzeInput( qidinput.getValue() );
}
return new OO.ui.Process( function() {
if ( input ) {
var qidres;
var wdapi = new mw.ForeignApi( 'https://www.wikidata.org/w/api.php' );
if ( input.dbname ) {
qidres = wdapi.get( {
action: 'wbgetentities',
sites: input.dbname,
titles: input.pagename,
props: null,
normalize: 'yes'
});
} else {
qidres = wdapi.get( {
action: 'wbgetentities',
ids: input.qid,
props: null
});
}
qidres.then( function( data ) {
var qid = Object.keys( data.entities )[ 0 ];
if ( qid === '-1' || data.entities[ qid ].hasOwnProperty( 'missing' ) ) {
dialog.close();
mw.notify( mw.msg( 'wminc-gadget-iw-error-invalid' ), {
title: mw.msg( 'wminc-gadget-iw-error-title' ),
type: 'error',
autoHide: false
} );
} else {
var oldIwRegex = /(\[\[ *((?!mw:|doi:|voy)[a-z]{2,3}|simple)(-[a-z]+){0,2} *: *.+?\]\][\u00AD ]*\n*)+/g,
iwplaceholder = '!!IWGADGETREPLACEME!!',
insert = '{{INTERWIKI|' + qid + '}}';
new mw.Api().edit( conf.wgPageName, function( revision ) {
var source = revision.content,
tags = 'gadget-interwiki';
source = source.replace( oldIwRegex, iwplaceholder );
if ( conf.skin === 'minerva' ) {
tags = 'gadget-interwiki|gadget-interwiki-mobile';
}
if ( /<noinclude>(.|\n)*?!!IWGADGETREPLACEME!!(.|\n)*?<\/noinclude>/gi.test( source ) ) {
source = source.replace( iwplaceholder, insert + '\n' );
// .replace only replaces the first occurence.
// Just in case, let's replace any other occurences too.
source = source.replace( new RegExp( iwplaceholder, 'g' ), '' ).trimEnd();
} else if ( conf.wgNamespaceNumber === 10 ) {
source = source.replace( new RegExp( iwplaceholder, 'g' ), '' );
if ( /<\/noinclude>\s*$/i.test( source ) ) {
source = source.replace( /<\/noinclude>\s*$/i, '\n\n' + insert + '\n</noinclude>' );
} else {
source = source.trimEnd() + '<noinclude>\n\n' + insert + '\n</noinclude>';
}
} else {
source = source.replace( new RegExp( iwplaceholder, 'g' ), '' );
source = source.trimEnd() + '\n\n' + insert;
}
return {
text: source,
tags: tags,
summary: mw.msg( 'wminc-gadget-iw-editsummary', qid ),
minor: true,
baserevid: conf.wgRevisionId
};
}).then( function( data ) {
location.reload();
}).catch( function( err ) {
dialog.close();
mw.notify( $( '<p>' + err + '</p><p>' + mw.msg( 'wminc-gadget-iw-error-reload' ) + '</p>' ), {
title: mw.msg( 'wminc-gadget-iw-error-title' ),
type: 'error',
autoHide: false
});
});
}
}).catch( function( err ) {
dialog.close();
mw.notify( mw.msg( 'wminc-gadget-iw-error-invalid' ), {
title: mw.msg( 'wminc-gadget-iw-error-title' ),
type: 'error',
autoHide: false
} );
});
}
});
} else if ( action ) {
return new OO.ui.Process( function() {
dialog.close( { action: action } );
});
}
return AddInterwikiDialog.super.prototype.getActionProcess.call( this, action );
};
AddInterwikiDialog.prototype.getReadyProcess = function( data ) {
return AddInterwikiDialog.parent.prototype.getReadyProcess.call( this, data ).next( function() {
qidinput.focus();
}, this );
};
var windowManager = new OO.ui.WindowManager();
$( document.body ).append( windowManager.$element );
var dialog = new AddInterwikiDialog();
windowManager.addWindows( [ dialog ] );
windowManager.openWindow( dialog );
});
});
}
}
})();