• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
12 namespace extensions {
13 
UtilsNativeHandler(ScriptContext * context)14 UtilsNativeHandler::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 
~UtilsNativeHandler()24 UtilsNativeHandler::~UtilsNativeHandler() {}
25 
CreateClassWrapper(const v8::FunctionCallbackInfo<v8::Value> & args)26 void 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 
DeepCopy(const v8::FunctionCallbackInfo<v8::Value> & args)88 void 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