MediaWiki:Gadget-ZkontrolovanoUcitelem.js: Porovnání verzí
(Obsah stránky nahrazen textem „mw.hook( 've.activationComplete' ).add(function(){ mw.loader.load('//meta.wikimedia.org/w/index.php?title=User:Matma_Rex/visualeditor-signature.js&action=raw&…“) |
|||
Řádek 1: | Řádek 1: | ||
− | mw. | + | mw.loader.using( 'ext.visualEditor.viewPageTarget.init' ).done( function () { |
− | mw.loader. | + | |
− | }); | + | /* |
+ | * Localisation messages. | ||
+ | */ | ||
+ | var translations = { | ||
+ | en: { | ||
+ | 'visualeditor-mwsignatureinspector-title': "Your signature" | ||
+ | }, | ||
+ | cs: { | ||
+ | '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' ); | ||
+ | |||
+ | |||
+ | |||
+ | // 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' } | ||
+ | ] ] } ) | ||
+ | ); | ||
+ | |||
+ | } ); | ||
+ | } ); | ||
+ | } ); |
Verze z 22. 12. 2014, 10:31
mw.loader.using( 'ext.visualEditor.viewPageTarget.init' ).done( function () {
/*
* Localisation messages.
*/
var translations = {
en: {
'visualeditor-mwsignatureinspector-title': "Your signature"
},
cs: {
'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' );
// 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' }
] ] } )
);
} );
} );
} );