360 lines
12 KiB
JavaScript
360 lines
12 KiB
JavaScript
/**
|
|
* Globalize v1.0.0
|
|
*
|
|
* http://github.com/jquery/globalize
|
|
*
|
|
* Copyright jQuery Foundation and other contributors
|
|
* Released under the MIT license
|
|
* http://jquery.org/license
|
|
*
|
|
* Date: 2015-04-23T12:02Z
|
|
*/
|
|
/*!
|
|
* Globalize v1.0.0 2015-04-23T12:02Z Released under the MIT license
|
|
* http://git.io/TrdQbw
|
|
*/
|
|
(function( root, factory ) {
|
|
|
|
// UMD returnExports
|
|
if ( typeof define === "function" && define.amd ) {
|
|
|
|
// AMD
|
|
define([
|
|
"cldr",
|
|
"../globalize",
|
|
"cldr/event",
|
|
"cldr/supplemental"
|
|
], factory );
|
|
} else if ( typeof exports === "object" ) {
|
|
|
|
// Node, CommonJS
|
|
module.exports = factory( require( "cldrjs" ), require( "globalize" ) );
|
|
} else {
|
|
|
|
// Global
|
|
factory( root.Cldr, root.Globalize );
|
|
}
|
|
}(this, function( Cldr, Globalize ) {
|
|
|
|
var validateCldr = Globalize._validateCldr,
|
|
validateDefaultLocale = Globalize._validateDefaultLocale,
|
|
validateParameterPresence = Globalize._validateParameterPresence,
|
|
validateParameterType = Globalize._validateParameterType,
|
|
validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject;
|
|
var MakePlural;
|
|
/* jshint ignore:start */
|
|
MakePlural = (function() {
|
|
|
|
|
|
var _toArray = function (arr) { return Array.isArray(arr) ? arr : Array.from(arr); };
|
|
|
|
var _toConsumableArray = function (arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } };
|
|
|
|
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } };
|
|
|
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
|
|
|
|
|
/**
|
|
* make-plural.js -- https://github.com/eemeli/make-plural.js/
|
|
* Copyright (c) 2014-2015 by Eemeli Aro <eemeli@gmail.com>
|
|
*
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* The software is provided "as is" and the author disclaims all warranties
|
|
* with regard to this software including all implied warranties of
|
|
* merchantability and fitness. In no event shall the author be liable for
|
|
* any special, direct, indirect, or consequential damages or any damages
|
|
* whatsoever resulting from loss of use, data or profits, whether in an
|
|
* action of contract, negligence or other tortious action, arising out of
|
|
* or in connection with the use or performance of this software.
|
|
*/
|
|
|
|
var Parser = (function () {
|
|
function Parser() {
|
|
_classCallCheck(this, Parser);
|
|
}
|
|
|
|
_createClass(Parser, [{
|
|
key: 'parse',
|
|
value: function parse(cond) {
|
|
var _this = this;
|
|
|
|
if (cond === 'i = 0 or n = 1') {
|
|
return 'n >= 0 && n <= 1';
|
|
}if (cond === 'i = 0,1') {
|
|
return 'n >= 0 && n < 2';
|
|
}if (cond === 'i = 1 and v = 0') {
|
|
this.v0 = 1;
|
|
return 'n == 1 && v0';
|
|
}
|
|
return cond.replace(/([tv]) (!?)= 0/g, function (m, sym, noteq) {
|
|
var sn = sym + '0';
|
|
_this[sn] = 1;
|
|
return noteq ? '!' + sn : sn;
|
|
}).replace(/\b[fintv]\b/g, function (m) {
|
|
_this[m] = 1;
|
|
return m;
|
|
}).replace(/([fin]) % (10+)/g, function (m, sym, num) {
|
|
var sn = sym + num;
|
|
_this[sn] = 1;
|
|
return sn;
|
|
}).replace(/n10+ = 0/g, 't0 && $&').replace(/(\w+ (!?)= )([0-9.]+,[0-9.,]+)/g, function (m, se, noteq, x) {
|
|
if (m === 'n = 0,1') return '(n == 0 || n == 1)';
|
|
if (noteq) return se + x.split(',').join(' && ' + se);
|
|
return '(' + se + x.split(',').join(' || ' + se) + ')';
|
|
}).replace(/(\w+) (!?)= ([0-9]+)\.\.([0-9]+)/g, function (m, sym, noteq, x0, x1) {
|
|
if (Number(x0) + 1 === Number(x1)) {
|
|
if (noteq) return '' + sym + ' != ' + x0 + ' && ' + sym + ' != ' + x1;
|
|
return '(' + sym + ' == ' + x0 + ' || ' + sym + ' == ' + x1 + ')';
|
|
}
|
|
if (noteq) return '(' + sym + ' < ' + x0 + ' || ' + sym + ' > ' + x1 + ')';
|
|
if (sym === 'n') {
|
|
_this.t0 = 1;return '(t0 && n >= ' + x0 + ' && n <= ' + x1 + ')';
|
|
}
|
|
return '(' + sym + ' >= ' + x0 + ' && ' + sym + ' <= ' + x1 + ')';
|
|
}).replace(/ and /g, ' && ').replace(/ or /g, ' || ').replace(/ = /g, ' == ');
|
|
}
|
|
}, {
|
|
key: 'vars',
|
|
value: (function (_vars) {
|
|
function vars() {
|
|
return _vars.apply(this, arguments);
|
|
}
|
|
|
|
vars.toString = function () {
|
|
return _vars.toString();
|
|
};
|
|
|
|
return vars;
|
|
})(function () {
|
|
var vars = [];
|
|
if (this.i) vars.push('i = s[0]');
|
|
if (this.f || this.v) vars.push('f = s[1] || \'\'');
|
|
if (this.t) vars.push('t = (s[1] || \'\').replace(/0+$/, \'\')');
|
|
if (this.v) vars.push('v = f.length');
|
|
if (this.v0) vars.push('v0 = !s[1]');
|
|
if (this.t0 || this.n10 || this.n100) vars.push('t0 = Number(s[0]) == n');
|
|
for (var k in this) {
|
|
if (/^.10+$/.test(k)) {
|
|
var k0 = k[0] === 'n' ? 't0 && s[0]' : k[0];
|
|
vars.push('' + k + ' = ' + k0 + '.slice(-' + k.substr(2).length + ')');
|
|
}
|
|
}if (!vars.length) return '';
|
|
return 'var ' + ['s = String(n).split(\'.\')'].concat(vars).join(', ');
|
|
})
|
|
}]);
|
|
|
|
return Parser;
|
|
})();
|
|
|
|
|
|
|
|
var MakePlural = (function () {
|
|
function MakePlural(lc) {
|
|
var _ref = arguments[1] === undefined ? MakePlural : arguments[1];
|
|
|
|
var cardinals = _ref.cardinals;
|
|
var ordinals = _ref.ordinals;
|
|
|
|
_classCallCheck(this, MakePlural);
|
|
|
|
if (!cardinals && !ordinals) throw new Error('At least one type of plural is required');
|
|
this.lc = lc;
|
|
this.categories = { cardinal: [], ordinal: [] };
|
|
this.parser = new Parser();
|
|
|
|
this.fn = this.buildFunction(cardinals, ordinals);
|
|
this.fn._obj = this;
|
|
this.fn.categories = this.categories;
|
|
|
|
this.fn.toString = this.fnToString.bind(this);
|
|
return this.fn;
|
|
}
|
|
|
|
_createClass(MakePlural, [{
|
|
key: 'compile',
|
|
value: function compile(type, req) {
|
|
var cases = [];
|
|
var rules = MakePlural.rules[type][this.lc];
|
|
if (!rules) {
|
|
if (req) throw new Error('Locale "' + this.lc + '" ' + type + ' rules not found');
|
|
this.categories[type] = ['other'];
|
|
return '\'other\'';
|
|
}
|
|
for (var r in rules) {
|
|
var _rules$r$trim$split = rules[r].trim().split(/\s*@\w*/);
|
|
|
|
var _rules$r$trim$split2 = _toArray(_rules$r$trim$split);
|
|
|
|
var cond = _rules$r$trim$split2[0];
|
|
var examples = _rules$r$trim$split2.slice(1);
|
|
var cat = r.replace('pluralRule-count-', '');
|
|
if (cond) cases.push([this.parser.parse(cond), cat]);
|
|
|
|
}
|
|
this.categories[type] = cases.map(function (c) {
|
|
return c[1];
|
|
}).concat('other');
|
|
if (cases.length === 1) {
|
|
return '(' + cases[0][0] + ') ? \'' + cases[0][1] + '\' : \'other\'';
|
|
} else {
|
|
return [].concat(_toConsumableArray(cases.map(function (c) {
|
|
return '(' + c[0] + ') ? \'' + c[1] + '\'';
|
|
})), ['\'other\'']).join('\n : ');
|
|
}
|
|
}
|
|
}, {
|
|
key: 'buildFunction',
|
|
value: function buildFunction(cardinals, ordinals) {
|
|
var _this3 = this;
|
|
|
|
var compile = function compile(c) {
|
|
return c ? (c[1] ? 'return ' : 'if (ord) return ') + _this3.compile.apply(_this3, _toConsumableArray(c)) : '';
|
|
},
|
|
fold = { vars: function vars(str) {
|
|
return (' ' + str + ';').replace(/(.{1,78})(,|$) ?/g, '$1$2\n ');
|
|
},
|
|
cond: function cond(str) {
|
|
return (' ' + str + ';').replace(/(.{1,78}) (\|\| |$) ?/gm, '$1\n $2');
|
|
} },
|
|
cond = [ordinals && ['ordinal', !cardinals], cardinals && ['cardinal', true]].map(compile).map(fold.cond),
|
|
body = [fold.vars(this.parser.vars())].concat(_toConsumableArray(cond)).join('\n').replace(/\s+$/gm, '').replace(/^[\s;]*[\r\n]+/gm, ''),
|
|
args = ordinals && cardinals ? 'n, ord' : 'n';
|
|
return new Function(args, body);
|
|
}
|
|
}, {
|
|
key: 'fnToString',
|
|
value: function fnToString(name) {
|
|
return Function.prototype.toString.call(this.fn).replace(/^function( \w+)?/, name ? 'function ' + name : 'function').replace('\n/**/', '');
|
|
}
|
|
}], [{
|
|
key: 'load',
|
|
value: function load() {
|
|
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
|
|
args.forEach(function (cldr) {
|
|
var data = cldr && cldr.supplemental || null;
|
|
if (!data) throw new Error('Data does not appear to be CLDR data');
|
|
MakePlural.rules = {
|
|
cardinal: data['plurals-type-cardinal'] || MakePlural.rules.cardinal,
|
|
ordinal: data['plurals-type-ordinal'] || MakePlural.rules.ordinal
|
|
};
|
|
});
|
|
return MakePlural;
|
|
}
|
|
}]);
|
|
|
|
return MakePlural;
|
|
})();
|
|
|
|
|
|
|
|
MakePlural.cardinals = true;
|
|
MakePlural.ordinals = false;
|
|
MakePlural.rules = { cardinal: {}, ordinal: {} };
|
|
|
|
|
|
return MakePlural;
|
|
}());
|
|
/* jshint ignore:end */
|
|
|
|
|
|
var validateParameterTypeNumber = function( value, name ) {
|
|
validateParameterType(
|
|
value,
|
|
name,
|
|
value === undefined || typeof value === "number",
|
|
"Number"
|
|
);
|
|
};
|
|
|
|
|
|
|
|
|
|
var validateParameterTypePluralType = function( value, name ) {
|
|
validateParameterType(
|
|
value,
|
|
name,
|
|
value === undefined || value === "cardinal" || value === "ordinal",
|
|
"String \"cardinal\" or \"ordinal\""
|
|
);
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
* .plural( value )
|
|
*
|
|
* @value [Number]
|
|
*
|
|
* Return the corresponding form (zero | one | two | few | many | other) of a
|
|
* value given locale.
|
|
*/
|
|
Globalize.plural =
|
|
Globalize.prototype.plural = function( value, options ) {
|
|
validateParameterPresence( value, "value" );
|
|
validateParameterTypeNumber( value, "value" );
|
|
return this.pluralGenerator( options )( value );
|
|
};
|
|
|
|
/**
|
|
* .pluralGenerator( [options] )
|
|
*
|
|
* Return a plural function (of the form below).
|
|
*
|
|
* fn( value )
|
|
*
|
|
* @value [Number]
|
|
*
|
|
* Return the corresponding form (zero | one | two | few | many | other) of a value given the
|
|
* default/instance locale.
|
|
*/
|
|
Globalize.pluralGenerator =
|
|
Globalize.prototype.pluralGenerator = function( options ) {
|
|
var cldr, isOrdinal, plural, type;
|
|
|
|
validateParameterTypePlainObject( options, "options" );
|
|
|
|
options = options || {};
|
|
type = options.type || "cardinal";
|
|
cldr = this.cldr;
|
|
|
|
validateParameterTypePluralType( options.type, "options.type" );
|
|
|
|
validateDefaultLocale( cldr );
|
|
|
|
isOrdinal = type === "ordinal";
|
|
|
|
cldr.on( "get", validateCldr );
|
|
cldr.supplemental([ "plurals-type-" + type, "{language}" ]);
|
|
cldr.off( "get", validateCldr );
|
|
|
|
MakePlural.rules = {};
|
|
MakePlural.rules[ type ] = cldr.supplemental( "plurals-type-" + type );
|
|
|
|
plural = new MakePlural( cldr.attributes.language, {
|
|
"ordinals": isOrdinal,
|
|
"cardinals": !isOrdinal
|
|
});
|
|
|
|
return function( value ) {
|
|
validateParameterPresence( value, "value" );
|
|
validateParameterTypeNumber( value, "value" );
|
|
|
|
return plural( value );
|
|
};
|
|
};
|
|
|
|
return Globalize;
|
|
|
|
|
|
|
|
|
|
}));
|