Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Unified Diff: Source/bindings/core/dart/DartJsInterop.cpp

Issue 1908423004: Fix switching interceptor if element needs to upgraded after custom element is registered (Closed) Base URL: https://chromium.googlesource.com/dart/dartium/blink@2454_1
Patch Set: Merged Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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" },
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698