| 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 |