| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012, Google Inc. | |
| 2 // 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 #include "config.h" | |
| 31 #include "bindings/core/dart/DartNativeUtilities.h" | |
| 32 | |
| 33 #include "bindings/core/dart/DartController.h" | |
| 34 #include "bindings/core/dart/DartCustomElementConstructorBuilder.h" | |
| 35 #include "bindings/core/dart/DartCustomElementLifecycleCallbacks.h" | |
| 36 #include "bindings/core/dart/DartCustomElementWrapper.h" | |
| 37 #include "bindings/core/dart/DartDOMData.h" | |
| 38 #include "bindings/core/dart/DartDOMStringMap.h" | |
| 39 #include "bindings/core/dart/DartDOMWrapper.h" | |
| 40 #include "bindings/core/dart/DartDocument.h" | |
| 41 #include "bindings/core/dart/DartElement.h" | |
| 42 #include "bindings/core/dart/DartHTMLElement.h" | |
| 43 #include "bindings/core/dart/DartJsInterop.h" | |
| 44 #include "bindings/core/dart/DartUtilities.h" | |
| 45 #include "bindings/core/dart/DartWindow.h" | |
| 46 #include "bindings/core/dart/V8Converter.h" | |
| 47 #include "bindings/core/v8/ScriptController.h" | |
| 48 #include "bindings/core/v8/npruntime_impl.h" | |
| 49 #include "core/dom/Document.h" | |
| 50 #include "core/dom/custom/CustomElementCallbackDispatcher.h" | |
| 51 #include "core/dom/custom/CustomElementRegistrationContext.h" | |
| 52 #include "core/frame/LocalFrame.h" | |
| 53 #include "core/html/HTMLElement.h" | |
| 54 #include "platform/RuntimeEnabledFeatures.h" | |
| 55 | |
| 56 #include "wtf/HashMap.h" | |
| 57 #include "wtf/StdLibExtras.h" | |
| 58 #include "wtf/text/CString.h" | |
| 59 #include "wtf/text/StringHash.h" | |
| 60 #include <bindings/npruntime.h> | |
| 61 #include <dart_api.h> | |
| 62 | |
| 63 namespace blink { | |
| 64 | |
| 65 namespace DartNativeUtilitiesInternal { | |
| 66 | |
| 67 static void topLevelWindow(Dart_NativeArguments args) | |
| 68 { | |
| 69 // Return full LocalDOMWindow implementation (DartDOMWrapper::createWrapper
always returns a secure wrapper). | |
| 70 LocalDOMWindow* window = DartUtilities::domWindowForCurrentIsolate(); | |
| 71 DartDOMWrapper::returnToDart<DartWindow>(args, window); | |
| 72 } | |
| 73 | |
| 74 /** | |
| 75 * Gadget for testing. | |
| 76 * | |
| 77 * With DART_FORWARDING_PRINT environment variable set, it invokes dartPrint | |
| 78 * JavaScript function on global object to communicate to Dart test framework. | |
| 79 */ | |
| 80 static void forwardingPrint(Dart_NativeArguments args) | |
| 81 { | |
| 82 v8::Isolate* v8Isolate = v8::Isolate::GetCurrent(); | |
| 83 v8::HandleScope v8Scope(v8Isolate); | |
| 84 ExecutionContext* scriptExecutionContext = DartUtilities::scriptExecutionCon
text(); | |
| 85 ASSERT(scriptExecutionContext); | |
| 86 | |
| 87 DartController* dartController = DartController::retrieve(scriptExecutionCon
text); | |
| 88 if (!dartController) | |
| 89 return; | |
| 90 LocalFrame* frame = dartController->frame(); | |
| 91 v8::Handle<v8::Context> v8Context = toV8Context(frame, DOMWrapperWorld::main
World()); | |
| 92 v8::Context::Scope scope(v8Context); | |
| 93 v8::TryCatch tryCatch; | |
| 94 | |
| 95 v8::Handle<v8::Value> function = v8Context->Global()->Get(v8::String::NewFro
mUtf8(v8Isolate, "dartPrint")); | |
| 96 if (function.IsEmpty() || !function->IsFunction()) | |
| 97 return; | |
| 98 | |
| 99 v8::Handle<v8::Value> message = V8Converter::stringToV8(Dart_GetNativeArgume
nt(args, 0)); | |
| 100 function.As<v8::Function>()->Call(v8Context->Global(), 1, &message); | |
| 101 } | |
| 102 | |
| 103 static void getNewIsolateId(Dart_NativeArguments args) | |
| 104 { | |
| 105 static int isolateId = 0; | |
| 106 Dart_SetReturnValue(args, DartUtilities::intToDart(isolateId++)); | |
| 107 } | |
| 108 | |
| 109 static void registerElement(Dart_NativeArguments args) | |
| 110 { | |
| 111 DartApiScope dartApiScope; | |
| 112 Dart_Handle exception = 0; | |
| 113 { | |
| 114 ExecutionContext* ALLOW_UNUSED scriptExecutionContext = DartUtilities::s
criptExecutionContext(); | |
| 115 ASSERT(scriptExecutionContext); | |
| 116 | |
| 117 Document* document = DartDocument::toNative(args, 0, exception); | |
| 118 if (exception) | |
| 119 goto fail; | |
| 120 | |
| 121 DartStringAdapter name = DartUtilities::dartToString(args, 1, exception)
; | |
| 122 if (exception) | |
| 123 goto fail; | |
| 124 | |
| 125 Dart_Handle customType = Dart_GetNativeArgument(args, 2); | |
| 126 ASSERT(Dart_IsType(customType)); | |
| 127 | |
| 128 AtomicString extendsTagName; | |
| 129 Dart_Handle extendsArg = Dart_GetNativeArgument(args, 3); | |
| 130 if (!Dart_IsNull(extendsArg)) { | |
| 131 extendsTagName = DartUtilities::dartToString(extendsArg, exception); | |
| 132 if (exception) { | |
| 133 goto fail; | |
| 134 } | |
| 135 } | |
| 136 | |
| 137 CustomElementRegistrationContext* registrationContext = document->regist
rationContext(); | |
| 138 if (!registrationContext) { | |
| 139 DartExceptionState es; | |
| 140 es.throwDOMException(NotSupportedError); | |
| 141 exception = es.toDart(args); | |
| 142 goto fail; | |
| 143 } | |
| 144 | |
| 145 DartScriptState* scriptState = DartUtilities::currentScriptState(); | |
| 146 | |
| 147 CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope; | |
| 148 | |
| 149 const Dictionary dictionary; | |
| 150 DartCustomElementConstructorBuilder constructorBuilder(customType, exten
dsTagName, scriptState, &dictionary); | |
| 151 DartExceptionState es; | |
| 152 registrationContext->registerElement(document, &constructorBuilder, name
, CustomElement::AllNames, es); | |
| 153 if (es.hadException()) { | |
| 154 exception = es.toDart(args); | |
| 155 goto fail; | |
| 156 } | |
| 157 return; | |
| 158 } | |
| 159 | |
| 160 fail: | |
| 161 Dart_ThrowException(exception); | |
| 162 ASSERT_NOT_REACHED(); | |
| 163 } | |
| 164 | |
| 165 // Fast-path for Document.createElement, when typeExtension is not needed. | |
| 166 void createElement(Dart_NativeArguments args) | |
| 167 { | |
| 168 Dart_Handle exception = 0; | |
| 169 { | |
| 170 Document* receiver = DartDOMWrapper::receiver< Document >(args); | |
| 171 | |
| 172 DartStringAdapter localName = DartUtilities::dartToString(args, 1, excep
tion); | |
| 173 if (exception) | |
| 174 goto fail; | |
| 175 | |
| 176 DartExceptionState es; | |
| 177 RefPtr<Element> result; | |
| 178 { | |
| 179 CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope
; | |
| 180 | |
| 181 result = receiver->createElement(localName, es); | |
| 182 } | |
| 183 DartElement::returnToDart(args, result); | |
| 184 if (es.hadException()) { | |
| 185 exception = es.toDart(args); | |
| 186 goto fail; | |
| 187 } | |
| 188 return; | |
| 189 } | |
| 190 | |
| 191 fail: | |
| 192 Dart_ThrowException(exception); | |
| 193 ASSERT_NOT_REACHED(); | |
| 194 } | |
| 195 | |
| 196 void initializeCustomElement(Dart_NativeArguments args) | |
| 197 { | |
| 198 Dart_Handle exception = 0; | |
| 199 { | |
| 200 Dart_Handle elementWrapper = Dart_GetNativeArgument(args, 0); | |
| 201 if (!DartDOMWrapper::subtypeOf(elementWrapper, DartHTMLElement::dartClas
sId)) { | |
| 202 exception = Dart_NewStringFromCString("created called outside of cus
tom element creation."); | |
| 203 goto fail; | |
| 204 } | |
| 205 DartCustomElementWrapper<HTMLElement>::initializeCustomElement(elementWr
apper, exception); | |
| 206 if (exception) { | |
| 207 goto fail; | |
| 208 } | |
| 209 return; | |
| 210 } | |
| 211 | |
| 212 fail: | |
| 213 Dart_ThrowException(exception); | |
| 214 ASSERT_NOT_REACHED(); | |
| 215 } | |
| 216 | |
| 217 void spawnDomUri(Dart_NativeArguments args) | |
| 218 { | |
| 219 Dart_Handle exception = 0; | |
| 220 | |
| 221 { | |
| 222 ExecutionContext* scriptExecutionContext = DartUtilities::scriptExecutio
nContext(); | |
| 223 ASSERT(scriptExecutionContext); | |
| 224 DartController* dartController = DartController::retrieve(scriptExecutio
nContext); | |
| 225 if (!dartController) | |
| 226 return; | |
| 227 | |
| 228 DartStringAdapter uri = DartUtilities::dartToString(args, 0, exception); | |
| 229 if (exception) | |
| 230 goto fail; | |
| 231 | |
| 232 // TODO(vsm): Return isolate future. | |
| 233 dartController->spawnDomUri(uri); | |
| 234 return; | |
| 235 } | |
| 236 | |
| 237 fail: | |
| 238 Dart_ThrowException(exception); | |
| 239 ASSERT_NOT_REACHED(); | |
| 240 } | |
| 241 | |
| 242 void changeElementWrapper(Dart_NativeArguments args) | |
| 243 { | |
| 244 Dart_Handle exception = 0; | |
| 245 { | |
| 246 Dart_Handle elementWrapper = Dart_GetNativeArgument(args, 0); | |
| 247 if (!DartDOMWrapper::subtypeOf(elementWrapper, DartHTMLElement::dartClas
sId)) { | |
| 248 exception = Dart_NewStringFromCString("Invalid class: expected insta
nce of HtmlElement"); | |
| 249 goto fail; | |
| 250 } | |
| 251 | |
| 252 Dart_Handle wrapperType = Dart_GetNativeArgument(args, 1); | |
| 253 if (!Dart_IsType(wrapperType)) { | |
| 254 exception = Dart_NewStringFromCString("Expected instance of Type"); | |
| 255 goto fail; | |
| 256 } | |
| 257 | |
| 258 Dart_Handle newWrapper = DartCustomElementWrapper<HTMLElement>::changeEl
ementWrapper(elementWrapper, wrapperType); | |
| 259 if (Dart_IsError(newWrapper)) { | |
| 260 exception = newWrapper; | |
| 261 goto fail; | |
| 262 } | |
| 263 Dart_SetReturnValue(args, newWrapper); | |
| 264 return; | |
| 265 } | |
| 266 | |
| 267 fail: | |
| 268 Dart_ThrowException(exception); | |
| 269 ASSERT_NOT_REACHED(); | |
| 270 } | |
| 271 | |
| 272 } // namespace DartNativeUtilitiesInternal | |
| 273 | |
| 274 namespace DartWindowInternal { | |
| 275 | |
| 276 void historyCrossFrameGetter(Dart_NativeArguments); | |
| 277 | |
| 278 void locationCrossFrameGetter(Dart_NativeArguments); | |
| 279 | |
| 280 } | |
| 281 | |
| 282 extern Dart_NativeFunction blinkSnapshotResolver(Dart_Handle name, int argumentC
ount, bool* autoSetupScope); | |
| 283 extern Dart_NativeFunction customDartDOMStringMapResolver(Dart_Handle name, int
argumentCount, bool* autoSetupScope); | |
| 284 | |
| 285 static DartNativeEntry nativeEntries[] = { | |
| 286 { DartNativeUtilitiesInternal::topLevelWindow, 0, "Utils_window" }, | |
| 287 { DartNativeUtilitiesInternal::forwardingPrint, 1, "Utils_forwardingPrint" }
, | |
| 288 { DartNativeUtilitiesInternal::getNewIsolateId, 0, "Utils_getNewIsolateId" }
, | |
| 289 { DartNativeUtilitiesInternal::registerElement, 4, "Utils_register" }, | |
| 290 { DartNativeUtilitiesInternal::createElement, 2, "Utils_createElement" }, | |
| 291 { DartNativeUtilitiesInternal::initializeCustomElement, 1, "Utils_initialize
CustomElement" }, | |
| 292 { DartNativeUtilitiesInternal::changeElementWrapper, 2, "Utils_changeElement
Wrapper" }, | |
| 293 { DartNativeUtilitiesInternal::spawnDomUri, 1, "Utils_spawnDomUri" }, | |
| 294 { DartWindowInternal::historyCrossFrameGetter, 1, "Window_history_cross_fram
e_Getter" }, | |
| 295 { DartWindowInternal::locationCrossFrameGetter, 1, "Window_location_cross_fr
ame_Getter" }, | |
| 296 { 0, 0, 0 }, | |
| 297 }; | |
| 298 | |
| 299 Dart_NativeFunction domIsolateHtmlResolver(Dart_Handle name, int argumentCount,
bool* autoSetupScope) | |
| 300 { | |
| 301 // Some utility functions. | |
| 302 if (Dart_NativeFunction func = blinkSnapshotResolver(name, argumentCount, au
toSetupScope)) | |
| 303 return func; | |
| 304 if (Dart_NativeFunction func = customDartDOMStringMapResolver(name, argument
Count, autoSetupScope)) | |
| 305 return func; | |
| 306 if (Dart_NativeFunction func = JsInterop::resolver(name, argumentCount, auto
SetupScope)) | |
| 307 return func; | |
| 308 | |
| 309 String str = DartUtilities::toString(name); | |
| 310 ASSERT(autoSetupScope); | |
| 311 *autoSetupScope = true; | |
| 312 for (intptr_t i = 0; nativeEntries[i].nativeFunction != 0; i++) { | |
| 313 if (argumentCount == nativeEntries[i].argumentCount && str == nativeEntr
ies[i].name) { | |
| 314 return nativeEntries[i].nativeFunction; | |
| 315 } | |
| 316 } | |
| 317 return 0; | |
| 318 } | |
| 319 | |
| 320 extern const uint8_t* blinkSnapshotSymbolizer(Dart_NativeFunction); | |
| 321 extern const uint8_t* customDartDOMStringMapSymbolizer(Dart_NativeFunction); | |
| 322 | |
| 323 const uint8_t* domIsolateHtmlSymbolizer(Dart_NativeFunction nf) | |
| 324 { | |
| 325 const uint8_t* r = 0; | |
| 326 r = blinkSnapshotSymbolizer(nf); | |
| 327 if (r) { | |
| 328 return r; | |
| 329 } | |
| 330 r = customDartDOMStringMapSymbolizer(nf); | |
| 331 if (r) { | |
| 332 return r; | |
| 333 } | |
| 334 r = JsInterop::symbolizer(nf); | |
| 335 if (r) { | |
| 336 return r; | |
| 337 } | |
| 338 | |
| 339 for (intptr_t i = 0; nativeEntries[i].nativeFunction != 0; i++) { | |
| 340 if (nf == nativeEntries[i].nativeFunction) { | |
| 341 return reinterpret_cast<const uint8_t*>(nativeEntries[i].name); | |
| 342 } | |
| 343 } | |
| 344 | |
| 345 return 0; | |
| 346 } | |
| 347 | |
| 348 | |
| 349 } | |
| OLD | NEW |