1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "extensions/renderer/utils_native_handler.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/stringprintf.h" 80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "extensions/renderer/script_context.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" 106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "third_party/WebKit/public/web/WebSerializedScriptValue.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace extensions { 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 140529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochUtilsNativeHandler::UtilsNativeHandler(ScriptContext* context) 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : ObjectBackedNativeHandler(context) { 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RouteFunction("createClassWrapper", 170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Bind(&UtilsNativeHandler::CreateClassWrapper, 180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Unretained(this))); 196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) RouteFunction( 206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) "deepCopy", 216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Bind(&UtilsNativeHandler::DeepCopy, base::Unretained(this))); 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)UtilsNativeHandler::~UtilsNativeHandler() {} 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void UtilsNativeHandler::CreateClassWrapper( 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const v8::FunctionCallbackInfo<v8::Value>& args) { 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_EQ(3, args.Length()); 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(args[0]->IsString()); 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string name = *v8::String::Utf8Value(args[0]); 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(args[1]->IsObject()); 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Local<v8::Object> cls = args[1].As<v8::Object>(); 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK(args[2]->IsObject() || args[2]->IsUndefined()); 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) v8::Local<v8::Value> superclass = args[2]; 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::HandleScope handle_scope(GetIsolate()); 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(fsamuel): Consider moving the source wrapping to ModuleSystem. 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::String> source = v8::String::NewFromUtf8( 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetIsolate(), 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::StringPrintf( 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "(function($Object, $Function, privates, cls, superclass) {" 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "'use strict';\n" 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) " function %s() {\n" 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) " var privateObj = $Object.create(cls.prototype);\n" 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) " $Function.apply(cls, privateObj, arguments);\n" 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) " privateObj.wrapper = this;\n" 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) " privates(this).impl = privateObj;\n" 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) " };\n" 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) " if (superclass) {\n" 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) " %s.prototype = Object.create(superclass.prototype);\n" 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) " }\n" 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) " return %s;\n" 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) "})", 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) name.c_str(), 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) name.c_str(), 560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch name.c_str()).c_str()); 570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch v8::Handle<v8::Value> func_as_value = context()->module_system()->RunString( 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch source, v8::String::NewFromUtf8(GetIsolate(), name.c_str())); 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (func_as_value.IsEmpty() || func_as_value->IsUndefined()) { 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) args.GetReturnValue().SetUndefined(); 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(fsamuel): Move privates from ModuleSystem to a shared location. 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Object> natives(context()->module_system()->NewInstance()); 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CHECK(!natives.IsEmpty()); // this can happen if v8 has issues 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Function> func = func_as_value.As<v8::Function>(); 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Handle<v8::Value> func_args[] = { 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) context()->safe_builtins()->GetObjekt(), 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) context()->safe_builtins()->GetFunction(), 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) natives->Get(v8::String::NewFromUtf8( 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetIsolate(), "privates", v8::String::kInternalizedString)), 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) cls, 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) superclass}; 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Local<v8::Value> result; 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::TryCatch try_catch; 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) try_catch.SetCaptureMessage(true); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result = context()->CallFunction(func, arraysize(func_args), func_args); 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (try_catch.HasCaught()) { 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) args.GetReturnValue().SetUndefined(); 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) args.GetReturnValue().Set(result); 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void UtilsNativeHandler::DeepCopy( 896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const v8::FunctionCallbackInfo<v8::Value>& args) { 906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) CHECK_EQ(1, args.Length()); 916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) args.GetReturnValue().Set( 926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) blink::WebSerializedScriptValue::serialize(args[0]).deserialize()); 936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace extensions 96