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

Unified Diff: src/extensions/i18n/i18n-utils.js

Issue 23622028: Snapshot i18n Javascript code (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/extensions/i18n/i18n-extension.cc ('k') | src/extensions/i18n/locale.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/extensions/i18n/i18n-utils.js
diff --git a/src/extensions/i18n/i18n-utils.js b/src/extensions/i18n/i18n-utils.js
deleted file mode 100644
index 545082ecbba4d6ba9755c9639234a28ba4889cf5..0000000000000000000000000000000000000000
--- a/src/extensions/i18n/i18n-utils.js
+++ /dev/null
@@ -1,536 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// limitations under the License.
-
-// ECMAScript 402 API implementation is broken into separate files for
-// each service. The build system combines them together into one
-// Intl namespace.
-
-/**
- * Adds bound method to the prototype of the given object.
- */
-function addBoundMethod(obj, methodName, implementation, length) {
- function getter() {
- if (!this || typeof this !== 'object' ||
- this.__initializedIntlObject === undefined) {
- throw new TypeError('Method ' + methodName + ' called on a ' +
- 'non-object or on a wrong type of object.');
- }
- var internalName = '__bound' + methodName + '__';
- if (this[internalName] === undefined) {
- var that = this;
- var boundMethod;
- if (length === undefined || length === 2) {
- boundMethod = function(x, y) {
- if (%_IsConstructCall()) {
- throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
- }
- return implementation(that, x, y);
- }
- } else if (length === 1) {
- boundMethod = function(x) {
- if (%_IsConstructCall()) {
- throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
- }
- return implementation(that, x);
- }
- } else {
- boundMethod = function() {
- if (%_IsConstructCall()) {
- throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
- }
- // DateTimeFormat.format needs to be 0 arg method, but can stil
- // receive optional dateValue param. If one was provided, pass it
- // along.
- if (arguments.length > 0) {
- return implementation(that, arguments[0]);
- } else {
- return implementation(that);
- }
- }
- }
- %FunctionSetName(boundMethod, internalName);
- %FunctionRemovePrototype(boundMethod);
- %SetNativeFlag(boundMethod);
- this[internalName] = boundMethod;
- }
- return this[internalName];
- }
-
- %FunctionSetName(getter, methodName);
- %FunctionRemovePrototype(getter);
- %SetNativeFlag(getter);
-
- Object.defineProperty(obj.prototype, methodName, {
- get: getter,
- enumerable: false,
- configurable: true
- });
-}
-
-
-/**
- * Returns an intersection of locales and service supported locales.
- * Parameter locales is treated as a priority list.
- */
-function supportedLocalesOf(service, locales, options) {
- if (service.match(SERVICE_RE) === null) {
- throw new Error('Internal error, wrong service type: ' + service);
- }
-
- // Provide defaults if matcher was not specified.
- if (options === undefined) {
- options = {};
- } else {
- options = toObject(options);
- }
-
- var matcher = options.localeMatcher;
- if (matcher !== undefined) {
- matcher = String(matcher);
- if (matcher !== 'lookup' && matcher !== 'best fit') {
- throw new RangeError('Illegal value for localeMatcher:' + matcher);
- }
- } else {
- matcher = 'best fit';
- }
-
- var requestedLocales = initializeLocaleList(locales);
-
- // Cache these, they don't ever change per service.
- if (AVAILABLE_LOCALES[service] === undefined) {
- AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
- }
-
- // Use either best fit or lookup algorithm to match locales.
- if (matcher === 'best fit') {
- return initializeLocaleList(bestFitSupportedLocalesOf(
- requestedLocales, AVAILABLE_LOCALES[service]));
- }
-
- return initializeLocaleList(lookupSupportedLocalesOf(
- requestedLocales, AVAILABLE_LOCALES[service]));
-}
-
-
-/**
- * Returns the subset of the provided BCP 47 language priority list for which
- * this service has a matching locale when using the BCP 47 Lookup algorithm.
- * Locales appear in the same order in the returned list as in the input list.
- */
-function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
- var matchedLocales = [];
- for (var i = 0; i < requestedLocales.length; ++i) {
- // Remove -u- extension.
- var locale = requestedLocales[i].replace(UNICODE_EXTENSION_RE, '');
- do {
- if (availableLocales[locale] !== undefined) {
- // Push requested locale not the resolved one.
- matchedLocales.push(requestedLocales[i]);
- break;
- }
- // Truncate locale if possible, if not break.
- var pos = locale.lastIndexOf('-');
- if (pos === -1) {
- break;
- }
- locale = locale.substring(0, pos);
- } while (true);
- }
-
- return matchedLocales;
-}
-
-
-/**
- * Returns the subset of the provided BCP 47 language priority list for which
- * this service has a matching locale when using the implementation
- * dependent algorithm.
- * Locales appear in the same order in the returned list as in the input list.
- */
-function bestFitSupportedLocalesOf(requestedLocales, availableLocales) {
- // TODO(cira): implement better best fit algorithm.
- return lookupSupportedLocalesOf(requestedLocales, availableLocales);
-}
-
-
-/**
- * Returns a getOption function that extracts property value for given
- * options object. If property is missing it returns defaultValue. If value
- * is out of range for that property it throws RangeError.
- */
-function getGetOption(options, caller) {
- if (options === undefined) {
- throw new Error('Internal ' + caller + ' error. ' +
- 'Default options are missing.');
- }
-
- var getOption = function getOption(property, type, values, defaultValue) {
- if (options[property] !== undefined) {
- var value = options[property];
- switch (type) {
- case 'boolean':
- value = Boolean(value);
- break;
- case 'string':
- value = String(value);
- break;
- case 'number':
- value = Number(value);
- break;
- default:
- throw new Error('Internal error. Wrong value type.');
- }
- if (values !== undefined && values.indexOf(value) === -1) {
- throw new RangeError('Value ' + value + ' out of range for ' + caller +
- ' options property ' + property);
- }
-
- return value;
- }
-
- return defaultValue;
- }
-
- return getOption;
-}
-
-
-/**
- * Compares a BCP 47 language priority list requestedLocales against the locales
- * in availableLocales and determines the best available language to meet the
- * request. Two algorithms are available to match the locales: the Lookup
- * algorithm described in RFC 4647 section 3.4, and an implementation dependent
- * best-fit algorithm. Independent of the locale matching algorithm, options
- * specified through Unicode locale extension sequences are negotiated
- * separately, taking the caller's relevant extension keys and locale data as
- * well as client-provided options into consideration. Returns an object with
- * a locale property whose value is the language tag of the selected locale,
- * and properties for each key in relevantExtensionKeys providing the selected
- * value for that key.
- */
-function resolveLocale(service, requestedLocales, options) {
- requestedLocales = initializeLocaleList(requestedLocales);
-
- var getOption = getGetOption(options, service);
- var matcher = getOption('localeMatcher', 'string',
- ['lookup', 'best fit'], 'best fit');
- var resolved;
- if (matcher === 'lookup') {
- resolved = lookupMatcher(service, requestedLocales);
- } else {
- resolved = bestFitMatcher(service, requestedLocales);
- }
-
- return resolved;
-}
-
-
-/**
- * Returns best matched supported locale and extension info using basic
- * lookup algorithm.
- */
-function lookupMatcher(service, requestedLocales) {
- if (service.match(SERVICE_RE) === null) {
- throw new Error('Internal error, wrong service type: ' + service);
- }
-
- // Cache these, they don't ever change per service.
- if (AVAILABLE_LOCALES[service] === undefined) {
- AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
- }
-
- for (var i = 0; i < requestedLocales.length; ++i) {
- // Remove all extensions.
- var locale = requestedLocales[i].replace(ANY_EXTENSION_RE, '');
- do {
- if (AVAILABLE_LOCALES[service][locale] !== undefined) {
- // Return the resolved locale and extension.
- var extensionMatch = requestedLocales[i].match(UNICODE_EXTENSION_RE);
- var extension = (extensionMatch === null) ? '' : extensionMatch[0];
- return {'locale': locale, 'extension': extension, 'position': i};
- }
- // Truncate locale if possible.
- var pos = locale.lastIndexOf('-');
- if (pos === -1) {
- break;
- }
- locale = locale.substring(0, pos);
- } while (true);
- }
-
- // Didn't find a match, return default.
- if (DEFAULT_ICU_LOCALE === undefined) {
- DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
- }
-
- return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
-}
-
-
-/**
- * Returns best matched supported locale and extension info using
- * implementation dependend algorithm.
- */
-function bestFitMatcher(service, requestedLocales) {
- // TODO(cira): implement better best fit algorithm.
- return lookupMatcher(service, requestedLocales);
-}
-
-
-/**
- * Parses Unicode extension into key - value map.
- * Returns empty object if the extension string is invalid.
- * We are not concerned with the validity of the values at this point.
- */
-function parseExtension(extension) {
- var extensionSplit = extension.split('-');
-
- // Assume ['', 'u', ...] input, but don't throw.
- if (extensionSplit.length <= 2 ||
- (extensionSplit[0] !== '' && extensionSplit[1] !== 'u')) {
- return {};
- }
-
- // Key is {2}alphanum, value is {3,8}alphanum.
- // Some keys may not have explicit values (booleans).
- var extensionMap = {};
- var previousKey = undefined;
- for (var i = 2; i < extensionSplit.length; ++i) {
- var length = extensionSplit[i].length;
- var element = extensionSplit[i];
- if (length === 2) {
- extensionMap[element] = undefined;
- previousKey = element;
- } else if (length >= 3 && length <=8 && previousKey !== undefined) {
- extensionMap[previousKey] = element;
- previousKey = undefined;
- } else {
- // There is a value that's too long, or that doesn't have a key.
- return {};
- }
- }
-
- return extensionMap;
-}
-
-
-/**
- * Converts parameter to an Object if possible.
- */
-function toObject(value) {
- if (value === undefined || value === null) {
- throw new TypeError('Value cannot be converted to an Object.');
- }
-
- return Object(value);
-}
-
-
-/**
- * Populates internalOptions object with boolean key-value pairs
- * from extensionMap and options.
- * Returns filtered extension (number and date format constructors use
- * Unicode extensions for passing parameters to ICU).
- * It's used for extension-option pairs only, e.g. kn-normalization, but not
- * for 'sensitivity' since it doesn't have extension equivalent.
- * Extensions like nu and ca don't have options equivalent, so we place
- * undefined in the map.property to denote that.
- */
-function setOptions(inOptions, extensionMap, keyValues, getOption, outOptions) {
- var extension = '';
-
- var updateExtension = function updateExtension(key, value) {
- return '-' + key + '-' + String(value);
- }
-
- var updateProperty = function updateProperty(property, type, value) {
- if (type === 'boolean' && (typeof value === 'string')) {
- value = (value === 'true') ? true : false;
- }
-
- if (property !== undefined) {
- defineWEProperty(outOptions, property, value);
- }
- }
-
- for (var key in keyValues) {
- if (keyValues.hasOwnProperty(key)) {
- var value = undefined;
- var map = keyValues[key];
- if (map.property !== undefined) {
- // This may return true if user specifies numeric: 'false', since
- // Boolean('nonempty') === true.
- value = getOption(map.property, map.type, map.values);
- }
- if (value !== undefined) {
- updateProperty(map.property, map.type, value);
- extension += updateExtension(key, value);
- continue;
- }
- // User options didn't have it, check Unicode extension.
- // Here we want to convert strings 'true', 'false' into proper Boolean
- // values (not a user error).
- if (extensionMap.hasOwnProperty(key)) {
- value = extensionMap[key];
- if (value !== undefined) {
- updateProperty(map.property, map.type, value);
- extension += updateExtension(key, value);
- } else if (map.type === 'boolean') {
- // Boolean keys are allowed not to have values in Unicode extension.
- // Those default to true.
- updateProperty(map.property, map.type, true);
- extension += updateExtension(key, true);
- }
- }
- }
- }
-
- return extension === ''? '' : '-u' + extension;
-}
-
-
-/**
- * Converts all OwnProperties into
- * configurable: false, writable: false, enumerable: true.
- */
-function freezeArray(array) {
- array.forEach(function(element, index) {
- Object.defineProperty(array, index, {value: element,
- configurable: false,
- writable: false,
- enumerable: true});
- });
-
- Object.defineProperty(array, 'length', {value: array.length,
- writable: false});
-
- return array;
-}
-
-
-/**
- * It's sometimes desireable to leave user requested locale instead of ICU
- * supported one (zh-TW is equivalent to zh-Hant-TW, so we should keep shorter
- * one, if that was what user requested).
- * This function returns user specified tag if its maximized form matches ICU
- * resolved locale. If not we return ICU result.
- */
-function getOptimalLanguageTag(original, resolved) {
- // Returns Array<Object>, where each object has maximized and base properties.
- // Maximized: zh -> zh-Hans-CN
- // Base: zh-CN-u-ca-gregory -> zh-CN
- // Take care of grandfathered or simple cases.
- if (original === resolved) {
- return original;
- }
-
- var locales = %GetLanguageTagVariants([original, resolved]);
- if (locales[0].maximized !== locales[1].maximized) {
- return resolved;
- }
-
- // Preserve extensions of resolved locale, but swap base tags with original.
- var resolvedBase = new RegExp('^' + locales[1].base);
- return resolved.replace(resolvedBase, locales[0].base);
-}
-
-
-/**
- * Returns an Object that contains all of supported locales for a given
- * service.
- * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ
- * that is supported. This is required by the spec.
- */
-function getAvailableLocalesOf(service) {
- var available = %AvailableLocalesOf(service);
-
- for (var i in available) {
- if (available.hasOwnProperty(i)) {
- var parts = i.match(/^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/);
- if (parts !== null) {
- // Build xx-ZZ. We don't care about the actual value,
- // as long it's not undefined.
- available[parts[1] + '-' + parts[3]] = null;
- }
- }
- }
-
- return available;
-}
-
-
-/**
- * Defines a property and sets writable and enumerable to true.
- * Configurable is false by default.
- */
-function defineWEProperty(object, property, value) {
- Object.defineProperty(object, property,
- {value: value, writable: true, enumerable: true});
-}
-
-
-/**
- * Adds property to an object if the value is not undefined.
- * Sets configurable descriptor to false.
- */
-function addWEPropertyIfDefined(object, property, value) {
- if (value !== undefined) {
- defineWEProperty(object, property, value);
- }
-}
-
-
-/**
- * Defines a property and sets writable, enumerable and configurable to true.
- */
-function defineWECProperty(object, property, value) {
- Object.defineProperty(object, property,
- {value: value,
- writable: true,
- enumerable: true,
- configurable: true});
-}
-
-
-/**
- * Adds property to an object if the value is not undefined.
- * Sets all descriptors to true.
- */
-function addWECPropertyIfDefined(object, property, value) {
- if (value !== undefined) {
- defineWECProperty(object, property, value);
- }
-}
-
-
-/**
- * Returns titlecased word, aMeRricA -> America.
- */
-function toTitleCaseWord(word) {
- return word.substr(0, 1).toUpperCase() + word.substr(1).toLowerCase();
-}
« no previous file with comments | « src/extensions/i18n/i18n-extension.cc ('k') | src/extensions/i18n/locale.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698