OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (C) 2014 Google Inc. All rights reserved. |
| 3 * |
| 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are |
| 6 * met: |
| 7 * |
| 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above |
| 11 * copyright notice, this list of conditions and the following disclaimer |
| 12 * in the documentation and/or other materials provided with the |
| 13 * distribution. |
| 14 * * Neither the name of Google Inc. nor the names of its |
| 15 * contributors may be used to endorse or promote products derived from |
| 16 * this software without specific prior written permission. |
| 17 * |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ |
| 30 |
| 31 #include "config.h" |
| 32 #include "bindings/v8/V8BlinkInJavaScript.h" |
| 33 |
| 34 #include "BlinkInJavaScript.h" |
| 35 #include "V8Window.h" |
| 36 #include "bindings/v8/DOMWrapperWorld.h" |
| 37 #include "bindings/v8/ScriptController.h" |
| 38 #include "bindings/v8/V8Binding.h" |
| 39 #include "bindings/v8/V8PerIsolateData.h" |
| 40 #include "bindings/v8/V8ScriptRunner.h" |
| 41 #include "bindings/v8/V8WindowShell.h" |
| 42 #include "core/dom/Document.h" |
| 43 #include "core/frame/Frame.h" |
| 44 |
| 45 namespace WebCore { |
| 46 |
| 47 static v8::Handle<v8::Value> compileBlinkInJavaScript(String className, v8::Isol
ate* isolate) |
| 48 { |
| 49 size_t index; |
| 50 // |kBlinkInJavaScriptSources| is defined in BlinkInJavaScript.h, which is a
uto-generated |
| 51 // by make_blink_in_javascript.py. |
| 52 for (index = 0; index < WTF_ARRAY_LENGTH(kBlinkInJavaScriptSources); index++
) { |
| 53 if (className == kBlinkInJavaScriptSources[index].name) |
| 54 break; |
| 55 } |
| 56 RELEASE_ASSERT(index != WTF_ARRAY_LENGTH(kBlinkInJavaScriptSources)); |
| 57 |
| 58 String source(reinterpret_cast<const char*>(kBlinkInJavaScriptSources[index]
.source), kBlinkInJavaScriptSources[index].size); |
| 59 return V8ScriptRunner::compileAndRunInternalScript(v8String(isolate, source)
, isolate); |
| 60 } |
| 61 |
| 62 static v8::Handle<v8::Value> convertWrapperForThisWorld(v8::Handle<v8::Value> wr
apper, v8::Isolate* isolate) |
| 63 { |
| 64 // We don't need to convert primitive values. |
| 65 if (wrapper.IsEmpty() || !wrapper->IsObject()) |
| 66 return wrapper; |
| 67 |
| 68 // FIXME: We need to support conversion for Objects, Functions, Arrays etc. |
| 69 |
| 70 // FIXME: This implementation is a temporary hack just for window wrappers. |
| 71 // What we really need here is something like the following code: |
| 72 // |
| 73 // if (WrapperTypeInfo* typeInfo = WrapperTypeInfo::wrapperTypeInfo(wrapper)
) { |
| 74 // return typeInfo->toV8(typeInfo->toNative(), v8::Handle<v8::Object>(),
isolate); |
| 75 // } |
| 76 // |
| 77 // To make the above code workable, we need to store toNative() and toV8() t
o WrapperTypeInfo. |
| 78 // We also need to implement wrapperTypeInfo() which returns WrapperTypeInfo |
| 79 // only when |wrapper| is a valid DOM wrapper. |
| 80 if (V8Window::hasInstanceInAnyWorld(wrapper, isolate)) { |
| 81 v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(wrapper); |
| 82 DOMWindow* imp = V8Window::toNative(object); |
| 83 return toV8(imp, v8::Handle<v8::Object>(), isolate); |
| 84 } |
| 85 RELEASE_ASSERT(0); |
| 86 } |
| 87 |
| 88 v8::Handle<v8::Value> V8BlinkInJavaScript::runBlinkInJavaScript(String className
, String functionName, v8::Handle<v8::Value> receiver, int argc, v8::Handle<v8::
Value> argv[], v8::Isolate* isolate) |
| 89 { |
| 90 Document* document = currentDocument(); |
| 91 if (!document || !document->frame()) |
| 92 return v8::Handle<v8::Value>(); |
| 93 |
| 94 // Blink-in-JavaScript runs in the same security level as content scripts of
Chrome extensions. |
| 95 // Specifically, Blink-in-JavaScript runs in a dedicated isolated world. |
| 96 RefPtr<DOMWrapperWorld> world = DOMWrapperWorld::ensureIsolatedWorld(BlinkIn
JavaScriptIsolatedWorldId, DOMWrapperWorld::blinkInJavaScriptWorldExtensionGroup
); |
| 97 V8WindowShell* isolatedWorldShell = document->frame()->script().windowShell(
world.get()); |
| 98 if (!isolatedWorldShell->isContextInitialized()) |
| 99 return v8::Handle<v8::Value>(); |
| 100 |
| 101 v8::Handle<v8::Context> context = isolatedWorldShell->context(); |
| 102 v8::Handle<v8::Value> result; |
| 103 { |
| 104 // Switch to the context of Blink-in-JavaScript's isolated world. |
| 105 v8::Context::Scope contextScope(context); |
| 106 |
| 107 v8::Handle<v8::Value> compiledClass = V8PerIsolateData::from(isolate)->c
ompiledBlinkInJavaScript(className); |
| 108 if (compiledClass.IsEmpty()) { |
| 109 v8::Handle<v8::Value> installedClasses = V8PerIsolateData::from(isol
ate)->compiledBlinkInJavaScript("BlinkInJavaScriptController"); |
| 110 if (installedClasses.IsEmpty()) { |
| 111 installedClasses = compileBlinkInJavaScript("BlinkInJavaScriptCo
ntroller", isolate); |
| 112 V8PerIsolateData::from(isolate)->setCompiledBlinkInJavaScript("B
linkInJavaScriptController", installedClasses); |
| 113 } |
| 114 RELEASE_ASSERT(!installedClasses.IsEmpty()); |
| 115 RELEASE_ASSERT(installedClasses->IsObject()); |
| 116 |
| 117 compileBlinkInJavaScript(className, isolate); |
| 118 |
| 119 compiledClass = v8::Handle<v8::Object>::Cast(installedClasses)->Get(
v8String(isolate, className)); |
| 120 RELEASE_ASSERT(!compiledClass.IsEmpty()); |
| 121 RELEASE_ASSERT(compiledClass->IsObject()); |
| 122 V8PerIsolateData::from(isolate)->setCompiledBlinkInJavaScript(classN
ame, compiledClass); |
| 123 } |
| 124 |
| 125 v8::Handle<v8::Value> function = v8::Handle<v8::Object>::Cast(compiledCl
ass)->Get(v8String(isolate, functionName)); |
| 126 RELEASE_ASSERT(!function.IsEmpty()); |
| 127 RELEASE_ASSERT(function->IsFunction()); |
| 128 |
| 129 // We have to convert argument wrappers to wrappers in Blink-in-JavaScri
pt's isolated world. |
| 130 receiver = convertWrapperForThisWorld(receiver, isolate); |
| 131 for (int i = 0; i < argc; i++) { |
| 132 argv[i] = convertWrapperForThisWorld(argv[i], isolate); |
| 133 } |
| 134 |
| 135 result = V8ScriptRunner::callFunction(v8::Handle<v8::Function>::Cast(fun
ction), document, receiver, argc, argv, isolate); |
| 136 } |
| 137 |
| 138 // We have to convert a return wrapper created in Blink-in-JavaScript's isol
ated world |
| 139 // to a wrapper in the original world. |
| 140 return convertWrapperForThisWorld(result, isolate); |
| 141 } |
| 142 |
| 143 } // namespace WebCore |
OLD | NEW |