Uživatel:Miroslav.gajda/common.js: Porovnání verzí

Řádek 1: Řádek 1:
 
/* Translate the following to your language: */
 
/* Translate the following to your language: */
mw.hook( 've.activationComplete' ).add(function(){
+
//mw.hook( 've.activationComplete' ).add(function(){
if (!mw.messages.exists( 've-SearchAndReplaceDialog-title' )) {
+
//});
mw.messages.set({
+
 
've-SearchAndReplaceDialog-title': 'Search and replace',
+
 
've-SearchAndReplaceDialog-from-label': 'From:',
+
mw.loader.using( 'ext.visualEditor.viewPageTarget.init' ).done( function () {
've-SearchAndReplaceDialog-to-label': 'To:',
 
've-SearchAndReplaceDialog-from-placeholder': 'From text',
 
've-SearchAndReplaceDialog-to-placeholder': 'To text',
 
've-SearchAndReplaceDialog-replaceAll': 'Repalce all',
 
've-SearchAndReplaceDialog-replace': 'Repalce',
 
've-SearchAndReplaceDialog-matchcase': 'Match case',
 
've-SearchAndReplaceDialog-replace-complete': 'Found and replaced $1 occurrences',
 
've-ReplaceTool-ToolbarButton': 'Replace'
 
});
 
}
 
/* end of translations */
 
 
   
 
   
/*!
+
/*
* VisualEditor replace gadget
+
* Localisation messages.
*
+
*/
* @copyright [[User:ערן|Eranroz]] and [[User:Ravid ziv|Ravid ziv]]
+
var translations = {
* @license The MIT License (MIT)
+
en: {
*/
+
'visualeditor-mwsignatureinspector-title': "Your signature"
function extractText(){
+
},
var nodes = [];
+
pl: {
var model = ve.instances[0].model;
+
'visualeditor-mwsignatureinspector-title': "Twój podpis"
function getTextNodes( obj ) {
+
}
var i;
+
};
 
   
 
   
for ( i = 0; i < obj.children.length; i++ ) {
+
var userLanguage = mw.config.get( 'wgUserLanguage' );
if ( obj.children[i].type == 'text'){
+
mw.messages.set( translations[userLanguage] || translations.en );
nodes.push(obj.children[i]);
 
}
 
 
   
 
   
if ( obj.children[i].children ) {
+
// This configuration method might change without warning in the future if core MediaWiki gets a
getTextNodes( obj.children[i] );
+
// better way to specify which namespaces may have signatures.
}
+
var currentNamespace = mw.config.get( 'wgNamespaceNumber' );
}
+
var noSigNamespaces = mw.config.exists( 'wgVisualEditorNoSignatureNamespaces' ) ?
 +
mw.config.get( 'wgVisualEditorNoSignatureNamespaces' ) :
 +
mw.config.get( 'wgContentNamespaces' );
 +
 +
// Most of all, never enable this in content namespaces (unless configured otherwise).
 +
if ( $.inArray( currentNamespace, noSigNamespaces ) !== -1 ) {
 +
return;
 
}
 
}
getTextNodes(ve.instances[0].model.documentModel.getDocumentNode());
 
return nodes;
 
}
 
 
   
 
   
function searchAndReplace( fromText, toText, replaceAll, matchCase ) {
+
// Add signature icon
var textNodes = extractText();
+
mw.loader.using( 'mediawiki.util' ).done( function () {
var model = ve.instances[0].model;
+
mw.util.addCSS(
var firstIndex = 0;
+
'.oo-ui-icon-signature {' +
var numReplacements = 0;
+
'background-image: url(//upload.wikimedia.org/wikipedia/commons/a/a0/WikiFont_signature_icon.svg);' +
for (var nodeI = 0; nodeI < textNodes.length; nodeI++) {
+
'}'
var node = textNodes[nodeI];
+
);
var nodeRange = node.getRange();
+
} );
var nodeData = model.getFragment( nodeRange ).getData();
+
var nodeText = $.map(nodeData, function( e ){
+
mw.libs.ve.addPlugin( function () {
if ( e instanceof Array){ return e[0]; } else { return e; }
+
return mw.loader.using( ['ext.visualEditor.core', 'ext.visualEditor.mwtransclusion', 'mediawiki.api'] )
}).join('');
+
.done( function () {
 +
/*
 +
* Update the timestamp on inserted signatures every minute.
 +
*/
 +
var liveSignatures = [];
 +
setInterval( function () {
 +
var updatedSignatures = [];
 +
for ( var i = 0; i < liveSignatures.length; i++ ) {
 +
var sig = liveSignatures[i];
 +
try {
 +
sig.forceUpdate();
 +
updatedSignatures.push( sig );
 +
} catch ( er ) {
 +
// Do nothing
 +
}
 +
}
 +
liveSignatures = updatedSignatures;
 +
}, 60 * 1000 );
 +
 +
 +
/**
 +
* ContentEditable MediaWiki signature node. This defines the behavior of the signature node
 +
* inserted into the ContentEditable document.
 +
*
 +
* @class
 +
* @extends ve.ce.MWTransclusionInlineNode
 +
*
 +
* @constructor
 +
* @param {ve.dm.MWSignatureNode} model Model to observe
 +
*/
 +
ve.ce.MWSignatureNode = function VeCeMWSignatureNode( model ) {
 +
// Parent constructor
 +
ve.ce.MWTransclusionInlineNode.call( this, model );
 +
 +
// DOM changes
 +
this.$element.addClass( 've-ce-mwSignatureNode' );
 +
 +
// Keep track for magical text updating
 +
liveSignatures.push( this );
 +
};
 +
 +
/* Inheritance */
 +
 +
OO.inheritClass( ve.ce.MWSignatureNode, ve.ce.MWTransclusionInlineNode );
 +
 +
/* Static Properties */
 +
 +
ve.ce.MWSignatureNode.static.name = 'mwSignature';
 +
 +
ve.ce.MWSignatureNode.static.tagName = 'span';
 +
 +
ve.ce.MWSignatureNode.static.primaryCommandName = 'signature';
 +
 +
/* Methods */
 +
 +
ve.ce.MWSignatureNode.prototype.generateContents = function ( config ) {
 +
// Parsoid doesn't support pre-save transforms. PHP parser doesn't support Parsoid's
 +
// meta attributes (that may or may not be required).
 +
 +
// We could try hacking up one (or even both) of these, but just calling the two parsers
 +
// in order seems slightly saner.
 +
 +
var wikitext = '~~' + '~~';
 +
// We must have only one top-level node, this is the easiest way.
 +
wikitext = '<span>' + wikitext + '</span>';
 +
var signatureNode = this;
 
   
 
   
 +
var api = new mw.Api();
 +
var deferred = $.Deferred();
 +
var xhr = api.post( {
 +
'action': 'parse',
 +
'text': wikitext,
 +
'contentmodel': 'wikitext',
 +
'prop': 'text',
 +
'onlypst': true
 +
} )
 +
// This code is very wonky…
 +
.done( function ( resp ) {
 +
if ( resp && resp.parse && resp.parse.text && resp.parse.text['*'] ) {
 +
// Call parent method with the wikitext with PST applied.
 +
ve.ce.MWTransclusionInlineNode.prototype.generateContents.call(
 +
signatureNode,
 +
{ wikitext: resp.parse.text['*'] }
 +
).done( function ( nodes ) {
 +
deferred.resolve( nodes );
 +
} );
 +
} else {
 +
signatureNode.onParseError( deferred );
 +
}
 +
} )
 +
.fail( this.onParseError.bind( this, deferred ) );
 +
 +
return deferred.promise( { abort: xhr.abort } );
 +
};
 +
 +
/* Registration */
 +
 +
ve.ce.nodeFactory.register( ve.ce.MWSignatureNode );
 
   
 
   
var fromIndex = matchCase? nodeText.toUpperCase().indexOf( fromText.toUpperCase(), firstIndex ) : nodeText.indexOf( fromText, firstIndex );
 
if ( fromIndex == -1 ) {
 
firstIndex = 0;
 
continue;
 
}
 
var start = nodeRange.from+fromIndex;
 
var end = start+fromText.length;
 
if (!replaceAll && model.selection.start > start) {
 
continue;//skip replacements before selection
 
}
 
var removeRange = new ve.Range( start, end );
 
var transaction = ve.dm.Transaction.newFromReplacement(
 
ve.instances[0].view.documentView.model,
 
removeRange,
 
toText
 
);
 
var newSelection = new ve.Range(0,0);
 
if (!replaceAll) {
 
newSelection = new ve.Range( start, start+toText.length );
 
}
 
ve.instances[0].view.changeModel(transaction, newSelection);
 
numReplacements++;
 
if (!replaceAll) {
 
break;
 
}
 
firstIndex = fromIndex + toText.length;
 
nodeI = nodeI -1;
 
}
 
if (numReplacements==0 || replaceAll) {
 
mw.notify( mw.msg( 've-SearchAndReplaceDialog-replace-complete', numReplacements ) );
 
}
 
}
 
 
   
 
   
ve.ui.SearchAndReplaceDialog = function( manager, config ) {
+
/**
// Parent constructor
+
* DataModel MediaWiki signature node. This defines the behavior of the data model for the
ve.ui.SearchAndReplaceDialog.super.call( this, manager, config );
+
* signature, especially the fact that it needs to be converted into a wikitext signature on
 +
* save.
 +
*
 +
* @class
 +
* @extends ve.dm.MWTransclusionInlineNode
 +
*
 +
* @constructor
 +
* @param {Object} [element] Reference to element in linear model
 +
*/
 +
ve.dm.MWSignatureNode = function VeDmMWSignatureNode( element ) {
 +
// Parent constructor
 +
ve.dm.MWTransclusionInlineNode.call( this, element );
 +
};
 
   
 
   
};
+
/* Inheritance */
/* Inheritance */
 
 
   
 
   
OO.inheritClass( ve.ui.SearchAndReplaceDialog, ve.ui.FragmentDialog );
+
OO.inheritClass( ve.dm.MWSignatureNode, ve.dm.MWTransclusionInlineNode );
 
   
 
   
ve.ui.SearchAndReplaceDialog.prototype.getActionProcess  = function ( action ) {
+
/* Static members */
var fromVal = this.fromInput.getValue(),
 
toVal = this.toInput.getValue(),
 
matchCase = this.matchCaseCheckbox.getValue();
 
 
   
 
   
if ( action === 'replace' ) {
+
ve.dm.MWSignatureNode.static.name = 'mwSignature';
return new OO.ui.Process( function () {
 
searchAndReplace( fromVal, toVal, false, matchCase );
 
}, this );
 
} else if ( action === 'replace-all' ) {
 
return new OO.ui.Process( function () {
 
searchAndReplace( fromVal, toVal, true, matchCase );
 
this.close( );
 
}, this );
 
}
 
return ve.ui.MWMediaDialog.super.prototype.getActionProcess.call( this, action );
 
}
 
 
   
 
   
ve.ui.SearchAndReplaceDialog.prototype.getBodyHeight = function () {
+
ve.dm.MWSignatureNode.static.matchTagNames = null;
return 200;
 
};
 
 
   
 
   
/* Static Properties */
+
ve.dm.MWSignatureNode.static.matchRdfaTypes = [];
ve.ui.SearchAndReplaceDialog.static.name = 'search';
 
ve.ui.SearchAndReplaceDialog.static.title = mw.msg( 've-SearchAndReplaceDialog-title' );
 
ve.ui.SearchAndReplaceDialog.static.size = 'medium';
 
 
   
 
   
ve.ui.SearchAndReplaceDialog.static.actions = [
+
ve.dm.MWSignatureNode.static.matchFunction = function ( domElement ) {
{
+
return false;
'action': 'replace',
+
};
'label': mw.msg( 've-SearchAndReplaceDialog-replace' ),
 
'flags': [ 'constructive' ],
 
'modes': 'insert'
 
},
 
{
 
'label': OO.ui.deferMsg( 'visualeditor-dialog-action-cancel' ),
 
'flags': 'safe',
 
'modes': [ 'edit', 'insert', 'select' ]
 
},
 
{
 
'action': 'replace-all',
 
'label': mw.msg( 've-SearchAndReplaceDialog-replaceAll' ),
 
'flags': [ 'constructive' ],
 
'modes': 'insert'
 
}
 
];
 
 
   
 
   
ve.ui.SearchAndReplaceDialog.prototype.initialize = function () {
+
ve.dm.MWSignatureNode.static.getHashObject = function ( dataElement ) {
ve.ui.SearchAndReplaceDialog.super.prototype.initialize.call( this );
+
return {
this.panel = new OO.ui.PanelLayout( { '$': this.$, 'scrollable': true, 'padded': true } );
+
type: dataElement.type
this.inputsFieldset = new OO.ui.FieldsetLayout( {
+
};
'$': this.$
+
};
} );
 
// input from
 
this.fromInput = new OO.ui.TextInputWidget(
 
{ '$': this.$, 'multiline': false, 'placeholder': mw.msg( 've-SearchAndReplaceDialog-from-placeholder' ) }
 
);
 
//input to
 
this.toInput = new OO.ui.TextInputWidget(
 
{ '$': this.$, 'multiline': false, 'placeholder': mw.msg( 've-SearchAndReplaceDialog-to-placeholder' ) }
 
);
 
this.fromField = new OO.ui.FieldLayout( this.fromInput, {
 
'$': this.$,
 
'label': mw.msg( 've-SearchAndReplaceDialog-from-label' )
 
} );
 
this.toField = new OO.ui.FieldLayout( this.toInput, {
 
'$': this.$,
 
'label': mw.msg( 've-SearchAndReplaceDialog-to-label' )
 
} );
 
 
   
 
   
 +
ve.dm.MWSignatureNode.static.toDomElements = function ( dataElement, doc, converter ) {
 +
dataElement = ve.dm.MWSignatureNode.static.toDataElement();
 +
return ve.dm.MWTransclusionNode.static.toDomElements( dataElement, doc, converter );
 +
};
 
   
 
   
this.matchCaseCheckbox = new OO.ui.CheckboxInputWidget( {
+
ve.dm.MWSignatureNode.static.toDataElement = function ( domElements, converter ) {
'$': this.$
+
return {
} );
+
'type': 'mwTransclusionInline',
var matchCaseField = new OO.ui.FieldLayout( this.matchCaseCheckbox, {
+
'attributes': {
'$': this.$,
+
'mw': {
'align': 'inline',
+
'parts': [ '~~' + '~~' ]
'label': mw.msg( 've-SearchAndReplaceDialog-matchcase' )
+
}
} );
+
}
 +
};
 +
};
 
   
 
   
this.inputsFieldset.$element.append(
+
/* Methods */
this.fromField.$element,
 
this.toField.$element,
 
matchCaseField.$element
 
);
 
this.panel.$element.append( this.inputsFieldset.$element );
 
this.$body.append( this.panel.$element );
 
 
   
 
   
}
+
ve.dm.MWSignatureNode.prototype.getPartsList = function () {
 +
return [ { 'content': '~~' + '~~' } ];
 +
};
 
   
 
   
ve.ui.windowFactory.register( ve.ui.SearchAndReplaceDialog );
+
/* Registration */
 
   
 
   
//---------- replace tool ------------------
+
ve.dm.modelRegistry.register( ve.dm.MWSignatureNode );
 
   
 
   
function ReplaceTool( toolGroup, config ) {
 
OO.ui.Tool.call( this, toolGroup, config );
 
 
   
 
   
}
+
/**
OO.inheritClass( ReplaceTool, OO.ui.Tool );
+
* MediaWiki UserInterface signature tool. This defines the menu button and its action.
 +
*
 +
* @class
 +
* @extends ve.ui.InspectorTool
 +
* @constructor
 +
* @param {OO.ui.ToolGroup} toolGroup
 +
* @param {Object} [config] Configuration options
 +
*/
 +
ve.ui.MWSignatureTool = function VeUiMWSignatureTool( toolGroup, config ) {
 +
// Parent constructor
 +
ve.ui.MWTransclusionDialogTool.call( this, toolGroup, config );
 +
};
 +
OO.inheritClass( ve.ui.MWSignatureTool, ve.ui.MWTransclusionDialogTool );
 
   
 
   
ReplaceTool.static.name = 'ReplaceTool';
+
ve.ui.MWSignatureTool.static.name = 'signature';
ReplaceTool.static.title = mw.msg('ve-ReplaceTool-ToolbarButton');
+
ve.ui.MWSignatureTool.static.group = 'object';
 +
ve.ui.MWSignatureTool.static.icon = 'signature';
 +
ve.ui.MWSignatureTool.static.title =
 +
OO.ui.deferMsg( 'visualeditor-mwsignatureinspector-title' );
 +
ve.ui.MWSignatureTool.static.modelClasses = [ ve.dm.MWSignatureNode ];
 +
// Link the tool to the command defined below
 +
ve.ui.MWSignatureTool.static.commandName = 'signature';
 
   
 
   
ReplaceTool.prototype.onSelect = function () {
+
ve.ui.toolFactory.register( ve.ui.MWSignatureTool );
this.toolbar.getSurface().execute( 'window', 'open', 'search', null );
 
};
 
 
   
 
   
ReplaceTool.prototype.onUpdateState = function () {
+
// Command to insert signature node.
this.setActive( false );
+
ve.ui.commandRegistry.register(
};
+
new ve.ui.Command( 'signature', 'content', 'insert', { args: [ [
 +
{ type: 'mwSignature' },
 +
{ type: '/mwSignature' }
 +
] ] } )
 +
);
 
   
 
   
ve.ui.toolFactory.register( ReplaceTool );
+
} );
});
+
} );
 +
} );

Verze z 7. 12. 2014, 12:26

/* Translate the following to your language: */
//mw.hook( 've.activationComplete' ).add(function(){
//});


mw.loader.using( 'ext.visualEditor.viewPageTarget.init' ).done( function () {
 
	/*
	 * Localisation messages.
	 */
	var translations = {
		en: {
			'visualeditor-mwsignatureinspector-title': "Your signature"
		},
		pl: {
			'visualeditor-mwsignatureinspector-title': "Twój podpis"
		}
	};
 
	var userLanguage = mw.config.get( 'wgUserLanguage' );
	mw.messages.set( translations[userLanguage] || translations.en );
 
	// This configuration method might change without warning in the future if core MediaWiki gets a
	// better way to specify which namespaces may have signatures.
	var currentNamespace = mw.config.get( 'wgNamespaceNumber' );
	var noSigNamespaces = mw.config.exists( 'wgVisualEditorNoSignatureNamespaces' ) ?
		mw.config.get( 'wgVisualEditorNoSignatureNamespaces' ) :
		mw.config.get( 'wgContentNamespaces' );
 
	// Most of all, never enable this in content namespaces (unless configured otherwise).
	if ( $.inArray( currentNamespace, noSigNamespaces ) !== -1 ) {
		return;
	}
 
	// Add signature icon
	mw.loader.using( 'mediawiki.util' ).done( function () {
		mw.util.addCSS(
			'.oo-ui-icon-signature {' +
				'background-image: url(//upload.wikimedia.org/wikipedia/commons/a/a0/WikiFont_signature_icon.svg);' +
			'}'
		);
	} );
 
	mw.libs.ve.addPlugin( function () {
		return mw.loader.using( ['ext.visualEditor.core', 'ext.visualEditor.mwtransclusion', 'mediawiki.api'] )
			.done( function () {
				/*
				 * Update the timestamp on inserted signatures every minute.
				 */
				var liveSignatures = [];
				setInterval( function () {
					var updatedSignatures = [];
					for ( var i = 0; i < liveSignatures.length; i++ ) {
						var sig = liveSignatures[i];
						try {
							sig.forceUpdate();
							updatedSignatures.push( sig );
						} catch ( er ) {
							// Do nothing
						}
					}
					liveSignatures = updatedSignatures;
				}, 60 * 1000 );
 
 
				/**
				 * ContentEditable MediaWiki signature node. This defines the behavior of the signature node
				 * inserted into the ContentEditable document.
				 *
				 * @class
				 * @extends ve.ce.MWTransclusionInlineNode
				 *
				 * @constructor
				 * @param {ve.dm.MWSignatureNode} model Model to observe
				 */
				ve.ce.MWSignatureNode = function VeCeMWSignatureNode( model ) {
					// Parent constructor
					ve.ce.MWTransclusionInlineNode.call( this, model );
 
					// DOM changes
					this.$element.addClass( 've-ce-mwSignatureNode' );
 
					// Keep track for magical text updating
					liveSignatures.push( this );
				};
 
				/* Inheritance */
 
				OO.inheritClass( ve.ce.MWSignatureNode, ve.ce.MWTransclusionInlineNode );
 
				/* Static Properties */
 
				ve.ce.MWSignatureNode.static.name = 'mwSignature';
 
				ve.ce.MWSignatureNode.static.tagName = 'span';
 
				ve.ce.MWSignatureNode.static.primaryCommandName = 'signature';
 
				/* Methods */
 
				ve.ce.MWSignatureNode.prototype.generateContents = function ( config ) {
					// Parsoid doesn't support pre-save transforms. PHP parser doesn't support Parsoid's
					// meta attributes (that may or may not be required).
 
					// We could try hacking up one (or even both) of these, but just calling the two parsers
					// in order seems slightly saner.
 
					var wikitext = '~~' + '~~';
					// We must have only one top-level node, this is the easiest way.
					wikitext = '<span>' + wikitext + '</span>';
					var signatureNode = this;
 
					var api = new mw.Api();
					var deferred = $.Deferred();
					var xhr = api.post( {
						'action': 'parse',
						'text': wikitext,
						'contentmodel': 'wikitext',
						'prop': 'text',
						'onlypst': true
					} )
						// This code is very wonky…
						.done( function ( resp ) {
							if ( resp && resp.parse && resp.parse.text && resp.parse.text['*'] ) {
								// Call parent method with the wikitext with PST applied.
								ve.ce.MWTransclusionInlineNode.prototype.generateContents.call(
									signatureNode,
									{ wikitext: resp.parse.text['*'] }
								).done( function ( nodes ) {
									deferred.resolve( nodes );
								} );
							} else {
								signatureNode.onParseError( deferred );
							}
						} )
						.fail( this.onParseError.bind( this, deferred ) );
 
					return deferred.promise( { abort: xhr.abort } );
				};
 
				/* Registration */
 
				ve.ce.nodeFactory.register( ve.ce.MWSignatureNode );
 
 
				/**
				 * DataModel MediaWiki signature node. This defines the behavior of the data model for the
				 * signature, especially the fact that it needs to be converted into a wikitext signature on
				 * save.
				 *
				 * @class
				 * @extends ve.dm.MWTransclusionInlineNode
				 *
				 * @constructor
				 * @param {Object} [element] Reference to element in linear model
				 */
				ve.dm.MWSignatureNode = function VeDmMWSignatureNode( element ) {
					// Parent constructor
					ve.dm.MWTransclusionInlineNode.call( this, element );
				};
 
				/* Inheritance */
 
				OO.inheritClass( ve.dm.MWSignatureNode, ve.dm.MWTransclusionInlineNode );
 
				/* Static members */
 
				ve.dm.MWSignatureNode.static.name = 'mwSignature';
 
				ve.dm.MWSignatureNode.static.matchTagNames = null;
 
				ve.dm.MWSignatureNode.static.matchRdfaTypes = [];
 
				ve.dm.MWSignatureNode.static.matchFunction = function ( domElement ) {
					return false;
				};
 
				ve.dm.MWSignatureNode.static.getHashObject = function ( dataElement ) {
					return {
						type: dataElement.type
					};
				};
 
				ve.dm.MWSignatureNode.static.toDomElements = function ( dataElement, doc, converter ) {
					dataElement = ve.dm.MWSignatureNode.static.toDataElement();
					return ve.dm.MWTransclusionNode.static.toDomElements( dataElement, doc, converter );
				};
 
				ve.dm.MWSignatureNode.static.toDataElement = function ( domElements, converter ) {
					return {
						'type': 'mwTransclusionInline',
						'attributes': {
							'mw': {
								'parts': [ '~~' + '~~' ]
							}
						}
					};
				};
 
				/* Methods */
 
				ve.dm.MWSignatureNode.prototype.getPartsList = function () {
					return [ { 'content': '~~' + '~~' } ];
				};
 
				/* Registration */
 
				ve.dm.modelRegistry.register( ve.dm.MWSignatureNode );
 
 
				/**
				 * MediaWiki UserInterface signature tool. This defines the menu button and its action.
				 *
				 * @class
				 * @extends ve.ui.InspectorTool
				 * @constructor
				 * @param {OO.ui.ToolGroup} toolGroup
				 * @param {Object} [config] Configuration options
				 */
				ve.ui.MWSignatureTool = function VeUiMWSignatureTool( toolGroup, config ) {
					// Parent constructor
					ve.ui.MWTransclusionDialogTool.call( this, toolGroup, config );
				};
				OO.inheritClass( ve.ui.MWSignatureTool, ve.ui.MWTransclusionDialogTool );
 
				ve.ui.MWSignatureTool.static.name = 'signature';
				ve.ui.MWSignatureTool.static.group = 'object';
				ve.ui.MWSignatureTool.static.icon = 'signature';
				ve.ui.MWSignatureTool.static.title =
					OO.ui.deferMsg( 'visualeditor-mwsignatureinspector-title' );
				ve.ui.MWSignatureTool.static.modelClasses = [ ve.dm.MWSignatureNode ];
				// Link the tool to the command defined below
				ve.ui.MWSignatureTool.static.commandName = 'signature';
 
				ve.ui.toolFactory.register( ve.ui.MWSignatureTool );
 
				// Command to insert signature node.
				ve.ui.commandRegistry.register(
					new ve.ui.Command( 'signature', 'content', 'insert', { args: [ [
						{ type: 'mwSignature' },
						{ type: '/mwSignature' }
					] ] } )
				);
 
			} );
	} );
} );