Changeset 205085 in webkit


Ignore:
Timestamp:
Aug 27, 2016 3:13:44 PM (8 years ago)
Author:
rniwa@webkit.org
Message:

Source/WebCore:
Add adopted callback for custom elements
https://bugs.webkit.org/show_bug.cgi?id=161284

Reviewed by Antti Koivisto.

Added the support for adoptedCallback: https://dom.spec.whatwg.org/#concept-node-adopt
For now, we only support this callback on appendChild.

Test: fast/custom-elements/adopted-callback.html

  • bindings/js/JSCustomElementInterface.cpp:

(WebCore::JSCustomElementInterface::invokeCallback): Added JSDOMGlobalObject* as an argument to the callback so that
we can invoke toJS on Document in invokeAdoptedCallback.
(WebCore::JSCustomElementInterface::setAdoptedCallback): Added.
(WebCore::JSCustomElementInterface::invokeAdoptedCallback): Added.
(WebCore::JSCustomElementInterface::setAttributeChangedCallback):

  • bindings/js/JSCustomElementInterface.h:

(WebCore::JSCustomElementInterface::hasConnectedCallback): Added.
(WebCore::JSCustomElementInterface::hasDisconnectedCallback): Added.
(WebCore::JSCustomElementInterface::hasAdoptedCallback): Added.

  • bindings/js/JSCustomElementRegistryCustom.cpp:

(WebCore::JSCustomElementRegistry::define):

  • dom/CustomElementReactionQueue.cpp:

(WebCore::CustomElementReactionQueueItem::CustomElementReactionQueueItem): Added a variant that takes two documents.
(WebCore::CustomElementReactionQueueItem::invoke):
(WebCore::CustomElementReactionQueue::enqueueConnectedCallbackIfNeeded): Fixed a bug that this function was always
enqueuing a callback even when the interface didn't have connectedCallback. Also, there is no need to check
the nullity of the interface since it should never be null.
(WebCore::CustomElementReactionQueue::enqueueDisconnectedCallbackIfNeeded): Ditto.
(WebCore::CustomElementReactionQueue::enqueueAdoptedCallbackIfNeeded): Added.
(WebCore::CustomElementReactionQueue::enqueueAttributeChangedCallbackIfNeeded): Assert that the interface is never
null instead of exiting early.

  • dom/CustomElementReactionQueue.h:
  • dom/Element.cpp:

(WebCore::Element::didMoveToNewDocument): Added a call to enqueueAdoptedCallbackIfNeeded.

LayoutTests:
adoptcallback

Add adopted callback for custom elements
https://bugs.webkit.org/show_bug.cgi?id=161284

Reviewed by Antti Koivisto.

  • fast/custom-elements/adopted-callback-expected.txt: Added.
  • fast/custom-elements/adopted-callback.html: Added.
  • fast/custom-elements/resources/document-types.js:

(const.DocumentTypes.create):

Location:
trunk
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r205083 r205085  
     12016-08-27  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        adoptcallback
     4
     5        Add adopted callback for custom elements
     6        https://bugs.webkit.org/show_bug.cgi?id=161284
     7
     8        Reviewed by Antti Koivisto.
     9
     10        * fast/custom-elements/adopted-callback-expected.txt: Added.
     11        * fast/custom-elements/adopted-callback.html: Added.
     12        * fast/custom-elements/resources/document-types.js:
     13        (const.DocumentTypes.create):
     14
    1152016-08-27  Youenn Fablet  <youenn@apple.com>
    216
  • trunk/LayoutTests/fast/custom-elements/resources/document-types.js

    r205060 r205085  
    22    {
    33        name: 'document',
    4         create: function () { return Promise.resolve(document); }
     4        create: function () { return Promise.resolve(document); },
     5        isOwner: true,
    56    },
    67    {
  • trunk/Source/WebCore/ChangeLog

    r205084 r205085  
     12016-08-27  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Add adopted callback for custom elements
     4        https://bugs.webkit.org/show_bug.cgi?id=161284
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Added the support for adoptedCallback: https://dom.spec.whatwg.org/#concept-node-adopt
     9        For now, we only support this callback on appendChild.
     10
     11        Test: fast/custom-elements/adopted-callback.html
     12
     13        * bindings/js/JSCustomElementInterface.cpp:
     14        (WebCore::JSCustomElementInterface::invokeCallback): Added JSDOMGlobalObject* as an argument to the callback so that
     15        we can invoke toJS on Document in invokeAdoptedCallback.
     16        (WebCore::JSCustomElementInterface::setAdoptedCallback): Added.
     17        (WebCore::JSCustomElementInterface::invokeAdoptedCallback): Added.
     18        (WebCore::JSCustomElementInterface::setAttributeChangedCallback):
     19        * bindings/js/JSCustomElementInterface.h:
     20        (WebCore::JSCustomElementInterface::hasConnectedCallback): Added.
     21        (WebCore::JSCustomElementInterface::hasDisconnectedCallback): Added.
     22        (WebCore::JSCustomElementInterface::hasAdoptedCallback): Added.
     23        * bindings/js/JSCustomElementRegistryCustom.cpp:
     24        (WebCore::JSCustomElementRegistry::define):
     25        * dom/CustomElementReactionQueue.cpp:
     26        (WebCore::CustomElementReactionQueueItem::CustomElementReactionQueueItem): Added a variant that takes two documents.
     27        (WebCore::CustomElementReactionQueueItem::invoke):
     28        (WebCore::CustomElementReactionQueue::enqueueConnectedCallbackIfNeeded): Fixed a bug that this function was always
     29        enqueuing a callback even when the interface didn't have connectedCallback. Also, there is no need to check
     30        the nullity of the interface since it should never be null.
     31        (WebCore::CustomElementReactionQueue::enqueueDisconnectedCallbackIfNeeded): Ditto.
     32        (WebCore::CustomElementReactionQueue::enqueueAdoptedCallbackIfNeeded): Added.
     33        (WebCore::CustomElementReactionQueue::enqueueAttributeChangedCallbackIfNeeded): Assert that the interface is never
     34        null instead of exiting early.
     35        * dom/CustomElementReactionQueue.h:
     36        * dom/Element.cpp:
     37        (WebCore::Element::didMoveToNewDocument): Added a call to enqueueAdoptedCallbackIfNeeded.
     38
    1392016-08-27  Yoshiaki Jitsukawa  <Yoshiaki.Jitsukawa@sony.com>
    240
  • trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp

    r205060 r205085  
    151151}
    152152
    153 void JSCustomElementInterface::invokeCallback(Element& element, JSObject* callback, const WTF::Function<void(ExecState*, MarkedArgumentBuffer&)>& addArguments)
     153void JSCustomElementInterface::invokeCallback(Element& element, JSObject* callback, const WTF::Function<void(ExecState*, JSDOMGlobalObject*, MarkedArgumentBuffer&)>& addArguments)
    154154{
    155155    if (!canInvokeCallback())
     
    175175
    176176    MarkedArgumentBuffer args;
    177     addArguments(state, args);
     177    addArguments(state, globalObject, args);
    178178
    179179    InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(context, callType, callData);
     
    206206{
    207207    invokeCallback(element, m_disconnectedCallback.get());
     208}
     209
     210void JSCustomElementInterface::setAdoptedCallback(JSC::JSObject* callback)
     211{
     212    m_adoptedCallback = callback;
     213}
     214
     215void JSCustomElementInterface::invokeAdoptedCallback(Element& element, Document& oldDocument, Document& newDocument)
     216{
     217    invokeCallback(element, m_adoptedCallback.get(), [&](ExecState* state, JSDOMGlobalObject* globalObject, MarkedArgumentBuffer& args) {
     218        args.append(toJS(state, globalObject, oldDocument));
     219        args.append(toJS(state, globalObject, newDocument));
     220    });
    208221}
    209222
     
    218231void JSCustomElementInterface::invokeAttributeChangedCallback(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
    219232{
    220     invokeCallback(element, m_attributeChangedCallback.get(), [&](ExecState* state, MarkedArgumentBuffer& args) {
     233    invokeCallback(element, m_attributeChangedCallback.get(), [&](ExecState* state, JSDOMGlobalObject*, MarkedArgumentBuffer& args) {
    221234        args.append(jsStringWithCache(state, attributeName.localName()));
    222235        args.append(jsStringOrNull(state, oldValue));
  • trunk/Source/WebCore/bindings/js/JSCustomElementInterface.h

    r204619 r205085  
    5151
    5252class DOMWrapperWorld;
     53class Document;
    5354class Element;
    5455class JSDOMGlobalObject;
     
    6970
    7071    void setConnectedCallback(JSC::JSObject*);
     72    bool hasConnectedCallback() const { return !!m_connectedCallback; }
    7173    void invokeConnectedCallback(Element&);
    7274
    7375    void setDisconnectedCallback(JSC::JSObject*);
     76    bool hasDisconnectedCallback() const { return !!m_disconnectedCallback; }
    7477    void invokeDisconnectedCallback(Element&);
     78
     79    void setAdoptedCallback(JSC::JSObject*);
     80    bool hasAdoptedCallback() const { return !!m_adoptedCallback; }
     81    void invokeAdoptedCallback(Element&, Document& oldDocument, Document& newDocument);
    7582
    7683    void setAttributeChangedCallback(JSC::JSObject* callback, const Vector<String>& observedAttributes);
     
    9299    JSCustomElementInterface(const QualifiedName&, JSC::JSObject* callback, JSDOMGlobalObject*);
    93100
    94     void invokeCallback(Element&, JSC::JSObject* callback, const WTF::Function<void(JSC::ExecState*, JSC::MarkedArgumentBuffer&)>& addArguments = {});
     101    void invokeCallback(Element&, JSC::JSObject* callback, const WTF::Function<void(JSC::ExecState*, JSDOMGlobalObject*, JSC::MarkedArgumentBuffer&)>& addArguments = { });
    95102
    96103    QualifiedName m_name;
     
    98105    JSC::Weak<JSC::JSObject> m_connectedCallback;
    99106    JSC::Weak<JSC::JSObject> m_disconnectedCallback;
     107    JSC::Weak<JSC::JSObject> m_adoptedCallback;
    100108    JSC::Weak<JSC::JSObject> m_attributeChangedCallback;
    101109    RefPtr<DOMWrapperWorld> m_isolatedWorld;
  • trunk/Source/WebCore/bindings/js/JSCustomElementRegistryCustom.cpp

    r204732 r205085  
    120120        elementInterface->setDisconnectedCallback(disconnectedCallback);
    121121
    122     // FIXME: Add the support for adoptedCallback.
    123     getCustomElementCallback(state, prototypeObject, Identifier::fromString(&vm, "adoptedCallback"));
     122    auto* adoptedCallback = getCustomElementCallback(state, prototypeObject, Identifier::fromString(&vm, "adoptedCallback"));
    124123    if (state.hadException())
    125124        return jsUndefined();
     125    if (adoptedCallback)
     126        elementInterface->setAdoptedCallback(adoptedCallback);
    126127
    127128    auto* attributeChangedCallback = getCustomElementCallback(state, prototypeObject, Identifier::fromString(&vm, "attributeChangedCallback"));
  • trunk/Source/WebCore/dom/CustomElementReactionQueue.cpp

    r205060 r205085  
    4747        Connected,
    4848        Disconnected,
     49        Adopted,
    4950        AttributeChanged,
    5051    };
     
    5455        , m_element(element)
    5556        , m_interface(elementInterface)
     57    { }
     58
     59    CustomElementReactionQueueItem(Element& element, JSCustomElementInterface& elementInterface, Document& oldDocument, Document& newDocument)
     60        : m_type(Type::Adopted)
     61        , m_element(element)
     62        , m_interface(elementInterface)
     63        , m_oldDocument(&oldDocument)
     64        , m_newDocument(&newDocument)
    5665    { }
    5766
     
    7786            m_interface->invokeDisconnectedCallback(m_element.get());
    7887            break;
     88        case Type::Adopted:
     89            m_interface->invokeAdoptedCallback(m_element.get(), *m_oldDocument, *m_newDocument);
     90            break;
    7991        case Type::AttributeChanged:
    8092            ASSERT(m_attributeName);
     
    88100    Ref<Element> m_element;
    89101    Ref<JSCustomElementInterface> m_interface;
     102    RefPtr<Document> m_oldDocument;
     103    RefPtr<Document> m_newDocument;
    90104    Optional<QualifiedName> m_attributeName;
    91105    AtomicString m_oldValue;
     
    109123void CustomElementReactionQueue::enqueueConnectedCallbackIfNeeded(Element& element)
    110124{
    111     auto* elementInterface = element.customElementInterface();
    112     if (!elementInterface)
     125    ASSERT(element.isCustomElement());
     126    auto* elementInterface = element.customElementInterface();
     127    ASSERT(elementInterface);
     128    if (!elementInterface->hasConnectedCallback())
    113129        return;
    114130
     
    119135void CustomElementReactionQueue::enqueueDisconnectedCallbackIfNeeded(Element& element)
    120136{
    121     auto* elementInterface = element.customElementInterface();
    122     if (!elementInterface)
     137    ASSERT(element.isCustomElement());
     138    auto* elementInterface = element.customElementInterface();
     139    ASSERT(elementInterface);
     140    if (!elementInterface->hasDisconnectedCallback())
    123141        return;
    124142
     
    127145}
    128146
     147void CustomElementReactionQueue::enqueueAdoptedCallbackIfNeeded(Element& element, Document& oldDocument, Document& newDocument)
     148{
     149    ASSERT(element.isCustomElement());
     150    auto* elementInterface = element.customElementInterface();
     151    ASSERT(elementInterface);
     152    if (!elementInterface->hasAdoptedCallback())
     153        return;
     154
     155    if (auto* queue = CustomElementReactionStack::ensureCurrentQueue())
     156        queue->m_items.append({element, *elementInterface, oldDocument, newDocument});
     157}
     158
    129159void CustomElementReactionQueue::enqueueAttributeChangedCallbackIfNeeded(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
    130160{
    131     auto* elementInterface = element.customElementInterface();
    132     if (!elementInterface || !elementInterface->observesAttribute(attributeName.localName()))
     161    ASSERT(element.isCustomElement());
     162    auto* elementInterface = element.customElementInterface();
     163    ASSERT(elementInterface);
     164    if (!elementInterface->observesAttribute(attributeName.localName()))
    133165        return;
    134166
  • trunk/Source/WebCore/dom/CustomElementReactionQueue.h

    r204717 r205085  
    3535
    3636class CustomElementReactionQueueItem;
     37class Document;
    3738class Element;
    3839class JSCustomElementInterface;
     
    4849    static void enqueueConnectedCallbackIfNeeded(Element&);
    4950    static void enqueueDisconnectedCallbackIfNeeded(Element&);
     51    static void enqueueAdoptedCallbackIfNeeded(Element&, Document& oldDocument, Document& newDocument);
    5052    static void enqueueAttributeChangedCallbackIfNeeded(Element&, const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
    5153
  • trunk/Source/WebCore/dom/Element.cpp

    r205060 r205085  
    14941494            attributeChanged(classAttr, nullAtom, getAttribute(classAttr));
    14951495    }
     1496
     1497#if ENABLE(CUSTOM_ELEMENTS)
     1498    if (UNLIKELY(isCustomElement()))
     1499        CustomElementReactionQueue::enqueueAdoptedCallbackIfNeeded(*this, *oldDocument, document());
     1500#endif
    14961501}
    14971502
Note: See TracChangeset for help on using the changeset viewer.