Fix broken console.error.call in IE9
[lhc/web/wiklou.git] / resources / mediawiki / mediawiki.jqueryMsg.js
index 1866352..043ebce 100644 (file)
                 */
                return function( args ) {
                        var key = args[0];
-                       var replacements = $.isArray( args[1] ) ? args[1] : $.makeArray( args ).slice( 1 ); 
+                       var argsArray = $.isArray( args[1] ) ? args[1] : $.makeArray( args ).slice( 1 ); 
+                       var escapedArgsArray = $.map( argsArray, function( arg ) { 
+                               return typeof arg === 'string' ? mw.html.escape( arg ) : arg;
+                       } );
                        try {
-                               return parser.parse( key, replacements );
+                               return parser.parse( key, escapedArgsArray );
                        } catch ( e ) {
                                return $( '<span></span>' ).append( key + ': ' + e.message );
                        }
        };
 
        var parserDefaults = { 
-               'magic' : {},
+               'magic' : {
+                       'SITENAME' : mw.config.get( 'wgSiteName' )
+               },
                'messages' : mw.messages,
                'language' : mw.language
        };
                                return result === null ? null : [ result[0], result[2] ];
                        }
 
+                       function templateWithOutReplacement() {
+                               var result = sequence( [
+                                       templateName,
+                                       colon,
+                                       paramExpression
+                               ] );
+                               return result === null ? null : [ result[0], result[2] ];
+                       }
+
                        var colon = makeStringParser(':');
 
                        var templateContents = choice( [
                                function() {
                                        var res = sequence( [
-                                               templateWithReplacement,
+                                               // templates can have placeholders for dynamic replacement eg: {{PLURAL:$1|one car|$1 cars}}
+                                               // or no placeholders eg: {{GRAMMAR:genitive|{{SITENAME}}}
+                                               choice( [ templateWithReplacement, templateWithOutReplacement ] ),
                                                nOrMore( 0, templateParam )
                                        ] );
                                        return res === null ? null : res[0].concat( res[1] );
 
                /**
                 * Transform parsed structure into gender
-                * @param {Array} of nodes, [ {String}, {String}, {String} ... ] 
+                * Usage {{gender:[gender| mw.user object ] | masculine|feminine|neutral}}.
+                * @param {Array} of nodes, [ {String|mw.User}, {String}, {String} , {String} ] 
                 * @return {String} selected gender form according to current language
                 */
                gender: function( nodes ) { 
-                       var gender = nodes[0];
+                       var gender;
+                       if  ( nodes[0] && nodes[0].options instanceof mw.Map ){
+                               gender = nodes[0].options.get( 'gender' );
+                       } else {
+                               gender = nodes[0];
+                       }
                        var forms = nodes.slice(1);
                        return this.language.gender( gender, forms );
-               }
+               },
 
+               /**
+                * Transform parsed structure into grammar conversion.
+                * Invoked by putting {{grammar:form|word}} in a message
+                * @param {Array} of nodes [{Grammar case eg: genitive}, {String word}]
+                * @return {String} selected grammatical form according to current language
+                */
+               grammar: function( nodes ) {
+                       var form = nodes[0];
+                       var word = nodes[1];
+                       return word && form && this.language.convertGrammar( word, form );
+               }
        };
 
-       // TODO figure out a way to make magic work with common globals like wgSiteName, without requiring init from library users...
-       // var options = { magic: { 'SITENAME' : mw.config.get( 'wgSiteName' ) } };
-
        // deprecated! don't rely on gM existing.
        // the window.gM ought not to be required - or if required, not required here. But moving it to extensions breaks it (?!)
        // Need to fix plugin so it could do attributes as well, then will be okay to remove this.
        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.apply( this );
+               }
+               
+               var messageFunction = mw.jqueryMsg.getMessageFunction( { 'messages': this.map } );
+               return messageFunction( this.key, this.parameters );
+       };
 
 } )( mediaWiki, jQuery );