From 844e6f0d7f6a927b3a3cbfdbf6255f01c9110400 Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Fri, 6 Jan 2012 14:11:34 +0000 Subject: [PATCH] Fix up r108203: just loading mw.jqueryMsg in the bottom queue, then assuming its presence in mw.Message doesn't work, see CR comments. * Moved message parsing (including $1 replacement) to Message.prototype.parser(), and let jqueryMsg override that when loaded ** Make the Message constructor public to make this possible ** Moved logic for skipping jqueryMsg when the message is simple from mw.Message to mw.jqueryMsg, where it belongs * Remove mw.jqueryMsg from the default modules list in OutputPage. Modules that require PLURAL/GENDER should depend on mw.jqueryMsg * TODOs ** The jqueryMsg parser is recreated for every mw.msg() call. It should probably be cached, but the only way I can think of is to add it as a member of the Map object, which is kind of weird ** Because jqueryMsg doesn't support a 'text' mode that expands PLURAL/GENDER but doesn't output HTML (leaves e.g. links alone), mw.Message.plain() and mw.Message.parse() currently behave identically. This is wrong and should be fixed, but that needs support in jqueryMsg too --- includes/OutputPage.php | 1 - resources/mediawiki/mediawiki.jqueryMsg.js | 17 +++++++++ resources/mediawiki/mediawiki.js | 44 ++++++++++++++-------- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/includes/OutputPage.php b/includes/OutputPage.php index b57284014e..ee1ee4f8ef 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -2446,7 +2446,6 @@ $templates 'mediawiki.util', 'mediawiki.page.startup', 'mediawiki.page.ready', - 'mediawiki.jqueryMsg', ) ); if ( $wgIncludeLegacyJavaScript ){ $this->addModules( 'mediawiki.legacy.wikibits' ); diff --git a/resources/mediawiki/mediawiki.jqueryMsg.js b/resources/mediawiki/mediawiki.jqueryMsg.js index 7a7c12b40f..78bc171ba6 100644 --- a/resources/mediawiki/mediawiki.jqueryMsg.js +++ b/resources/mediawiki/mediawiki.jqueryMsg.js @@ -661,5 +661,22 @@ window.gM = mw.jqueryMsg.getMessageFunction(); $.fn.msg = mw.jqueryMsg.getPlugin(); + + // Replace the default message parser with jqueryMsg + var oldParser = mw.Message.prototype.parser; + mw.Message.prototype.parser = function() { + // TODO: should we cache the message function so we don't create a new one every time? Benchmark this maybe? + // Caching is somewhat problematic, because we do need different message functions for different maps, so + // we'd have to cache the parser as a member of this.map, which sounds a bit ugly. + + // Do not use mw.jqueryMsg unless required + if ( this.map.get( this.key ).indexOf( '{{' ) < 0 ) { + // Fall back to mw.msg's simple parser + return oldParser( this.key, this.parameters ); + } + + var messageFunction = mw.jqueryMsg.getMessageFunction( { 'messages': this.map } ); + return messageFunction( this.key, this.parameters ); + }; } )( mediaWiki, jQuery ); diff --git a/resources/mediawiki/mediawiki.js b/resources/mediawiki/mediawiki.js index a3faf92725..e390069f09 100644 --- a/resources/mediawiki/mediawiki.js +++ b/resources/mediawiki/mediawiki.js @@ -8,7 +8,6 @@ var mw = ( function ( $, undefined ) { /* Private Members */ var hasOwn = Object.prototype.hasOwnProperty; - var parser; /* Object constructors */ /** @@ -125,12 +124,25 @@ var mw = ( function ( $, undefined ) { this.format = 'plain'; this.map = map; this.key = key; - parser = parser || mw.jqueryMsg.getMessageFunction( ); this.parameters = parameters === undefined ? [] : $.makeArray( parameters ); return this; } Message.prototype = { + /** + * Simple message parser, does $N replacement and nothing else. + * This may be overridden to provide a more complex message parser. + * + * This function will not be called for nonexistent messages. + */ + parser: function() { + var parameters = this.parameters; + return this.map.get( this.key ).replace( /\$(\d+)/g, function ( str, match ) { + var index = parseInt( match, 10 ) - 1; + return parameters[index] !== undefined ? parameters[index] : '$' + match; + } ); + }, + /** * Appends (does not replace) parameters for replacement to the .parameters property. * @@ -159,29 +171,24 @@ var mw = ( function ( $, undefined ) { } return '<' + this.key + '>'; } - var text = this.map.get( this.key ), - parameters = this.parameters; + var text; if ( this.format === 'plain' ) { - // Do not use parser unless required. - if ( text.indexOf( '{{' ) < 0 ) { - text = text.replace( /\$(\d+)/g, function ( str, match ) { - var index = parseInt( match, 10 ) - 1; - return parameters[index] !== undefined ? parameters[index] : '$' + match; - } ); - } - else{ - text = parser( this.key, this.parameters ); - } + // FIXME this is wrong. There should be a way + // to tell parser() whether we're looking for + // plain text or HTML, but I don't know jQueryMsg + // well enough to implement this. + // Currently it always outputs HTML + text = this.parser(); } if ( this.format === 'escaped' ) { - text = parser( this.key, this.parameters ); + text = this.parser(); text = mw.html.escape( text ); } if ( this.format === 'parse' ) { - text = parser( this.key, this.parameters ); + text = this.parser(); } return text; @@ -240,6 +247,11 @@ var mw = ( function ( $, undefined ) { * @var constructor Make the Map constructor publicly available. */ Map: Map, + + /** + * @var constructor Make the Message constructor publicly available. + */ + Message: Message, /** * List of configuration values -- 2.20.1