// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights // reserved. Use of this source code is governed by a BSD-style license that // can be found in the LICENSE file. #include "libcef/renderer/chrome_bindings.h" #include "libcef/renderer/browser_impl.h" #include #include "base/logging.h" #include "base/values.h" #include "content/public/common/url_constants.h" namespace scheme { namespace { void SetList(CefRefPtr source, base::ListValue* target); // Transfer a V8 value to a List index. void SetListValue(base::ListValue* list, int index, CefRefPtr value) { if (value->IsArray()) { base::ListValue* new_list = new base::ListValue(); SetList(value, new_list); list->Set(index, new_list); } else if (value->IsString()) { list->Set(index, base::Value::CreateStringValue(value->GetStringValue().ToString())); } else if (value->IsBool()) { list->Set(index, base::Value::CreateBooleanValue(value->GetBoolValue())); } else if (value->IsInt()) { list->Set(index, base::Value::CreateIntegerValue(value->GetIntValue())); } else if (value->IsDouble()) { list->Set(index, base::Value::CreateDoubleValue(value->GetDoubleValue())); } } // Transfer a V8 array to a List. void SetList(CefRefPtr source, base::ListValue* target) { DCHECK(source->IsArray()); int arg_length = source->GetArrayLength(); if (arg_length == 0) return; for (int i = 0; i < arg_length; ++i) SetListValue(target, i, source->GetValue(i)); } class V8Handler : public CefV8Handler { public: V8Handler() {} virtual bool Execute(const CefString& name, CefRefPtr object, const CefV8ValueList& arguments, CefRefPtr& retval, CefString& exception) OVERRIDE { std::string nameStr = name; if (nameStr == "send") { if (arguments.size() > 0 && arguments.size() <= 2 && arguments[0]->IsString()) { base::ListValue args; SetListValue(&args, 0, arguments[0]); if (arguments.size() > 1) SetListValue(&args, 1, arguments[1]); CefRefPtr browser = static_cast( CefV8Context::GetCurrentContext()->GetBrowser().get()); browser->SendProcessMessage(PID_BROWSER, kChromeProcessMessage, &args, false); retval = CefV8Value::CreateBool(true); } else { exception = "Invalid number of arguments or argument format"; } return true; } else if (nameStr == "bind") { // Return the "send" object. DCHECK(object->GetFunctionName() == "send"); retval = object; return true; } NOTREACHED(); return false; } IMPLEMENT_REFCOUNTING(V8Handler); }; } // namespace void OnContextCreated(CefRefPtr browser, CefRefPtr frame, CefRefPtr context) { GURL url = GURL(frame->GetURL().ToString()); if (url.scheme() != chrome::kChromeUIScheme) return; CefRefPtr global = context->GetGlobal(); CefRefPtr handler = new V8Handler(); // Add "chrome". CefRefPtr chrome = CefV8Value::CreateObject(NULL); global->SetValue("chrome", chrome, V8_PROPERTY_ATTRIBUTE_NONE); // Add "chrome.send". CefRefPtr send = CefV8Value::CreateFunction("send", handler); chrome->SetValue("send", send, V8_PROPERTY_ATTRIBUTE_NONE); // Add "chrome.send.bind". CefRefPtr bind = CefV8Value::CreateFunction("bind", handler); send->SetValue("bind", bind, V8_PROPERTY_ATTRIBUTE_NONE); } } // namespace scheme