Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(482)

Side by Side Diff: src/js/i18n.js

Issue 2736543002: [intl] Implement Intl.PluralRules
Patch Set: clarify comment Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // ECMAScript 402 API implementation. 5 // ECMAScript 402 API implementation.
6 6
7 /** 7 /**
8 * Intl object is a single object that has some named properties, 8 * Intl object is a single object that has some named properties,
9 * all of which are constructors. 9 * all of which are constructors.
10 */ 10 */
11 (function(global, utils) { 11 (function(global, utils) {
12 12
13 "use strict"; 13 "use strict";
14 14
15 %CheckIsBootstrapping(); 15 %CheckIsBootstrapping();
16 16
17 // ------------------------------------------------------------------- 17 // -------------------------------------------------------------------
18 // Imports 18 // Imports
19 19
20 var ArrayJoin; 20 var ArrayJoin;
21 var ArrayPush; 21 var ArrayPush;
22 var GlobalDate = global.Date; 22 var GlobalDate = global.Date;
23 var GlobalIntl = global.Intl; 23 var GlobalIntl = global.Intl;
24 var GlobalIntlDateTimeFormat = GlobalIntl.DateTimeFormat; 24 var GlobalIntlDateTimeFormat = GlobalIntl.DateTimeFormat;
25 var GlobalIntlNumberFormat = GlobalIntl.NumberFormat; 25 var GlobalIntlNumberFormat = GlobalIntl.NumberFormat;
26 var GlobalIntlCollator = GlobalIntl.Collator; 26 var GlobalIntlCollator = GlobalIntl.Collator;
27 var GlobalIntlPluralRules = utils.ImportNow("PluralRules");
27 var GlobalIntlv8BreakIterator = GlobalIntl.v8BreakIterator; 28 var GlobalIntlv8BreakIterator = GlobalIntl.v8BreakIterator;
28 var GlobalNumber = global.Number; 29 var GlobalNumber = global.Number;
29 var GlobalRegExp = global.RegExp; 30 var GlobalRegExp = global.RegExp;
30 var GlobalString = global.String; 31 var GlobalString = global.String;
31 var IntlFallbackSymbol = utils.ImportNow("intl_fallback_symbol"); 32 var IntlFallbackSymbol = utils.ImportNow("intl_fallback_symbol");
32 var InstallFunctions = utils.InstallFunctions; 33 var InstallFunctions = utils.InstallFunctions;
33 var InstallGetter = utils.InstallGetter; 34 var InstallGetter = utils.InstallGetter;
34 var InternalArray = utils.InternalArray; 35 var InternalArray = utils.InternalArray;
35 var MaxSimple; 36 var MaxSimple;
36 var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty"); 37 var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty");
38 var ObjectKeys = global.Object.keys;
37 var OverrideFunction = utils.OverrideFunction; 39 var OverrideFunction = utils.OverrideFunction;
38 var patternSymbol = utils.ImportNow("intl_pattern_symbol"); 40 var patternSymbol = utils.ImportNow("intl_pattern_symbol");
39 var resolvedSymbol = utils.ImportNow("intl_resolved_symbol"); 41 var resolvedSymbol = utils.ImportNow("intl_resolved_symbol");
40 var SetFunctionName = utils.SetFunctionName; 42 var SetFunctionName = utils.SetFunctionName;
41 var StringSubstr = GlobalString.prototype.substr; 43 var StringSubstr = GlobalString.prototype.substr;
42 var StringSubstring = GlobalString.prototype.substring; 44 var StringSubstring = GlobalString.prototype.substring;
43 45
44 utils.Import(function(from) { 46 utils.Import(function(from) {
45 ArrayJoin = from.ArrayJoin; 47 ArrayJoin = from.ArrayJoin;
46 ArrayPush = from.ArrayPush; 48 ArrayPush = from.ArrayPush;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 133
132 // ------------------------------------------------------------------- 134 // -------------------------------------------------------------------
133 135
134 /** 136 /**
135 * Caches available locales for each service. 137 * Caches available locales for each service.
136 */ 138 */
137 var AVAILABLE_LOCALES = { 139 var AVAILABLE_LOCALES = {
138 'collator': UNDEFINED, 140 'collator': UNDEFINED,
139 'numberformat': UNDEFINED, 141 'numberformat': UNDEFINED,
140 'dateformat': UNDEFINED, 142 'dateformat': UNDEFINED,
141 'breakiterator': UNDEFINED 143 'breakiterator': UNDEFINED,
144 'pluralrules': UNDEFINED,
142 }; 145 };
143 146
144 /** 147 /**
145 * Caches default ICU locale. 148 * Caches default ICU locale.
146 */ 149 */
147 var DEFAULT_ICU_LOCALE = UNDEFINED; 150 var DEFAULT_ICU_LOCALE = UNDEFINED;
148 151
149 function GetDefaultICULocaleJS() { 152 function GetDefaultICULocaleJS() {
150 if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) { 153 if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
151 DEFAULT_ICU_LOCALE = %GetDefaultICULocale(); 154 DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 } 200 }
198 201
199 /** 202 /**
200 * Matches valid service name. 203 * Matches valid service name.
201 */ 204 */
202 var SERVICE_RE = UNDEFINED; 205 var SERVICE_RE = UNDEFINED;
203 206
204 function GetServiceRE() { 207 function GetServiceRE() {
205 if (IS_UNDEFINED(SERVICE_RE)) { 208 if (IS_UNDEFINED(SERVICE_RE)) {
206 SERVICE_RE = 209 SERVICE_RE =
207 new GlobalRegExp('^(collator|numberformat|dateformat|breakiterator)$'); 210 new GlobalRegExp('^(' + %_Call(ArrayJoin, ObjectKeys(AVAILABLE_LOCALES), '|') + ')$');
208 } 211 }
209 return SERVICE_RE; 212 return SERVICE_RE;
210 } 213 }
211 214
212 /** 215 /**
213 * Validates a language tag against bcp47 spec. 216 * Validates a language tag against bcp47 spec.
214 * Actual value is assigned on first run. 217 * Actual value is assigned on first run.
215 */ 218 */
216 var LANGUAGE_TAG_RE = UNDEFINED; 219 var LANGUAGE_TAG_RE = UNDEFINED;
217 220
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after
1099 * on whether x comes before y in the sort order, the Strings are equal under 1102 * on whether x comes before y in the sort order, the Strings are equal under
1100 * the sort order, or x comes after y in the sort order, respectively. 1103 * the sort order, or x comes after y in the sort order, respectively.
1101 */ 1104 */
1102 function compare(collator, x, y) { 1105 function compare(collator, x, y) {
1103 return %InternalCompare(collator, TO_STRING(x), TO_STRING(y)); 1106 return %InternalCompare(collator, TO_STRING(x), TO_STRING(y));
1104 }; 1107 };
1105 1108
1106 1109
1107 AddBoundMethod(GlobalIntlCollator, 'compare', compare, 2, 'collator', false); 1110 AddBoundMethod(GlobalIntlCollator, 'compare', compare, 2, 'collator', false);
1108 1111
1112 function PluralRulesConstructor() {
1113 var locales = arguments[0];
1114 var options = arguments[1];
1115
1116 if (IS_UNDEFINED(options)) {
1117 options = {};
1118 }
1119
1120 var getOption = getGetOption(options, 'pluralrules');
1121
1122 var locale = resolveLocale('pluralrules', locales, options);
1123
1124 var internalOptions = {};
1125 defineWEProperty(internalOptions, 'type', getOption(
1126 'type', 'string', ['cardinal', 'ordinal'], 'cardinal'));
1127
1128 SetNumberFormatDigitOptions(internalOptions, options, 0, 3);
1129
1130 var requestedLocale = locale.locale;
1131 var resolved = %object_define_properties({}, {
1132 type: {value: internalOptions.type, writable: true},
1133 locale: {writable: true},
1134 maximumFractionDigits: {writable: true},
1135 minimumFractionDigits: {writable: true},
1136 minimumIntegerDigits: {writable: true},
1137 requestedLocale: {value: requestedLocale, writable: true},
1138 });
1139 if (HAS_OWN_PROPERTY(internalOptions, 'minimumSignificantDigits')) {
1140 defineWEProperty(resolved, 'minimumSignificantDigits', UNDEFINED);
1141 }
1142 if (HAS_OWN_PROPERTY(internalOptions, 'maximumSignificantDigits')) {
1143 defineWEProperty(resolved, 'maximumSignificantDigits', UNDEFINED);
1144 }
1145 defineWEProperty(resolved, 'pluralCategories', []);
1146 var pluralRules = %CreatePluralRules(requestedLocale, internalOptions,
1147 resolved);
1148
1149 %MarkAsInitializedIntlObjectOfType(pluralRules, 'pluralrules');
1150 pluralRules[resolvedSymbol] = resolved;
1151
1152 return pluralRules;
1153 }
1154 %SetCode(GlobalIntlPluralRules, PluralRulesConstructor);
1155
1156 InstallFunction(GlobalIntlPluralRules.prototype, 'resolvedOptions',
1157 function() {
1158 if (!%IsInitializedIntlObjectOfType(this, 'pluralrules')) {
1159 throw %make_type_error(kIncompatibleMethodReceiver,
1160 'Intl.PluralRules.prototype.resolvedOptions',
1161 this);
1162 }
1163 var locale = getOptimalLanguageTag(this[resolvedSymbol].requestedLocale,
1164 this[resolvedSymbol].locale);
1165
1166 var result = {
1167 locale: locale,
1168 type: this[resolvedSymbol].type,
1169 minimumIntegerDigits: this[resolvedSymbol].minimumIntegerDigits,
1170 minimumFractionDigits: this[resolvedSymbol].minimumFractionDigits,
1171 maximumFractionDigits: this[resolvedSymbol].maximumFractionDigits,
1172 };
1173
1174 if (HAS_OWN_PROPERTY(this[resolvedSymbol], 'minimumSignificantDigits')) {
1175 defineWECProperty(result, 'minimumSignificantDigits',
1176 this[resolvedSymbol].minimumSignificantDigits);
1177 }
1178
1179 if (HAS_OWN_PROPERTY(this[resolvedSymbol], 'maximumSignificantDigits')) {
1180 defineWECProperty(result, 'maximumSignificantDigits',
1181 this[resolvedSymbol].maximumSignificantDigits);
1182 }
1183
1184 defineWECProperty(result, 'pluralCategories',
1185 this[resolvedSymbol].pluralCategories);
1186
1187 return result;
1188 }
1189 );
1190
1191 InstallFunction(GlobalIntlPluralRules, 'supportedLocalesOf',
1192 function(locales) {
1193 return supportedLocalesOf('pluralrules', locales, arguments[1]);
1194 }
1195 );
1196
1197 InstallFunction(GlobalIntlPluralRules.prototype, 'select',
1198 function(value) {
1199 if (!%IsInitializedIntlObjectOfType(this, 'pluralrules')) {
1200 throw %make_type_error(kIncompatibleMethodReceiver,
1201 'Intl.PluralRules.prototype.select',
1202 this);
1203 }
1204
1205 return %PluralRulesSelect(this, TO_NUMBER(value) + 0);
1206 }
1207 );
1208
1109 /** 1209 /**
1110 * Verifies that the input is a well-formed ISO 4217 currency code. 1210 * Verifies that the input is a well-formed ISO 4217 currency code.
1111 * Don't uppercase to test. It could convert invalid code into a valid one. 1211 * Don't uppercase to test. It could convert invalid code into a valid one.
1112 * For example \u00DFP (Eszett+P) becomes SSP. 1212 * For example \u00DFP (Eszett+P) becomes SSP.
1113 */ 1213 */
1114 function isWellFormedCurrencyCode(currency) { 1214 function isWellFormedCurrencyCode(currency) {
1115 return typeof currency === "string" && currency.length === 3 && 1215 return typeof currency === "string" && currency.length === 3 &&
1116 IS_NULL(%regexp_internal_match(/[^A-Za-z]/, currency)); 1216 IS_NULL(%regexp_internal_match(/[^A-Za-z]/, currency));
1117 } 1217 }
1118 1218
(...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after
2166 2266
2167 utils.Export(function(to) { 2267 utils.Export(function(to) {
2168 to.FormatDateToParts = FormatDateToParts; 2268 to.FormatDateToParts = FormatDateToParts;
2169 to.ToLowerCaseI18N = ToLowerCaseI18N; 2269 to.ToLowerCaseI18N = ToLowerCaseI18N;
2170 to.ToUpperCaseI18N = ToUpperCaseI18N; 2270 to.ToUpperCaseI18N = ToUpperCaseI18N;
2171 to.ToLocaleLowerCaseI18N = ToLocaleLowerCaseI18N; 2271 to.ToLocaleLowerCaseI18N = ToLocaleLowerCaseI18N;
2172 to.ToLocaleUpperCaseI18N = ToLocaleUpperCaseI18N; 2272 to.ToLocaleUpperCaseI18N = ToLocaleUpperCaseI18N;
2173 }); 2273 });
2174 2274
2175 }) 2275 })
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698