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/utils_native_handler.h" 6 7#include "base/strings/stringprintf.h" 8#include "extensions/renderer/script_context.h" 9#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" 10#include "third_party/WebKit/public/web/WebSerializedScriptValue.h" 11 12namespace extensions { 13 14UtilsNativeHandler::UtilsNativeHandler(ScriptContext* context) 15 : ObjectBackedNativeHandler(context) { 16 RouteFunction("createClassWrapper", 17 base::Bind(&UtilsNativeHandler::CreateClassWrapper, 18 base::Unretained(this))); 19 RouteFunction( 20 "deepCopy", 21 base::Bind(&UtilsNativeHandler::DeepCopy, base::Unretained(this))); 22} 23 24UtilsNativeHandler::~UtilsNativeHandler() {} 25 26void UtilsNativeHandler::CreateClassWrapper( 27 const v8::FunctionCallbackInfo<v8::Value>& args) { 28 CHECK_EQ(3, args.Length()); 29 CHECK(args[0]->IsString()); 30 std::string name = *v8::String::Utf8Value(args[0]); 31 CHECK(args[1]->IsObject()); 32 v8::Local<v8::Object> cls = args[1].As<v8::Object>(); 33 CHECK(args[2]->IsObject() || args[2]->IsUndefined()); 34 v8::Local<v8::Value> superclass = args[2]; 35 36 v8::HandleScope handle_scope(GetIsolate()); 37 // TODO(fsamuel): Consider moving the source wrapping to ModuleSystem. 38 v8::Handle<v8::String> source = v8::String::NewFromUtf8( 39 GetIsolate(), 40 base::StringPrintf( 41 "(function($Object, $Function, privates, cls, superclass) {" 42 "'use strict';\n" 43 " function %s() {\n" 44 " var privateObj = $Object.create(cls.prototype);\n" 45 " $Function.apply(cls, privateObj, arguments);\n" 46 " privateObj.wrapper = this;\n" 47 " privates(this).impl = privateObj;\n" 48 " };\n" 49 " if (superclass) {\n" 50 " %s.prototype = Object.create(superclass.prototype);\n" 51 " }\n" 52 " return %s;\n" 53 "})", 54 name.c_str(), 55 name.c_str(), 56 name.c_str()).c_str()); 57 v8::Handle<v8::Value> func_as_value = context()->module_system()->RunString( 58 source, v8::String::NewFromUtf8(GetIsolate(), name.c_str())); 59 if (func_as_value.IsEmpty() || func_as_value->IsUndefined()) { 60 args.GetReturnValue().SetUndefined(); 61 return; 62 } 63 64 // TODO(fsamuel): Move privates from ModuleSystem to a shared location. 65 v8::Handle<v8::Object> natives(context()->module_system()->NewInstance()); 66 CHECK(!natives.IsEmpty()); // this can happen if v8 has issues 67 v8::Handle<v8::Function> func = func_as_value.As<v8::Function>(); 68 v8::Handle<v8::Value> func_args[] = { 69 context()->safe_builtins()->GetObjekt(), 70 context()->safe_builtins()->GetFunction(), 71 natives->Get(v8::String::NewFromUtf8( 72 GetIsolate(), "privates", v8::String::kInternalizedString)), 73 cls, 74 superclass}; 75 v8::Local<v8::Value> result; 76 { 77 v8::TryCatch try_catch; 78 try_catch.SetCaptureMessage(true); 79 result = context()->CallFunction(func, arraysize(func_args), func_args); 80 if (try_catch.HasCaught()) { 81 args.GetReturnValue().SetUndefined(); 82 return; 83 } 84 } 85 args.GetReturnValue().Set(result); 86} 87 88void UtilsNativeHandler::DeepCopy( 89 const v8::FunctionCallbackInfo<v8::Value>& args) { 90 CHECK_EQ(1, args.Length()); 91 args.GetReturnValue().Set( 92 blink::WebSerializedScriptValue::serialize(args[0]).deserialize()); 93} 94 95} // namespace extensions 96