Move helper methods from i18n extension into runtime.
BUG=v8:2475 R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/21499003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16015 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
71cad9edb6
commit
738237e877
@ -31,7 +31,6 @@
|
||||
#include "break-iterator.h"
|
||||
#include "collator.h"
|
||||
#include "date-format.h"
|
||||
#include "locale.h"
|
||||
#include "natives.h"
|
||||
#include "number-format.h"
|
||||
|
||||
@ -49,17 +48,6 @@ Extension::Extension()
|
||||
|
||||
v8::Handle<v8::FunctionTemplate> Extension::GetNativeFunction(
|
||||
v8::Handle<v8::String> name) {
|
||||
// Standalone, helper methods.
|
||||
if (name->Equals(v8::String::New("NativeJSCanonicalizeLanguageTag"))) {
|
||||
return v8::FunctionTemplate::New(JSCanonicalizeLanguageTag);
|
||||
} else if (name->Equals(v8::String::New("NativeJSAvailableLocalesOf"))) {
|
||||
return v8::FunctionTemplate::New(JSAvailableLocalesOf);
|
||||
} else if (name->Equals(v8::String::New("NativeJSGetDefaultICULocale"))) {
|
||||
return v8::FunctionTemplate::New(JSGetDefaultICULocale);
|
||||
} else if (name->Equals(v8::String::New("NativeJSGetLanguageTagVariants"))) {
|
||||
return v8::FunctionTemplate::New(JSGetLanguageTagVariants);
|
||||
}
|
||||
|
||||
// Date format and parse.
|
||||
if (name->Equals(v8::String::New("NativeJSCreateDateTimeFormat"))) {
|
||||
return v8::FunctionTemplate::New(DateFormat::JSCreateDateTimeFormat);
|
||||
|
@ -255,8 +255,6 @@ function resolveLocale(service, requestedLocales, options) {
|
||||
* lookup algorithm.
|
||||
*/
|
||||
function lookupMatcher(service, requestedLocales) {
|
||||
native function NativeJSGetDefaultICULocale();
|
||||
|
||||
if (service.match(SERVICE_RE) === null) {
|
||||
throw new Error('Internal error, wrong service type: ' + service);
|
||||
}
|
||||
@ -287,7 +285,7 @@ function lookupMatcher(service, requestedLocales) {
|
||||
|
||||
// Didn't find a match, return default.
|
||||
if (DEFAULT_ICU_LOCALE === undefined) {
|
||||
DEFAULT_ICU_LOCALE = NativeJSGetDefaultICULocale();
|
||||
DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
|
||||
}
|
||||
|
||||
return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
|
||||
@ -446,14 +444,12 @@ 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
|
||||
native function NativeJSGetLanguageTagVariants();
|
||||
|
||||
// Take care of grandfathered or simple cases.
|
||||
if (original === resolved) {
|
||||
return original;
|
||||
}
|
||||
|
||||
var locales = NativeJSGetLanguageTagVariants([original, resolved]);
|
||||
var locales = %GetLanguageTagVariants([original, resolved]);
|
||||
if (locales[0].maximized !== locales[1].maximized) {
|
||||
return resolved;
|
||||
}
|
||||
@ -471,8 +467,7 @@ function getOptimalLanguageTag(original, resolved) {
|
||||
* that is supported. This is required by the spec.
|
||||
*/
|
||||
function getAvailableLocalesOf(service) {
|
||||
native function NativeJSAvailableLocalesOf();
|
||||
var available = NativeJSAvailableLocalesOf(service);
|
||||
var available = %AvailableLocalesOf(service);
|
||||
|
||||
for (var i in available) {
|
||||
if (available.hasOwnProperty(i)) {
|
||||
|
@ -1,251 +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.
|
||||
|
||||
#include "locale.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "unicode/brkiter.h"
|
||||
#include "unicode/coll.h"
|
||||
#include "unicode/datefmt.h"
|
||||
#include "unicode/numfmt.h"
|
||||
#include "unicode/uloc.h"
|
||||
#include "unicode/uversion.h"
|
||||
|
||||
namespace v8_i18n {
|
||||
|
||||
void JSCanonicalizeLanguageTag(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
// Expect locale id which is a string.
|
||||
if (args.Length() != 1 || !args[0]->IsString()) {
|
||||
v8::ThrowException(v8::Exception::SyntaxError(
|
||||
v8::String::New("Locale identifier, as a string, is required.")));
|
||||
return;
|
||||
}
|
||||
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
|
||||
char icu_result[ULOC_FULLNAME_CAPACITY];
|
||||
int icu_length = 0;
|
||||
|
||||
// Return value which denotes invalid language tag.
|
||||
const char* const kInvalidTag = "invalid-tag";
|
||||
|
||||
v8::String::AsciiValue locale_id(args[0]->ToString());
|
||||
if (*locale_id == NULL) {
|
||||
args.GetReturnValue().Set(v8::String::New(kInvalidTag));
|
||||
return;
|
||||
}
|
||||
|
||||
uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
|
||||
&icu_length, &error);
|
||||
if (U_FAILURE(error) || icu_length == 0) {
|
||||
args.GetReturnValue().Set(v8::String::New(kInvalidTag));
|
||||
return;
|
||||
}
|
||||
|
||||
char result[ULOC_FULLNAME_CAPACITY];
|
||||
|
||||
// Force strict BCP47 rules.
|
||||
uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
|
||||
|
||||
if (U_FAILURE(error)) {
|
||||
args.GetReturnValue().Set(v8::String::New(kInvalidTag));
|
||||
return;
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(v8::String::New(result));
|
||||
}
|
||||
|
||||
|
||||
void JSAvailableLocalesOf(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
// Expect service name which is a string.
|
||||
if (args.Length() != 1 || !args[0]->IsString()) {
|
||||
v8::ThrowException(v8::Exception::SyntaxError(
|
||||
v8::String::New("Service identifier, as a string, is required.")));
|
||||
return;
|
||||
}
|
||||
|
||||
const icu::Locale* available_locales = NULL;
|
||||
|
||||
int32_t count = 0;
|
||||
v8::String::AsciiValue service(args[0]->ToString());
|
||||
if (strcmp(*service, "collator") == 0) {
|
||||
available_locales = icu::Collator::getAvailableLocales(count);
|
||||
} else if (strcmp(*service, "numberformat") == 0) {
|
||||
available_locales = icu::NumberFormat::getAvailableLocales(count);
|
||||
} else if (strcmp(*service, "dateformat") == 0) {
|
||||
available_locales = icu::DateFormat::getAvailableLocales(count);
|
||||
} else if (strcmp(*service, "breakiterator") == 0) {
|
||||
available_locales = icu::BreakIterator::getAvailableLocales(count);
|
||||
}
|
||||
|
||||
v8::TryCatch try_catch;
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
char result[ULOC_FULLNAME_CAPACITY];
|
||||
v8::Handle<v8::Object> locales = v8::Object::New();
|
||||
|
||||
for (int32_t i = 0; i < count; ++i) {
|
||||
const char* icu_name = available_locales[i].getName();
|
||||
|
||||
error = U_ZERO_ERROR;
|
||||
// No need to force strict BCP47 rules.
|
||||
uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
|
||||
if (U_FAILURE(error)) {
|
||||
// This shouldn't happen, but lets not break the user.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Index is just a dummy value for the property value.
|
||||
locales->Set(v8::String::New(result), v8::Integer::New(i));
|
||||
if (try_catch.HasCaught()) {
|
||||
// Ignore error, but stop processing and return.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(locales);
|
||||
}
|
||||
|
||||
|
||||
void JSGetDefaultICULocale(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
icu::Locale default_locale;
|
||||
|
||||
// Set the locale
|
||||
char result[ULOC_FULLNAME_CAPACITY];
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
uloc_toLanguageTag(
|
||||
default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
|
||||
if (U_SUCCESS(status)) {
|
||||
args.GetReturnValue().Set(v8::String::New(result));
|
||||
return;
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(v8::String::New("und"));
|
||||
}
|
||||
|
||||
|
||||
void JSGetLanguageTagVariants(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
v8::TryCatch try_catch;
|
||||
|
||||
// Expect an array of strings.
|
||||
if (args.Length() != 1 || !args[0]->IsArray()) {
|
||||
v8::ThrowException(v8::Exception::SyntaxError(
|
||||
v8::String::New("Internal error. Expected Array<String>.")));
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Local<v8::Array> input = v8::Local<v8::Array>::Cast(args[0]);
|
||||
v8::Handle<v8::Array> output = v8::Array::New(input->Length());
|
||||
for (unsigned int i = 0; i < input->Length(); ++i) {
|
||||
v8::Local<v8::Value> locale_id = input->Get(i);
|
||||
if (try_catch.HasCaught()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!locale_id->IsString()) {
|
||||
v8::ThrowException(v8::Exception::SyntaxError(
|
||||
v8::String::New("Internal error. Array element is missing "
|
||||
"or it isn't a string.")));
|
||||
return;
|
||||
}
|
||||
|
||||
v8::String::AsciiValue ascii_locale_id(locale_id);
|
||||
if (*ascii_locale_id == NULL) {
|
||||
v8::ThrowException(v8::Exception::SyntaxError(
|
||||
v8::String::New("Internal error. Non-ASCII locale identifier.")));
|
||||
return;
|
||||
}
|
||||
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
|
||||
// Convert from BCP47 to ICU format.
|
||||
// de-DE-u-co-phonebk -> de_DE@collation=phonebook
|
||||
char icu_locale[ULOC_FULLNAME_CAPACITY];
|
||||
int icu_locale_length = 0;
|
||||
uloc_forLanguageTag(*ascii_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
|
||||
&icu_locale_length, &error);
|
||||
if (U_FAILURE(error) || icu_locale_length == 0) {
|
||||
v8::ThrowException(v8::Exception::SyntaxError(
|
||||
v8::String::New("Internal error. Failed to convert locale to ICU.")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Maximize the locale.
|
||||
// de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
|
||||
char icu_max_locale[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_addLikelySubtags(
|
||||
icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
|
||||
|
||||
// Remove extensions from maximized locale.
|
||||
// de_Latn_DE@collation=phonebook -> de_Latn_DE
|
||||
char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_getBaseName(
|
||||
icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
|
||||
|
||||
// Get original name without extensions.
|
||||
// de_DE@collation=phonebook -> de_DE
|
||||
char icu_base_locale[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_getBaseName(
|
||||
icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
|
||||
|
||||
// Convert from ICU locale format to BCP47 format.
|
||||
// de_Latn_DE -> de-Latn-DE
|
||||
char base_max_locale[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
|
||||
ULOC_FULLNAME_CAPACITY, FALSE, &error);
|
||||
|
||||
// de_DE -> de-DE
|
||||
char base_locale[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_toLanguageTag(
|
||||
icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
|
||||
|
||||
if (U_FAILURE(error)) {
|
||||
v8::ThrowException(v8::Exception::SyntaxError(
|
||||
v8::String::New("Internal error. Couldn't generate maximized "
|
||||
"or base locale.")));
|
||||
return;
|
||||
}
|
||||
|
||||
v8::Handle<v8::Object> result = v8::Object::New();
|
||||
result->Set(v8::String::New("maximized"), v8::String::New(base_max_locale));
|
||||
result->Set(v8::String::New("base"), v8::String::New(base_locale));
|
||||
if (try_catch.HasCaught()) {
|
||||
break;
|
||||
}
|
||||
|
||||
output->Set(i, result);
|
||||
if (try_catch.HasCaught()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(output);
|
||||
}
|
||||
|
||||
} // namespace v8_i18n
|
@ -1,56 +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.
|
||||
|
||||
#ifndef V8_EXTENSIONS_I18N_SRC_LOCALE_H_
|
||||
#define V8_EXTENSIONS_I18N_SRC_LOCALE_H_
|
||||
|
||||
#include "unicode/uversion.h"
|
||||
#include "v8.h"
|
||||
|
||||
namespace v8_i18n {
|
||||
|
||||
// Canonicalizes the BCP47 language tag using BCP47 rules.
|
||||
// Returns 'invalid-tag' in case input was not well formed.
|
||||
void JSCanonicalizeLanguageTag(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
// Returns a list of available locales for collator, date or number formatter.
|
||||
void JSAvailableLocalesOf(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
// Returns default ICU locale.
|
||||
void JSGetDefaultICULocale(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
// Returns an array of objects, that have maximized and base names of inputs.
|
||||
// Unicode extensions are dropped from both.
|
||||
// Input: ['zh-TW-u-nu-thai', 'sr']
|
||||
// Output: [{maximized: 'zh-Hant-TW', base: 'zh-TW'},
|
||||
// {maximized: 'sr-Cyrl-RS', base: 'sr'}]
|
||||
void JSGetLanguageTagVariants(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
} // namespace v8_i18n
|
||||
|
||||
#endif // V8_EXTENSIONS_I18N_LOCALE_H_
|
@ -34,8 +34,6 @@
|
||||
* Canonicalizes the language tag, or throws in case the tag is invalid.
|
||||
*/
|
||||
function canonicalizeLanguageTag(localeID) {
|
||||
native function NativeJSCanonicalizeLanguageTag();
|
||||
|
||||
// null is typeof 'object' so we have to do extra check.
|
||||
if (typeof localeID !== 'string' && typeof localeID !== 'object' ||
|
||||
localeID === null) {
|
||||
@ -52,7 +50,7 @@ function canonicalizeLanguageTag(localeID) {
|
||||
// ICU bug filled - http://bugs.icu-project.org/trac/ticket/9265.
|
||||
// TODO(cira): check if -u-kn-true-kc-true-kh-true still throws after
|
||||
// upgrade to ICU 4.9.
|
||||
var tag = NativeJSCanonicalizeLanguageTag(localeString);
|
||||
var tag = %CanonicalizeLanguageTag(localeString);
|
||||
if (tag === 'invalid-tag') {
|
||||
throw new RangeError('Invalid language tag: ' + localeString);
|
||||
}
|
||||
|
203
src/runtime.cc
203
src/runtime.cc
@ -66,6 +66,15 @@
|
||||
#include "v8threads.h"
|
||||
#include "vm-state-inl.h"
|
||||
|
||||
#ifdef V8_I18N_SUPPORT
|
||||
#include "unicode/brkiter.h"
|
||||
#include "unicode/coll.h"
|
||||
#include "unicode/datefmt.h"
|
||||
#include "unicode/numfmt.h"
|
||||
#include "unicode/uloc.h"
|
||||
#include "unicode/uversion.h"
|
||||
#endif
|
||||
|
||||
#ifndef _STLP_VENDOR_CSTD
|
||||
// STLPort doesn't import fpclassify and isless into the std namespace.
|
||||
using std::fpclassify;
|
||||
@ -13362,6 +13371,200 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHeapUsage) {
|
||||
#endif // ENABLE_DEBUGGER_SUPPORT
|
||||
|
||||
|
||||
#ifdef V8_I18N_SUPPORT
|
||||
RUNTIME_FUNCTION(MaybeObject*, Runtime_CanonicalizeLanguageTag) {
|
||||
HandleScope scope(isolate);
|
||||
|
||||
ASSERT(args.length() == 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
|
||||
|
||||
v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
|
||||
|
||||
// Return value which denotes invalid language tag.
|
||||
const char* const kInvalidTag = "invalid-tag";
|
||||
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
char icu_result[ULOC_FULLNAME_CAPACITY];
|
||||
int icu_length = 0;
|
||||
|
||||
uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
|
||||
&icu_length, &error);
|
||||
if (U_FAILURE(error) || icu_length == 0) {
|
||||
return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag));
|
||||
}
|
||||
|
||||
char result[ULOC_FULLNAME_CAPACITY];
|
||||
|
||||
// Force strict BCP47 rules.
|
||||
uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
|
||||
|
||||
if (U_FAILURE(error)) {
|
||||
return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag));
|
||||
}
|
||||
|
||||
return isolate->heap()->AllocateStringFromOneByte(CStrVector(result));
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, Runtime_AvailableLocalesOf) {
|
||||
HandleScope scope(isolate);
|
||||
|
||||
ASSERT(args.length() == 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
|
||||
|
||||
const icu::Locale* available_locales = NULL;
|
||||
int32_t count = 0;
|
||||
|
||||
if (service->IsUtf8EqualTo(CStrVector("collator"))) {
|
||||
available_locales = icu::Collator::getAvailableLocales(count);
|
||||
} else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
|
||||
available_locales = icu::NumberFormat::getAvailableLocales(count);
|
||||
} else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
|
||||
available_locales = icu::DateFormat::getAvailableLocales(count);
|
||||
} else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
|
||||
available_locales = icu::BreakIterator::getAvailableLocales(count);
|
||||
}
|
||||
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
char result[ULOC_FULLNAME_CAPACITY];
|
||||
Handle<JSObject> locales =
|
||||
isolate->factory()->NewJSObject(isolate->object_function());
|
||||
|
||||
for (int32_t i = 0; i < count; ++i) {
|
||||
const char* icu_name = available_locales[i].getName();
|
||||
|
||||
error = U_ZERO_ERROR;
|
||||
// No need to force strict BCP47 rules.
|
||||
uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
|
||||
if (U_FAILURE(error)) {
|
||||
// This shouldn't happen, but lets not break the user.
|
||||
continue;
|
||||
}
|
||||
|
||||
RETURN_IF_EMPTY_HANDLE(isolate,
|
||||
JSObject::SetLocalPropertyIgnoreAttributes(
|
||||
locales,
|
||||
isolate->factory()->NewStringFromAscii(CStrVector(result)),
|
||||
isolate->factory()->NewNumber(i),
|
||||
NONE));
|
||||
}
|
||||
|
||||
return *locales;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultICULocale) {
|
||||
SealHandleScope shs(isolate);
|
||||
|
||||
ASSERT(args.length() == 0);
|
||||
|
||||
icu::Locale default_locale;
|
||||
|
||||
// Set the locale
|
||||
char result[ULOC_FULLNAME_CAPACITY];
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
uloc_toLanguageTag(
|
||||
default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
|
||||
if (U_SUCCESS(status)) {
|
||||
return isolate->heap()->AllocateStringFromOneByte(CStrVector(result));
|
||||
}
|
||||
|
||||
return isolate->heap()->AllocateStringFromOneByte(CStrVector("und"));
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) {
|
||||
HandleScope scope(isolate);
|
||||
|
||||
ASSERT(args.length() == 1);
|
||||
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
|
||||
|
||||
uint32_t length = static_cast<uint32_t>(input->length()->Number());
|
||||
Handle<FixedArray> output = isolate->factory()->NewFixedArray(length);
|
||||
Handle<Name> maximized =
|
||||
isolate->factory()->NewStringFromAscii(CStrVector("maximized"));
|
||||
Handle<Name> base =
|
||||
isolate->factory()->NewStringFromAscii(CStrVector("base"));
|
||||
for (unsigned int i = 0; i < length; ++i) {
|
||||
MaybeObject* maybe_string = input->GetElement(i);
|
||||
Object* locale_id;
|
||||
if (!maybe_string->ToObject(&locale_id) || !locale_id->IsString()) {
|
||||
return isolate->Throw(isolate->heap()->illegal_argument_string());
|
||||
}
|
||||
|
||||
v8::String::Utf8Value utf8_locale_id(
|
||||
v8::Utils::ToLocal(Handle<String>(String::cast(locale_id))));
|
||||
|
||||
UErrorCode error = U_ZERO_ERROR;
|
||||
|
||||
// Convert from BCP47 to ICU format.
|
||||
// de-DE-u-co-phonebk -> de_DE@collation=phonebook
|
||||
char icu_locale[ULOC_FULLNAME_CAPACITY];
|
||||
int icu_locale_length = 0;
|
||||
uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
|
||||
&icu_locale_length, &error);
|
||||
if (U_FAILURE(error) || icu_locale_length == 0) {
|
||||
return isolate->Throw(isolate->heap()->illegal_argument_string());
|
||||
}
|
||||
|
||||
// Maximize the locale.
|
||||
// de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
|
||||
char icu_max_locale[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_addLikelySubtags(
|
||||
icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
|
||||
|
||||
// Remove extensions from maximized locale.
|
||||
// de_Latn_DE@collation=phonebook -> de_Latn_DE
|
||||
char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_getBaseName(
|
||||
icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
|
||||
|
||||
// Get original name without extensions.
|
||||
// de_DE@collation=phonebook -> de_DE
|
||||
char icu_base_locale[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_getBaseName(
|
||||
icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
|
||||
|
||||
// Convert from ICU locale format to BCP47 format.
|
||||
// de_Latn_DE -> de-Latn-DE
|
||||
char base_max_locale[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
|
||||
ULOC_FULLNAME_CAPACITY, FALSE, &error);
|
||||
|
||||
// de_DE -> de-DE
|
||||
char base_locale[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_toLanguageTag(
|
||||
icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
|
||||
|
||||
if (U_FAILURE(error)) {
|
||||
return isolate->Throw(isolate->heap()->illegal_argument_string());
|
||||
}
|
||||
|
||||
Handle<JSObject> result =
|
||||
isolate->factory()->NewJSObject(isolate->object_function());
|
||||
RETURN_IF_EMPTY_HANDLE(isolate,
|
||||
JSObject::SetLocalPropertyIgnoreAttributes(
|
||||
result,
|
||||
maximized,
|
||||
isolate->factory()->NewStringFromAscii(CStrVector(base_max_locale)),
|
||||
NONE));
|
||||
RETURN_IF_EMPTY_HANDLE(isolate,
|
||||
JSObject::SetLocalPropertyIgnoreAttributes(
|
||||
result,
|
||||
base,
|
||||
isolate->factory()->NewStringFromAscii(CStrVector(base_locale)),
|
||||
NONE));
|
||||
output->set(i, *result);
|
||||
}
|
||||
|
||||
Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(output);
|
||||
result->set_length(Smi::FromInt(length));
|
||||
return *result;
|
||||
}
|
||||
#endif // V8_I18N_SUPPORT
|
||||
|
||||
|
||||
// Finds the script object from the script data. NOTE: This operation uses
|
||||
// heap traversal to find the function generated for the source position
|
||||
// for the requested break point. For lazily compiled functions several heap
|
||||
|
@ -534,6 +534,21 @@ namespace internal {
|
||||
#define RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef V8_I18N_SUPPORT
|
||||
#define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F) \
|
||||
/* i18n support */ \
|
||||
/* Standalone, helper methods. */ \
|
||||
F(CanonicalizeLanguageTag, 1, 1) \
|
||||
F(AvailableLocalesOf, 1, 1) \
|
||||
F(GetDefaultICULocale, 0, 1) \
|
||||
F(GetLanguageTagVariants, 1, 1) \
|
||||
|
||||
#else
|
||||
#define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#define RUNTIME_FUNCTION_LIST_DEBUG(F) \
|
||||
/* Testing */ \
|
||||
@ -551,7 +566,8 @@ namespace internal {
|
||||
RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
|
||||
RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
|
||||
RUNTIME_FUNCTION_LIST_DEBUG(F) \
|
||||
RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F)
|
||||
RUNTIME_FUNCTION_LIST_DEBUGGER_SUPPORT(F) \
|
||||
RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// INLINE_FUNCTION_LIST defines all inlined functions accessed
|
||||
|
@ -832,8 +832,6 @@
|
||||
'../../src/extensions/i18n/i18n-extension.h',
|
||||
'../../src/extensions/i18n/i18n-utils.cc',
|
||||
'../../src/extensions/i18n/i18n-utils.h',
|
||||
'../../src/extensions/i18n/locale.cc',
|
||||
'../../src/extensions/i18n/locale.h',
|
||||
'../../src/extensions/i18n/number-format.cc',
|
||||
'../../src/extensions/i18n/number-format.h',
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user