Changeset 204611 in webkit


Ignore:
Timestamp:
Aug 18, 2016 3:19:59 PM (8 years ago)
Author:
rniwa@webkit.org
Message:

Add basic support for connected and disconnected callbacks
https://bugs.webkit.org/show_bug.cgi?id=160950

Reviewed by Chris Dumez.

Source/WebCore:

Added the basic support for custom elements' connectedCallback and disconnectedCallback. These callbacks
are enqueued by inserting and removing a node as spec'ed by https://dom.spec.whatwg.org/#concept-node-insert
and https://dom.spec.whatwg.org/#concept-node-remove

For now, we only support callbacks on appendChild and removeChild to limit the amount of code changes and
tests that need to be included in this patch.

This patch also renames InvokesCustomElementLifecycleCallbacks IDL attribute to CEReactions to match
the latest specification: https://html.spec.whatwg.org/multipage/scripting.html#cereactions

Tests: fast/custom-elements/connected-callbacks.html

fast/custom-elements/disconnected-callbacks.html

  • bindings/js/JSCustomElementInterface.cpp:

(WebCore::JSCustomElementInterface::invokeCallback): Extracted from invokeAttributeChangedCallback.
(WebCore::JSCustomElementInterface::setConnectedCallback): Added.
(WebCore::JSCustomElementInterface::invokeConnectedCallback): Added.
(WebCore::JSCustomElementInterface::setDisconnectedCallback): Added.
(WebCore::JSCustomElementInterface::invokeDisconnectedCallback): Added.
(WebCore::JSCustomElementInterface::setAttributeChangedCallback):
(WebCore::JSCustomElementInterface::invokeAttributeChangedCallback): Renamed from attributeChanged.

  • bindings/js/JSCustomElementInterface.h: Added m_connectedCallback and m_disconnectedCallback as instance

variables. Also removed the superfluous mutable qualifier from m_constructor m_attributeChangedCallback.

  • bindings/js/JSCustomElementsRegistryCustom.cpp:

(WebCore::JSCustomElementsRegistry::define): Store connectedCallback and disconnectedCallback.

  • bindings/scripts/CodeGeneratorJS.pm:

(GenerateImplementation):

  • bindings/scripts/IDLAttributes.txt:
  • dom/CustomElementsRegistry.idl:
  • dom/Element.cpp:

(WebCore::Element::insertedInto): Call enqueueConnectedCallbackIfNeeded.
(WebCore::Element::removedFrom): Call enqueueDisconnectedCallbackIfNeeded.

  • dom/Element.idl:
  • dom/LifecycleCallbackQueue.cpp:

(WebCore::LifecycleQueueItem::invoke): Added calls to invokeConnectedCallback and invokeDisconnectedCallback.
(WebCore::findInterfaceForCustomElement): Extracted from enqueueAttributeChangedCallbackIfNeeded.
(WebCore::LifecycleCallbackQueue::enqueueConnectedCallbackIfNeeded): Added.
(WebCore::LifecycleCallbackQueue::enqueueDisconnectedCallbackIfNeeded): Added.
(WebCore::LifecycleCallbackQueue::enqueueAttributeChangedCallbackIfNeeded):
(WebCore::CustomElementLifecycleProcessingStack::ensureCurrentQueue):

  • dom/LifecycleCallbackQueue.h:
  • dom/Node.idl:

LayoutTests:

Added W3C style testharness.js tests for connectedCallback and disconnectedCallback.

Four test cases are failing due to a bug in window-less document's custom element registry,
which will be addressed in a future patch.

  • fast/custom-elements/connected-callbacks-expected.txt: Added.
  • fast/custom-elements/connected-callbacks.html: Added.
  • fast/custom-elements/disconnected-callbacks-expected.txt: Added.
  • fast/custom-elements/disconnected-callbacks.html: Added.
Location:
trunk
Files:
4 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r204605 r204611  
     12016-08-17  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Add basic support for connected and disconnected callbacks
     4        https://bugs.webkit.org/show_bug.cgi?id=160950
     5
     6        Reviewed by Chris Dumez.
     7
     8        Added W3C style testharness.js tests for connectedCallback and disconnectedCallback.
     9
     10        Four test cases are failing due to a bug in window-less document's custom element registry,
     11        which will be addressed in a future patch.
     12
     13        * fast/custom-elements/connected-callbacks-expected.txt: Added.
     14        * fast/custom-elements/connected-callbacks.html: Added.
     15        * fast/custom-elements/disconnected-callbacks-expected.txt: Added.
     16        * fast/custom-elements/disconnected-callbacks.html: Added.
     17
    1182016-08-18  Chris Dumez  <cdumez@apple.com>
    219
  • trunk/Source/WebCore/ChangeLog

    r204610 r204611  
     12016-08-17  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Add basic support for connected and disconnected callbacks
     4        https://bugs.webkit.org/show_bug.cgi?id=160950
     5
     6        Reviewed by Chris Dumez.
     7
     8        Added the basic support for custom elements' connectedCallback and disconnectedCallback. These callbacks
     9        are enqueued by inserting and removing a node as spec'ed by https://dom.spec.whatwg.org/#concept-node-insert
     10        and https://dom.spec.whatwg.org/#concept-node-remove
     11
     12        For now, we only support callbacks on appendChild and removeChild to limit the amount of code changes and
     13        tests that need to be included in this patch.
     14
     15        This patch also renames InvokesCustomElementLifecycleCallbacks IDL attribute to CEReactions to match
     16        the latest specification: https://html.spec.whatwg.org/multipage/scripting.html#cereactions
     17
     18        Tests: fast/custom-elements/connected-callbacks.html
     19               fast/custom-elements/disconnected-callbacks.html
     20
     21        * bindings/js/JSCustomElementInterface.cpp:
     22        (WebCore::JSCustomElementInterface::invokeCallback): Extracted from invokeAttributeChangedCallback.
     23        (WebCore::JSCustomElementInterface::setConnectedCallback): Added.
     24        (WebCore::JSCustomElementInterface::invokeConnectedCallback): Added.
     25        (WebCore::JSCustomElementInterface::setDisconnectedCallback): Added.
     26        (WebCore::JSCustomElementInterface::invokeDisconnectedCallback): Added.
     27        (WebCore::JSCustomElementInterface::setAttributeChangedCallback):
     28        (WebCore::JSCustomElementInterface::invokeAttributeChangedCallback): Renamed from attributeChanged.
     29        * bindings/js/JSCustomElementInterface.h: Added m_connectedCallback and m_disconnectedCallback as instance
     30        variables. Also removed the superfluous mutable qualifier from m_constructor m_attributeChangedCallback.
     31        * bindings/js/JSCustomElementsRegistryCustom.cpp:
     32        (WebCore::JSCustomElementsRegistry::define): Store connectedCallback and disconnectedCallback.
     33        * bindings/scripts/CodeGeneratorJS.pm:
     34        (GenerateImplementation):
     35        * bindings/scripts/IDLAttributes.txt:
     36        * dom/CustomElementsRegistry.idl:
     37        * dom/Element.cpp:
     38        (WebCore::Element::insertedInto): Call enqueueConnectedCallbackIfNeeded.
     39        (WebCore::Element::removedFrom): Call enqueueDisconnectedCallbackIfNeeded.
     40        * dom/Element.idl:
     41        * dom/LifecycleCallbackQueue.cpp:
     42        (WebCore::LifecycleQueueItem::invoke): Added calls to invokeConnectedCallback and invokeDisconnectedCallback.
     43        (WebCore::findInterfaceForCustomElement): Extracted from enqueueAttributeChangedCallbackIfNeeded.
     44        (WebCore::LifecycleCallbackQueue::enqueueConnectedCallbackIfNeeded): Added.
     45        (WebCore::LifecycleCallbackQueue::enqueueDisconnectedCallbackIfNeeded): Added.
     46        (WebCore::LifecycleCallbackQueue::enqueueAttributeChangedCallbackIfNeeded):
     47        (WebCore::CustomElementLifecycleProcessingStack::ensureCurrentQueue):
     48        * dom/LifecycleCallbackQueue.h:
     49        * dom/Node.idl:
     50
    1512016-08-18  Beth Dakin  <bdakin@apple.com>
    252
  • trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp

    r204553 r204611  
    152152}
    153153
     154void JSCustomElementInterface::invokeCallback(Element& element, JSObject* callback, const Function<void(ExecState*, MarkedArgumentBuffer&)>& addArguments)
     155{
     156    if (!canInvokeCallback())
     157        return;
     158
     159    auto* context = scriptExecutionContext();
     160    if (!context)
     161        return;
     162
     163    Ref<JSCustomElementInterface> protectedThis(*this);
     164    JSLockHolder lock(m_isolatedWorld->vm());
     165
     166    ASSERT(context);
     167    ASSERT(context->isDocument());
     168    JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, *m_isolatedWorld);
     169    ExecState* state = globalObject->globalExec();
     170
     171    JSObject* jsElement = asObject(toJS(state, globalObject, element));
     172
     173    CallData callData;
     174    CallType callType = callback->methodTable()->getCallData(callback, callData);
     175    ASSERT(callType != CallType::None);
     176
     177    MarkedArgumentBuffer args;
     178    addArguments(state, args);
     179
     180    InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(context, callType, callData);
     181
     182    NakedPtr<Exception> exception;
     183    JSMainThreadExecState::call(state, callback, callType, callData, jsElement, args, exception);
     184
     185    InspectorInstrumentation::didCallFunction(cookie, context);
     186
     187    if (exception)
     188        reportException(state, exception);
     189}
     190
     191void JSCustomElementInterface::setConnectedCallback(JSC::JSObject* callback)
     192{
     193    m_connectedCallback = callback;
     194}
     195
     196void JSCustomElementInterface::invokeConnectedCallback(Element& element)
     197{
     198    invokeCallback(element, m_connectedCallback.get());
     199}
     200
     201void JSCustomElementInterface::setDisconnectedCallback(JSC::JSObject* callback)
     202{
     203    m_disconnectedCallback = callback;
     204}
     205
     206void JSCustomElementInterface::invokeDisconnectedCallback(Element& element)
     207{
     208    invokeCallback(element, m_disconnectedCallback.get());
     209}
     210
    154211void JSCustomElementInterface::setAttributeChangedCallback(JSC::JSObject* callback, const Vector<String>& observedAttributes)
    155212{
     
    160217}
    161218
    162 void JSCustomElementInterface::attributeChanged(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
    163 {
    164     if (!canInvokeCallback())
    165         return;
    166 
    167     Ref<JSCustomElementInterface> protectedThis(*this);
    168 
    169     JSLockHolder lock(m_isolatedWorld->vm());
    170 
    171     ScriptExecutionContext* context = scriptExecutionContext();
    172     if (!context)
    173         return;
    174 
    175     ASSERT(context->isDocument());
    176     JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, *m_isolatedWorld);
    177     ExecState* state = globalObject->globalExec();
    178 
    179     JSObject* jsElement = asObject(toJS(state, globalObject, element));
    180 
    181     CallData callData;
    182     CallType callType = m_attributeChangedCallback->methodTable()->getCallData(m_attributeChangedCallback.get(), callData);
    183     ASSERT(callType != CallType::None);
    184 
    185     const AtomicString& namespaceURI = attributeName.namespaceURI();
    186     MarkedArgumentBuffer args;
    187     args.append(jsStringWithCache(state, attributeName.localName()));
    188     args.append(oldValue == nullAtom ? jsNull() : jsStringWithCache(state, oldValue));
    189     args.append(newValue == nullAtom ? jsNull() : jsStringWithCache(state, newValue));
    190     args.append(namespaceURI == nullAtom ? jsNull() : jsStringWithCache(state, attributeName.namespaceURI()));
    191 
    192     InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(context, callType, callData);
    193 
    194     NakedPtr<Exception> exception;
    195     JSMainThreadExecState::call(state, m_attributeChangedCallback.get(), callType, callData, jsElement, args, exception);
    196 
    197     InspectorInstrumentation::didCallFunction(cookie, context);
    198 
    199     if (exception)
    200         reportException(state, exception);
    201 }
    202    
     219void JSCustomElementInterface::invokeAttributeChangedCallback(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
     220{
     221    invokeCallback(element, m_attributeChangedCallback.get(), [&](ExecState* state, MarkedArgumentBuffer& args) {
     222        args.append(jsStringWithCache(state, attributeName.localName()));
     223        args.append(jsStringOrNull(state, oldValue));
     224        args.append(jsStringOrNull(state, newValue));
     225        args.append(jsStringOrNull(state, attributeName.namespaceURI()));
     226    });
     227}
     228
    203229void JSCustomElementInterface::didUpgradeLastElementInConstructionStack()
    204230{
  • trunk/Source/WebCore/bindings/js/JSCustomElementInterface.h

    r204553 r204611  
    3636#include <runtime/JSObject.h>
    3737#include <wtf/Forward.h>
     38#include <wtf/Function.h>
    3839#include <wtf/RefCounted.h>
    3940#include <wtf/RefPtr.h>
     
    6768    void upgradeElement(Element&);
    6869
     70    void setConnectedCallback(JSC::JSObject*);
     71    void invokeConnectedCallback(Element&);
     72
     73    void setDisconnectedCallback(JSC::JSObject*);
     74    void invokeDisconnectedCallback(Element&);
     75
    6976    void setAttributeChangedCallback(JSC::JSObject* callback, const Vector<String>& observedAttributes);
    7077    bool observesAttribute(const AtomicString& name) const { return m_observedAttributes.contains(name); }
    71     void attributeChanged(Element&, const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
     78    void invokeAttributeChangedCallback(Element&, const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
    7279
    7380    ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); }
     
    8592    JSCustomElementInterface(const QualifiedName&, JSC::JSObject* callback, JSDOMGlobalObject*);
    8693
     94    void invokeCallback(Element&, JSC::JSObject* callback, const Function<void(JSC::ExecState*, JSC::MarkedArgumentBuffer&)>& addArguments = {});
     95
    8796    QualifiedName m_name;
    88     mutable JSC::Weak<JSC::JSObject> m_constructor;
    89     mutable JSC::Weak<JSC::JSObject> m_attributeChangedCallback;
     97    JSC::Weak<JSC::JSObject> m_constructor;
     98    JSC::Weak<JSC::JSObject> m_connectedCallback;
     99    JSC::Weak<JSC::JSObject> m_disconnectedCallback;
     100    JSC::Weak<JSC::JSObject> m_attributeChangedCallback;
    90101    RefPtr<DOMWrapperWorld> m_isolatedWorld;
    91102    Vector<RefPtr<Element>, 1> m_constructionStack;
  • trunk/Source/WebCore/bindings/js/JSCustomElementsRegistryCustom.cpp

    r204553 r204611  
    105105    JSObject& prototypeObject = *asObject(prototypeValue);
    106106
    107     // FIXME: Add the support for connectedCallback.
    108     getLifecycleCallback(state, prototypeObject, Identifier::fromString(&vm, "connectedCallback"));
     107    QualifiedName name(nullAtom, localName, HTMLNames::xhtmlNamespaceURI);
     108    auto elementInterface = JSCustomElementInterface::create(name, constructor, globalObject());
     109
     110    auto* connectedCallback = getLifecycleCallback(state, prototypeObject, Identifier::fromString(&vm, "connectedCallback"));
    109111    if (state.hadException())
    110112        return jsUndefined();
     113    if (connectedCallback)
     114        elementInterface->setConnectedCallback(connectedCallback);
    111115
    112     // FIXME: Add the support for disconnectedCallback.
    113     getLifecycleCallback(state, prototypeObject, Identifier::fromString(&vm, "disconnectedCallback"));
     116    auto* disconnectedCallback = getLifecycleCallback(state, prototypeObject, Identifier::fromString(&vm, "disconnectedCallback"));
    114117    if (state.hadException())
    115118        return jsUndefined();
     119    if (disconnectedCallback)
     120        elementInterface->setDisconnectedCallback(disconnectedCallback);
    116121
    117122    // FIXME: Add the support for adoptedCallback.
     
    119124    if (state.hadException())
    120125        return jsUndefined();
    121 
    122     QualifiedName name(nullAtom, localName, HTMLNames::xhtmlNamespaceURI);
    123     auto elementInterface = JSCustomElementInterface::create(name, constructor, globalObject());
    124126
    125127    auto* attributeChangedCallback = getLifecycleCallback(state, prototypeObject, Identifier::fromString(&vm, "attributeChangedCallback"));
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r204589 r204611  
    33413341            $implIncludes{"<runtime/Error.h>"} = 1;
    33423342
    3343             if ($function->signature->extendedAttributes->{"InvokesCustomElementLifecycleCallbacks"}) {
     3343            if ($function->signature->extendedAttributes->{"CEReactions"}) {
    33443344                push(@implContent, "#if ENABLE(CUSTOM_ELEMENTS)\n");
    33453345                push(@implContent, "    CustomElementLifecycleProcessingStack customElementLifecycleProcessingStack;\n");
  • trunk/Source/WebCore/bindings/scripts/IDLAttributes.txt

    r204481 r204611  
    2222AppleCopyright
    2323AtomicString
     24CEReactions
    2425CachedAttribute
    2526CallbackNeedsOperatorEqual
     
    9293MasqueradesAsUndefined
    9394NamedConstructor=*
    94 InvokesCustomElementLifecycleCallbacks
    9595NewImpurePropertyFiresWatchpoints
    9696NewObject
  • trunk/Source/WebCore/dom/CustomElementsRegistry.idl

    r204367 r204611  
    3030] interface CustomElementsRegistry {
    3131
    32     [InvokesCustomElementLifecycleCallbacks, Custom] void define(DOMString name, Function constructor);
     32    [CEReactions, Custom] void define(DOMString name, Function constructor);
    3333
    3434};
  • trunk/Source/WebCore/dom/Element.cpp

    r204594 r204611  
    15971597    }
    15981598
     1599#if ENABLE(CUSTOM_ELEMENTS)
     1600    if (newDocument && UNLIKELY(isCustomElement()))
     1601        LifecycleCallbackQueue::enqueueConnectedCallbackIfNeeded(*this);
     1602#endif
     1603
    15991604    return InsertionDone;
    16001605}
     
    16421647                updateLabel(*oldScope, attributeWithoutSynchronization(forAttr), nullAtom);
    16431648        }
     1649
     1650#if ENABLE(CUSTOM_ELEMENTS)
     1651        if (oldDocument && UNLIKELY(isCustomElement()))
     1652            LifecycleCallbackQueue::enqueueDisconnectedCallbackIfNeeded(*this);
     1653#endif
    16441654    }
    16451655
  • trunk/Source/WebCore/dom/Element.idl

    r204594 r204611  
    3232    DOMString? getAttribute(DOMString name);
    3333
    34     [ObjCLegacyUnnamedParameters, RaisesException, InvokesCustomElementLifecycleCallbacks]
    35 
    36     void setAttribute(DOMString name, DOMString value);
    37 
    38     [InvokesCustomElementLifecycleCallbacks] void removeAttribute(DOMString name);
     34    [ObjCLegacyUnnamedParameters, RaisesException, CEReactions] void setAttribute(DOMString name, DOMString value);
     35
     36    [CEReactions] void removeAttribute(DOMString name);
    3937    Attr? getAttributeNode(DOMString name);
    4038
    41     [RaisesException, InvokesCustomElementLifecycleCallbacks] Attr? setAttributeNode(Attr newAttr);
    42     [RaisesException, InvokesCustomElementLifecycleCallbacks] Attr removeAttributeNode(Attr oldAttr);
     39    [RaisesException, CEReactions] Attr? setAttributeNode(Attr newAttr);
     40    [RaisesException, CEReactions] Attr removeAttributeNode(Attr oldAttr);
    4341
    4442    HTMLCollection getElementsByTagName(DOMString name);
     
    5149    [ObjCLegacyUnnamedParameters] DOMString? getAttributeNS(DOMString? namespaceURI, DOMString localName);
    5250
    53     [ObjCLegacyUnnamedParameters, RaisesException, InvokesCustomElementLifecycleCallbacks]
    54 
    55     void setAttributeNS(DOMString? namespaceURI, DOMString qualifiedName, DOMString value);
    56 
    57     [ObjCLegacyUnnamedParameters, InvokesCustomElementLifecycleCallbacks] void removeAttributeNS(DOMString? namespaceURI, DOMString localName);
     51    [ObjCLegacyUnnamedParameters, RaisesException, CEReactions] void setAttributeNS(DOMString? namespaceURI, DOMString qualifiedName, DOMString value);
     52
     53    [ObjCLegacyUnnamedParameters, CEReactions] void removeAttributeNS(DOMString? namespaceURI, DOMString localName);
    5854
    5955    HTMLCollection getElementsByTagNameNS(DOMString? namespaceURI, DOMString localName);
    6056
    6157    [ObjCLegacyUnnamedParameters] Attr? getAttributeNodeNS(DOMString? namespaceURI, DOMString localName);
    62     [RaisesException, InvokesCustomElementLifecycleCallbacks] Attr? setAttributeNodeNS(Attr newAttr);
     58    [RaisesException, CEReactions] Attr? setAttributeNodeNS(Attr newAttr);
    6359    boolean hasAttribute(DOMString name);
    6460
  • trunk/Source/WebCore/dom/LifecycleCallbackQueue.cpp

    r204553 r204611  
    4545    enum class Type {
    4646        ElementUpgrade,
     47        Connected,
     48        Disconnected,
    4749        AttributeChanged,
    4850    };
     
    6971            m_interface->upgradeElement(m_element.get());
    7072            break;
     73        case Type::Connected:
     74            m_interface->invokeConnectedCallback(m_element.get());
     75            break;
     76        case Type::Disconnected:
     77            m_interface->invokeDisconnectedCallback(m_element.get());
     78            break;
    7179        case Type::AttributeChanged:
    7280            ASSERT(m_attributeName);
    73             m_interface->attributeChanged(m_element.get(), m_attributeName.value(), m_oldValue, m_newValue);
     81            m_interface->invokeAttributeChangedCallback(m_element.get(), m_attributeName.value(), m_oldValue, m_newValue);
    7482            break;
    7583        }
     
    99107}
    100108
    101 void LifecycleCallbackQueue::enqueueAttributeChangedCallbackIfNeeded(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
     109static JSCustomElementInterface* findInterfaceForCustomElement(Element& element)
    102110{
    103111    ASSERT(element.isCustomElement());
    104112    auto* window = element.document().domWindow();
    105113    if (!window)
    106         return;
     114        return nullptr;
    107115
    108116    auto* registry = window->customElementsRegistry();
    109117    if (!registry)
    110         return;
     118        return nullptr;
    111119
    112     auto* elementInterface = registry->findInterface(element.tagQName());
    113     if (!elementInterface->observesAttribute(attributeName.localName()))
     120    return registry->findInterface(element.tagQName());
     121}
     122
     123void LifecycleCallbackQueue::enqueueConnectedCallbackIfNeeded(Element& element)
     124{
     125    auto* elementInterface = findInterfaceForCustomElement(element);
     126    if (!elementInterface)
    114127        return;
    115128
    116129    if (auto* queue = CustomElementLifecycleProcessingStack::ensureCurrentQueue())
    117         queue->m_items.append(LifecycleQueueItem(element, *elementInterface, attributeName, oldValue, newValue));
     130        queue->m_items.append({LifecycleQueueItem::Type::Connected, element, *elementInterface});
     131}
     132
     133void LifecycleCallbackQueue::enqueueDisconnectedCallbackIfNeeded(Element& element)
     134{
     135    auto* elementInterface = findInterfaceForCustomElement(element);
     136    if (!elementInterface)
     137        return;
     138
     139    if (auto* queue = CustomElementLifecycleProcessingStack::ensureCurrentQueue())
     140        queue->m_items.append({LifecycleQueueItem::Type::Disconnected, element, *elementInterface});
     141}
     142
     143void LifecycleCallbackQueue::enqueueAttributeChangedCallbackIfNeeded(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
     144{
     145    auto* elementInterface = findInterfaceForCustomElement(element);
     146    if (!elementInterface || !elementInterface->observesAttribute(attributeName.localName()))
     147        return;
     148
     149    if (auto* queue = CustomElementLifecycleProcessingStack::ensureCurrentQueue())
     150        queue->m_items.append({element, *elementInterface, attributeName, oldValue, newValue});
    118151}
    119152
     
    128161LifecycleCallbackQueue* CustomElementLifecycleProcessingStack::ensureCurrentQueue()
    129162{
    130     // FIXME: This early exit indicates a bug that some DOM API is missing InvokesCustomElementLifecycleCallbacks
     163    // FIXME: This early exit indicates a bug that some DOM API is missing CEReactions
    131164    if (!s_currentProcessingStack)
    132165        return nullptr;
  • trunk/Source/WebCore/dom/LifecycleCallbackQueue.h

    r204553 r204611  
    4747
    4848    static void enqueueElementUpgrade(Element&, JSCustomElementInterface&);
     49    static void enqueueConnectedCallbackIfNeeded(Element&);
     50    static void enqueueDisconnectedCallbackIfNeeded(Element&);
    4951    static void enqueueAttributeChangedCallbackIfNeeded(Element&, const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
    5052
  • trunk/Source/WebCore/dom/Node.idl

    r204259 r204611  
    11/*
    2  * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
    33 * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
    44 *
     
    5858    [ObjCLegacyUnnamedParameters, Custom, RaisesException] Node insertBefore([CustomReturn] Node newChild, Node? refChild);
    5959    [ObjCLegacyUnnamedParameters, Custom, RaisesException] Node replaceChild(Node newChild, [CustomReturn] Node oldChild);
    60     [Custom, RaisesException] Node removeChild([CustomReturn] Node oldChild);
    61     [Custom, RaisesException] Node appendChild([CustomReturn] Node newChild);
     60    [Custom, RaisesException, CEReactions] Node removeChild([CustomReturn] Node oldChild);
     61    [Custom, RaisesException, CEReactions] Node appendChild([CustomReturn] Node newChild);
    6262
    6363    boolean            hasChildNodes();
    6464
    65     [NewObject, RaisesException, ImplementedAs=cloneNodeForBindings, InvokesCustomElementLifecycleCallbacks]
    66     Node cloneNode(optional boolean deep = false);
     65    [NewObject, RaisesException, ImplementedAs=cloneNodeForBindings, CEReactions] Node cloneNode(optional boolean deep = false);
    6766
    6867    void               normalize();
Note: See TracChangeset for help on using the changeset viewer.