mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-22 09:30:28 +00:00
181 lines
6.3 KiB
JavaScript
181 lines
6.3 KiB
JavaScript
'use strict';
|
|
|
|
var converter = require('./converter.js');
|
|
|
|
exports.extractNumberSymbols = extractNumberSymbols;
|
|
exports.extractCurrencySymbols = extractCurrencySymbols;
|
|
exports.extractDateTimeSymbols = extractDateTimeSymbols;
|
|
exports.pluralExtractor = pluralExtractor;
|
|
exports.outputLocale = outputLocale;
|
|
exports.correctedLocaleId = correctedLocaleId;
|
|
exports.findLocaleId = findLocaleId;
|
|
exports.serializeContent = serializeContent;
|
|
|
|
var goog = { provide: function() {},
|
|
require: function() {},
|
|
i18n: {currency: {}, pluralRules: {}} };
|
|
|
|
function findLocaleId(str, type) {
|
|
if (type === 'num') {
|
|
return (str.match(/^NumberFormatSymbols_(.+)$/) || [])[1];
|
|
}
|
|
|
|
if (type != 'datetime') { throw new Error('unknown type in findLocaleId: ' + type); }
|
|
|
|
return (str.match(/^DateTimeSymbols_(.+)$/) || [])[1];
|
|
}
|
|
|
|
|
|
function getInfoForLocale(localeInfo, localeID) {
|
|
if (!localeInfo[localeID]) {
|
|
localeInfo[localeID] = {};
|
|
//localeIds.push(localeID);
|
|
}
|
|
return localeInfo[localeID];
|
|
}
|
|
|
|
function extractNumberSymbols(content, localeInfo, currencySymbols) {
|
|
//eval script in the current context so that we get access to all the symbols
|
|
eval(content.toString());
|
|
for (var propName in goog.i18n) {
|
|
var localeID = findLocaleId(propName, 'num');
|
|
if (localeID) {
|
|
var info = getInfoForLocale(localeInfo, localeID);
|
|
info.NUMBER_FORMATS =
|
|
converter.convertNumberData(goog.i18n[propName], currencySymbols);
|
|
}
|
|
}
|
|
}
|
|
|
|
function extractCurrencySymbols(content) {
|
|
//eval script in the current context so that we get access to all the symbols
|
|
eval(content.toString());
|
|
var currencySymbols = goog.i18n.currency.CurrencyInfo;
|
|
currencySymbols.__proto__ = goog.i18n.currency.CurrencyInfoTier2;
|
|
|
|
return currencySymbols;
|
|
}
|
|
|
|
function extractDateTimeSymbols(content, localeInfo) {
|
|
//eval script in the current context so that we get access to all the symbols
|
|
eval(content.toString());
|
|
for (var propName in goog.i18n) {
|
|
var localeID = findLocaleId(propName, 'datetime');
|
|
if (localeID) {
|
|
var info = getInfoForLocale(localeInfo, localeID);
|
|
localeInfo[localeID].DATETIME_FORMATS =
|
|
converter.convertDatetimeData(goog.i18n[propName]);
|
|
}
|
|
}
|
|
}
|
|
|
|
function pluralExtractor(content, localeInfo) {
|
|
var contentText = content.toString();
|
|
var localeIds = Object.keys(localeInfo);
|
|
for (var i = 0; i < localeIds.length; i++) {
|
|
//We don't need to care about country ID because the plural rules in more specific id are
|
|
//always the same as those in its language ID.
|
|
// e.g. plural rules for en_SG is the same as those for en.
|
|
goog.LOCALE = localeIds[i].match(/[^_]+/)[0];
|
|
try {
|
|
eval(contentText);
|
|
} catch(e) {
|
|
console.log("Error in eval(contentText): " + e.stack);
|
|
}
|
|
if (!goog.i18n.pluralRules.select) {
|
|
console.log('No select for lang [' + goog.LOCALE + ']');
|
|
continue;
|
|
}
|
|
var temp = goog.i18n.pluralRules.select.toString().
|
|
replace(/goog.i18n.pluralRules.Keyword/g, 'PLURAL_CATEGORY').replace(/\n/g, '');
|
|
|
|
///@@ is a crazy place holder to be replaced before writing to file
|
|
localeInfo[localeIds[i]].pluralCat = "@@" + temp + "@@";
|
|
}
|
|
}
|
|
|
|
function correctedLocaleId(localeID) {
|
|
// e.g. from zh_CN to zh-CN, from en_US to en-US
|
|
return localeID.replace(/_/g, '-').toLowerCase();
|
|
}
|
|
|
|
function canonicalizeForJsonStringify(unused_key, object) {
|
|
// This function is intended to be called as the 2nd argument to
|
|
// JSON.stringify. The goal here is to ensure that the generated JSON has
|
|
// objects with their keys in ascending order. Without this, it's much
|
|
// harder to diff the generated files in src/ngLocale as the order isn't
|
|
// exactly consistent. We've gotten lucky in the past.
|
|
//
|
|
// Iteration order, for string keys, ends up being the same as insertion
|
|
// order. Refer :-
|
|
// 1. http://ejohn.org/blog/javascript-in-chrome/
|
|
// (search for "for loop order").
|
|
// Currently all major browsers loop over the properties of an object
|
|
// in the order in which they were defined.
|
|
// - John Resig
|
|
// 2. https://code.google.com/p/v8/issues/detail?id=164
|
|
// ECMA-262 does not specify enumeration order. The de facto standard
|
|
// is to match insertion order, which V8 also does ...
|
|
if (typeof object != "object" || Object.prototype.toString.apply(object) === '[object Array]') {
|
|
return object;
|
|
}
|
|
var result = {};
|
|
Object.keys(object).sort().forEach(function(key) {
|
|
result[key] = object[key];
|
|
});
|
|
return result;
|
|
}
|
|
|
|
function serializeContent(localeObj) {
|
|
return JSON.stringify(localeObj, canonicalizeForJsonStringify, ' ')
|
|
.replace(new RegExp('[\\u007f-\\uffff]', 'g'), function(c) { return '\\u'+('0000'+c.charCodeAt(0).toString(16)).slice(-4); })
|
|
.replace(/"@@|@@"/g, '');
|
|
}
|
|
|
|
function outputLocale(localeInfo, localeID) {
|
|
var fallBackID = localeID.match(/[A-Za-z]+/)[0],
|
|
localeObj = localeInfo[localeID],
|
|
fallBackObj = localeInfo[fallBackID];
|
|
|
|
// fallBack to language formats when country format is missing
|
|
// e.g. if NUMBER_FORMATS of en_xyz is not present, use the NUMBER_FORMATS of en instead
|
|
if (!localeObj.NUMBER_FORMATS) {
|
|
localeObj.NUMBER_FORMATS = fallBackObj.NUMBER_FORMATS;
|
|
}
|
|
|
|
// datetimesymbolsext.js provides more top level locales than the other
|
|
// files. We process datetimesymbolsext.js because we want the country
|
|
// specific formats that are missing from datetimesymbols.js. However, we
|
|
// don't want to write locale files that only have dateformat (i.e. missing
|
|
// number formats.) So we skip them.
|
|
if (!localeObj.NUMBER_FORMATS) {
|
|
console.log("Skipping locale %j: Don't have any number formats", localeID);
|
|
return null;
|
|
}
|
|
|
|
if (!localeObj.DATETIME_FORMATS) {
|
|
localeObj.DATETIME_FORMATS = fallBackObj.DATETIME_FORMATS;
|
|
}
|
|
localeObj.id = correctedLocaleId(localeID);
|
|
|
|
var prefix =
|
|
"'use strict';\n" +
|
|
'angular.module("ngLocale", [], ["$provide", function($provide) {\n' +
|
|
'var PLURAL_CATEGORY = {' +
|
|
'ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"' +
|
|
'};\n' +
|
|
'$provide.value("$locale", ';
|
|
|
|
var suffix = ');\n}]);';
|
|
|
|
localeObj = {
|
|
DATETIME_FORMATS: localeObj.DATETIME_FORMATS,
|
|
NUMBER_FORMATS: localeObj.NUMBER_FORMATS,
|
|
pluralCat: localeObj.pluralCat,
|
|
id: localeObj.id
|
|
};
|
|
|
|
var content = serializeContent(localeInfo[localeID]);
|
|
|
|
return prefix + content + suffix;
|
|
}
|