*/
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 );