OLD | NEW |
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 */ |
(...skipping 14 matching lines...) Expand all Loading... |
25 var GlobalIntlNumberFormat = GlobalIntl.NumberFormat; | 25 var GlobalIntlNumberFormat = GlobalIntl.NumberFormat; |
26 var GlobalIntlCollator = GlobalIntl.Collator; | 26 var GlobalIntlCollator = GlobalIntl.Collator; |
27 var GlobalIntlv8BreakIterator = GlobalIntl.v8BreakIterator; | 27 var GlobalIntlv8BreakIterator = GlobalIntl.v8BreakIterator; |
28 var GlobalNumber = global.Number; | 28 var GlobalNumber = global.Number; |
29 var GlobalRegExp = global.RegExp; | 29 var GlobalRegExp = global.RegExp; |
30 var GlobalString = global.String; | 30 var GlobalString = global.String; |
31 var IntlFallbackSymbol = utils.ImportNow("intl_fallback_symbol"); | 31 var IntlFallbackSymbol = utils.ImportNow("intl_fallback_symbol"); |
32 var InstallFunctions = utils.InstallFunctions; | 32 var InstallFunctions = utils.InstallFunctions; |
33 var InstallGetter = utils.InstallGetter; | 33 var InstallGetter = utils.InstallGetter; |
34 var InternalArray = utils.InternalArray; | 34 var InternalArray = utils.InternalArray; |
| 35 var MaxSimple; |
35 var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty"); | 36 var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty"); |
36 var OverrideFunction = utils.OverrideFunction; | 37 var OverrideFunction = utils.OverrideFunction; |
37 var patternSymbol = utils.ImportNow("intl_pattern_symbol"); | 38 var patternSymbol = utils.ImportNow("intl_pattern_symbol"); |
38 var resolvedSymbol = utils.ImportNow("intl_resolved_symbol"); | 39 var resolvedSymbol = utils.ImportNow("intl_resolved_symbol"); |
39 var SetFunctionName = utils.SetFunctionName; | 40 var SetFunctionName = utils.SetFunctionName; |
40 var StringSubstr = GlobalString.prototype.substr; | 41 var StringSubstr = GlobalString.prototype.substr; |
41 var StringSubstring = GlobalString.prototype.substring; | 42 var StringSubstring = GlobalString.prototype.substring; |
42 | 43 |
43 utils.Import(function(from) { | 44 utils.Import(function(from) { |
44 ArrayJoin = from.ArrayJoin; | 45 ArrayJoin = from.ArrayJoin; |
45 ArrayPush = from.ArrayPush; | 46 ArrayPush = from.ArrayPush; |
| 47 MaxSimple = from.MaxSimple; |
46 }); | 48 }); |
47 | 49 |
48 // Utilities for definitions | 50 // Utilities for definitions |
49 | 51 |
50 function InstallFunction(object, name, func) { | 52 function InstallFunction(object, name, func) { |
51 InstallFunctions(object, DONT_ENUM, [name, func]); | 53 InstallFunctions(object, DONT_ENUM, [name, func]); |
52 } | 54 } |
53 | 55 |
54 | 56 |
55 /** | 57 /** |
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
927 var language = '(' + alpha + '{2,3}(-' + extLang + ')?|' + alpha + '{4}|' + | 929 var language = '(' + alpha + '{2,3}(-' + extLang + ')?|' + alpha + '{4}|' + |
928 alpha + '{5,8})'; | 930 alpha + '{5,8})'; |
929 var langTag = language + '(-' + script + ')?(-' + region + ')?(-' + | 931 var langTag = language + '(-' + script + ')?(-' + region + ')?(-' + |
930 variant + ')*(-' + extension + ')*(-' + privateUse + ')?'; | 932 variant + ')*(-' + extension + ')*(-' + privateUse + ')?'; |
931 | 933 |
932 var languageTag = | 934 var languageTag = |
933 '^(' + langTag + '|' + privateUse + '|' + grandfathered + ')$'; | 935 '^(' + langTag + '|' + privateUse + '|' + grandfathered + ')$'; |
934 LANGUAGE_TAG_RE = new GlobalRegExp(languageTag, 'i'); | 936 LANGUAGE_TAG_RE = new GlobalRegExp(languageTag, 'i'); |
935 } | 937 } |
936 | 938 |
937 var resolvedAccessor = { | |
938 get() { | |
939 %IncrementUseCounter(kIntlResolved); | |
940 return this[resolvedSymbol]; | |
941 }, | |
942 set(value) { | |
943 this[resolvedSymbol] = value; | |
944 } | |
945 }; | |
946 | |
947 // ECMA 402 section 8.2.1 | 939 // ECMA 402 section 8.2.1 |
948 InstallFunction(GlobalIntl, 'getCanonicalLocales', function(locales) { | 940 InstallFunction(GlobalIntl, 'getCanonicalLocales', function(locales) { |
949 return makeArray(canonicalizeLocaleList(locales)); | 941 return makeArray(canonicalizeLocaleList(locales)); |
950 } | 942 } |
951 ); | 943 ); |
952 | 944 |
953 /** | 945 /** |
954 * Initializes the given object so it's a valid Collator instance. | 946 * Initializes the given object so it's a valid Collator instance. |
955 * Useful for subclassing. | 947 * Useful for subclassing. |
956 */ | 948 */ |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1130 value = TO_NUMBER(value); | 1122 value = TO_NUMBER(value); |
1131 if (NUMBER_IS_NAN(value) || value < min || value > max) { | 1123 if (NUMBER_IS_NAN(value) || value < min || value > max) { |
1132 throw %make_range_error(kPropertyValueOutOfRange, property); | 1124 throw %make_range_error(kPropertyValueOutOfRange, property); |
1133 } | 1125 } |
1134 return %math_floor(value); | 1126 return %math_floor(value); |
1135 } | 1127 } |
1136 | 1128 |
1137 return fallback; | 1129 return fallback; |
1138 } | 1130 } |
1139 | 1131 |
1140 | |
1141 /** | 1132 /** |
1142 * Returns the valid digit count for a property, or throws RangeError on | 1133 * Returns the valid digit count for a property, or throws RangeError on |
1143 * a value out of the range. | 1134 * a value out of the range. |
1144 */ | 1135 */ |
1145 function getNumberOption(options, property, min, max, fallback) { | 1136 function getNumberOption(options, property, min, max, fallback) { |
1146 var value = options[property]; | 1137 var value = options[property]; |
1147 return defaultNumberOption(value, min, max, fallback, property); | 1138 return defaultNumberOption(value, min, max, fallback, property); |
1148 } | 1139 } |
1149 | 1140 |
1150 var patternAccessor = { | 1141 // ECMA 402 #sec-setnfdigitoptions |
1151 get() { | 1142 // SetNumberFormatDigitOptions ( intlObj, options, mnfdDefault, mxfdDefault ) |
1152 %IncrementUseCounter(kIntlPattern); | 1143 function SetNumberFormatDigitOptions(internalOptions, options, |
1153 return this[patternSymbol]; | 1144 mnfdDefault, mxfdDefault) { |
1154 }, | 1145 // Digit ranges. |
1155 set(value) { | 1146 var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1); |
1156 this[patternSymbol] = value; | 1147 defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid); |
| 1148 |
| 1149 var mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, |
| 1150 mnfdDefault); |
| 1151 defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd); |
| 1152 |
| 1153 var mxfdActualDefault = MaxSimple(mnfd, mxfdDefault); |
| 1154 |
| 1155 var mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, |
| 1156 mxfdActualDefault); |
| 1157 |
| 1158 defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd); |
| 1159 |
| 1160 var mnsd = options['minimumSignificantDigits']; |
| 1161 var mxsd = options['maximumSignificantDigits']; |
| 1162 if (!IS_UNDEFINED(mnsd) || !IS_UNDEFINED(mxsd)) { |
| 1163 mnsd = defaultNumberOption(mnsd, 1, 21, 1, 'minimumSignificantDigits'); |
| 1164 defineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd); |
| 1165 |
| 1166 mxsd = defaultNumberOption(mxsd, mnsd, 21, 21, 'maximumSignificantDigits'); |
| 1167 defineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd); |
1157 } | 1168 } |
1158 }; | 1169 } |
1159 | 1170 |
1160 /** | 1171 /** |
1161 * Initializes the given object so it's a valid NumberFormat instance. | 1172 * Initializes the given object so it's a valid NumberFormat instance. |
1162 * Useful for subclassing. | 1173 * Useful for subclassing. |
1163 */ | 1174 */ |
1164 function CreateNumberFormat(locales, options) { | 1175 function CreateNumberFormat(locales, options) { |
1165 if (IS_UNDEFINED(options)) { | 1176 if (IS_UNDEFINED(options)) { |
1166 options = {}; | 1177 options = {}; |
1167 } | 1178 } |
1168 | 1179 |
1169 var getOption = getGetOption(options, 'numberformat'); | 1180 var getOption = getGetOption(options, 'numberformat'); |
1170 | 1181 |
1171 var locale = resolveLocale('numberformat', locales, options); | 1182 var locale = resolveLocale('numberformat', locales, options); |
1172 | 1183 |
1173 var internalOptions = {}; | 1184 var internalOptions = {}; |
1174 defineWEProperty(internalOptions, 'style', getOption( | 1185 defineWEProperty(internalOptions, 'style', getOption( |
1175 'style', 'string', ['decimal', 'percent', 'currency'], 'decimal')); | 1186 'style', 'string', ['decimal', 'percent', 'currency'], 'decimal')); |
1176 | 1187 |
1177 var currency = getOption('currency', 'string'); | 1188 var currency = getOption('currency', 'string'); |
1178 if (!IS_UNDEFINED(currency) && !isWellFormedCurrencyCode(currency)) { | 1189 if (!IS_UNDEFINED(currency) && !isWellFormedCurrencyCode(currency)) { |
1179 throw %make_range_error(kInvalidCurrencyCode, currency); | 1190 throw %make_range_error(kInvalidCurrencyCode, currency); |
1180 } | 1191 } |
1181 | 1192 |
1182 if (internalOptions.style === 'currency' && IS_UNDEFINED(currency)) { | 1193 if (internalOptions.style === 'currency' && IS_UNDEFINED(currency)) { |
1183 throw %make_type_error(kCurrencyCode); | 1194 throw %make_type_error(kCurrencyCode); |
1184 } | 1195 } |
1185 | 1196 |
| 1197 var mnfdDefault, mxfdDefault; |
| 1198 |
1186 var currencyDisplay = getOption( | 1199 var currencyDisplay = getOption( |
1187 'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol'); | 1200 'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol'); |
1188 if (internalOptions.style === 'currency') { | 1201 if (internalOptions.style === 'currency') { |
1189 defineWEProperty(internalOptions, 'currency', %StringToUpperCaseI18N(currenc
y)); | 1202 defineWEProperty(internalOptions, 'currency', %StringToUpperCaseI18N(currenc
y)); |
1190 defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay); | 1203 defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay); |
| 1204 |
| 1205 mnfdDefault = mxfdDefault = %CurrencyDigits(internalOptions.currency); |
| 1206 } else { |
| 1207 mnfdDefault = 0; |
| 1208 mxfdDefault = internalOptions.style === 'percent' ? 0 : 3; |
1191 } | 1209 } |
1192 | 1210 |
1193 // Digit ranges. | 1211 SetNumberFormatDigitOptions(internalOptions, options, mnfdDefault, |
1194 var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1); | 1212 mxfdDefault); |
1195 defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid); | |
1196 | |
1197 var mnfd = options['minimumFractionDigits']; | |
1198 var mxfd = options['maximumFractionDigits']; | |
1199 if (!IS_UNDEFINED(mnfd) || internalOptions.style !== 'currency') { | |
1200 mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0); | |
1201 defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd); | |
1202 } | |
1203 | |
1204 if (!IS_UNDEFINED(mxfd) || internalOptions.style !== 'currency') { | |
1205 var min_mxfd = internalOptions.style === 'percent' ? 0 : 3; | |
1206 mnfd = IS_UNDEFINED(mnfd) ? 0 : mnfd; | |
1207 var fallback_limit = (mnfd > min_mxfd) ? mnfd : min_mxfd; | |
1208 mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, fallback_
limit); | |
1209 defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd); | |
1210 } | |
1211 | |
1212 var mnsd = options['minimumSignificantDigits']; | |
1213 var mxsd = options['maximumSignificantDigits']; | |
1214 if (!IS_UNDEFINED(mnsd) || !IS_UNDEFINED(mxsd)) { | |
1215 mnsd = defaultNumberOption(mnsd, 1, 21, 1, 'minimumSignificantDigits'); | |
1216 defineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd); | |
1217 | |
1218 mxsd = defaultNumberOption(mxsd, mnsd, 21, 21, 'maximumSignificantDigits'); | |
1219 defineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd); | |
1220 } | |
1221 | 1213 |
1222 // Grouping. | 1214 // Grouping. |
1223 defineWEProperty(internalOptions, 'useGrouping', getOption( | 1215 defineWEProperty(internalOptions, 'useGrouping', getOption( |
1224 'useGrouping', 'boolean', UNDEFINED, true)); | 1216 'useGrouping', 'boolean', UNDEFINED, true)); |
1225 | 1217 |
1226 // ICU prefers options to be passed using -u- extension key/values for | 1218 // ICU prefers options to be passed using -u- extension key/values for |
1227 // number format, so we need to build that. | 1219 // number format, so we need to build that. |
1228 var extensionMap = parseExtension(locale.extension); | 1220 var extensionMap = parseExtension(locale.extension); |
1229 | 1221 |
1230 /** | 1222 /** |
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2149 | 2141 |
2150 utils.Export(function(to) { | 2142 utils.Export(function(to) { |
2151 to.FormatDateToParts = FormatDateToParts; | 2143 to.FormatDateToParts = FormatDateToParts; |
2152 to.ToLowerCaseI18N = ToLowerCaseI18N; | 2144 to.ToLowerCaseI18N = ToLowerCaseI18N; |
2153 to.ToUpperCaseI18N = ToUpperCaseI18N; | 2145 to.ToUpperCaseI18N = ToUpperCaseI18N; |
2154 to.ToLocaleLowerCaseI18N = ToLocaleLowerCaseI18N; | 2146 to.ToLocaleLowerCaseI18N = ToLocaleLowerCaseI18N; |
2155 to.ToLocaleUpperCaseI18N = ToLocaleUpperCaseI18N; | 2147 to.ToLocaleUpperCaseI18N = ToLocaleUpperCaseI18N; |
2156 }); | 2148 }); |
2157 | 2149 |
2158 }) | 2150 }) |
OLD | NEW |