| Index: Source/bindings/core/dart/DartJsInterop.cpp
|
| diff --git a/Source/bindings/core/dart/DartJsInterop.cpp b/Source/bindings/core/dart/DartJsInterop.cpp
|
| index 7d6498dc64925223ce02e25b1cf395316bb3d055..408e0e10f0fa89366a809d57a7b72d37708f5ff2 100644
|
| --- a/Source/bindings/core/dart/DartJsInterop.cpp
|
| +++ b/Source/bindings/core/dart/DartJsInterop.cpp
|
| @@ -759,6 +759,10 @@ Dart_Handle JsObject::createTyped(v8::Local<v8::Object> object, DartDOMData* dom
|
| Dart_Handle wrapper = DartDOMWrapper::createWrapperForType<JsObject>(domData, jsObject.get(), JsObject::dartClassId, interceptorData->m_type);
|
|
|
| if (interceptorData->m_isCustomElement) {
|
| + // Need to cache immediately in case we call back and forth between Dart and JS.
|
| + ASSERT(Dart_IsInstance(wrapper));
|
| + cache->m_typedInterop = Dart_NewPersistentHandle(wrapper);
|
| +
|
| Dart_Handle ret = Dart_InvokeConstructor(wrapper, Dart_NewStringFromCString("created"), 0, 0);
|
| if (Dart_IsError(ret)) {
|
| DartUtilities::reportProblem(domData->scriptExecutionContext(), ret);
|
| @@ -772,18 +776,21 @@ Dart_Handle JsObject::createTyped(v8::Local<v8::Object> object, DartDOMData* dom
|
| // We need a fresh JsObject to create a new DOM wrapper.
|
| jsObject = JsObject::create(object, v8Isolate);
|
| wrapper = DartDOMWrapper::createWrapperForType<JsObject>(domData, jsObject.get(), JsObject::dartClassId, domData->htmlElementType());
|
| + // Need to cache immediately in case we call back and forth between Dart and JS.
|
| + ASSERT(Dart_IsInstance(wrapper));
|
| + cache->m_typedInterop = Dart_NewPersistentHandle(wrapper);
|
| }
|
| + } else {
|
| + // Simulate the behavior of the Dart dev compiler where new List() is
|
| + // equivalent to a JavaScript array. We accomplish this by creating a
|
| + // JavaScript object that fakes that it is a JavaScript array but is
|
| + // actually backed by a Dart list. This is not a breaking change as
|
| + // existing Dart-JS interop passed arrays as opaque Dart handles.
|
| + // The jsify method can still be called if you wish to create a copy
|
| + // of a json like Dart data structure.
|
| + ASSERT(Dart_IsInstance(wrapper));
|
| + cache->m_typedInterop = Dart_NewPersistentHandle(wrapper);
|
| }
|
| -
|
| - ASSERT(Dart_IsInstance(wrapper));
|
| - // Simulate the behavior of the Dart dev compiler where new List() is
|
| - // equivalent to a JavaScript array. We accomplish this by creating a
|
| - // JavaScript object that fakes that it is a JavaScript array but is
|
| - // actually backed by a Dart list. This is not a breaking change as
|
| - // existing Dart-JS interop passed arrays as opaque Dart handles.
|
| - // The jsify method can still be called if you wish to create a copy
|
| - // of a json like Dart data structure.
|
| - cache->m_typedInterop = Dart_NewPersistentHandle(wrapper);
|
| return wrapper;
|
| }
|
|
|
| @@ -1697,6 +1704,64 @@ fail:
|
| ASSERT_NOT_REACHED();
|
| }
|
|
|
| +// Callback to force an instance to adopt a a specific custom element type.
|
| +// Element accessed before custom class registerElement called. After which
|
| +// each element with 'is' attribute custom type createdCallback is called with
|
| +// the element to upgrade.
|
| +static void setInstanceInterceptorCustomUpgradeCallback(Dart_NativeArguments args)
|
| +{
|
| + Dart_Handle exception = 0;
|
| + {
|
| + DartDOMData* domData = static_cast<DartDOMData*>(Dart_GetNativeIsolateData(args));
|
| + auto v8Isolate = domData->v8Isolate();
|
| + v8::Local<v8::Context> context = domData->v8Context();
|
| + JsInteropScopes scopes(args, context);
|
| + JsObject* jsObject = toJsObject(args, 0, exception);
|
| + if (exception)
|
| + goto fail;
|
| + v8::Local<v8::Object> v8Object = jsObject->localV8Object(v8Isolate);
|
| + if (scopes.handleJsException(&exception))
|
| + goto fail;
|
| +
|
| + // Get the type of the element (check to see if the interceptor is the
|
| + // CustomElementType).
|
| + Dart_Handle arg0 = Dart_GetNativeArgument(args, 0);
|
| + Dart_Handle dartType = Dart_InstanceGetType(arg0);
|
| + ASSERT(Dart_IsType(dartType));
|
| + Dart_Handle instanceType = Dart_TypeName(dartType);
|
| +
|
| + // Get the interceptor
|
| + auto cache = domData->m_dartHandles.get(v8Object, v8Isolate);
|
| + InterceptorData* interceptor = jsObject->computeInterceptor(v8Object, domData, cache);
|
| +
|
| + // Get the interceptor's custom element type.
|
| + Dart_Handle interceptorType = Dart_HandleFromPersistent(interceptor->m_type);
|
| + ASSERT(Dart_IsType(interceptorType));
|
| + Dart_Handle customType = Dart_TypeName(interceptorType);
|
| + ASSERT(Dart_IsType(customType));
|
| +
|
| + bool equal = false;
|
| + Dart_ObjectEquals(instanceType, customType, &equal);
|
| + if (!equal) {
|
| + // Type of the instance isn't the same as the custom element type so
|
| + // then we must change the interceptor. Upgrade to the registered
|
| + // element.
|
| + RELEASE_ASSERT(interceptor->m_isCustomElement);
|
| + cache->m_typedInterop = 0; // Clear existing handle.
|
| + scopes.setReturnValue(JsObject::createTyped(v8Object, domData, interceptor, cache));
|
| +
|
| + if (scopes.handleJsException(&exception))
|
| + goto fail;
|
| + }
|
| + return;
|
| + }
|
| +
|
| +fail:
|
| + Dart_ThrowException(exception);
|
| + ASSERT_NOT_REACHED();
|
| +}
|
| +
|
| +
|
| static void callMethodCallbackHelper(Dart_NativeArguments args, bool legacy)
|
| {
|
| Dart_Handle exception = 0;
|
| @@ -2386,6 +2451,7 @@ static DartNativeEntry nativeEntries[] = {
|
| { JsInteropInternal::defineInterceptorCustomElementCallback, 2, "Utils_defineInterceptorCustomElement" },
|
| { JsInteropInternal::defineInterceptorCallback, 2, "Utils_defineInterceptor" },
|
| { JsInteropInternal::setInstanceInterceptorCallback, 3, "Utils_setInstanceInterceptor" },
|
| + { JsInteropInternal::setInstanceInterceptorCustomUpgradeCallback, 1, "Utils_setInstanceInterceptorCustomUpgrade" },
|
| { JsInteropInternal::initializeCustomElement, 1, "Utils_initializeCustomElement" },
|
|
|
| { JsInteropInternal::toTypedObjectCallback, 1, "JSNative_toTypedObject" },
|
|
|