Benutzer:ICON/TemplateWizard.js
Aus WiiDatabase Wiki
Zur Navigation springenZur Suche springen
Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.
- Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
- Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
- Internet Explorer/Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
- Opera: Strg+F5
( function ( mw, $ ) {
// <nowiki>
function defineClasses() {
/*
* Messages will be moved to JSON files later on.
*/
mw.messages.set( 'templatewizard', 'TemplateWizard (beta)' );
mw.messages.set( 'templatewizard-dialog-title', 'Vorlage einfügen' );
mw.messages.set( 'templatewizard-opens-in-new-tab', 'Öffnet in einem neuen Tab' );
mw.messages.set( 'templatewizard-help-page', 'Hilfeseite' );
mw.messages.set( 'templatewizard-invalid-title', 'Ungültiger Titel' );
mw.messages.set( 'templatewizard-template-not-found',
'$1 kann nicht im TemplateWizard genutzt werden.' +
' Dies liegt eventuell daran, dass die Vorlage nicht existiert oder keine $2-Tags besitzt.' +
' Bitte behebe dies und versuche es erneut.'
);
mw.messages.set( 'templatewizard-default', 'Standard: $1' );
mw.messages.set( 'templatewizard-example', 'Beispiel: $1' );
mw.messages.set( 'templatewizard-parameters-required', 'Erforderliche Parameter' );
mw.messages.set( 'templatewizard-parameters-suggested', 'Vorgeschlagene Parameter' );
mw.messages.set( 'templatewizard-parameters-optional', 'Optionale Parameter' );
mw.messages.set( 'templatewizard-insert', 'Einfügen' );
mw.messages.set( 'templatewizard-cancel', 'Abbrechen' );
mw.messages.set( 'templatewizard-use', 'Benutzen' );
mw.messages.set( 'templatewizard-select-template', 'Wähle eine Vorlage:' );
/* Extension namespace. */
mediaWiki.TemplateWizard = {};
/**
* @class
* @constructor
* @param {Object} [config] Configuration options
*/
mediaWiki.TemplateWizard.TemplateForm = function mediaWikiTemplateWizardTemplateForm( config ) {
// Parent constructor
OO.ui.Widget.parent.call( this, config );
this.$element = $( '<div>' ).addClass( 'ext-templatewizard-templateform' );
};
OO.inheritClass( mediaWiki.TemplateWizard.TemplateForm, OO.ui.Widget );
/**
* Set the template title.
* @param {string} newTitle No leading 'Template:' required.
*/
mediaWiki.TemplateWizard.TemplateForm.prototype.setTitle = function ( newTitle ) {
this.title = mw.Title.newFromText( newTitle, mw.config.get( 'wgNamespaceIds' ).template );
if ( !this.title ) {
throw new Error( mw.message( 'templatewizard-invalid-title' ) );
}
this.$element.append( this.getHeader() );
this.loadTemplateData();
};
mediaWiki.TemplateWizard.TemplateForm.prototype.setDialog = function ( dialog ) {
this.dialog = dialog;
};
mediaWiki.TemplateWizard.TemplateForm.prototype.getTitle = function () {
return this.title;
};
mediaWiki.TemplateWizard.TemplateForm.prototype.getFormat = function () {
return this.format;
};
mediaWiki.TemplateWizard.TemplateForm.prototype.getHeader = function () {
var link;
link = $( '<a>' )
.attr( 'target', '_blank' )
.attr( 'title', mw.message( 'templatewizard-opens-in-new-tab' ) )
.attr( 'href', this.title.getUrl() )
.text( this.title.getMainText() );
return $( '<h2>' ).html( link );
};
mediaWiki.TemplateWizard.TemplateForm.prototype.getInputWidgetForParam = function ( param, paramDefinition ) {
var widget, config = { name: param };
if ( paramDefinition.autovalue ) {
config.value = paramDefinition.autovalue;
}
if ( paramDefinition.required ) {
config.required = true;
}
if ( paramDefinition.type === 'number' ) {
widget = new OO.ui.NumberInputWidget( config );
} else if ( paramDefinition.type === 'date' ) {
widget = new mw.widgets.DateInputWidget( config );
} else if ( paramDefinition.type === 'wiki-user-name' ) {
widget = new mw.widgets.UserInputWidget( config );
} else if ( paramDefinition.type === 'wiki-page-name' ) {
widget = new mw.widgets.TitleInputWidget( config );
} else if ( paramDefinition.type === 'wiki-file-name' ) {
config.showImages = true;
config.namespace = mw.config.get( 'wgNamespaceIds' ).file;
widget = new mw.widgets.TitleInputWidget( config );
} else if ( paramDefinition.type === 'wiki-template-name' ) {
config.namespace = mw.config.get( 'wgNamespaceIds' ).template;
widget = new mw.widgets.TitleInputWidget( config );
} else {
widget = new OO.ui.TextInputWidget( config );
}
return widget;
};
mediaWiki.TemplateWizard.TemplateForm.prototype.getParameterFieldsets = function ( groupedParams ) {
var $fieldsets = $( '<div>' ),
self = this;
$.each( groupedParams, function ( groupName, group ) {
var fieldsetLabel = mw.message( 'templatewizard-parameters-' + groupName ).text(),
fieldset = new OO.ui.FieldsetLayout( { label: fieldsetLabel } );
if ( groupName === 'required' ) {
fieldset.$label.css( 'color', '#e04006' );
}
if ( groupName === 'suggested' ) {
fieldset.$label.css( 'color', '#f99d31' );
}
if ( groupName === 'optional' ) {
fieldset.$label.css( 'color', '#78ab46' );
}
$.each( group, function ( param, details ) {
var widget, field, label, description;
widget = self.getInputWidgetForParam( param, details );
description = '';
if ( details.description ) {
description = details.description;
}
if ( details.default ) {
description += '<br>' + mw.message( 'templatewizard-default', details.default ).escaped();
}
if ( details.example ) {
description += '<br>' + mw.message( 'templatewizard-example', details.example ).escaped();
}
label = param;
if ( details.label ) {
label = details.label;
}
field = new OO.ui.FieldLayout( widget, {
label: label,
help: new OO.ui.HtmlSnippet( description )
} );
fieldset.addItems( [ field ] );
} );
if ( !fieldset.isEmpty() ) {
$fieldsets.append( fieldset.$element );
}
} );
return $fieldsets;
};
mediaWiki.TemplateWizard.TemplateForm.prototype.processTemplateData = function ( apiResponse ) {
var id, templateData, description, templateLink, templateDataLink, helpLink, groupedParams;
// Get the first page's template data.
id = $.map( apiResponse.pages, function ( _value, key ) {
return key;
} );
templateData = apiResponse.pages[ id ];
// 1. Description.
description = '';
if ( templateData.description ) {
description = templateData.description;
} else if ( templateData.missing !== undefined || templateData.params === undefined ) {
// Treat non-existant and non-TemplateData templates the same.
templateLink = $( '<a>' )
.attr( 'target', '_blank' )
.attr( 'title', mw.message( 'templatewizard-opens-in-new-tab' ) )
.attr( 'href', this.title.getUrl() )
.text( '{{' + this.title.getMainText() + '}}' );
templateDataLink = $( '<a>' )
.attr( 'target', '_blank' )
.attr( 'title', mw.message( 'templatewizard-opens-in-new-tab' ) )
.attr( 'href', 'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:TemplateData#Structure_of_TemplateData' )
.text( 'TemplateData' );
helpLink = $( '<a>' )
.attr( 'target', '_blank' )
.attr( 'title', 'Opens in new tab' )
.attr( 'href', 'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Extension:TemplateWizard' )
.text( mw.message( 'templatewizard-help-page' ) );
description = mw.message(
'templatewizard-template-not-found',
templateLink[ 0 ].outerHTML,
templateDataLink[ 0 ].outerHTML,
helpLink[ 0 ].outerHTML
).plain();
}
if ( description ) {
this.$element.append( $( '<p>' ).addClass( 'description' ).append( description ) );
}
// 2. Parameters.
if ( templateData.params ) {
groupedParams = this.processParameters( templateData.params );
this.$element.append( this.getParameterFieldsets( groupedParams ) );
}
// 3. Format.
if ( templateData.format ) {
this.format = templateData.format;
} else {
this.format = 'inline';
}
};
mediaWiki.TemplateWizard.TemplateForm.prototype.getParameters = function () {
var params = {};
this.$element.find( ':input' ).each( function () {
var name = $( this ).attr( 'name' ),
value = $( this ).val();
if ( value ) {
params[ name ] = value;
}
} );
return params;
};
mediaWiki.TemplateWizard.TemplateForm.prototype.processParameters = function ( params ) {
var groupedParams = {
required: {},
suggested: {},
optional: {}
};
$.each( params, function ( param, details ) {
if ( details.deprecated ) {
// Don't include even a mention of a deprecated parameter.
return;
}
if ( details.required ) {
groupedParams.required[ param ] = details;
} else if ( details.suggested ) {
groupedParams.suggested[ param ] = details;
} else {
groupedParams.optional[ param ] = details;
}
} );
return groupedParams;
};
/**
*
*/
mediaWiki.TemplateWizard.TemplateForm.prototype.loadTemplateData = function () {
var templateForm = this;
templateForm.dialog.pushPending();
new mw.Api().get( {
action: 'templatedata',
titles: this.title.getPrefixedDb(),
redirects: true,
doNotIgnoreMissingTitles: true,
lang: mw.config.get( 'wgUserLanguage' )
} )
.done( function ( apiResponse ) {
var fieldsets = templateForm.processTemplateData( apiResponse );
templateForm.$element.append( fieldsets );
} )
.always( function () {
templateForm.dialog.popPending();
} );
};
/**
* @class
* @constructor
* @param {Object} [config] Configuration options.
* @param {OO.ui.ProcessDialog} [dialog] The dialog to attach the form to.
*/
mediaWiki.TemplateWizard.SearchForm = function mediaWikiTemplateWizardSearchForm( config, dialog ) {
config.padded = true;
config.expanded = true;
mediaWiki.TemplateWizard.SearchForm.super.call( this, config );
this.dialog = dialog;
this.titleSearchWidget = new mw.widgets.TitleInputWidget( {
validate: true,
namespace: mw.config.get( 'wgNamespaceIds' ).template
} );
this.titleSearchWidget.connect( this, { change: 'onSearchWidgetChange', enter: 'onSearchWidgetEnter' } );
this.searchButton = new OO.ui.ButtonWidget( { label: OO.ui.deferMsg( 'templatewizard-use' ), flags: [ 'progressive' ] } );
this.searchButton.connect( this, { click: 'onSearchButtonClick' } );
this.searchField = new OO.ui.ActionFieldLayout(
this.titleSearchWidget,
this.searchButton,
{ label: OO.ui.deferMsg( 'templatewizard-select-template' ) }
);
this.titleSearchWidget.emit( 'change' );
this.$element.append( this.searchField.$element );
};
OO.inheritClass( mediaWiki.TemplateWizard.SearchForm, OO.ui.PanelLayout );
mediaWiki.TemplateWizard.SearchForm.prototype.getTemplateForm = function () {
return this.templateForm;
};
mediaWiki.TemplateWizard.SearchForm.prototype.onSearchButtonClick = function () {
this.searchField.setErrors( [] );
this.templateForm = new mw.TemplateWizard.TemplateForm();
try {
this.templateForm.setDialog( this.dialog );
this.templateForm.setTitle( this.titleSearchWidget.value );
this.dialog.setResultsPanel( this.templateForm.$element );
this.dialog.actions.setMode( 'insert' );
} catch ( e ) {
this.titleSearchWidget.$input.focus();
this.titleSearchWidget.$element.addClass( 'oo-ui-flaggedElement-invalid' );
this.dialog.actions.setMode( 'choose' );
this.searchField.setErrors( [ e.message ] );
}
};
mediaWiki.TemplateWizard.SearchForm.prototype.onSearchWidgetChange = function () {
this.titleSearchWidget.$element.removeClass( 'oo-ui-flaggedElement-invalid' );
this.searchButton.setDisabled( !this.titleSearchWidget.value );
};
mediaWiki.TemplateWizard.SearchForm.prototype.onSearchWidgetEnter = function () {
this.searchButton.$button.focus();
this.searchButton.emit( 'click' );
};
/**
* @class
* @constructor
*/
mediaWiki.TemplateWizard.TemplateFormatter = function mwTemplateWizardTemplateFormatter() {
this.name = '';
this.format = '';
this.params = {};
};
OO.initClass( mediaWiki.TemplateWizard.TemplateFormatter );
mediaWiki.TemplateWizard.TemplateFormatter.static.FORMATSTRING_REGEXP =
/^(\n)?(\{\{ *_+)(\n? *\|\n? *_+ *= *)(_+)(\n? *\}\})(\n)?$/;
mediaWiki.TemplateWizard.TemplateFormatter.prototype.setTemplateName = function ( newName ) {
this.name = newName;
};
mediaWiki.TemplateWizard.TemplateFormatter.prototype.setParameters = function ( params ) {
this.params = params;
};
mediaWiki.TemplateWizard.TemplateFormatter.prototype.setFormat = function ( format ) {
var parsedFormat,
inlineFormat = '{{_|_=_}}';
if ( format === 'inline' ) {
format = inlineFormat;
}
if ( format === 'block' ) {
format = '{{_\n| _ = _\n}}';
}
// Check format string for validity, and fall back to 'inline' if it's not.
parsedFormat = format.match( this.constructor.static.FORMATSTRING_REGEXP );
if ( !parsedFormat ) {
parsedFormat = inlineFormat.match( this.constructor.static.FORMATSTRING_REGEXP );
}
this.format = {
startOfLine: parsedFormat[ 1 ],
start: parsedFormat[ 2 ],
paramName: parsedFormat[ 3 ],
paramValue: parsedFormat[ 4 ],
end: parsedFormat[ 5 ],
endOfLine: parsedFormat[ 6 ]
};
};
mediaWiki.TemplateWizard.TemplateFormatter.prototype.getFormat = function () {
if ( !this.format ) {
this.setFormat( 'inline' );
}
return this.format;
};
mediaWiki.TemplateWizard.TemplateFormatter.prototype.getTemplate = function () {
var template,
formatter = this,
format = this.getFormat();
// Start building the template.
template = '';
if ( format.startOfLine ) {
template += '\n';
}
template += this.constructor.static.formatStringSubst( format.start, this.name );
// Process the parameters.
$.each( formatter.params, function ( key, val ) {
template += formatter.constructor.static.formatStringSubst( format.paramName, key ) +
formatter.constructor.static.formatStringSubst( format.paramValue, val );
} );
// End and return the template.
template += format.end;
if ( format.endOfLine && !template.match( /\n$/ ) ) {
template += '\n';
}
return template;
};
/**
* Format a part of the template, based on the TemplateData format string.
* This method is based on that of the same name in Parsoid:
* https://github.com/wikimedia/parsoid/blob/9c80dd597a8c057d43598303fd53e90cbed4ffdb/lib/html2wt/WikitextSerializer.js#L405
* @param {String} format
* @param {String} value
* @return {String}
*/
mediaWiki.TemplateWizard.TemplateFormatter.static.formatStringSubst = function ( format, value ) {
value = value.trim();
return format.replace( /_+/, function ( hole ) {
if ( value === '' || hole.length <= value.length ) {
return value;
}
// Right-pad with spaces.
while ( value.length < hole.length ) {
value += ' ';
}
return value; // + ( ' '.repeat( hole.length - value.length ) );
} );
};
/**
* The main dialog box for the TemplateWizard.
* @class
* @constructor
* @extends OO.ui.ProcessDialog
* @param {object} config
*/
mediaWiki.TemplateWizard.Dialog = function mediaWikiTemplateWizardDialog( config ) {
mediaWiki.TemplateWizard.Dialog.super.call( this, config );
};
OO.inheritClass( mediaWiki.TemplateWizard.Dialog, OO.ui.ProcessDialog );
mediaWiki.TemplateWizard.Dialog.static.name = 'templateWizard';
mediaWiki.TemplateWizard.Dialog.static.title = OO.ui.deferMsg( 'templatewizard-dialog-title' );
mediaWiki.TemplateWizard.Dialog.static.actions = [
{ label: OO.ui.deferMsg( 'templatewizard-insert' ), flags: [ 'primary', 'progressive' ], action: 'insert', modes: 'insert' },
{ label: OO.ui.deferMsg( 'templatewizard-cancel' ), flags: 'safe', modes: [ 'choose', 'insert' ] }
];
mediaWiki.TemplateWizard.Dialog.prototype.getBodyHeight = function () {
return 400;
};
mediaWiki.TemplateWizard.Dialog.prototype.initialize = function () {
mediaWiki.TemplateWizard.Dialog.super.prototype.initialize.apply( this, arguments );
// Set up the search form and results panel.
this.searchForm = new mw.TemplateWizard.SearchForm( {}, this );
this.resultsPanel = new OO.ui.PanelLayout( { padded: true, expanded: true } );
// Put the panels together and add to the dialog body.
this.stack = new OO.ui.StackLayout( { items: [ this.searchForm, this.resultsPanel ], continuous: true } );
this.$body.append( this.stack.$element );
};
mediaWiki.TemplateWizard.Dialog.prototype.setResultsPanel = function ( panelContents ) {
this.resultsPanel.$element.html( panelContents );
};
mediaWiki.TemplateWizard.Dialog.prototype.getSetupProcess = function ( data ) {
return mediaWiki.TemplateWizard.Dialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
this.actions.setMode( 'choose' );
}, this );
};
mediaWiki.TemplateWizard.Dialog.prototype.getActionProcess = function ( action ) {
var dialog = this, templateFormatter;
if ( action === 'insert' ) {
templateFormatter = new mw.TemplateWizard.TemplateFormatter();
templateFormatter.setTemplateName( this.searchForm.getTemplateForm().getTitle().getMainText() );
templateFormatter.setFormat( this.searchForm.getTemplateForm().getFormat() );
templateFormatter.setParameters( this.searchForm.getTemplateForm().getParameters() );
$( '#wpTextbox1' ).textSelection( 'encapsulateSelection', { post: templateFormatter.getTemplate() } );
return new OO.ui.Process( function () {
dialog.close( { action: action } );
} );
}
// Fallback to parent handler.
return mediaWiki.TemplateWizard.Dialog.super.prototype.getActionProcess.call( this, action );
};
addButton();
}
function addButton() {
$( '#wpTextbox1' ).wikiEditor( 'addToToolbar', {
section: 'main',
group: 'insert',
tools: {
'template-wizard': {
labelMsg: 'templatewizard-dialog-title',
type: 'button',
icon: 'https://wiki.wiidatabase.de/images/e/ef/Puzzle.png',
action: {
type: 'callback',
execute: function () {
var templateWizard = new mw.TemplateWizard.Dialog(),
windowManager = new OO.ui.WindowManager();
$( 'body' ).append( windowManager.$element );
windowManager.addWindows( [ templateWizard ] );
windowManager.openWindow( templateWizard );
}
}
}
}
} );
}
function main() {
// @TODO $( '#wpTextbox1' ).on( 'wikiEditor-toolbar-doneInitialSections', addButton );
var isEditing = $.inArray( mw.config.get( 'wgAction' ), [ 'edit', 'submit' ] ) !== -1;
if ( !isEditing ) {
return;
}
// Otherwise, add the toolbar button.
mw.loader.using( 'user.options', function () {
var dependencies;
// This can be the string "0" if the user disabled the preference.
if ( mw.user.options.get( 'usebetatoolbar' ) ) {
dependencies = [
'ext.wikiEditor',
'jquery.textSelection',
'oojs-ui-core',
'oojs-ui-windows',
'oojs-ui-widgets',
'mediawiki.widgets',
'mediawiki.widgets.UserInputWidget',
'mediawiki.widgets.DateInputWidget'
];
mw.loader.using( dependencies, $.ready ).then( defineClasses );
}
} );
}
main();
// </nowiki>
}( mediaWiki, jQuery ) );