Custom Elements: "readyCallback" lifecycle callback should be called.
authormorrita@google.com <morrita@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Mar 2013 06:16:07 +0000 (06:16 +0000)
committermorrita@google.com <morrita@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Mar 2013 06:16:07 +0000 (06:16 +0000)
commit1f508da4374695486744c90f565e282a7522be41
tree860ab39576a51aa1b147f0f36220ce3f336dea0d
parent36254736ad4e476db8faf1814b5ff0edbc4fca88
Custom Elements: "readyCallback" lifecycle callback should be called.
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: https://svn.webkit.org/repository/webkit/trunk@146565 268f45cc-cd09-0410-ab3c-d52691b4dbfc
38 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/custom/lifecycle-ready-createElement-recursion-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-createElement-recursion.html [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-createElement-reentrancy-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-createElement-reentrancy.html [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-creation-api-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-creation-api.html [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-innerHTML-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-innerHTML.html [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-parser-only-expected.html [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-parser-only.html [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-parser-script-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-parser-script.html [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-paste-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/custom/lifecycle-ready-paste.html [new file with mode: 0644]
Source/WTF/ChangeLog
Source/WTF/wtf/HashSet.h
Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/CodeGeneratorV8.pm
Source/WebCore/bindings/scripts/IDLAttributes.txt
Source/WebCore/bindings/v8/CustomElementHelpers.cpp
Source/WebCore/bindings/v8/CustomElementHelpers.h
Source/WebCore/bindings/v8/V8RecursionScope.cpp
Source/WebCore/dom/CustomElementConstructor.cpp
Source/WebCore/dom/CustomElementConstructor.h
Source/WebCore/dom/CustomElementRegistry.cpp
Source/WebCore/dom/CustomElementRegistry.h
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/Document.idl
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/Element.h
Source/WebCore/dom/Node.idl
Source/WebCore/dom/ShadowRoot.idl
Source/WebCore/html/HTMLElement.idl
Source/WebCore/html/parser/HTMLScriptRunner.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/WebKit.cpp