Changeset 236002 in webkit


Ignore:
Timestamp:
Sep 13, 2018 10:56:19 PM (6 years ago)
Author:
rniwa@webkit.org
Message:

Capturing event listeners are called during bubbling phase for shadow hosts
https://bugs.webkit.org/show_bug.cgi?id=174288
LayoutTests/imported/w3c:

Reviewed by Darin Adler.

  • web-platform-tests/dom/events/Event-dispatch-handlers-changed-expected.txt: Rebaselined. This test's

expectation is now wrong because event listner 3 is added after the event listener list is cloned for
capturing event listeners but before cloned for bubbling event listeners. As a result, event listener 3
is now invoked. It used to be not called because both bubbling and capturing event listeners are called
after cloning the event listner list once, which didn't have event listener 3.

  • web-platform-tests/dom/events/EventTarget-dispatchEvent-expected.txt: Rebaselined. This test expects

event listener 2, which is bubbling, to be called between two capturing event listeners 1 and 3, which
is no longer true after this patch.

Source/WebCore:

<rdar://problem/33530455>

Reviewed by Darin Adler.

Implemented the new behavior proposed in https://github.com/whatwg/dom/pull/686 [1] to fix the problem
that capturing event listeners on a shadow host is invoked during bubbling phase when an event is
dispatched within its shadow tree.

To see why this is a problem, suppose we fire a composed event at span#target in the following DOM tree:

section#hostParent

+ div#host -- ShadowRoot

  • p#parent
    • span#target

Then capturing and bubbling event listeners on #target, #parent, #host, and #hostParent are invoked in
the following order in WebKit & Chrome right now:

  1. #hostParent, capturing, eventPhase: CAPTURING_PHASE
  2. #parent, capturing, eventPhase: CAPTURING_PHASE
  3. #target, capturing, eventPhase: AT_TARGET
  4. #target, non-capturing, eventPhase: AT_TARGET
  5. #parent, non-capturing, eventPhase: BUBBLING_PHASE
  6. #host, capturing, eventPhase: AT_TARGET
  7. #host, non-capturing, eventPhase: AT_TARGET
  8. #hostParent, non-capturing, eventPhase: BUBBLING_PHASE

This is counter-intuitive because capturing event listeners on #host isn't invoked until bubblign phase
started. A more natural ordering would be:

  1. #hostParent, capturing, eventPhase: CAPTURING_PHASE
  2. #host, capturing, eventPhase: AT_TARGET
  3. #parent, capturing, eventPhase: CAPTURING_PHASE
  4. #target, capturing, eventPhase: AT_TARGET
  5. #target, non-capturing, eventPhase: AT_TARGET
  6. #parent, non-capturing, eventPhase: BUBBLING_PHASE
  7. #host, non-capturing, eventPhase: AT_TARGET
  8. #hostParent, non-capturing, eventPhase: BUBBLING_PHASE

This also happens to be the order by which Gecko's current shadow DOM implementation invoke event listners.
This patch implements this new behavior using the spec-change proposed in [1]. Note that this patch also
impacts the invocation order of event listeners when there is no shadow tree. Namely, before this patch,
event listeners on the event's target is invoked in the registration order. After this patch, all capturing
event listeners are invoked before bubbling event listeners are invoked.

To implement this behavior, this patch introduces EventTarget::EventInvokePhase indicating whether we're
in the capturing phase or bubbling phase to EventTarget::fireEventListeners. We can't use Event's eventPhase
enum because that's set to Event::Phase::AT_TARGET when we're at a shadow host.

Test: fast/shadow-dom/capturing-and-bubbling-event-listeners-across-shadow-trees.html

  • Modules/modern-media-controls/media/media-controller-support.js:

(MediaControllerSupport.prototype.enable): Use capturing event listeners so that we can update the states of
media controls before author scripts recieve the event.
(MediaControllerSupport.prototype.disable): Ditto.

  • dom/EventContext.cpp:

(WebCore::EventContext::handleLocalEvents const):
(WebCore::MouseOrFocusEventContext::handleLocalEvents const):
(WebCore::TouchEventContext::handleLocalEvents const):

  • dom/EventContext.h:
  • dom/EventDispatcher.cpp:

(WebCore::dispatchEventInDOM): Invoke capturing event listners even when target and current target are same.
This happens when the current target is a shadow host and event's target is in its shadow tree. Also merged
the special code path for the event's target with the code in the bubbling phase.

  • dom/EventPath.cpp:

(WebCore::WindowEventContext::handleLocalEvents const):

  • dom/EventTarget.cpp:

(WebCore::EventTarget::dispatchEvent): Invoke capturing and bubbling event listeners in the order.
(WebCore::EventTarget::fireEventListeners):
(WebCore::EventTarget::innerInvokeEventListeners): Renamed from fireEventListeners to match the spec. Use
EventInvokePhase to filter out event listeners so that we can invoke capturing event listners before bubbling
event listeners even when eventPhase is Event::Phase::AT_TARGET.

  • dom/EventTarget.h:
  • dom/Node.cpp:

(WebCore::Node::handleLocalEvents):

  • dom/Node.h:
  • html/HTMLFormElement.cpp:

(WebCore::HTMLFormElement::handleLocalEvents):

  • html/HTMLFormElement.h:
  • page/DOMWindow.cpp:

(WebCore::DOMWindow::dispatchEvent):

LayoutTests:

Reviewed by Darin Adler.

Added a W3C style testharness.js test and rebaselined two tests. See below for rationals of rebaselines.

  • fast/shadow-dom/capturing-and-bubbling-event-listeners-across-shadow-trees-expected.txt: Added.
  • fast/shadow-dom/capturing-and-bubbling-event-listeners-across-shadow-trees.html: Added.
  • media/media-load-event-expected.txt: Rebaselined. The logging of oncanplaythrough event is now happening

before canplaythrough() is called because the logging is done by waitForEvent which uses a capturing event
listener whereas canplaythrough is called by a event handler, which is non-capturing.

  • platform/ios-11/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-expected.txt:
  • platform/ios/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-expected.txt:
Location:
trunk
Files:
2 added
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r236001 r236002  
     12018-09-13  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Capturing event listeners are called during bubbling phase for shadow hosts
     4        https://bugs.webkit.org/show_bug.cgi?id=174288
     5
     6        Reviewed by Darin Adler.
     7
     8        Added a W3C style testharness.js test and rebaselined two tests. See below for rationals of rebaselines.
     9
     10        * fast/shadow-dom/capturing-and-bubbling-event-listeners-across-shadow-trees-expected.txt: Added.
     11        * fast/shadow-dom/capturing-and-bubbling-event-listeners-across-shadow-trees.html: Added.
     12
     13        * media/media-load-event-expected.txt: Rebaselined. The logging of oncanplaythrough event is now happening
     14        before canplaythrough() is called because the logging is done by waitForEvent which uses a capturing event
     15        listener whereas canplaythrough is called by a event handler, which is non-capturing.
     16
     17        * platform/ios-11/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-expected.txt:
     18        * platform/ios/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-expected.txt:
     19
    1202018-09-13  Justin Fan  <justin_fan@apple.com>
    221
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r235958 r236002  
     12018-09-12  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Capturing event listeners are called during bubbling phase for shadow hosts
     4        https://bugs.webkit.org/show_bug.cgi?id=174288
     5
     6        Reviewed by Darin Adler.
     7
     8        * web-platform-tests/dom/events/Event-dispatch-handlers-changed-expected.txt: Rebaselined. This test's
     9        expectation is now wrong because event listner 3 is added after the event listener list is cloned for
     10        capturing event listeners but before cloned for bubbling event listeners. As a result, event listener 3
     11        is now invoked. It used to be not called because both bubbling and capturing event listeners are called
     12        after cloning the event listner list once, which didn't have event listener 3.
     13
     14        * web-platform-tests/dom/events/EventTarget-dispatchEvent-expected.txt: Rebaselined. This test expects
     15        event listener 2, which is bubbling, to be called between two capturing event listeners 1 and 3, which
     16        is no longer true after this patch.
     17
    1182018-09-12  Chris Dumez  <cdumez@apple.com>
    219
  • trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-handlers-changed-expected.txt

    r189471 r236002  
    11
    2 PASS  Dispatch additional events inside an event listener 
     2FAIL  Dispatch additional events inside an event listener  assert_array_equals: actual_targets lengths differ, expected 16 got 17
    33
  • trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-expected.txt

    r223023 r236002  
    2626PASS Exceptions from event listeners must not be propagated.
    2727PASS Event listeners added during dispatch should be called
    28 PASS Event listeners should be called in order of addition
     28FAIL Event listeners should be called in order of addition assert_array_equals: property 1, expected 2 but got 3
    2929
  • trunk/LayoutTests/media/media-load-event-expected.txt

    r50063 r236002  
    99EVENT(loadeddata)
    1010EVENT(canplaythrough)
     11EVENT(canplaythrough)
    1112
    1213RUN(document.getElementById('parent').appendChild(mediaElement))
    1314RUN(mediaElement.play())
    1415
    15 EVENT(canplaythrough)
    1616EVENT(play)
    1717EVENT(playing)
  • trunk/LayoutTests/platform/ios-11/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-expected.txt

    r233832 r236002  
    2626PASS Exceptions from event listeners must not be propagated.
    2727PASS Event listeners added during dispatch should be called
    28 PASS Event listeners should be called in order of addition
     28FAIL Event listeners should be called in order of addition assert_array_equals: property 1, expected 2 but got 3
    2929
  • trunk/LayoutTests/platform/ios/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-expected.txt

    r233832 r236002  
    2626PASS Exceptions from event listeners must not be propagated.
    2727PASS Event listeners added during dispatch should be called
    28 PASS Event listeners should be called in order of addition
     28PASS Event listeners should be +FAIL Event listeners should be called in order of addition assert_array_equals: property 1, expected 2 but got 3
    2929
  • trunk/Source/WebCore/ChangeLog

    r235999 r236002  
     12018-09-13  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Capturing event listeners are called during bubbling phase for shadow hosts
     4        https://bugs.webkit.org/show_bug.cgi?id=174288
     5        <rdar://problem/33530455>
     6
     7        Reviewed by Darin Adler.
     8
     9        Implemented the new behavior proposed in https://github.com/whatwg/dom/pull/686 [1] to fix the problem
     10        that capturing event listeners on a shadow host is invoked during bubbling phase when an event is
     11        dispatched within its shadow tree.
     12
     13        To see why this is a problem, suppose we fire a composed event at span#target in the following DOM tree:
     14          section#hostParent
     15            + div#host -- ShadowRoot
     16                            - p#parent
     17                                - span#target
     18        Then capturing and bubbling event listeners on #target, #parent, #host, and #hostParent are invoked in
     19        the following order in WebKit & Chrome right now:
     20
     21        1. #hostParent, capturing, eventPhase: CAPTURING_PHASE
     22        2. #parent, capturing, eventPhase: CAPTURING_PHASE
     23        3. #target, capturing, eventPhase: AT_TARGET
     24        4. #target, non-capturing, eventPhase: AT_TARGET
     25        5. #parent, non-capturing, eventPhase: BUBBLING_PHASE
     26        6. #host, capturing, eventPhase: AT_TARGET
     27        7. #host, non-capturing, eventPhase: AT_TARGET
     28        8. #hostParent, non-capturing, eventPhase: BUBBLING_PHASE
     29
     30        This is counter-intuitive because capturing event listeners on #host isn't invoked until bubblign phase
     31        started. A more natural ordering would be:
     32
     33        1. #hostParent, capturing, eventPhase: CAPTURING_PHASE
     34        2. #host, capturing, eventPhase: AT_TARGET
     35        3. #parent, capturing, eventPhase: CAPTURING_PHASE
     36        4. #target, capturing, eventPhase: AT_TARGET
     37        5. #target, non-capturing, eventPhase: AT_TARGET
     38        6. #parent, non-capturing, eventPhase: BUBBLING_PHASE
     39        7. #host, non-capturing, eventPhase: AT_TARGET
     40        8. #hostParent, non-capturing, eventPhase: BUBBLING_PHASE
     41
     42        This also happens to be the order by which Gecko's current shadow DOM implementation invoke event listners.
     43        This patch implements this new behavior using the spec-change proposed in [1]. Note that this patch also
     44        impacts the invocation order of event listeners when there is no shadow tree. Namely, before this patch,
     45        event listeners on the event's target is invoked in the registration order. After this patch, all capturing
     46        event listeners are invoked before bubbling event listeners are invoked.
     47
     48        To implement this behavior, this patch introduces EventTarget::EventInvokePhase indicating whether we're
     49        in the capturing phase or bubbling phase to EventTarget::fireEventListeners. We can't use Event's eventPhase
     50        enum because that's set to Event::Phase::AT_TARGET when we're at a shadow host.
     51
     52        Test: fast/shadow-dom/capturing-and-bubbling-event-listeners-across-shadow-trees.html
     53
     54        * Modules/modern-media-controls/media/media-controller-support.js:
     55        (MediaControllerSupport.prototype.enable): Use capturing event listeners so that we can update the states of
     56        media controls before author scripts recieve the event.
     57        (MediaControllerSupport.prototype.disable): Ditto.
     58        * dom/EventContext.cpp:
     59        (WebCore::EventContext::handleLocalEvents const):
     60        (WebCore::MouseOrFocusEventContext::handleLocalEvents const):
     61        (WebCore::TouchEventContext::handleLocalEvents const):
     62        * dom/EventContext.h:
     63        * dom/EventDispatcher.cpp:
     64        (WebCore::dispatchEventInDOM): Invoke capturing event listners even when target and current target are same.
     65        This happens when the current target is a shadow host and event's target is in its shadow tree. Also merged
     66        the special code path for the event's target with the code in the bubbling phase.
     67        * dom/EventPath.cpp:
     68        (WebCore::WindowEventContext::handleLocalEvents const):
     69        * dom/EventTarget.cpp:
     70        (WebCore::EventTarget::dispatchEvent): Invoke capturing and bubbling event listeners in the order.
     71        (WebCore::EventTarget::fireEventListeners):
     72        (WebCore::EventTarget::innerInvokeEventListeners): Renamed from fireEventListeners to match the spec. Use
     73        EventInvokePhase to filter out event listeners so that we can invoke capturing event listners before bubbling
     74        event listeners even when eventPhase is Event::Phase::AT_TARGET.
     75        * dom/EventTarget.h:
     76        * dom/Node.cpp:
     77        (WebCore::Node::handleLocalEvents):
     78        * dom/Node.h:
     79        * html/HTMLFormElement.cpp:
     80        (WebCore::HTMLFormElement::handleLocalEvents):
     81        * html/HTMLFormElement.h:
     82        * page/DOMWindow.cpp:
     83        (WebCore::DOMWindow::dispatchEvent):
     84
    1852018-09-13  Megan Gardner  <megan_gardner@apple.com>
    286
  • trunk/Source/WebCore/Modules/modern-media-controls/media/media-controller-support.js

    r226796 r236002  
    3939    {
    4040        for (let eventType of this.mediaEvents)
    41             this.mediaController.media.addEventListener(eventType, this);
     41            this.mediaController.media.addEventListener(eventType, this, true);
    4242
    4343        for (let tracks of this.tracksToMonitor) {
     
    5656    {
    5757        for (let eventType of this.mediaEvents)
    58             this.mediaController.media.removeEventListener(eventType, this);
     58            this.mediaController.media.removeEventListener(eventType, this, true);
    5959
    6060        for (let tracks of this.tracksToMonitor) {
  • trunk/Source/WebCore/dom/EventContext.cpp

    r224748 r236002  
    4646EventContext::~EventContext() = default;
    4747
    48 void EventContext::handleLocalEvents(Event& event) const
     48void EventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const
    4949{
    5050    event.setTarget(m_target.get());
     
    5252    // FIXME: Consider merging handleLocalEvents and fireEventListeners.
    5353    if (m_node)
    54         m_node->handleLocalEvents(event);
     54        m_node->handleLocalEvents(event, phase);
    5555    else
    56         m_currentTarget->fireEventListeners(event);
     56        m_currentTarget->fireEventListeners(event, phase);
    5757}
    5858
     
    7474MouseOrFocusEventContext::~MouseOrFocusEventContext() = default;
    7575
    76 void MouseOrFocusEventContext::handleLocalEvents(Event& event) const
     76void MouseOrFocusEventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const
    7777{
    7878    if (m_relatedTarget)
    7979        event.setRelatedTarget(*m_relatedTarget);
    80     EventContext::handleLocalEvents(event);
     80    EventContext::handleLocalEvents(event, phase);
    8181}
    8282
     
    9898TouchEventContext::~TouchEventContext() = default;
    9999
    100 void TouchEventContext::handleLocalEvents(Event& event) const
     100void TouchEventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const
    101101{
    102102    checkReachability(m_touches);
     
    107107    touchEvent.setTargetTouches(m_targetTouches.ptr());
    108108    touchEvent.setChangedTouches(m_changedTouches.ptr());
    109     EventContext::handleLocalEvents(event);
     109    EventContext::handleLocalEvents(event, phase);
    110110}
    111111
  • trunk/Source/WebCore/dom/EventContext.h

    r224740 r236002  
    3737    WTF_MAKE_FAST_ALLOCATED;
    3838public:
     39    using EventInvokePhase = EventTarget::EventInvokePhase;
     40
    3941    EventContext(Node*, EventTarget* currentTarget, EventTarget*);
    4042    virtual ~EventContext();
     
    4446    EventTarget* target() const { return m_target.get(); }
    4547
    46     virtual void handleLocalEvents(Event&) const;
     48    virtual void handleLocalEvents(Event&, EventInvokePhase) const;
    4749
    4850    virtual bool isMouseOrFocusEventContext() const;
     
    6870
    6971private:
    70     void handleLocalEvents(Event&) const final;
     72    void handleLocalEvents(Event&, EventInvokePhase) const final;
    7173    bool isMouseOrFocusEventContext() const final;
    7274
     
    8587
    8688private:
    87     void handleLocalEvents(Event&) const final;
     89    void handleLocalEvents(Event&, EventInvokePhase) const final;
    8890    bool isTouchEventContext() const final;
    8991
  • trunk/Source/WebCore/dom/EventDispatcher.cpp

    r234718 r236002  
    7676static void dispatchEventInDOM(Event& event, const EventPath& path)
    7777{
    78     // Trigger capturing event handlers, starting at the top and working our way down.
    79     event.setEventPhase(Event::CAPTURING_PHASE);
    80 
    81     for (size_t i = path.size() - 1; i > 0; --i) {
    82         const EventContext& eventContext = path.contextAt(i);
     78    // Invoke capturing event listeners in the reverse order.
     79    for (size_t i = path.size(); i > 0; --i) {
     80        const EventContext& eventContext = path.contextAt(i - 1);
    8381        if (eventContext.currentTarget() == eventContext.target())
    84             continue;
    85         eventContext.handleLocalEvents(event);
     82            event.setEventPhase(Event::AT_TARGET);
     83        else
     84            event.setEventPhase(Event::CAPTURING_PHASE);
     85        eventContext.handleLocalEvents(event, EventTarget::EventInvokePhase::Capturing);
    8686        if (event.propagationStopped())
    8787            return;
    8888    }
    8989
    90     event.setEventPhase(Event::AT_TARGET);
    91     path.contextAt(0).handleLocalEvents(event);
    92     if (event.propagationStopped())
    93         return;
    94 
    95     // Trigger bubbling event handlers, starting at the bottom and working our way up.
     90    // Invoke bubbling event listeners.
    9691    size_t size = path.size();
    97     for (size_t i = 1; i < size; ++i) {
     92    for (size_t i = 0; i < size; ++i) {
    9893        const EventContext& eventContext = path.contextAt(i);
    9994        if (eventContext.currentTarget() == eventContext.target())
     
    10398        else
    10499            continue;
    105         eventContext.handleLocalEvents(event);
     100        eventContext.handleLocalEvents(event, EventTarget::EventInvokePhase::Bubbling);
    106101        if (event.propagationStopped())
    107102            return;
  • trunk/Source/WebCore/dom/EventPath.cpp

    r228827 r236002  
    3838    WindowEventContext(Node&, DOMWindow&, EventTarget&);
    3939private:
    40     void handleLocalEvents(Event&) const final;
     40    void handleLocalEvents(Event&, EventInvokePhase) const final;
    4141};
    4242
     
    4646}
    4747
    48 void WindowEventContext::handleLocalEvents(Event& event) const
     48void WindowEventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const
    4949{
    5050    event.setTarget(m_target.get());
    5151    event.setCurrentTarget(m_currentTarget.get());
    52     m_currentTarget->fireEventListeners(event);
     52    m_currentTarget->fireEventListeners(event, phase);
    5353}
    5454
  • trunk/Source/WebCore/dom/EventTarget.cpp

    r233493 r236002  
    184184void EventTarget::dispatchEvent(Event& event)
    185185{
     186    // FIXME: We should always use EventDispatcher.
    186187    ASSERT(event.isInitialized());
    187188    ASSERT(!event.isBeingDispatched());
     
    191192    event.setEventPhase(Event::AT_TARGET);
    192193    event.resetBeforeDispatch();
    193     fireEventListeners(event);
     194    fireEventListeners(event, EventInvokePhase::Capturing);
     195    fireEventListeners(event, EventInvokePhase::Bubbling);
    194196    event.resetAfterDispatch();
    195197}
     
    220222}
    221223
    222 void EventTarget::fireEventListeners(Event& event)
     224// https://dom.spec.whatwg.org/#concept-event-listener-invoke
     225void EventTarget::fireEventListeners(Event& event, EventInvokePhase phase)
    223226{
    224227    ASSERT_WITH_SECURITY_IMPLICATION(ScriptDisallowedScope::isEventAllowedInMainThread());
     
    232235
    233236    if (auto* listenersVector = data->eventListenerMap.find(event.type())) {
    234         fireEventListeners(event, *listenersVector);
     237        innerInvokeEventListeners(event, *listenersVector, phase);
    235238        return;
    236239    }
     
    245248            AtomicString typeName = event.type();
    246249            event.setType(legacyTypeName);
    247             fireEventListeners(event, *legacyListenersVector);
     250            innerInvokeEventListeners(event, *legacyListenersVector, phase);
    248251            event.setType(typeName);
    249252        }
     
    253256// Intentionally creates a copy of the listeners vector to avoid event listeners added after this point from being run.
    254257// Note that removal still has an effect due to the removed field in RegisteredEventListener.
    255 void EventTarget::fireEventListeners(Event& event, EventListenerVector listeners)
     258// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
     259void EventTarget::innerInvokeEventListeners(Event& event, EventListenerVector listeners, EventInvokePhase phase)
    256260{
    257261    Ref<EventTarget> protectedThis(*this);
     
    269273            continue;
    270274
    271         if (event.eventPhase() == Event::CAPTURING_PHASE && !registeredListener->useCapture())
    272             continue;
    273         if (event.eventPhase() == Event::BUBBLING_PHASE && registeredListener->useCapture())
     275        if (phase == EventInvokePhase::Capturing && !registeredListener->useCapture())
     276            continue;
     277        if (phase == EventInvokePhase::Bubbling && registeredListener->useCapture())
    274278            continue;
    275279
  • trunk/Source/WebCore/dom/EventTarget.h

    r233443 r236002  
    103103    const EventListenerVector& eventListeners(const AtomicString& eventType);
    104104
    105     void fireEventListeners(Event&);
     105    enum class EventInvokePhase { Capturing, Bubbling };
     106    void fireEventListeners(Event&, EventInvokePhase);
    106107    bool isFiringEventListeners() const;
    107108
     
    121122    virtual void derefEventTarget() = 0;
    122123   
    123     void fireEventListeners(Event&, EventListenerVector);
     124    void innerInvokeEventListeners(Event&, EventListenerVector, EventInvokePhase);
    124125
    125126    friend class EventListenerIterator;
  • trunk/Source/WebCore/dom/Node.cpp

    r235331 r236002  
    23082308}
    23092309
    2310 void Node::handleLocalEvents(Event& event)
     2310void Node::handleLocalEvents(Event& event, EventInvokePhase phase)
    23112311{
    23122312    if (!hasEventTargetData())
     
    23172317        return;
    23182318
    2319     fireEventListeners(event);
     2319    fireEventListeners(event, phase);
    23202320}
    23212321
  • trunk/Source/WebCore/dom/Node.h

    r235780 r236002  
    487487    void dispatchScopedEvent(Event&);
    488488
    489     virtual void handleLocalEvents(Event&);
     489    virtual void handleLocalEvents(Event&, EventInvokePhase);
    490490
    491491    void dispatchSubtreeModifiedEvent();
  • trunk/Source/WebCore/html/HTMLFormElement.cpp

    r234995 r236002  
    143143}
    144144
    145 void HTMLFormElement::handleLocalEvents(Event& event)
     145void HTMLFormElement::handleLocalEvents(Event& event, EventInvokePhase phase)
    146146{
    147147    if (event.eventPhase() != Event::CAPTURING_PHASE && is<Node>(event.target()) && event.target() != this && (event.type() == eventNames().submitEvent || event.type() == eventNames().resetEvent)) {
     
    149149        return;
    150150    }
    151     HTMLElement::handleLocalEvents(event);
     151    HTMLElement::handleLocalEvents(event, phase);
    152152}
    153153
  • trunk/Source/WebCore/html/HTMLFormElement.h

    r230229 r236002  
    134134    void finishParsingChildren() final;
    135135
    136     void handleLocalEvents(Event&) final;
     136    void handleLocalEvents(Event&, EventInvokePhase) final;
    137137
    138138    void parseAttribute(const QualifiedName&, const AtomicString&) final;
  • trunk/Source/WebCore/page/DOMWindow.cpp

    r235994 r236002  
    20532053    event.resetBeforeDispatch();
    20542054    auto cookie = InspectorInstrumentation::willDispatchEventOnWindow(frame(), event, *this);
    2055     fireEventListeners(event);
     2055    // FIXME: We should use EventDispatcher everywhere.
     2056    fireEventListeners(event, EventInvokePhase::Capturing);
     2057    fireEventListeners(event, EventInvokePhase::Bubbling);
    20562058    InspectorInstrumentation::didDispatchEventOnWindow(cookie);
    20572059    event.resetAfterDispatch();
Note: See TracChangeset for help on using the changeset viewer.