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

Side by Side Diff: src/extensions/experimental/i18n-extension.cc

Issue 5671002: Adding experimental JavaScript internationalization API to V8 as an extension... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years 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 | Annotate | Revision Log
« no previous file with comments | « src/extensions/experimental/i18n-extension.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "i18n-extension.h"
29
30 #include <string>
31
32 #include "unicode/locid.h"
33
34 namespace v8 {
35 namespace internal {
36
37 I18NExtension* I18NExtension::extension_ = NULL;
38
39 // TODO(cira): maybe move JS code to a .js file and generata cc files from it?
40 const char* const I18NExtension::kSource =
41 "Locale = function(optLocale) {"
42 " native function NativeJSLocale();"
Mads Ager (chromium) 2010/12/09 00:36:13 Please use two-space indent.
Nebojša Ćirić 2010/12/09 00:57:13 Done.
43 " var properties = NativeJSLocale(optLocale);"
44 " this.locale = properties.locale;"
45 " this.language = properties.language;"
46 " this.script = properties.script;"
47 " this.region = properties.region;"
48 "};"
49 "Locale.availableLocales = function() {"
50 " native function NativeJSAvailableLocales();"
51 " return NativeJSAvailableLocales();"
52 "};"
53 "Locale.prototype.maximizedLocale = function() {"
54 " native function NativeJSMaximizedLocale();"
55 " return new Locale(NativeJSMaximizedLocale(this.locale));"
56 "};"
57 "Locale.prototype.minimizedLocale = function() {"
58 " native function NativeJSMinimizedLocale();"
59 " return new Locale(NativeJSMinimizedLocale(this.locale));"
60 "};"
61 "Locale.prototype.displayLocale_ = function(displayLocale) {"
62 " var result = this.locale;"
63 " if (displayLocale !== undefined) {"
64 " result = displayLocale.locale;"
65 " }"
66 " return result;"
67 "};"
68 "Locale.prototype.displayLanguage = function(optDisplayLocale) {"
69 " var displayLocale = this.displayLocale_(optDisplayLocale);"
70 " native function NativeJSDisplayLanguage();"
71 " return NativeJSDisplayLanguage(this.locale, displayLocale);"
72 "};"
73 "Locale.prototype.displayScript = function(optDisplayLocale) {"
74 " var displayLocale = this.displayLocale_(optDisplayLocale);"
75 " native function NativeJSDisplayScript();"
76 " return NativeJSDisplayScript(this.locale, displayLocale);"
77 "};"
78 "Locale.prototype.displayRegion = function(optDisplayLocale) {"
79 " var displayLocale = this.displayLocale_(optDisplayLocale);"
80 " native function NativeJSDisplayRegion();"
81 " return NativeJSDisplayRegion(this.locale, displayLocale);"
82 "};"
83 "Locale.prototype.displayName = function(optDisplayLocale) {"
84 " var displayLocale = this.displayLocale_(optDisplayLocale);"
85 " native function NativeJSDisplayName();"
86 " return NativeJSDisplayName(this.locale, displayLocale);"
87 "};";
88
89 v8::Handle<v8::FunctionTemplate> I18NExtension::GetNativeFunction(
90 v8::Handle<v8::String> name) {
91 if (name->Equals(v8::String::New("NativeJSLocale"))) {
92 return v8::FunctionTemplate::New(JSLocale);
93 } else if (name->Equals(v8::String::New("NativeJSAvailableLocales"))) {
94 return v8::FunctionTemplate::New(JSAvailableLocales);
95 } else if (name->Equals(v8::String::New("NativeJSMaximizedLocale"))) {
96 return v8::FunctionTemplate::New(JSMaximizedLocale);
97 } else if (name->Equals(v8::String::New("NativeJSMinimizedLocale"))) {
98 return v8::FunctionTemplate::New(JSMinimizedLocale);
99 } else if (name->Equals(v8::String::New("NativeJSDisplayLanguage"))) {
100 return v8::FunctionTemplate::New(JSDisplayLanguage);
101 } else if (name->Equals(v8::String::New("NativeJSDisplayScript"))) {
102 return v8::FunctionTemplate::New(JSDisplayScript);
103 } else if (name->Equals(v8::String::New("NativeJSDisplayRegion"))) {
104 return v8::FunctionTemplate::New(JSDisplayRegion);
105 } else if (name->Equals(v8::String::New("NativeJSDisplayName"))) {
106 return v8::FunctionTemplate::New(JSDisplayName);
107 }
108
109 return v8::Handle<v8::FunctionTemplate>();
110 }
111
112 v8::Handle<v8::Value> I18NExtension::JSLocale(const v8::Arguments& args) {
113 // TODO(cira): Fetch browser locale. Accept en-US as good default for now.
jungshik at Google 2010/12/09 00:05:35 Wonder what your plan is for this. Can the registr
Nebojša Ćirić 2010/12/09 00:57:13 Added your comment to todo. Seems reasonable.
114 std::string locale_name("en-US");
115 if (args.Length() == 1 && args[0]->IsString()) {
116 locale_name = *v8::String::Utf8Value(args[0]->ToString());
Mads Ager (chromium) 2010/12/09 00:36:13 two-space indent.
Nebojša Ćirić 2010/12/09 00:57:13 Done.
117 }
118
119 v8::Local<v8::Object> locale = v8::Object::New();
120 locale->Set(v8::String::New("locale"), v8::String::New(locale_name.c_str()));
121
122 icu::Locale icu_locale(locale_name.c_str());
123
124 const char* language = icu_locale.getLanguage();
125 locale->Set(v8::String::New("language"), v8::String::New(language));
126
127 const char* script = icu_locale.getScript();
128 if (strlen(script)) {
129 locale->Set(v8::String::New("script"), v8::String::New(script));
130 }
131
132 const char* region = icu_locale.getCountry();
133 if (strlen(region)) {
134 locale->Set(v8::String::New("region"), v8::String::New(region));
135 }
136
137 return locale;
138 }
139
140 // TODO(cira): Filter out locales that Chrome doesn't support.
141 v8::Handle<v8::Value> I18NExtension::JSAvailableLocales(
142 const v8::Arguments& args) {
143 v8::Local<v8::Array> all_locales = v8::Array::New();
144
145 int count = 0;
146 const Locale* icu_locales = icu::Locale::getAvailableLocales(count);
147 for (int i = 0; i < count; ++i)
148 all_locales->Set(i, v8::String::New(icu_locales[i].getName()));
Mads Ager (chromium) 2010/12/09 00:36:13 two-space indent and braces around the body of the
Nebojša Ćirić 2010/12/09 00:57:13 Done.
149
150 return all_locales;
151 }
152
153 // Use - as tag separator, not _ that ICU uses.
154 static std::string NormalizeLocale(const std::string& locale) {
155 std::string result(locale);
156 std::replace(result.begin(), result.end(), '_', '-');
jungshik at Google 2010/12/09 00:05:35 Wouldn't it be better (style-compliant) to include
Mads Ager (chromium) 2010/12/09 00:36:13 This is fine for an experimental extension. If thi
Nebojša Ćirić 2010/12/09 00:57:13 Done.
Nebojša Ćirić 2010/12/09 00:57:13 Ah joy :). Yes, this can be rewritten to not use S
157 return result;
158 }
159
160 v8::Handle<v8::Value> I18NExtension::JSMaximizedLocale(
161 const v8::Arguments& args) {
162 if (!args.Length() || !args[0]->IsString()) {
163 return v8::Undefined();
164 }
165
166 UErrorCode status = U_ZERO_ERROR;
167 std::string locale_name = *v8::String::Utf8Value(args[0]->ToString());
168 char max_locale[ULOC_FULLNAME_CAPACITY];
169 uloc_addLikelySubtags(locale_name.c_str(), max_locale,
jungshik at Google 2010/12/09 00:05:35 same here. For uloc_*, pls include <unicode/uloc.h
Nebojša Ćirić 2010/12/09 00:57:13 Done.
170 sizeof(max_locale), &status);
171 if (U_FAILURE(status)) {
172 return v8::Undefined();
Mads Ager (chromium) 2010/12/09 00:36:13 two space indent.
Nebojša Ćirić 2010/12/09 00:57:13 Done.
173 }
174
175 return v8::String::New(NormalizeLocale(max_locale).c_str());
176 }
177
178 v8::Handle<v8::Value> I18NExtension::JSMinimizedLocale(
179 const v8::Arguments& args) {
180 if (!args.Length() || !args[0]->IsString()) {
181 return v8::Undefined();
Mads Ager (chromium) 2010/12/09 00:36:13 two space indent.
Nebojša Ćirić 2010/12/09 00:57:13 Done.
182 }
183
184 UErrorCode status = U_ZERO_ERROR;
185 std::string locale_name = *v8::String::Utf8Value(args[0]->ToString());
186 char min_locale[ULOC_FULLNAME_CAPACITY];
187 uloc_minimizeSubtags(locale_name.c_str(), min_locale,
188 sizeof(min_locale), &status);
189 if (U_FAILURE(status)) {
190 return v8::Undefined();
Mads Ager (chromium) 2010/12/09 00:36:13 two space indent.
Nebojša Ćirić 2010/12/09 00:57:13 Done.
191 }
192
193 return v8::String::New(NormalizeLocale(min_locale).c_str());
194 }
195
196 // Common code for JSDisplayXXX methods.
197 static v8::Handle<v8::Value> GetDisplayItem(const v8::Arguments& args,
198 const std::string& item) {
199 if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) {
200 return v8::Undefined();
Mads Ager (chromium) 2010/12/09 00:36:13 two space indent.
Nebojša Ćirić 2010/12/09 00:57:13 Done.
201 }
202
203 std::string base_locale = *v8::String::Utf8Value(args[0]->ToString());
204 icu::Locale icu_locale(base_locale.c_str());
205 icu::Locale display_locale =
206 icu::Locale(*v8::String::Utf8Value(args[1]->ToString()));
207 UnicodeString result;
208 if (item == "language") {
209 icu_locale.getDisplayLanguage(display_locale, result);
210 } else if (item == "script") {
211 icu_locale.getDisplayScript(display_locale, result);
212 } else if (item == "region") {
213 icu_locale.getDisplayCountry(display_locale, result);
214 } else if (item == "name") {
215 icu_locale.getDisplayName(display_locale, result);
216 } else {
217 return v8::Undefined();
218 }
219
220 if (result.length()) {
221 return v8::String::New(
222 reinterpret_cast<const uint16_t*>(result.getBuffer()), result.length());
223 }
224
225 return v8::Undefined();
226 }
227
228 v8::Handle<v8::Value> I18NExtension::JSDisplayLanguage(
229 const v8::Arguments& args) {
230 return GetDisplayItem(args, "language");
231 }
232
233 v8::Handle<v8::Value> I18NExtension::JSDisplayScript(
234 const v8::Arguments& args) {
235 return GetDisplayItem(args, "script");
236 }
237
238 v8::Handle<v8::Value> I18NExtension::JSDisplayRegion(
239 const v8::Arguments& args) {
240 return GetDisplayItem(args, "region");
241 }
242
243 v8::Handle<v8::Value> I18NExtension::JSDisplayName(const v8::Arguments& args) {
244 return GetDisplayItem(args, "name");
245 }
246
247 I18NExtension* I18NExtension::get() {
248 if (!extension_) {
249 extension_ = new I18NExtension();
250 }
251 return extension_;
252 }
253
254 void I18NExtension::Register() {
255 static v8::DeclareExtension i18n_extension_declaration(I18NExtension::get());
256 }
257
258 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/extensions/experimental/i18n-extension.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698