-
morrita@google.com authored
https://bugs.webkit.org/show_bug.cgi?id=112538 Reviewed by Elliott Sprehn. Source/WebCore: This change allows each custom element definition to hook up its instantiation, namely "readyCallback" lifecycle callback. The change has two parts: - 1. Tracking which Element objects to be created. - 2. Invoking appropriate JavaScript functions, which are readyCallback(), before the Element object is visible from page script. For 1, CustomElementRegistry maintains list of "callback invocaions". Each list item ("invocation") tracks the element which has a lifecycle callback to be invoked. Each invocation is registered when - Any custom element C++ object is instantiated. See changes on CustomElementConstructor.cpp. This also happens when @is attribute is set by the parser or node cloning routine, which can turn a non-custom element into a type-extended custom element. See changes on Element.cpp. For 2, CustomElementRegistry basically follows what MutationObserver is doing, and introduces a method called deliverLifecycleCallbacks(). This function flushes all pending callback invocations. You can think it as a dual of MutationObserver::deliverAllMutations(). The delivery function is called places where MutationObserver's deliverAllMutations() is called. In addition, it is also called just before returning from a set of DOM APIs. For example, it is called just before createElement() returns, so that possibly created custom element becomes ready through its readyCallback(). Such APIs get "V8DeliverCustomElementCallbacks" IDL attribute. In principle, APIs which can create new custom element instnaces are marked. See CustomElementRegistry::CallbackDeliveryScope and changes on CodeGeneratorV8.pm. We need this extra work because the readyCallback() needs to give an illusion so that JavaScript programmers feel like the readyCallback() callback being called just after it is created, instead of called on arbitrary late timing like MutationObserver notifications. Tests: fast/dom/custom/lifecycle-ready-createElement-recursion.html fast/dom/custom/lifecycle-ready-createElement-reentrancy.html fast/dom/custom/lifecycle-ready-creation-api.html fast/dom/custom/lifecycle-ready-innerHTML.html fast/dom/custom/lifecycle-ready-parser-only.html fast/dom/custom/lifecycle-ready-parser-script.html fast/dom/custom/lifecycle-ready-paste.html * bindings/scripts/CodeGeneratorV8.pm: - Hooked up CallbackDeliveryScope through V8DeliverCustomElementCallbacks attriute. (GenerateCustomElementInvocationScopeIfNeeded): (GenerateNormalAttrSetter): (GenerateFunction): * bindings/scripts/IDLAttributes.txt: * bindings/v8/CustomElementHelpers.cpp: (WebCore::CustomElementHelpers::invokeReadyCallbackIfNeeded): (WebCore::CustomElementHelpers::invokeReadyCallbacksIfNeeded): * bindings/v8/CustomElementHelpers.h: (CustomElementHelpers): * bindings/v8/V8RecursionScope.cpp: Added deliverAllLifecycleCallbacks() (WebCore::V8RecursionScope::didLeaveScriptContext): * dom/CustomElementConstructor.cpp: (WebCore::CustomElementConstructor::createElement): (WebCore::CustomElementConstructor::createElementInternal): * dom/CustomElementConstructor.h: (WebCore::CustomElementConstructor::isExtended): (CustomElementConstructor): * dom/CustomElementRegistry.cpp: Adding element tracking and invocation execution. (WebCore::CustomElementInvocation::CustomElementInvocation): (WebCore::CustomElementInvocation::~CustomElementInvocation): (WebCore::activeCustomElementRegistries): (WebCore::CustomElementRegistry::~CustomElementRegistry): (WebCore::CustomElementRegistry::didGiveTypeExtension): (WebCore::CustomElementRegistry::didCreateElement): (WebCore::CustomElementRegistry::activate): (WebCore::CustomElementRegistry::deactivate): (WebCore::CustomElementRegistry::deliverLifecycleCallbacks): (WebCore::CustomElementRegistry::deliverAllLifecycleCallbacks): * dom/CustomElementRegistry.h: (CustomElementInvocation): (WebCore::CustomElementInvocation::element): (CallbackDeliveryScope): (WebCore::CustomElementRegistry::CallbackDeliveryScope::CallbackDeliveryScope): (WebCore::CustomElementRegistry::CallbackDeliveryScope::~CallbackDeliveryScope): (CustomElementRegistry): (WebCore::CustomElementRegistry::deliverAllLifecycleCallbacksIfNeeded): * dom/Document.cpp: (WebCore::Document::createElement): (WebCore::Document::didCreateCustomElement): * dom/Document.h: (Document): * dom/Document.idl: * dom/Element.cpp: (WebCore::Element::attributeChangedFromParserOrByCloning): Added to catch @is attribute (WebCore::Element::parserSetAttributes): (WebCore::Element::cloneAttributesFromElement): * dom/Element.h: * dom/Node.idl: * dom/ShadowRoot.idl: * html/HTMLElement.idl: * html/parser/HTMLScriptRunner.cpp: Added deliverAllLifecycleCallbacks() (WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent): (WebCore::HTMLScriptRunner::runScript): Source/WebKit/chromium: * src/WebKit.cpp: Added deliverAllLifecycleCallbacks() Source/WTF: * wtf/HashSet.h: (WTF::copyToVector): Generalized to let it accept variants like ListHahsSet instead of only HashSet. LayoutTests: * fast/dom/custom/lifecycle-ready-createElement-recursion-expected.txt: Added. * fast/dom/custom/lifecycle-ready-createElement-recursion.html: Added. * fast/dom/custom/lifecycle-ready-createElement-reentrancy-expected.txt: Added. * fast/dom/custom/lifecycle-ready-createElement-reentrancy.html: Added. * fast/dom/custom/lifecycle-ready-creation-api-expected.txt: Added. * fast/dom/custom/lifecycle-ready-creation-api.html: Added. * fast/dom/custom/lifecycle-ready-innerHTML-expected.txt: Added. * fast/dom/custom/lifecycle-ready-innerHTML.html: Added. * fast/dom/custom/lifecycle-ready-parser-only-expected.html: Added. * fast/dom/custom/lifecycle-ready-parser-only.html: Added. * fast/dom/custom/lifecycle-ready-parser-script-expected.txt: Added. * fast/dom/custom/lifecycle-ready-parser-script.html: Added. * fast/dom/custom/lifecycle-ready-paste-expected.txt: Added. * fast/dom/custom/lifecycle-ready-paste.html: Added. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@146565 268f45cc-cd09-0410-ab3c-d52691b4dbfc
e5501fe8