Fix up r108203: just loading mw.jqueryMsg in the bottom queue, then assuming its...
authorRoan Kattouw <catrope@users.mediawiki.org>
Fri, 6 Jan 2012 14:11:34 +0000 (14:11 +0000)
committerRoan Kattouw <catrope@users.mediawiki.org>
Fri, 6 Jan 2012 14:11:34 +0000 (14:11 +0000)
* 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
resources/mediawiki/mediawiki.jqueryMsg.js
resources/mediawiki/mediawiki.js

index b572840..ee1ee4f 100644 (file)
@@ -2446,7 +2446,6 @@ $templates
                        'mediawiki.util',
                        'mediawiki.page.startup',
                        'mediawiki.page.ready',
-                       'mediawiki.jqueryMsg',
                ) );
                if ( $wgIncludeLegacyJavaScript ){
                        $this->addModules( 'mediawiki.legacy.wikibits' );
index 7a7c12b..78bc171 100644 (file)
        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 );
index a3faf92..e390069 100644 (file)
@@ -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