MediaWiki:Common.js
MediaWiki interface page
More actions
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)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
( function () {
'use strict';
/* ---------- Live auto-updating grid (Platforms, Countries, Cities, etc.) ---------- */
function renderAutoGrid( $container ) {
var category = $container.data( 'category' );
if ( !category ) {
return;
}
$container.text( 'Loading...' );
mw.loader.using( 'mediawiki.api' ).then( function () {
return new mw.Api().get( {
action: 'query',
list: 'categorymembers',
cmtitle: 'Category:' + category,
cmlimit: 500,
cmsort: 'sortkey',
formatversion: 2,
format: 'json'
} );
} ).then( function ( data ) {
var members = ( data.query && data.query.categorymembers ) || [];
$container.empty();
if ( members.length === 0 ) {
$container.append( $( '<p>' ).text( 'Nothing has been added here yet.' ) );
return;
}
members.forEach( function ( member ) {
var title = member.title;
var displayName = title.split( ':' ).slice( 1 ).join( ':' ).split( '/' ).pop();
var $link = $( '<a>' )
.attr( 'href', mw.util.getUrl( title ) )
.text( displayName );
$container.append( $link );
} );
}, function () {
$container.text( 'Could not load this list right now.' );
} );
}
/* ---------- Instant-create core (used by typed-name forms AND letter clicks) ---------- */
function fallbackToManualEditor( newTitle, preloadTitle, $status, reason ) {
console.error( 'GAR instant-create fell back to manual editor. Reason: ' + reason + '. Title: ' + newTitle );
$status.text( ' Opening the normal editor instead...' );
window.location.href = mw.util.getUrl( newTitle, { action: 'edit', preload: preloadTitle } );
}
function safeReplacement( str ) {
return str.replace( /\$/g, '$$$$' );
}
function applyExtraFields( rawText, fields ) {
var text = rawText;
if ( fields.image ) {
text = text.replace( /\|image(\s*)=\s*\n/, function ( match, spacing ) {
return '|image' + spacing + '= ' + safeReplacement( fields.image ) + '\n';
} );
}
if ( fields.evidence ) {
text = text.replace( '<Add Picture Here>', safeReplacement( fields.evidence ) );
}
if ( fields.description ) {
text = text.replace( '<Write Text Here>', safeReplacement( fields.description ) );
}
return text;
}
function runInstantCreate( newTitle, preloadTitle, fields, $status ) {
$status.text( ' Creating...' );
mw.loader.using( 'mediawiki.api' ).then( function () {
var api = new mw.Api();
api.get( {
action: 'query',
titles: newTitle,
formatversion: 2,
format: 'json'
} ).then( function ( data ) {
var pages = ( data.query && data.query.pages ) || [];
var exists = false;
pages.forEach( function ( page ) {
if ( !page.missing ) {
exists = true;
}
} );
if ( exists ) {
$status.text( ' Already exists, opening it...' );
window.location.href = mw.util.getUrl( newTitle );
return;
}
api.get( {
action: 'query',
titles: preloadTitle,
prop: 'revisions',
rvprop: 'content',
rvslots: 'main',
formatversion: 2,
format: 'json'
} ).then( function ( tplData ) {
var tplPages = ( tplData.query && tplData.query.pages ) || [];
var rawText = '';
tplPages.forEach( function ( page ) {
if ( page.revisions && page.revisions[ 0 ] && page.revisions[ 0 ].slots && page.revisions[ 0 ].slots.main ) {
rawText = page.revisions[ 0 ].slots.main.content;
}
} );
if ( !rawText ) {
fallbackToManualEditor( newTitle, preloadTitle, $status, 'preload template came back empty' );
return;
}
var finalText = applyExtraFields( rawText, fields );
api.postWithToken( 'csrf', {
action: 'edit',
title: newTitle,
text: finalText,
createonly: true,
formatversion: 2,
summary: 'Auto-created'
} ).then( function ( editResult ) {
if ( editResult && editResult.edit && editResult.edit.result === 'Success' ) {
window.location.href = mw.util.getUrl( newTitle );
} else {
fallbackToManualEditor( newTitle, preloadTitle, $status, 'edit call did not report Success' );
}
}, function ( code, err ) {
fallbackToManualEditor( newTitle, preloadTitle, $status, 'edit call failed: ' + code );
} );
}, function ( code, err ) {
fallbackToManualEditor( newTitle, preloadTitle, $status, 'template fetch failed: ' + code );
} );
}, function ( code, err ) {
fallbackToManualEditor( newTitle, preloadTitle, $status, 'existence check failed: ' + code );
} );
} );
}
/* ---------- Typed-name forms (Platform, Country, City, Person, Case) ---------- */
function buildForm( $container ) {
var prefix = $container.data( 'prefix' );
var preloadTitle = $container.data( 'preload' );
var placeholder = $container.data( 'placeholder' ) || 'Enter a name';
var buttonLabel = $container.data( 'buttonlabel' ) || 'Add';
var extraFieldsRaw = $container.data( 'extrafields' ) || '';
var $input = $( '<input>' ).attr( 'type', 'text' ).attr( 'placeholder', placeholder ).css( 'width', '100%' ).css( 'margin-bottom', '6px' );
var $wrapper = $( '<div>' ).append( $input );
var extraInputs = {};
var plainExtraInputs = [];
if ( extraFieldsRaw ) {
extraFieldsRaw.split( ';' ).forEach( function ( pair ) {
var parts = pair.split( ':' );
var key = $.trim( parts[ 0 ] );
var label = $.trim( parts[ 1 ] || key );
var $extra;
if ( key === 'description' ) {
$extra = $( '<textarea>' ).attr( 'placeholder', label ).attr( 'rows', 3 ).css( 'width', '100%' ).css( 'margin-bottom', '6px' );
} else {
$extra = $( '<input>' ).attr( 'type', 'text' ).attr( 'placeholder', label ).css( 'width', '100%' ).css( 'margin-bottom', '6px' );
plainExtraInputs.push( $extra );
}
extraInputs[ key ] = $extra;
$wrapper.append( $( '<div>' ).append( $extra ) );
} );
}
var $button = $( '<button>' ).text( buttonLabel );
var $status = $( '<span>' ).addClass( 'gar-instant-status' );
$wrapper.append( $button, ' ', $status );
$container.empty().append( $wrapper );
function submit() {
var name = $.trim( $input.val() );
if ( !name ) {
return;
}
var fields = {};
for ( var key in extraInputs ) {
fields[ key ] = $.trim( extraInputs[ key ].val() );
}
runInstantCreate( prefix + name, preloadTitle, fields, $status );
}
$button.on( 'click', submit );
// Enter submits from the name field or any plain (non-textarea) extra field.
$input.on( 'keydown', function ( e ) {
if ( e.which === 13 ) {
e.preventDefault();
submit();
}
} );
plainExtraInputs.forEach( function ( $extra ) {
$extra.on( 'keydown', function ( e ) {
if ( e.which === 13 ) {
e.preventDefault();
submit();
}
} );
} );
}
/* ---------- Letter-grid clicks (A-Z navigation hops) ---------- */
function bindInstantLetter( $el ) {
$el.on( 'click', function () {
var title = $el.data( 'title' );
var preload = $el.data( 'preload' );
var $status = $( '<span>' ).addClass( 'gar-instant-status' );
$el.after( $status );
$el.off( 'click' );
$el.css( 'cursor', 'default' );
runInstantCreate( title, preload, {}, $status );
} );
}
/* ---------- Wire everything up once the page content is ready ---------- */
mw.hook( 'wikipage.content' ).add( function ( $content ) {
$content.find( '.gar-auto-grid' ).each( function () {
renderAutoGrid( $( this ) );
} );
$content.find( '.gar-instant-create' ).each( function () {
buildForm( $( this ) );
} );
$content.find( '.gar-instant-letter' ).each( function () {
bindInstantLetter( $( this ) );
} );
} );
}() );