Files
mediawiki-extensions-Univer…/lib/jquery.i18n/jquery.i18n.emitter.js
Santhosh Thottingal 28154206bf Remove jquery.i18n code that the ULS extension overrides
Instead of using the whole jquery.i18n code, use only required parts
that are not customized in MW ULS. For this define a new RL module
ext.uls.i18n.

Also refactor MW message store for jquery.i18n.

Change-Id: Idda9fe505428ade409d937314d7216ebb4232c36
2013-07-15 13:28:12 +00:00

170 lines
5.2 KiB
JavaScript

/**
* jQuery Internationalization library
*
* Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar
*
* jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
* anything special to choose one license or the other and you don't have to
* notify anyone which license you are using. You are free to use
* UniversalLanguageSelector in commercial projects as long as the copyright
* header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
*
* @licence GNU General Public Licence 2.0 or later
* @licence MIT License
*/
( function ( $ ) {
'use strict';
var MessageParserEmitter = function () {
this.language = $.i18n.languages[String.locale] || $.i18n.languages['default'];
};
MessageParserEmitter.prototype = {
constructor: MessageParserEmitter,
/**
* (We put this method definition here, and not in prototype, to make
* sure it's not overwritten by any magic.) Walk entire node structure,
* applying replacements and template functions when appropriate
*
* @param {Mixed} node abstract syntax tree (top node or subnode)
* @param {Array} replacements for $1, $2, ... $n
* @return {Mixed} single-string node or array of nodes suitable for
* jQuery appending.
*/
emit: function ( node, replacements ) {
var ret, subnodes, operation,
messageParserEmitter = this;
switch ( typeof node ) {
case 'string':
case 'number':
ret = node;
break;
case 'object':
// node is an array of nodes
subnodes = $.map( node.slice( 1 ), function ( n ) {
return messageParserEmitter.emit( n, replacements );
} );
operation = node[0].toLowerCase();
if ( typeof messageParserEmitter[operation] === 'function' ) {
ret = messageParserEmitter[operation]( subnodes, replacements );
} else {
throw new Error( 'unknown operation "' + operation + '"' );
}
break;
case 'undefined':
// Parsing the empty string (as an entire expression, or as a
// paramExpression in a template) results in undefined
// Perhaps a more clever parser can detect this, and return the
// empty string? Or is that useful information?
// The logical thing is probably to return the empty string here
// when we encounter undefined.
ret = '';
break;
default:
throw new Error( 'unexpected type in AST: ' + typeof node );
}
return ret;
},
/**
* Parsing has been applied depth-first we can assume that all nodes
* here are single nodes Must return a single node to parents -- a
* jQuery with synthetic span However, unwrap any other synthetic spans
* in our children and pass them upwards
*
* @param {Array} nodes Mixed, some single nodes, some arrays of nodes.
* @return String
*/
concat: function ( nodes ) {
var result = '';
$.each( nodes, function ( i, node ) {
// strings, integers, anything else
result += node;
} );
return result;
},
/**
* Return escaped replacement of correct index, or string if
* unavailable. Note that we expect the parsed parameter to be
* zero-based. i.e. $1 should have become [ 0 ]. if the specified
* parameter is not found return the same string (e.g. "$99" ->
* parameter 98 -> not found -> return "$99" ) TODO throw error if
* nodes.length > 1 ?
*
* @param {Array} nodes One element, integer, n >= 0
* @param {Array} replacements for $1, $2, ... $n
* @return {string} replacement
*/
replace: function ( nodes, replacements ) {
var index = parseInt( nodes[0], 10 );
if ( index < replacements.length ) {
// replacement is not a string, don't touch!
return replacements[index];
} else {
// index not found, fallback to displaying variable
return '$' + ( index + 1 );
}
},
/**
* Transform parsed structure into pluralization n.b. The first node may
* be a non-integer (for instance, a string representing an Arabic
* number). So convert it back with the current language's
* convertNumber.
*
* @param {Array} nodes List [ {String|Number}, {String}, {String} ... ]
* @return {String} selected pluralized form according to current
* language.
*/
plural: function ( nodes ) {
var count = parseFloat( this.language.convertNumber( nodes[0], 10 ) ),
forms = nodes.slice( 1 );
return forms.length ? this.language.convertPlural( count, forms ) : '';
},
/**
* Transform parsed structure into gender Usage
* {{gender:gender|masculine|feminine|neutral}}.
*
* @param {Array} nodes List [ {String}, {String}, {String} , {String} ]
* @return {String} selected gender form according to current language
*/
gender: function ( nodes ) {
var gender = nodes[0],
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} nodes List [{Grammar case eg: genitive}, {String word}]
* @return {String} selected grammatical form according to current
* language.
*/
grammar: function ( nodes ) {
var form = nodes[0],
word = nodes[1];
return word && form && this.language.convertGrammar( word, form );
}
};
$.extend( $.i18n.parser.emitter, new MessageParserEmitter() );
}( jQuery ) );