mediawiki-extensions-Visual.../modules/ve/init/sa/ve.init.sa.Platform.js

141 lines
3.4 KiB
JavaScript
Raw Normal View History

/**
* VisualEditor stand-alone initialization Target class.
*
* @copyright 2011-2012 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* Stand-alone platform.
*
* @class
* @constructor
Object management: Object create/inherit/clone utilities * For the most common case: - replace ve.extendClass with ve.inheritClass (chose slightly different names to detect usage of the old/new one, and I like 'inherit' better). - move it up to below the constructor, see doc block for why. * Cases where more than 2 arguments were passed to ve.extendClass are handled differently depending on the case. In case of a longer inheritance tree, the other arguments could be omitted (like in "ve.ce.FooBar, ve.FooBar, ve.Bar". ve.ce.FooBar only needs to inherit from ve.FooBar, because ve.ce.FooBar inherits from ve.Bar). In the case of where it previously had two mixins with ve.extendClass(), either one becomes inheritClass and one a mixin, both to mixinClass(). No visible changes should come from this commit as the instances still all have the same visible properties in the end. No more or less than before. * Misc.: - Be consistent in calling parent constructors in the same order as the inheritance. - Add missing @extends and @param documentation. - Replace invalid {Integer} type hint with {Number}. - Consistent doc comments order: @class, @abstract, @constructor, @extends, @params. - Fix indentation errors A fairly common mistake was a superfluous space before the identifier on the assignment line directly below the documentation comment. $ ack "^ [^*]" --js modules/ve - Typo "Inhertiance" -> "Inheritance". - Replacing the other confusing comment "Inheritance" (inside the constructor) with "Parent constructor". - Add missing @abstract for ve.ui.Tool. - Corrected ve.FormatDropdownTool to ve.ui.FormatDropdownTool.js - Add function names to all @constructor functions. Now that we have inheritance it is important and useful to have these functions not be anonymous. Example of debug shot: http://cl.ly/image/1j3c160w3D45 Makes the difference between < documentNode; > ve_dm_DocumentNode ... : ve_dm_BranchNode ... : ve_dm_Node ... : ve_dm_Node ... : Object ... without names (current situation): < documentNode; > Object ... : Object ... : Object ... : Object ... : Object ... though before this commit, it really looks like this (flattened since ve.extendClass really did a mixin): < documentNode; > Object ... ... ... Pattern in Sublime (case-sensitive) to find nameless constructor functions: "^ve\..*\.([A-Z])([^\.]+) = function \(" Change-Id: Iab763954fb8cf375900d7a9a92dec1c755d5407e
2012-09-05 06:07:47 +00:00
* @extends {ve.init.Platform}
*/
ve.init.sa.Platform = function VeInitSaPlatform() {
Object management: Object create/inherit/clone utilities * For the most common case: - replace ve.extendClass with ve.inheritClass (chose slightly different names to detect usage of the old/new one, and I like 'inherit' better). - move it up to below the constructor, see doc block for why. * Cases where more than 2 arguments were passed to ve.extendClass are handled differently depending on the case. In case of a longer inheritance tree, the other arguments could be omitted (like in "ve.ce.FooBar, ve.FooBar, ve.Bar". ve.ce.FooBar only needs to inherit from ve.FooBar, because ve.ce.FooBar inherits from ve.Bar). In the case of where it previously had two mixins with ve.extendClass(), either one becomes inheritClass and one a mixin, both to mixinClass(). No visible changes should come from this commit as the instances still all have the same visible properties in the end. No more or less than before. * Misc.: - Be consistent in calling parent constructors in the same order as the inheritance. - Add missing @extends and @param documentation. - Replace invalid {Integer} type hint with {Number}. - Consistent doc comments order: @class, @abstract, @constructor, @extends, @params. - Fix indentation errors A fairly common mistake was a superfluous space before the identifier on the assignment line directly below the documentation comment. $ ack "^ [^*]" --js modules/ve - Typo "Inhertiance" -> "Inheritance". - Replacing the other confusing comment "Inheritance" (inside the constructor) with "Parent constructor". - Add missing @abstract for ve.ui.Tool. - Corrected ve.FormatDropdownTool to ve.ui.FormatDropdownTool.js - Add function names to all @constructor functions. Now that we have inheritance it is important and useful to have these functions not be anonymous. Example of debug shot: http://cl.ly/image/1j3c160w3D45 Makes the difference between < documentNode; > ve_dm_DocumentNode ... : ve_dm_BranchNode ... : ve_dm_Node ... : ve_dm_Node ... : Object ... without names (current situation): < documentNode; > Object ... : Object ... : Object ... : Object ... : Object ... though before this commit, it really looks like this (flattened since ve.extendClass really did a mixin): < documentNode; > Object ... ... ... Pattern in Sublime (case-sensitive) to find nameless constructor functions: "^ve\..*\.([A-Z])([^\.]+) = function \(" Change-Id: Iab763954fb8cf375900d7a9a92dec1c755d5407e
2012-09-05 06:07:47 +00:00
// Parent constructor
ve.init.Platform.call( this );
// Properties
this.externalLinkUrlProtocolsRegExp = /^https?\:\/\//;
this.modulesUrl = 'extensions/VisualEditor/modules';
this.messages = {};
init.Platform: Refactor parsed messages. Rewrite VisualEditorMessagesModule: * Replace copy-paste dump of user-css module with stuff for VisualEditor (class commend and module::$origin). * Remove duplication between getMessages and getScript. * Actually implement getModifiedTime so that the comment in getMessages() about cache invalidation is actually true Fixes bug 42670: ext.visualEditor.specialMessages cache broken ve.init: * Implement addParsedMessages and getParsedMessage so that we don't mix up plain messages with raw html messages (minoredit was previously overloaded in mw.msg storage with a parsed html message and retrieved though ve.msg, which is documented as retuning plain text, not raw html). This is now separated into a different method. * Improved documentation of the other msg methods to emphasise their differences * Removed redundant code in attachSaveDialog() that was (partially) already done in setupSaveDialog() and moved the remaining bits into it as well. Checked all callers of these and they are both only called from ViewPageTarget.prototype.onLoad * Also implement them in the standalone platform implementation, with the html escaper based on mw.html.escape * Update init.platform.getMessage to use undefined instead of discouraged 'if-in' statement. * Add test suite. demos/test: * Re-run makeStaticLoader.php on test to add ve.init.Platform.test * Re-run makeStaticLoader.php on demos and update i18n caller to use ve.init.platform.addParsedMessages (also moved out of the auto-generated block for easier updating) Change-Id: I7f26b47e9467e850c08b9c217c4f1098590de109
2012-12-04 06:56:41 +00:00
this.parsedMessages = {};
};
Object management: Object create/inherit/clone utilities * For the most common case: - replace ve.extendClass with ve.inheritClass (chose slightly different names to detect usage of the old/new one, and I like 'inherit' better). - move it up to below the constructor, see doc block for why. * Cases where more than 2 arguments were passed to ve.extendClass are handled differently depending on the case. In case of a longer inheritance tree, the other arguments could be omitted (like in "ve.ce.FooBar, ve.FooBar, ve.Bar". ve.ce.FooBar only needs to inherit from ve.FooBar, because ve.ce.FooBar inherits from ve.Bar). In the case of where it previously had two mixins with ve.extendClass(), either one becomes inheritClass and one a mixin, both to mixinClass(). No visible changes should come from this commit as the instances still all have the same visible properties in the end. No more or less than before. * Misc.: - Be consistent in calling parent constructors in the same order as the inheritance. - Add missing @extends and @param documentation. - Replace invalid {Integer} type hint with {Number}. - Consistent doc comments order: @class, @abstract, @constructor, @extends, @params. - Fix indentation errors A fairly common mistake was a superfluous space before the identifier on the assignment line directly below the documentation comment. $ ack "^ [^*]" --js modules/ve - Typo "Inhertiance" -> "Inheritance". - Replacing the other confusing comment "Inheritance" (inside the constructor) with "Parent constructor". - Add missing @abstract for ve.ui.Tool. - Corrected ve.FormatDropdownTool to ve.ui.FormatDropdownTool.js - Add function names to all @constructor functions. Now that we have inheritance it is important and useful to have these functions not be anonymous. Example of debug shot: http://cl.ly/image/1j3c160w3D45 Makes the difference between < documentNode; > ve_dm_DocumentNode ... : ve_dm_BranchNode ... : ve_dm_Node ... : ve_dm_Node ... : Object ... without names (current situation): < documentNode; > Object ... : Object ... : Object ... : Object ... : Object ... though before this commit, it really looks like this (flattened since ve.extendClass really did a mixin): < documentNode; > Object ... ... ... Pattern in Sublime (case-sensitive) to find nameless constructor functions: "^ve\..*\.([A-Z])([^\.]+) = function \(" Change-Id: Iab763954fb8cf375900d7a9a92dec1c755d5407e
2012-09-05 06:07:47 +00:00
/* Inheritance */
ve.inheritClass( ve.init.sa.Platform, ve.init.Platform );
/* Methods */
/**
* Gets a regular expression that matches allowed external link URLs.
*
* @method
* @returns {RegExp} Regular expression object
*/
ve.init.sa.Platform.prototype.getExternalLinkUrlProtocolsRegExp = function () {
return this.externalLinkUrlProtocolsRegExp;
};
/**
* Sets the remotely accessible URL to the modules directory.
*
* @method
* @param {String} url Remote modules URL
*/
ve.init.sa.Platform.prototype.setModulesUrl = function ( url ) {
this.modulesUrl = url;
};
/**
* Gets a remotely accessible URL to the modules directory.
*
* @method
* @returns {String} Remote modules URL
*/
ve.init.sa.Platform.prototype.getModulesUrl = function () {
return this.modulesUrl;
};
/**
* Adds multiple messages to the localization system.
*
* @method
* @param {Object} messages Map of message-key/message-string pairs
*/
ve.init.sa.Platform.prototype.addMessages = function ( messages ) {
for ( var key in messages ) {
this.messages[key] = messages[key];
}
};
/**
* Gets a message from the localization system.
*
* @method
* @param {String} key Message key
* @param {Mixed} [...] List of arguments which will be injected at $1, $2, etc. in the messaage
* @returns {String} Localized message
*/
ve.init.sa.Platform.prototype.getMessage = function ( key ) {
if ( key in this.messages ) {
// Simple message parser, does $N replacement and nothing else.
var parameters = Array.prototype.slice.call( arguments, 1 );
return this.messages[key].replace( /\$(\d+)/g, function ( str, match ) {
var index = parseInt( match, 10 ) - 1;
return parameters[index] !== undefined ? parameters[index] : '$' + match;
} );
}
return '<' + key + '>';
};
init.Platform: Refactor parsed messages. Rewrite VisualEditorMessagesModule: * Replace copy-paste dump of user-css module with stuff for VisualEditor (class commend and module::$origin). * Remove duplication between getMessages and getScript. * Actually implement getModifiedTime so that the comment in getMessages() about cache invalidation is actually true Fixes bug 42670: ext.visualEditor.specialMessages cache broken ve.init: * Implement addParsedMessages and getParsedMessage so that we don't mix up plain messages with raw html messages (minoredit was previously overloaded in mw.msg storage with a parsed html message and retrieved though ve.msg, which is documented as retuning plain text, not raw html). This is now separated into a different method. * Improved documentation of the other msg methods to emphasise their differences * Removed redundant code in attachSaveDialog() that was (partially) already done in setupSaveDialog() and moved the remaining bits into it as well. Checked all callers of these and they are both only called from ViewPageTarget.prototype.onLoad * Also implement them in the standalone platform implementation, with the html escaper based on mw.html.escape * Update init.platform.getMessage to use undefined instead of discouraged 'if-in' statement. * Add test suite. demos/test: * Re-run makeStaticLoader.php on test to add ve.init.Platform.test * Re-run makeStaticLoader.php on demos and update i18n caller to use ve.init.platform.addParsedMessages (also moved out of the auto-generated block for easier updating) Change-Id: I7f26b47e9467e850c08b9c217c4f1098590de109
2012-12-04 06:56:41 +00:00
/**
* Adds multiple parsed messages to the localization system.
*
* @method
* @param {Object} messages Map of message-key/html pairs
*/
ve.init.sa.Platform.prototype.addParsedMessages = function ( messages ) {
for ( var key in messages ) {
this.parsedMessages[key] = messages[key];
}
};
/**
* Gets a parsed message as HTML string.
*
* Falls back to mw.messsage with .escaped().
* Does not support $# replacements.
*
* @method
* @param {String} key Message key
* @returns {String} Parsed localized message as HTML string.
*/
ve.init.sa.Platform.prototype.getParsedMessage = function ( key ) {
if ( key in this.parsedMessages ) {
// Prefer parsed results from VisualEditorMessagesModule.php if available.
return this.parsedMessages[key];
}
// Fallback to regular messages, html escaping applied.
return this.getMessage( key ).replace( /['"<>&]/g, function escapeCallback( s ) {
switch ( s ) {
case '\'':
return '&#039;';
case '"':
return '&quot;';
case '<':
return '&lt;';
case '>':
return '&gt;';
case '&':
return '&amp;';
}
} );
};
/* Initialization */
ve.init.platform = new ve.init.sa.Platform();