MediaWiki:Common.js: Difference between revisions
MediaWiki interface page
More actions
Palindromayd (talk | contribs) No edit summary |
Palindromayd (talk | contribs) No edit summary |
||
| Line 1: | Line 1: | ||
( function () { | ( function () { | ||
'use strict'; | 'use strict'; | ||
/* ---------- Live auto-updating grid (Platforms, Countries, Cities, etc.) ---------- */ | |||
function renderAutoGrid( $container ) { | function renderAutoGrid( $container ) { | ||
| Line 40: | Line 42: | ||
} ); | } ); | ||
} | } | ||
/* ---------- Instant-create forms (Country, City, Person, Case) ---------- */ | |||
function fallbackToManualEditor( newTitle, preloadTitle, $status ) { | |||
$status.text( ' Opening the normal editor instead...' ); | |||
window.location.href = mw.util.getUrl( newTitle, { action: 'edit', preload: preloadTitle } ); | |||
} | |||
function safeReplacement( str ) { | |||
// Prevents literal "$" sequences a user types from being | |||
// misread as regex backreferences by String.replace(). | |||
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, | |||
format: 'json' | |||
} ).then( function ( data ) { | |||
var pages = data.query.pages; | |||
var exists = false; | |||
for ( var id in pages ) { | |||
if ( !pages[ id ].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', | |||
format: 'json' | |||
} ).then( function ( tplData ) { | |||
var tplPages = tplData.query.pages; | |||
var rawText = ''; | |||
for ( var id in tplPages ) { | |||
var revs = tplPages[ id ].revisions; | |||
if ( revs && revs[ 0 ] && revs[ 0 ].slots && revs[ 0 ].slots.main ) { | |||
rawText = revs[ 0 ].slots.main[ '*' ]; | |||
} | |||
} | |||
var finalText = applyExtraFields( rawText, fields ); | |||
api.postWithToken( 'csrf', { | |||
action: 'edit', | |||
title: newTitle, | |||
text: finalText, | |||
createonly: true, | |||
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 ); | |||
} | |||
}, function () { | |||
fallbackToManualEditor( newTitle, preloadTitle, $status ); | |||
} ); | |||
}, function () { | |||
fallbackToManualEditor( newTitle, preloadTitle, $status ); | |||
} ); | |||
}, function () { | |||
fallbackToManualEditor( newTitle, preloadTitle, $status ); | |||
} ); | |||
} ); | |||
} | |||
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 = {}; | |||
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' ); | |||
} | |||
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 ); | |||
$button.on( 'click', function () { | |||
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 ); | |||
} ); | |||
} | |||
/* ---------- Wire everything up once the page content is ready ---------- */ | |||
mw.hook( 'wikipage.content' ).add( function ( $content ) { | mw.hook( 'wikipage.content' ).add( function ( $content ) { | ||
$content.find( '.gar-auto-grid' ).each( function () { | $content.find( '.gar-auto-grid' ).each( function () { | ||
renderAutoGrid( $( this ) ); | renderAutoGrid( $( this ) ); | ||
} ); | |||
$content.find( '.gar-instant-create' ).each( function () { | |||
buildForm( $( this ) ); | |||
} ); | } ); | ||
} ); | } ); | ||
}() ); | }() ); | ||
Revision as of 14:04, 27 June 2026
( 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',
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 forms (Country, City, Person, Case) ---------- */
function fallbackToManualEditor( newTitle, preloadTitle, $status ) {
$status.text( ' Opening the normal editor instead...' );
window.location.href = mw.util.getUrl( newTitle, { action: 'edit', preload: preloadTitle } );
}
function safeReplacement( str ) {
// Prevents literal "$" sequences a user types from being
// misread as regex backreferences by String.replace().
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,
format: 'json'
} ).then( function ( data ) {
var pages = data.query.pages;
var exists = false;
for ( var id in pages ) {
if ( !pages[ id ].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',
format: 'json'
} ).then( function ( tplData ) {
var tplPages = tplData.query.pages;
var rawText = '';
for ( var id in tplPages ) {
var revs = tplPages[ id ].revisions;
if ( revs && revs[ 0 ] && revs[ 0 ].slots && revs[ 0 ].slots.main ) {
rawText = revs[ 0 ].slots.main[ '*' ];
}
}
var finalText = applyExtraFields( rawText, fields );
api.postWithToken( 'csrf', {
action: 'edit',
title: newTitle,
text: finalText,
createonly: true,
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 );
}
}, function () {
fallbackToManualEditor( newTitle, preloadTitle, $status );
} );
}, function () {
fallbackToManualEditor( newTitle, preloadTitle, $status );
} );
}, function () {
fallbackToManualEditor( newTitle, preloadTitle, $status );
} );
} );
}
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 = {};
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' );
}
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 );
$button.on( 'click', function () {
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 );
} );
}
/* ---------- 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 ) );
} );
} );
}() );