1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "extensions/renderer/i18n_custom_bindings.h" 6 7 #include "base/bind.h" 8 #include "content/public/renderer/render_thread.h" 9 #include "content/public/renderer/render_view.h" 10 #include "extensions/common/extension_messages.h" 11 #include "extensions/common/message_bundle.h" 12 #include "extensions/renderer/script_context.h" 13 14 namespace extensions { 15 16 I18NCustomBindings::I18NCustomBindings(ScriptContext* context) 17 : ObjectBackedNativeHandler(context) { 18 RouteFunction( 19 "GetL10nMessage", 20 base::Bind(&I18NCustomBindings::GetL10nMessage, base::Unretained(this))); 21 RouteFunction("GetL10nUILanguage", 22 base::Bind(&I18NCustomBindings::GetL10nUILanguage, 23 base::Unretained(this))); 24 } 25 26 void I18NCustomBindings::GetL10nMessage( 27 const v8::FunctionCallbackInfo<v8::Value>& args) { 28 if (args.Length() != 3 || !args[0]->IsString()) { 29 NOTREACHED() << "Bad arguments"; 30 return; 31 } 32 33 std::string extension_id; 34 if (args[2]->IsNull() || !args[2]->IsString()) { 35 return; 36 } else { 37 extension_id = *v8::String::Utf8Value(args[2]->ToString()); 38 if (extension_id.empty()) 39 return; 40 } 41 42 L10nMessagesMap* l10n_messages = GetL10nMessagesMap(extension_id); 43 if (!l10n_messages) { 44 // Get the current RenderView so that we can send a routed IPC message 45 // from the correct source. 46 content::RenderView* renderview = context()->GetRenderView(); 47 if (!renderview) 48 return; 49 50 L10nMessagesMap messages; 51 // A sync call to load message catalogs for current extension. 52 renderview->Send( 53 new ExtensionHostMsg_GetMessageBundle(extension_id, &messages)); 54 55 // Save messages we got. 56 ExtensionToL10nMessagesMap& l10n_messages_map = 57 *GetExtensionToL10nMessagesMap(); 58 l10n_messages_map[extension_id] = messages; 59 60 l10n_messages = GetL10nMessagesMap(extension_id); 61 } 62 63 std::string message_name = *v8::String::Utf8Value(args[0]); 64 std::string message = 65 MessageBundle::GetL10nMessage(message_name, *l10n_messages); 66 67 v8::Isolate* isolate = args.GetIsolate(); 68 std::vector<std::string> substitutions; 69 if (args[1]->IsArray()) { 70 // chrome.i18n.getMessage("message_name", ["more", "params"]); 71 v8::Local<v8::Array> placeholders = v8::Local<v8::Array>::Cast(args[1]); 72 uint32_t count = placeholders->Length(); 73 if (count > 9) 74 return; 75 for (uint32_t i = 0; i < count; ++i) { 76 substitutions.push_back( 77 *v8::String::Utf8Value( 78 placeholders->Get(v8::Integer::New(isolate, i))->ToString())); 79 } 80 } else if (args[1]->IsString()) { 81 // chrome.i18n.getMessage("message_name", "one param"); 82 substitutions.push_back(*v8::String::Utf8Value(args[1]->ToString())); 83 } 84 85 args.GetReturnValue().Set(v8::String::NewFromUtf8( 86 isolate, 87 ReplaceStringPlaceholders(message, substitutions, NULL).c_str())); 88 } 89 90 void I18NCustomBindings::GetL10nUILanguage( 91 const v8::FunctionCallbackInfo<v8::Value>& args) { 92 args.GetReturnValue().Set(v8::String::NewFromUtf8( 93 args.GetIsolate(), content::RenderThread::Get()->GetLocale().c_str())); 94 } 95 96 } // namespace extensions 97