mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
feat(i18n): collect and convert locale info from closure
- add i18n/closure directory with closure i18n files and update-closure.sh script to update them - generate.sh script runs node.js scripts that extract localization rules from the closure library, transform them to a more suitable format and dumps them into i18n/locale directory as angular's $locale services - update Rakefile to copy i18n files to build/ and pkg/ dirs - copy i18n stuff during rake build - e2e tests for several locales
This commit is contained in:
parent
8534b7c7c0
commit
966cbd4cf8
22 changed files with 7384 additions and 0 deletions
3
Rakefile
3
Rakefile
|
|
@ -217,6 +217,8 @@ task :compile => [:init, :compile_scenario, :compile_jstd_scenario_adapter, :gen
|
|||
--language_in ECMASCRIPT5_STRICT \
|
||||
--js #{path_to('angular.js')} \
|
||||
--js_output_file #{path_to('angular.min.js')})
|
||||
|
||||
FileUtils.cp_r 'i18n/locale', path_to('i18n')
|
||||
end
|
||||
|
||||
|
||||
|
|
@ -252,6 +254,7 @@ task :package => [:clean, :compile, :docs] do
|
|||
FileUtils.cp(src, pkg_dir + '/' + dest)
|
||||
end
|
||||
|
||||
FileUtils.cp_r path_to('i18n'), "#{pkg_dir}/i18n-#{NG_VERSION.full}"
|
||||
FileUtils.cp_r path_to('docs'), "#{pkg_dir}/docs-#{NG_VERSION.full}"
|
||||
|
||||
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/index.html", File::RDWR) do |f|
|
||||
|
|
|
|||
12
i18n/README.md
Normal file
12
i18n/README.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# i18n directory overview:
|
||||
|
||||
- closure/ - closure files we use for ruleset generation
|
||||
- locale/ - angular's locale ruleset files
|
||||
- src/ - source files
|
||||
- spec/ - spec files for stuff in src directory
|
||||
- generate.sh - runs src scripts on closure dir and stores output in locale dir
|
||||
- update-closure.sh - downloads the latest version of closure files from public svn repo
|
||||
|
||||
The closure files (maintained by Shanjian Li (shanjian)) change very rarely, so we don't need to
|
||||
regenerate locale files very often.
|
||||
|
||||
385
i18n/closure/currencySymbols.js
Normal file
385
i18n/closure/currencySymbols.js
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview A utility to get better currency format pattern.
|
||||
*
|
||||
* This module implement a new currency format representation model. It
|
||||
* provides 3 currency representation forms: global, portable and local. Local
|
||||
* format is the most popular format people use to represent currency in its
|
||||
* circulating country without worrying about how it should be distinguished
|
||||
* from other currencies. Global format is a formal representation in context
|
||||
* of multiple currencies in same page, it is ISO 4217 currency code. Portable
|
||||
* format is a compromise between global and local. It looks similar to how
|
||||
* people would like to see how their currencies is being represented in other
|
||||
* media. While at the same time, it should be distinguishable to world's
|
||||
* popular currencies (like USD, EUR) and currencies somewhat relevant in the
|
||||
* area (like CNY in HK, though native currency is HKD). There is no guarantee
|
||||
* of uniqueness.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.i18n.currency');
|
||||
|
||||
|
||||
/**
|
||||
* The mask of precision field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.currency.PRECISION_MASK_ = 0x07;
|
||||
|
||||
|
||||
/**
|
||||
* If this flag is set, it means the currency sign should position before
|
||||
* number.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.currency.POSITION_FLAG_ = 0x08;
|
||||
|
||||
|
||||
/**
|
||||
* Should a space to inserted between number and currency sign.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.currency.SPACE_FLAG_ = 0x20;
|
||||
|
||||
|
||||
/**
|
||||
* This function will add tier2 currency support. Be default, only tier1
|
||||
* (most popular currencies) are supportted. If an application really need
|
||||
* to support some of the rarely used currency, it should call this function
|
||||
* before any other functions in this namespace.
|
||||
*/
|
||||
goog.i18n.currency.addTier2Support = function() {
|
||||
for (var key in goog.i18n.currency.CurrencyInfoTier2) {
|
||||
goog.i18n.currency.CurrencyInfo[key] =
|
||||
goog.i18n.currency.CurrencyInfoTier2[key];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Global currency pattern always uses ISO-4217 currency code as prefix. Local
|
||||
* currency sign is added if it is different from currency code. Each currency
|
||||
* is unique in this form. The negative side is that ISO code looks weird in
|
||||
* some countries as poeple normally do not use it. Local currency sign
|
||||
* alleviate the problem, but also make it a little verbose.
|
||||
*
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Global currency pattern string for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getGlobalCurrencyPattern = function(currencyCode) {
|
||||
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
|
||||
var patternNum = info[0];
|
||||
if (currencyCode == info[1]) {
|
||||
if ((patternNum & goog.i18n.currency.POSITION_FLAG_) == 0) {
|
||||
patternNum |= goog.i18n.currency.SPACE_FLAG_;
|
||||
}
|
||||
return goog.i18n.currency.getCurrencyPattern_(patternNum, info[1]);
|
||||
}
|
||||
return currencyCode + ' ' +
|
||||
goog.i18n.currency.getCurrencyPattern_(patternNum, info[1]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return global currency sign string for those applications
|
||||
* that want to handle currency sign themselves.
|
||||
*
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Global currency sign for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getGlobalCurrencySign = function(currencyCode) {
|
||||
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
|
||||
if (currencyCode == info[1]) {
|
||||
return currencyCode;
|
||||
}
|
||||
return currencyCode + ' ' + info[1];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Local currency pattern is the most frequently used pattern in currency's
|
||||
* native region. It does not care about how it is distinguished from other
|
||||
* currencies.
|
||||
*
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Local currency pattern string for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getLocalCurrencyPattern = function(currencyCode) {
|
||||
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
|
||||
return goog.i18n.currency.getCurrencyPattern_(info[0], info[1]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns local currency sign string for those applications that need to
|
||||
* handle currency sign separately.
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Local currency sign for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getLocalCurrencySign = function(currencyCode) {
|
||||
return goog.i18n.currency.CurrencyInfo[currencyCode][1];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Portable currency pattern is a compromise between local and global. It is
|
||||
* not a mere blend or mid-way between the two. Currency sign is chosen so that
|
||||
* it looks familiar to native users. It also has enough information to
|
||||
* distinguish itself from other popular currencies in its native region.
|
||||
* In this pattern, currency sign symbols that has availability problem in
|
||||
* popular fonts are also avoided.
|
||||
*
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Portable currency pattern string for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getPortableCurrencyPattern = function(currencyCode) {
|
||||
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
|
||||
return goog.i18n.currency.getCurrencyPattern_(info[0], info[2]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return portable currency sign string for those applications that need to
|
||||
* handle currency sign themselves.
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Portable currency sign for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getPortableCurrencySign = function(currencyCode) {
|
||||
return goog.i18n.currency.CurrencyInfo[currencyCode][2];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This function returns the default currency sign position. Some application
|
||||
* may want to handle currency sign and currency amount separately. This
|
||||
* function can be used in such situation to position the currency sign
|
||||
* relative to amount field correctly.
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {boolean} true if currency should be positioned before amount field.
|
||||
*/
|
||||
goog.i18n.currency.isPrefixSignPosition = function(currencyCode) {
|
||||
return (goog.i18n.currency.CurrencyInfo[currencyCode][0] &
|
||||
goog.i18n.currency.POSITION_FLAG_) == 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This function construct the currency pattern. Currency sign is provided. The
|
||||
* pattern information is encoded in patternNum.
|
||||
*
|
||||
* @param {number} patternNum Encoded pattern number that has
|
||||
* currency pattern information.
|
||||
* @param {string} sign the currency sign that will be used in pattern.
|
||||
*
|
||||
* @return {string} currency pattern string.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.currency.getCurrencyPattern_ = function(patternNum, sign) {
|
||||
var strParts = ['#,##0'];
|
||||
var precision = patternNum & goog.i18n.currency.PRECISION_MASK_;
|
||||
if (precision > 0) {
|
||||
strParts.push('.');
|
||||
for (var i = 0; i < precision; i++) {
|
||||
strParts.push('0');
|
||||
}
|
||||
}
|
||||
if ((patternNum & goog.i18n.currency.POSITION_FLAG_) == 0) {
|
||||
strParts.unshift((patternNum & goog.i18n.currency.SPACE_FLAG_) ?
|
||||
"' " : "'");
|
||||
strParts.unshift(sign);
|
||||
strParts.unshift("'");
|
||||
} else {
|
||||
strParts.push((patternNum & goog.i18n.currency.SPACE_FLAG_) ? " '" : "'",
|
||||
sign, "'");
|
||||
}
|
||||
return strParts.join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tier 1 currency information.
|
||||
* @type {!Object.<!Array>}
|
||||
*/
|
||||
goog.i18n.currency.CurrencyInfo = {
|
||||
'AED': [2, '\u062F\u002e\u0625', 'DH'],
|
||||
'ARS': [2, '$', 'AR$'],
|
||||
'AUD': [2, '$', 'AU$'],
|
||||
'BDT': [2, '\u09F3', 'Tk'],
|
||||
'BRL': [2, 'R$', 'R$'],
|
||||
'CAD': [2, '$', 'C$'],
|
||||
'CHF': [2, 'Fr.', 'CHF'],
|
||||
'CLP': [0, '$', 'CL$'],
|
||||
'CNY': [2, '¥', 'RMB¥'],
|
||||
'COP': [2, '$', 'COL$'],
|
||||
'CRC': [2, '\u20a1', 'CR₡'],
|
||||
'CUP': [2, '$', '$MN'],
|
||||
'CZK': [10, 'Kč', 'Kč'],
|
||||
'DKK': [26, 'kr', 'kr'],
|
||||
'DOP': [2, '$', 'RD$'],
|
||||
'EGP': [2, '£', 'LE'],
|
||||
'EUR': [26, '€', '€'],
|
||||
'GBP': [2, '£', 'GB£'],
|
||||
'HKD': [2, '$', 'HK$'],
|
||||
'ILS': [10, '\u20AA', 'IL₪'],
|
||||
'INR': [2, 'Rs', 'Rs'],
|
||||
'ISK': [10, 'kr', 'kr'],
|
||||
'JMD': [2, '$', 'JA$'],
|
||||
'JPY': [0, '¥', 'JP¥'],
|
||||
'KRW': [0, '\u20A9', 'KR₩'],
|
||||
'LKR': [2, 'Rs', 'SLRs'],
|
||||
'MNT': [2, '\u20AE', 'MN₮'],
|
||||
'MXN': [2, '$', 'Mex$'],
|
||||
'MYR': [2, 'RM', 'RM'],
|
||||
'NOK': [26, 'kr', 'NOkr'],
|
||||
'PAB': [2, 'B/.', 'B/.'],
|
||||
'PEN': [2, 'S/.', 'S/.'],
|
||||
'PHP': [2, 'P', 'PHP'],
|
||||
'PKR': [2, 'Rs.', 'PKRs.'],
|
||||
'RUB': [10, 'руб', 'руб'],
|
||||
'SAR': [2, '\u0633\u002E\u0631', 'SR'],
|
||||
'SEK': [10, 'kr', 'kr'],
|
||||
'SGD': [2, '$', 'S$'],
|
||||
'THB': [2, '\u0e3f', 'THB'],
|
||||
'TRY': [2, 'YTL', 'YTL'],
|
||||
'TWD': [2, 'NT$', 'NT$'],
|
||||
'USD': [2, '$', 'US$'],
|
||||
'UYU': [2, '$', 'UY$'],
|
||||
'VND': [10, '\u20AB', 'VN₫'],
|
||||
'YER': [2, 'YER', 'YER'],
|
||||
'ZAR': [2, 'R', 'ZAR']
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tier 2 currency information.
|
||||
* @type {!Object.<!Array>}
|
||||
*/
|
||||
goog.i18n.currency.CurrencyInfoTier2 = {
|
||||
'AFN': [18, '\u060b', 'AFN'],
|
||||
'ALL': [2, 'Lek', 'Lek'],
|
||||
'AMD': [10, '\u0564\u0580\u002e', 'dram'],
|
||||
'ANG': [2, '\u0083', 'NAƒ'],
|
||||
'AOA': [2, 'Kz', 'Kz'],
|
||||
'AWG': [2, 'ƒ', 'Afl.'],
|
||||
'AZN': [2, 'm', 'man'],
|
||||
'BAM': [18, 'КМ', 'KM'],
|
||||
'BBD': [2, '$', 'Bds$'],
|
||||
'BGN': [10, '\u043b\u0432', 'лв'],
|
||||
'BHD': [3, '\u0628\u002e\u062f\u002e', 'BD'],
|
||||
'BIF': [0, 'FBu', 'FBu'],
|
||||
'BMD': [2, '$', 'BD$'],
|
||||
'BND': [2, '$', 'B$'],
|
||||
'BOB': [2, 'B$', 'B$'],
|
||||
'BSD': [2, '$', 'B$'],
|
||||
'BTN': [2, 'Nu.', 'Nu.'],
|
||||
'BWP': [2, 'P', 'pula'],
|
||||
'BYR': [0, 'Br', 'Br'],
|
||||
'BZD': [2, '$', 'BZ$'],
|
||||
'CDF': [2, 'F', 'CDF'],
|
||||
'CVE': [2, '$', 'Esc'],
|
||||
'DJF': [0, 'Fdj', 'Fdj'],
|
||||
'DZD': [2, '\u062f\u062C', 'DA'],
|
||||
'EEK': [10, 'EEK', 'EEK'],
|
||||
'ERN': [2, 'Nfk', 'Nfk'],
|
||||
'ETB': [2, 'Br', 'Br'],
|
||||
'FJD': [2, '$', 'FJ$'],
|
||||
'FKP': [2, '£', 'FK£'],
|
||||
'GEL': [2, 'GEL', 'GEL'],
|
||||
'GHS': [2, '\u20B5', 'GHS¢'],
|
||||
'GIP': [2, '£', 'GI£'],
|
||||
'GMD': [2, 'D', 'GMD'],
|
||||
'GNF': [0, 'FG', 'FG'],
|
||||
'GTQ': [2, 'Q', 'GTQ'],
|
||||
'GYD': [2, '$', 'GY$'],
|
||||
'HNL': [2, 'L', 'HNL'],
|
||||
'HRK': [2, 'kn', 'kn'],
|
||||
'HTG': [2, 'G', 'HTG'],
|
||||
'HUF': [10, 'Ft', 'Ft'],
|
||||
'IDR': [2, 'Rp', 'Rp'],
|
||||
'IQD': [3, '\u0639\u062F', 'IQD'],
|
||||
'IRR': [2, '\ufdfc', 'IRR'],
|
||||
'JOD': [3, 'JOD', 'JOD'],
|
||||
'KES': [2, 'KSh', 'KSh'],
|
||||
'KGS': [2, 'som', 'som'],
|
||||
'KHR': [10, '\u17DB', 'KHR'],
|
||||
'KMF': [0, 'KMF', 'KMF'],
|
||||
'KPW': [2, '\u20A9', 'KPW'],
|
||||
'KWD': [3, '\u062F\u002e\u0643', 'KWD'],
|
||||
'KYD': [2, '$', 'CI$'],
|
||||
'KZT': [10, 'KZT', 'KZT'],
|
||||
'LAK': [2, '\u20AD', 'LA₭'],
|
||||
'LBP': [2, '\u0644\u002e\u0644', 'LBP'],
|
||||
'LRD': [2, '$', 'L$'],
|
||||
'LSL': [2, 'L', 'LSL'],
|
||||
'LTL': [10, 'Lt', 'Lt'],
|
||||
'LVL': [10, 'Ls', 'Ls'],
|
||||
'LYD': [3, '\u0644\u002e\u062F', 'LD'],
|
||||
'MAD': [2, '\u0645\u002E\u062F\u002E', 'MAD'],
|
||||
'MDL': [2, 'MDL', 'MDL'],
|
||||
'MGA': [1, 'MGA', 'MGA'],
|
||||
'MKD': [2, 'MKD', 'MKD'],
|
||||
'MMK': [2, 'K', 'MMK'],
|
||||
'MOP': [2, 'MOP$', 'MOP$'],
|
||||
'MRO': [1, 'UM', 'UM'],
|
||||
'MUR': [2, 'Rs', 'MURs'],
|
||||
'MVR': [2, 'Rf', 'MRF'],
|
||||
'MWK': [2, 'MK', 'MK'],
|
||||
'MZN': [2, 'MTn', 'MTn'],
|
||||
'NAD': [2, '$', 'N$'],
|
||||
'NGN': [2, '\u20A6', 'NG₦'],
|
||||
'NIO': [2, 'C$', 'C$'],
|
||||
'NPR': [2, 'Rs', 'NPRs'],
|
||||
'NZD': [2, '$', 'NZ$'],
|
||||
'OMR': [3, '\u0639\u002E\u062F\u002E', 'OMR'],
|
||||
'PGK': [2, 'K', 'PGK'],
|
||||
'PLN': [10, 'zł', 'zł'],
|
||||
'PYG': [0, '\u20b2', 'PYG'],
|
||||
'QAR': [2, '\u0642\u002E\u0631', 'QR'],
|
||||
'RON': [2, 'L', 'RON'],
|
||||
'RSD': [2, 'РС\u0414', 'RSD'],
|
||||
'RWF': [0, 'RF', 'RF'],
|
||||
'SBD': [2, '$', 'SI$'],
|
||||
'SCR': [2, 'SR', 'SCR'],
|
||||
'SDG': [2, 'SDG', 'SDG'],
|
||||
'SHP': [2, '£', 'SH£'],
|
||||
'SKK': [10, 'Sk', 'Sk'],
|
||||
'SLL': [2, 'Le', 'Le'],
|
||||
'SOS': [2, 'So. Sh.', 'So. Sh.'],
|
||||
'SRD': [2, '$', 'SR$'],
|
||||
'STD': [2, 'Db', 'Db'],
|
||||
'SYP': [18, 'SYP', 'SYP'],
|
||||
'SZL': [2, 'L', 'SZL'],
|
||||
'TJS': [2, 'TJS', 'TJS'],
|
||||
'TMM': [2, 'm', 'TMM'],
|
||||
'TND': [3, '\u062F\u002e\u062A ', 'DT'],
|
||||
'TOP': [2, 'T$', 'T$'],
|
||||
'TTD': [2, '$', 'TT$'],
|
||||
'TZS': [10, 'TZS', 'TZS'],
|
||||
'UAH': [10, '\u20B4', 'грн'],
|
||||
'UGX': [2, 'USh', 'USh'],
|
||||
'UZS': [2, 'UZS', 'UZS'],
|
||||
'VEF': [2, 'Bs.F', 'Bs.F'],
|
||||
'VUV': [0, 'Vt', 'Vt'],
|
||||
'WST': [2, 'WS$', 'WS$'],
|
||||
'XAF': [0, 'FCFA', 'FCFA'],
|
||||
'XCD': [2, '$', 'EC$'],
|
||||
'XOF': [0, 'CFA', 'CFA'],
|
||||
'XPF': [0, 'F', 'XPF'],
|
||||
'ZMK': [2, 'ZK', 'ZK'],
|
||||
'ZWL': [2, '$', 'ZW$']
|
||||
};
|
||||
3350
i18n/closure/datetimesymbols.js
Normal file
3350
i18n/closure/datetimesymbols.js
Normal file
File diff suppressed because it is too large
Load diff
3076
i18n/closure/numberSymbols.js
Normal file
3076
i18n/closure/numberSymbols.js
Normal file
File diff suppressed because it is too large
Load diff
79
i18n/e2e/i18n-e2e.js
Normal file
79
i18n/e2e/i18n-e2e.js
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
describe("localized filters", function() {
|
||||
describe("es locale", function() {
|
||||
beforeEach(function() {
|
||||
browser().navigateTo("localeTest_es.html");
|
||||
});
|
||||
|
||||
it('should check filters for es locale', function() {
|
||||
expect(binding('input | date:"medium"')).toBe('03/06/1977 18:07:23');
|
||||
expect(binding('input | date:"longDate"')).toBe("3 de junio de 1977");
|
||||
expect(binding('input | number')).toBe('234.234.443.432');
|
||||
expect(binding('input | currency')).toBe('€ 234.234.443.432,00');
|
||||
});
|
||||
});
|
||||
|
||||
describe("cs locale", function() {
|
||||
beforeEach(function() {
|
||||
browser().navigateTo("localeTest_cs.html");
|
||||
});
|
||||
|
||||
it('should check filters for cs locale', function() {
|
||||
expect(binding('input | date:"medium"')).toBe('3.6.1977 18:07:23');
|
||||
expect(binding('input | date:"longDate"')).toBe("3. června 1977");
|
||||
expect(binding('input | number')).toBe('234 234 443 432');
|
||||
expect(binding('input | currency')).toBe('234 234 443 432,00 K\u010d');
|
||||
});
|
||||
});
|
||||
|
||||
describe("de locale", function() {
|
||||
beforeEach(function() {
|
||||
browser().navigateTo("localeTest_de.html");
|
||||
});
|
||||
|
||||
it('should check filters for de locale', function() {
|
||||
expect(binding('input | date:"medium"')).toBe('03.06.1977 18:07:23');
|
||||
expect(binding('input | date:"longDate"')).toBe("3. Juni 1977");
|
||||
expect(binding('input | number')).toBe('234.234.443.432');
|
||||
expect(binding('input | currency')).toBe('234.234.443.432,00 €');
|
||||
});
|
||||
});
|
||||
|
||||
describe("en locale", function() {
|
||||
beforeEach(function() {
|
||||
browser().navigateTo("localeTest_en.html");
|
||||
});
|
||||
|
||||
it('should check filters for en locale', function() {
|
||||
expect(binding('input | date:"medium"')).toBe('Jun 3, 1977 6:07:23 PM');
|
||||
expect(binding('input | date:"longDate"')).toBe("June 3, 1977");
|
||||
expect(binding('input | number')).toBe('234,234,443,432');
|
||||
expect(binding('input | currency')).toBe('$234,234,443,432.00');
|
||||
});
|
||||
});
|
||||
|
||||
describe("sk locale", function() {
|
||||
beforeEach(function() {
|
||||
browser().navigateTo("localeTest_sk.html");
|
||||
});
|
||||
|
||||
it('should check filters for sk locale', function() {
|
||||
expect(binding('input | date:"medium"')).toBe('3.6.1977 18:07:23');
|
||||
expect(binding('input | date:"longDate"')).toBe("3. júna 1977");
|
||||
expect(binding('input | number')).toBe('234 234 443 432');
|
||||
expect(binding('input | currency')).toBe('234 234 443 432,00 Sk');
|
||||
});
|
||||
});
|
||||
|
||||
describe("zh locale", function() {
|
||||
beforeEach(function() {
|
||||
browser().navigateTo("localeTest_zh.html");
|
||||
});
|
||||
|
||||
it('should check filters for zh locale', function() {
|
||||
expect(binding('input | date:"medium"')).toBe('1977-6-3 下午6:07:23');
|
||||
expect(binding('input | date:"longDate"')).toBe("1977年6月3日");
|
||||
expect(binding('input | number')).toBe('234,234,443,432');
|
||||
expect(binding('input | currency')).toBe('¥234,234,443,432.00');
|
||||
});
|
||||
});
|
||||
});
|
||||
16
i18n/e2e/localeTest_cs.html
Normal file
16
i18n/e2e/localeTest_cs.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<!document html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>locale test</title>
|
||||
<script src="../../build/angular.js" ng:autobind></script>
|
||||
<script src="../../build/i18n/angular-locale_cs.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<input type="text" name="input" value="234234443432"><br>
|
||||
date: {{input | date:"medium"}}<br>
|
||||
date: {{input | date:"longDate"}}<br>
|
||||
number: {{input | number}}<br>
|
||||
currency: {{input | currency }}
|
||||
</body>
|
||||
</html>
|
||||
16
i18n/e2e/localeTest_de.html
Normal file
16
i18n/e2e/localeTest_de.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<!document html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>locale test</title>
|
||||
<script src="../../build/angular.js" ng:autobind></script>
|
||||
<script src="../../build/i18n/angular-locale_de.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<input type="text" name="input" value="234234443432"><br>
|
||||
date: {{input | date:"medium"}}<br>
|
||||
date: {{input | date:"longDate"}}<br>
|
||||
number: {{input | number}}<br>
|
||||
currency: {{input | currency }}
|
||||
</body>
|
||||
</html>
|
||||
18
i18n/e2e/localeTest_en.html
Normal file
18
i18n/e2e/localeTest_en.html
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<!document html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>locale test</title>
|
||||
<script src="../../build/angular.js" ng:autobind></script>
|
||||
<!-- not needed, already bundled in angular.js
|
||||
<script src="../../build/i18n/angular-locale_en.js"></script>
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
<input type="text" name="input" value="234234443432"><br>
|
||||
date: {{input | date:"medium"}}<br>
|
||||
date: {{input | date:"longDate"}}<br>
|
||||
number: {{input | number}}<br>
|
||||
currency: {{input | currency }}
|
||||
</body>
|
||||
</html>
|
||||
16
i18n/e2e/localeTest_es.html
Normal file
16
i18n/e2e/localeTest_es.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<!document html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>locale test</title>
|
||||
<script src="../../build/angular.js" ng:autobind></script>
|
||||
<script src="../../build/i18n/angular-locale_es.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<input type="text" name="input" value="234234443432"><br>
|
||||
date: {{input | date:"medium"}}<br>
|
||||
date: {{input | date:"longDate"}}<br>
|
||||
number: {{input | number}}<br>
|
||||
currency: {{input | currency }}
|
||||
</body>
|
||||
</html>
|
||||
16
i18n/e2e/localeTest_sk.html
Normal file
16
i18n/e2e/localeTest_sk.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<!document html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>locale test</title>
|
||||
<script src="../../build/angular.js" ng:autobind></script>
|
||||
<script src="../../build/i18n/angular-locale_sk-sk.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<input type="text" name="input" value="234234443432"><br>
|
||||
date: {{input | date:"medium"}}<br>
|
||||
date: {{input | date:"longDate"}}<br>
|
||||
number: {{input | number}}<br>
|
||||
currency: {{input | currency }}
|
||||
</body>
|
||||
</html>
|
||||
16
i18n/e2e/localeTest_zh.html
Normal file
16
i18n/e2e/localeTest_zh.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<!document html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>locale test</title>
|
||||
<script src="../../build/angular.js" ng:autobind></script>
|
||||
<script src="../../build/i18n/angular-locale_zh-cn.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<input type="text" name="input" value="234234443432"><br>
|
||||
date: {{input | date:"medium"}}<br>
|
||||
date: {{input | date:"longDate"}}<br>
|
||||
number: {{input | number}}<br>
|
||||
currency: {{input | currency }}
|
||||
</body>
|
||||
</html>
|
||||
11
i18n/e2e/runner.html
Normal file
11
i18n/e2e/runner.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html xmlns:ng="http://angularjs.org" wiki:ng="http://angularjs.org">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title><angular/> Docs Scenario Runner</title>
|
||||
<script type="text/javascript" src="../../build/angular-scenario.js" ng:autotest></script>
|
||||
<script type="text/javascript" src="i18n-e2e.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
7
i18n/generate.sh
Executable file
7
i18n/generate.sh
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
BASE_DIR=`dirname $0`
|
||||
cd $BASE_DIR
|
||||
|
||||
|
||||
/usr/bin/env jasmine-node spec/ --noColor | grep -v '/lib/jasmine' && node src/closureSlurper.js
|
||||
53
i18n/spec/converterSpec.js
Normal file
53
i18n/spec/converterSpec.js
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
var converter = require('../src/converter.js');
|
||||
|
||||
describe("convertNumberData", function() {
|
||||
var convert = converter.convertNumberData,
|
||||
dataObj = { DECIMAL_SEP: ',',
|
||||
GROUP_SEP: '.',
|
||||
DECIMAL_PATTERN: '#,##0.###;#,##0.###-',
|
||||
CURRENCY_PATTERN: '\u00A4#,##0.00;\u00A4#,##0.00-',
|
||||
DEF_CURRENCY_CODE: 'USD' };
|
||||
|
||||
it('should convert number object', function() {
|
||||
var processedData = convert(dataObj, {USD: ['x', '$', 'y']});
|
||||
expect(processedData.DECIMAL_SEP).toBe(',');
|
||||
expect(processedData.GROUP_SEP).toBe('.');
|
||||
expect(processedData.PATTERNS.length).toBe(2);
|
||||
expect(processedData.PATTERNS[0].gSize).toBe(3);
|
||||
expect(processedData.PATTERNS[0].negSuf).toBe('-');
|
||||
expect(processedData.CURRENCY_SYM).toBe('$');
|
||||
|
||||
dataObj.DEF_CURRENCY_CODE = 'NoSuchCode';
|
||||
processedData = convert(dataObj, {});
|
||||
expect(processedData.CURRENCY_SYM).toBe('NoSuchCode');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("convertDatetimeData", function() {
|
||||
var convert = converter.convertDatetimeData,
|
||||
dataObj = { MONTHS: ['Enero', 'Pebrero'],
|
||||
SHORTMONTHS: ['Ene', 'Peb'],
|
||||
WEEKDAYS: ['Linggo', 'Lunes'],
|
||||
SHORTWEEKDAYS: ['Lin', 'Lun'],
|
||||
AMPMS: ['AM', 'PM'],
|
||||
DATEFORMATS: ['a', 'b', 'c', 'd'],
|
||||
TIMEFORMATS: ['e', 'f', 'g', 'h'] };
|
||||
|
||||
it('should convert empty datetime obj', function() {
|
||||
var processedData = convert(dataObj);
|
||||
expect(processedData.MONTH).toEqual(['Enero', 'Pebrero']);
|
||||
expect(processedData.SHORTMONTH).toEqual(['Ene', 'Peb']);
|
||||
expect(processedData.DAY).toEqual(['Linggo', 'Lunes']);
|
||||
expect(processedData.SHORTDAY).toEqual(['Lin', 'Lun']);
|
||||
expect(processedData.AMPMS).toEqual(['AM', 'PM']);
|
||||
expect(processedData.medium).toBe('c g');
|
||||
expect(processedData.short).toBe('d h');
|
||||
expect(processedData.fullDate).toBe('a');
|
||||
expect(processedData.longDate).toBe('b');
|
||||
expect(processedData.mediumDate).toBe('c');
|
||||
expect(processedData.shortDate).toBe('d');
|
||||
expect(processedData.mediumTime).toBe('g');
|
||||
expect(processedData.shortTime).toBe('h');
|
||||
});
|
||||
});
|
||||
51
i18n/spec/parserSpec.js
Normal file
51
i18n/spec/parserSpec.js
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
var parsePattern = require('../src/parser.js').parsePattern;
|
||||
|
||||
describe('parsePattern', function() {
|
||||
function parseAndExpect(pattern, pp, np, ps, ns, mii, mif, maf, g, lg) {
|
||||
var p = parsePattern(pattern);
|
||||
|
||||
expect(p.minInt).toEqual(mii);
|
||||
expect(p.minFrac).toEqual(mif);
|
||||
expect(p.maxFrac).toEqual(maf);
|
||||
|
||||
expect(p.posPre).toEqual(pp);
|
||||
expect(p.posSuf).toEqual(ps);
|
||||
expect(p.negPre).toEqual(np);
|
||||
expect(p.negSuf).toEqual(ns);
|
||||
|
||||
expect(p.gSize).toBe(g);
|
||||
expect(p.lgSize).toBe(lg);
|
||||
}
|
||||
|
||||
it('should parse DECIMAL patterns', function() {
|
||||
// all DECIMAL patterns from closure
|
||||
parseAndExpect('#,##0.###', '', '-', '', '', 1, 0, 3, 3, 3);
|
||||
parseAndExpect('#,##0.###;#,##0.###-', '', '', '', '-', 1, 0, 3, 3, 3);
|
||||
parseAndExpect('#,##,##0.###', '', '-', '', '', 1, 0, 3, 2, 3);
|
||||
parseAndExpect("#,##0.###;\'\u202A\'-#,##0.###\'\u202C\'",
|
||||
'', '\u202A-', '', '\u202C', 1, 0, 3, 3, 3);
|
||||
});
|
||||
|
||||
it('should parse CURRENCY patterns', function() {
|
||||
// all CURRENCY patterns from closure
|
||||
parseAndExpect('#,##0.00 \u00A4', '', '-', ' \u00A4', ' \u00A4', 1, 2, 2, 3, 3);
|
||||
parseAndExpect("#,##0.00\u00A0\u00A4;\'\u202A\'-#,##0.00\'\u202C\'\u00A0\u00A4",
|
||||
'', '\u202A-', '\u00A0\u00A4', '\u202C\u00A0\u00A4', 1, 2, 2, 3, 3);
|
||||
parseAndExpect('#,##0.00 \u00A4;(#,##0.00 \u00A4)',
|
||||
'', '(', ' \u00A4', ' \u00A4)', 1, 2, 2, 3, 3);
|
||||
parseAndExpect('#,##,##0.00\u00A4', '', '-', '\u00A4', '\u00A4', 1, 2, 2, 2, 3);
|
||||
parseAndExpect('#,##,##0.00\u00A4;(#,##,##0.00\u00A4)',
|
||||
'', '(', '\u00A4', '\u00A4)', 1, 2, 2, 2, 3);
|
||||
parseAndExpect('\u00A4#,##0.00', '\u00A4', '\u00A4-', '', '', 1, 2, 2, 3, 3);
|
||||
parseAndExpect('\u00A4#,##0.00;(\u00A4#,##0.00)',
|
||||
'\u00A4', '(\u00A4', '', ')', 1, 2, 2, 3, 3);
|
||||
parseAndExpect('\u00A4#,##0.00;\u00A4-#,##0.00',
|
||||
'\u00A4', '\u00A4-', '', '', 1, 2, 2, 3, 3);
|
||||
parseAndExpect('\u00A4 #,##0.00', '\u00A4 ', '\u00A4 -', '', '', 1, 2, 2, 3, 3);
|
||||
parseAndExpect('\u00A4 #,##0.00;\u00A4-#,##0.00',
|
||||
'\u00A4 ', '\u00A4-', '', '', 1, 2, 2, 3, 3);
|
||||
parseAndExpect('\u00A4 #,##0.00;\u00A4 #,##0.00-',
|
||||
'\u00A4 ', '\u00A4 ', '', '-', 1, 2, 2, 3, 3);
|
||||
parseAndExpect('\u00A4 #,##,##0.00', '\u00A4 ', '\u00A4 -', '', '', 1, 2, 2, 2, 3);
|
||||
});
|
||||
});
|
||||
14
i18n/spec/utilSpec.js
Normal file
14
i18n/spec/utilSpec.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
var util = require('../src/util.js');
|
||||
|
||||
describe('findLocaleId', function() {
|
||||
it('should find localeId', function() {
|
||||
expect(util.findLocaleId('', 'num')).toBeUndefined();
|
||||
expect(util.findLocaleId('aa', 'datetime')).toBeUndefined();
|
||||
expect(util.findLocaleId('aa', 'randomType')).toBeUndefined();
|
||||
expect(util.findLocaleId('NumberFormatSymbols_en', 'datetime')).toBeUndefined();
|
||||
expect(util.findLocaleId('DateTimeSymbols_en', 'num')).toBeUndefined();
|
||||
|
||||
expect(util.findLocaleId('DateTimeSymbols_en', 'datetime')).toBe('en');
|
||||
expect(util.findLocaleId('NumberFormatSymbols_en_US', 'num')).toBe('en_US');
|
||||
});
|
||||
});
|
||||
106
i18n/src/closureSlurper.js
Normal file
106
i18n/src/closureSlurper.js
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
require.paths.push(__dirname);
|
||||
var Q = require('qq'),
|
||||
qfs = require('q-fs'),
|
||||
converter = require('converter.js'),
|
||||
util = require('util.js'),
|
||||
localeInfo = {},
|
||||
localeIds = [],
|
||||
currencySymbols,
|
||||
goog = { provide: function() {},
|
||||
require: function() {},
|
||||
i18n: {currency: {}} };
|
||||
|
||||
createFolder('../locale/').then(function() {
|
||||
var promiseA = Q.defer(),
|
||||
promiseB = Q.defer();
|
||||
|
||||
qfs.read(__dirname + '/../closure/currencySymbols.js', 'b').then(function(content) {
|
||||
eval(content.toString());
|
||||
currencySymbols = goog.i18n.currency.CurrencyInfo;
|
||||
currencySymbols.__proto__ = goog.i18n.currency.CurrencyInfoTier2;
|
||||
|
||||
qfs.read(__dirname + '/../closure/numberSymbols.js', 'b').then(function(content) {
|
||||
//eval script in the current context so that we get access to all the symbols
|
||||
eval(content.toString());
|
||||
for (propName in goog.i18n) {
|
||||
var localeID = util.findLocaleId(propName, 'num');
|
||||
if (localeID) {
|
||||
if (!localeInfo[localeID]) {
|
||||
localeInfo[localeID] = {};
|
||||
localeIds.push(localeID);
|
||||
}
|
||||
var convertedData = converter.convertNumberData(goog.i18n[propName], currencySymbols);
|
||||
localeInfo[localeID].NUMBER_FORMATS = convertedData;
|
||||
}
|
||||
}
|
||||
|
||||
promiseA.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
qfs.read(__dirname + '/../closure/datetimeSymbols.js', 'b').then(function(content) {
|
||||
eval(content.toString());
|
||||
for (propName in goog.i18n) {
|
||||
var localeID = util.findLocaleId(propName, 'datetime');
|
||||
if (localeID) {
|
||||
if (!localeInfo[localeID]) {
|
||||
localeInfo[localeID] = {};
|
||||
localeIds.push(localeID);
|
||||
}
|
||||
var convertedData = converter.convertDatetimeData(goog.i18n[propName]);
|
||||
localeInfo[localeID].DATETIME_FORMATS = convertedData;
|
||||
}
|
||||
}
|
||||
|
||||
promiseB.resolve();
|
||||
});
|
||||
|
||||
return Q.join(promiseA.promise, promiseB.promise, noop);
|
||||
}).then(function() {
|
||||
localeIds.forEach(function(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;
|
||||
}
|
||||
|
||||
if (!localeObj.DATETIME_FORMATS) {
|
||||
localeObj.DATETIME_FORMATS = fallBackObj.DATETIME_FORMATS;
|
||||
}
|
||||
|
||||
// e.g. from zh_CN to zh-CN, from en_US to en-US
|
||||
var correctedLocaleId = localeID.replace(/_/g, '-').toLowerCase();
|
||||
localeObj.id = correctedLocaleId;
|
||||
|
||||
var prefix = 'angular.service("$locale", function() {\nreturn ',
|
||||
content = JSON.stringify(localeInfo[localeID]).replace(/\¤/g,'\\u00A4'),
|
||||
suffix;
|
||||
|
||||
suffix = ';\n});';
|
||||
|
||||
var toWrite = prefix + content + suffix;
|
||||
|
||||
qfs.write(__dirname + '/../locale/' + 'angular-locale_' + correctedLocaleId + '.js', toWrite);
|
||||
});
|
||||
console.log('Generated ' + localeIds.length + ' locale files!');
|
||||
}).end();
|
||||
|
||||
function noop() {};
|
||||
|
||||
/**
|
||||
* Make a folder under current directory.
|
||||
* @param folder {string} name of the folder to be made
|
||||
*/
|
||||
function createFolder(folder) {
|
||||
return qfs.isDirectory(__dirname + '/' + folder).then(function(isDir) {
|
||||
if (!isDir) return qfs.makeDirectory(__dirname + '/' + folder);
|
||||
});
|
||||
}
|
||||
60
i18n/src/converter.js
Normal file
60
i18n/src/converter.js
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* after obtaining data from closure files, use converter to massage the data into the formats
|
||||
* we want
|
||||
*/
|
||||
exports.convertDatetimeData = convertDatetimeData;
|
||||
exports.convertNumberData = convertNumberData;
|
||||
|
||||
|
||||
require.paths.push(__dirname);
|
||||
|
||||
|
||||
var parsePattern = require('parser').parsePattern;
|
||||
|
||||
|
||||
function convertNumberData(dataObj, currencySymbols) {
|
||||
var numberFormats = {},
|
||||
|
||||
numberFormats = {
|
||||
DECIMAL_SEP: dataObj.DECIMAL_SEP,
|
||||
GROUP_SEP: dataObj.GROUP_SEP,
|
||||
PATTERNS: [parsePattern(dataObj.DECIMAL_PATTERN),
|
||||
parsePattern(dataObj.CURRENCY_PATTERN)]
|
||||
}
|
||||
|
||||
if (currencySymbols[dataObj.DEF_CURRENCY_CODE]) {
|
||||
numberFormats.CURRENCY_SYM = currencySymbols[dataObj.DEF_CURRENCY_CODE][1];
|
||||
} else {
|
||||
if (dataObj.DEF_CURRENCY_CODE == 'MTL') {
|
||||
numberFormats.CURRENCY_SYM = '₤'; //for some reason this is missing in closure
|
||||
} else {
|
||||
// if there is no corresponding currency symbol, just use currency code.
|
||||
var code = numberFormats.CURRENCY_SYM = dataObj.DEF_CURRENCY_CODE;
|
||||
console.log(code +' has no currency symbol in closure, used ' + code + ' instead!');
|
||||
}
|
||||
}
|
||||
return numberFormats;
|
||||
}
|
||||
|
||||
|
||||
function convertDatetimeData(dataObj) {
|
||||
var datetimeFormats = {};
|
||||
|
||||
datetimeFormats.MONTH = dataObj.MONTHS;
|
||||
datetimeFormats.SHORTMONTH = dataObj.SHORTMONTHS;
|
||||
datetimeFormats.DAY = dataObj.WEEKDAYS;
|
||||
datetimeFormats.SHORTDAY = dataObj.SHORTWEEKDAYS;
|
||||
datetimeFormats.AMPMS = dataObj.AMPMS;
|
||||
|
||||
|
||||
datetimeFormats.medium = dataObj.DATEFORMATS[2] + ' ' + dataObj.TIMEFORMATS[2];
|
||||
datetimeFormats.short = dataObj.DATEFORMATS[3] + ' ' + dataObj.TIMEFORMATS[3];
|
||||
datetimeFormats.fullDate = dataObj.DATEFORMATS[0];
|
||||
datetimeFormats.longDate = dataObj.DATEFORMATS[1];
|
||||
datetimeFormats.mediumDate = dataObj.DATEFORMATS[2];
|
||||
datetimeFormats.shortDate = dataObj.DATEFORMATS[3];
|
||||
datetimeFormats.mediumTime = dataObj.TIMEFORMATS[2];
|
||||
datetimeFormats.shortTime = dataObj.TIMEFORMATS[3];
|
||||
|
||||
return datetimeFormats;
|
||||
}
|
||||
64
i18n/src/parser.js
Normal file
64
i18n/src/parser.js
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* A simple parser to parse a number format into a pattern object
|
||||
*/
|
||||
|
||||
exports.parsePattern = parsePattern;
|
||||
|
||||
var PATTERN_SEP = ';',
|
||||
DECIMAL_SEP = '.',
|
||||
GROUP_SEP = ',',
|
||||
ZERO = '0',
|
||||
DIGIT = '#';
|
||||
|
||||
/**
|
||||
* main funciton for parser
|
||||
* @param str {string} pattern to be parsed (e.g. #,##0.###).
|
||||
*/
|
||||
function parsePattern(pattern) {
|
||||
var p = {
|
||||
minInt: 1,
|
||||
minFrac: 0,
|
||||
macFrac: 0,
|
||||
posPre: '',
|
||||
posSuf: '',
|
||||
negPre: '',
|
||||
negSuf: '',
|
||||
gSize: 0,
|
||||
lgSize: 0
|
||||
};
|
||||
|
||||
var parts = pattern.split(PATTERN_SEP),
|
||||
positive = parts[0],
|
||||
negative = parts[1];
|
||||
|
||||
var parts = positive.split(DECIMAL_SEP),
|
||||
integer = parts[0],
|
||||
fraction = parts[1];
|
||||
|
||||
p.posPre = integer.substr(0, integer.indexOf(DIGIT));
|
||||
|
||||
for (var i = 0; i < fraction.length; i++) {
|
||||
var ch = fraction.charAt(i);
|
||||
if (ch == ZERO) p.minFrac = p.maxFrac = i + 1;
|
||||
else if (ch == DIGIT) p.maxFrac = i + 1;
|
||||
else p.posSuf += ch;
|
||||
}
|
||||
|
||||
var groups = integer.split(GROUP_SEP);
|
||||
p.gSize = groups[1].length;
|
||||
p.lgSize = (groups[2] || groups[1]).length;
|
||||
|
||||
if (negative) {
|
||||
var trunkLen = positive.length - p.posPre.length - p.posSuf.length,
|
||||
pos = negative.indexOf(DIGIT);
|
||||
|
||||
p.negPre = negative.substr(0, pos).replace(/\'/g, '');
|
||||
p.negSuf = negative.substr(pos + trunkLen).replace(/\'/g, '');
|
||||
} else {
|
||||
// hardcoded '-' sign is fine as all locale use '-' as MINUS_SIGN. (\u2212 is the same as '-')
|
||||
p.negPre = p.posPre + '-';
|
||||
p.negSuf = p.posSuf;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
7
i18n/src/util.js
Normal file
7
i18n/src/util.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
exports.findLocaleId = function findLocaleId(str, type) {
|
||||
if (type === 'num') {
|
||||
return (str.match(/^NumberFormatSymbols_(.+)$/) || [])[1];
|
||||
} else if (type == 'datetime') {
|
||||
return (str.match(/^DateTimeSymbols_(.+)$/) || [])[1];
|
||||
}
|
||||
}
|
||||
8
i18n/update-closure.sh
Executable file
8
i18n/update-closure.sh
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/bash
|
||||
|
||||
BASE_DIR=`dirname $0`
|
||||
cd $BASE_DIR
|
||||
|
||||
curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/currency.js > closure/currencySymbols.js
|
||||
curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/datetimesymbols.js > closure/datetimeSymbols.js
|
||||
curl http://closure-library.googlecode.com/svn/trunk/closure/goog/i18n/numberformatsymbols.js > closure/numberSymbols.js
|
||||
Loading…
Reference in a new issue