10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "extensions/renderer/i18n_custom_bindings.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/renderer/render_thread.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_view.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/extension_messages.h" 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/message_bundle.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "extensions/renderer/script_context.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 160529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochI18NCustomBindings::I18NCustomBindings(ScriptContext* context) 170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : ObjectBackedNativeHandler(context) { 180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RouteFunction( 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "GetL10nMessage", 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&I18NCustomBindings::GetL10nMessage, base::Unretained(this))); 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RouteFunction("GetL10nUILanguage", 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&I18NCustomBindings::GetL10nUILanguage, 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this))); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void I18NCustomBindings::GetL10nMessage( 277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const v8::FunctionCallbackInfo<v8::Value>& args) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args.Length() != 3 || !args[0]->IsString()) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Bad arguments"; 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args[2]->IsNull() || !args[2]->IsString()) { 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_id = *v8::String::Utf8Value(args[2]->ToString()); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_id.empty()) 397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L10nMessagesMap* l10n_messages = GetL10nMessagesMap(extension_id); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!l10n_messages) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the current RenderView so that we can send a routed IPC message 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the correct source. 460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch content::RenderView* renderview = context()->GetRenderView(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!renderview) 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L10nMessagesMap messages; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A sync call to load message catalogs for current extension. 520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch renderview->Send( 530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch new ExtensionHostMsg_GetMessageBundle(extension_id, &messages)); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save messages we got. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionToL10nMessagesMap& l10n_messages_map = 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *GetExtensionToL10nMessagesMap(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_messages_map[extension_id] = messages; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_messages = GetL10nMessagesMap(extension_id); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string message_name = *v8::String::Utf8Value(args[0]); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string message = 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageBundle::GetL10nMessage(message_name, *l10n_messages); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Isolate* isolate = args.GetIsolate(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> substitutions; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args[1]->IsArray()) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // chrome.i18n.getMessage("message_name", ["more", "params"]); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Local<v8::Array> placeholders = v8::Local<v8::Array>::Cast(args[1]); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t count = placeholders->Length(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count > 9) 747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t i = 0; i < count; ++i) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) substitutions.push_back( 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *v8::String::Utf8Value( 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) placeholders->Get(v8::Integer::New(isolate, i))->ToString())); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (args[1]->IsString()) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // chrome.i18n.getMessage("message_name", "one param"); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) substitutions.push_back(*v8::String::Utf8Value(args[1]->ToString())); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch args.GetReturnValue().Set(v8::String::NewFromUtf8( 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch isolate, 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ReplaceStringPlaceholders(message, substitutions, NULL).c_str())); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void I18NCustomBindings::GetL10nUILanguage( 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const v8::FunctionCallbackInfo<v8::Value>& args) { 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) args.GetReturnValue().Set(v8::String::NewFromUtf8( 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) args.GetIsolate(), content::RenderThread::Get()->GetLocale().c_str())); 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace extensions 97