Title: [273477] trunk/Source/WebCore
Revision
273477
Author
[email protected]
Date
2021-02-25 00:30:59 -0800 (Thu, 25 Feb 2021)

Log Message

Avoid heap allocation for EventContexts
https://bugs.webkit.org/show_bug.cgi?id=222095
<rdar://problem/74586915>

Reviewed by Simon Fraser.

This patch merges all subclasses of EventContext into itself to avoid heap allocation for each
EventContext in EventPath::m_path. It also merges Node::handleLocalEvents into EventContext's
handleLocalEvents to avoid the extra virtual function call.

No new tests since there should be no observable behavioral differences.

* dom/EventContext.cpp:
(WebCore::EventContext::EventContext): Moved to the header to be inlined.
(WebCore::EventContext::handleLocalEvents const): Merged handleLocalEvents of HTMLFormElement
and Node. Moved the code to handle related target and touch targets from MouseOrFocusEventContext
and TouchEventContext as they have been merged into this class. Also special case dispatching
an event on window to preserve the behavior of WindowEventContext.
(WebCore::EventContext::initializeTouchLists): Added. Creates TouchList objects.
(WebCore::EventContext::isUnreachableNode const): Moved from the header.
(WebCore::EventContext::isMouseOrFocusEventContext const): Deleted.
(WebCore::EventContext::isTouchEventContext const): Deleted.
(WebCore::MouseOrFocusEventContext::MouseOrFocusEventContext): Deleted.
(WebCore::MouseOrFocusEventContext::handleLocalEvents const): Deleted.
(WebCore::MouseOrFocusEventContext::isMouseOrFocusEventContext const): Deleted.
(WebCore::TouchEventContext::TouchEventContext): Deleted.
(WebCore::TouchEventContext::handleLocalEvents const): Deleted.
(WebCore::TouchEventContext::isTouchEventContext const): Deleted.
(WebCore::TouchEventContext::checkReachability const): Deleted. Merged into handleLocalEvents.
* dom/EventContext.h:
(WebCore::EventContext::isMouseOrFocusEventContext const): Now simply checks m_type.
(WebCore::EventContext::isTouchEventContext const): Ditto.
(WebCore::EventContext::isWindowContext const): Ditto.
(WebCore::EventContext::relatedTarget const): Moved from MouseOrFocusEventContext.
(WebCore::EventContext::setRelatedTarget): Ditto.
(WebCore::EventContext::touchList): Moved from TouchEventContext.
(WebCore::m_contextNodeIsFormElement): Added. Caching this state here instead of checking it at
every event context during dispatching in EventContext::handleLocalEvents seems to be important
to get a speed up in Intel processors. Apple silicons don't seem to be affected by this.
(WebCore::m_type): Added.
(WebCore::MouseOrFocusEventContext): Deleted.
(WebCore::MouseOrFocusEventContext::relatedTarget const): Deleted.
(WebCore::TouchEventContext): Deleted.
(WebCore::EventContext::EventContext): Moved from cpp file to be inlined here.
(WebCore::EventContext::isUnreachableNode const): Moved into cpp as this is only used for
asserting shadow DOM related conditions.
(WebCore::EventContext::touchList): Renamed from TouchEventContext::touchList.
(isType): Deleted.
* dom/EventDispatcher.cpp:
(WebCore::EventDispatcher::dispatchEvent): Deleted the variant that takes a vector of elements
since it's not used anywhere.
* dom/EventDispatcher.h:
* dom/EventPath.cpp:
(WebCore::WindowEventContext): Deleted.
(WebCore::EventPath::EventPath): Avoid calling setRelatedTarget if related target is not a node
or the path is empty. These were early return conditions in setRelatedTarget before this patch.
(WebCore::EventPath::buildPath): Always create EventContext. Dramatically simplifies the code.
(WebCore::EventPath::setRelatedTarget): Moved the early exit to EventPath::EventPath.
(WebCore::EventPath::retargetTouch):
(WebCore::EventPath::retargetTouchList):
(WebCore::EventPath::retargetTouchLists):
(WebCore::EventPath::EventPath): Deleted the variant which takes a vector of elements as it's
not used anywhere.
* dom/EventPath.h:
(WebCore::EventPath::contextAt const):
(WebCore::EventPath::contextAt):
(WebCore::EventPath::m_path): Now allocates EventContext in place. The size of the inline buffer
has been reduced to 16 entries for EventContext from 32 entries for std::unique_ptr<EventContext>
since the former is considerably larger than the latter.
* dom/Node.cpp:
(WebCore::Node::handleLocalEvents): Deleted. Merged into EventContext::handleLocalEvents.
* dom/Node.h:
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::handleLocalEvents): Ditto.
* html/HTMLFormElement.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (273476 => 273477)


--- trunk/Source/WebCore/ChangeLog	2021-02-25 07:32:19 UTC (rev 273476)
+++ trunk/Source/WebCore/ChangeLog	2021-02-25 08:30:59 UTC (rev 273477)
@@ -1,3 +1,81 @@
+2021-02-25  Ryosuke Niwa  <[email protected]>
+
+        Avoid heap allocation for EventContexts
+        https://bugs.webkit.org/show_bug.cgi?id=222095
+        <rdar://problem/74586915>
+
+        Reviewed by Simon Fraser.
+
+        This patch merges all subclasses of EventContext into itself to avoid heap allocation for each
+        EventContext in EventPath::m_path. It also merges Node::handleLocalEvents into EventContext's
+        handleLocalEvents to avoid the extra virtual function call.
+
+        No new tests since there should be no observable behavioral differences.
+
+        * dom/EventContext.cpp:
+        (WebCore::EventContext::EventContext): Moved to the header to be inlined.
+        (WebCore::EventContext::handleLocalEvents const): Merged handleLocalEvents of HTMLFormElement
+        and Node. Moved the code to handle related target and touch targets from MouseOrFocusEventContext
+        and TouchEventContext as they have been merged into this class. Also special case dispatching
+        an event on window to preserve the behavior of WindowEventContext.
+        (WebCore::EventContext::initializeTouchLists): Added. Creates TouchList objects.
+        (WebCore::EventContext::isUnreachableNode const): Moved from the header.
+        (WebCore::EventContext::isMouseOrFocusEventContext const): Deleted.
+        (WebCore::EventContext::isTouchEventContext const): Deleted.
+        (WebCore::MouseOrFocusEventContext::MouseOrFocusEventContext): Deleted.
+        (WebCore::MouseOrFocusEventContext::handleLocalEvents const): Deleted.
+        (WebCore::MouseOrFocusEventContext::isMouseOrFocusEventContext const): Deleted.
+        (WebCore::TouchEventContext::TouchEventContext): Deleted.
+        (WebCore::TouchEventContext::handleLocalEvents const): Deleted.
+        (WebCore::TouchEventContext::isTouchEventContext const): Deleted.
+        (WebCore::TouchEventContext::checkReachability const): Deleted. Merged into handleLocalEvents.
+        * dom/EventContext.h:
+        (WebCore::EventContext::isMouseOrFocusEventContext const): Now simply checks m_type.
+        (WebCore::EventContext::isTouchEventContext const): Ditto.
+        (WebCore::EventContext::isWindowContext const): Ditto.
+        (WebCore::EventContext::relatedTarget const): Moved from MouseOrFocusEventContext.
+        (WebCore::EventContext::setRelatedTarget): Ditto.
+        (WebCore::EventContext::touchList): Moved from TouchEventContext.
+        (WebCore::m_contextNodeIsFormElement): Added. Caching this state here instead of checking it at
+        every event context during dispatching in EventContext::handleLocalEvents seems to be important
+        to get a speed up in Intel processors. Apple silicons don't seem to be affected by this.
+        (WebCore::m_type): Added.
+        (WebCore::MouseOrFocusEventContext): Deleted.
+        (WebCore::MouseOrFocusEventContext::relatedTarget const): Deleted.
+        (WebCore::TouchEventContext): Deleted.
+        (WebCore::EventContext::EventContext): Moved from cpp file to be inlined here.
+        (WebCore::EventContext::isUnreachableNode const): Moved into cpp as this is only used for
+        asserting shadow DOM related conditions.
+        (WebCore::EventContext::touchList): Renamed from TouchEventContext::touchList.
+        (isType): Deleted.
+        * dom/EventDispatcher.cpp:
+        (WebCore::EventDispatcher::dispatchEvent): Deleted the variant that takes a vector of elements
+        since it's not used anywhere.
+        * dom/EventDispatcher.h:
+        * dom/EventPath.cpp:
+        (WebCore::WindowEventContext): Deleted.
+        (WebCore::EventPath::EventPath): Avoid calling setRelatedTarget if related target is not a node
+        or the path is empty. These were early return conditions in setRelatedTarget before this patch.
+        (WebCore::EventPath::buildPath): Always create EventContext. Dramatically simplifies the code.
+        (WebCore::EventPath::setRelatedTarget): Moved the early exit to EventPath::EventPath.
+        (WebCore::EventPath::retargetTouch):
+        (WebCore::EventPath::retargetTouchList):
+        (WebCore::EventPath::retargetTouchLists):
+        (WebCore::EventPath::EventPath): Deleted the variant which takes a vector of elements as it's
+        not used anywhere.
+        * dom/EventPath.h:
+        (WebCore::EventPath::contextAt const):
+        (WebCore::EventPath::contextAt):
+        (WebCore::EventPath::m_path): Now allocates EventContext in place. The size of the inline buffer
+        has been reduced to 16 entries for EventContext from 32 entries for std::unique_ptr<EventContext>
+        since the former is considerably larger than the latter.
+        * dom/Node.cpp:
+        (WebCore::Node::handleLocalEvents): Deleted. Merged into EventContext::handleLocalEvents.
+        * dom/Node.h:
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::handleLocalEvents): Ditto.
+        * html/HTMLFormElement.h:
+
 2021-02-24  Ryosuke Niwa  <[email protected]>
 
         Optimize the code to check if an element delegates focus to its shadow root or not

Modified: trunk/Source/WebCore/dom/EventContext.cpp (273476 => 273477)


--- trunk/Source/WebCore/dom/EventContext.cpp	2021-02-25 07:32:19 UTC (rev 273476)
+++ trunk/Source/WebCore/dom/EventContext.cpp	2021-02-25 08:30:59 UTC (rev 273477)
@@ -28,23 +28,15 @@
 #include "config.h"
 #include "EventContext.h"
 
+#include "DOMWindow.h"
 #include "Document.h"
 #include "FocusEvent.h"
+#include "HTMLFormElement.h"
 #include "MouseEvent.h"
 #include "TouchEvent.h"
 
 namespace WebCore {
 
-EventContext::EventContext(Node* node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth)
-    : m_node { node }
-    , m_currentTarget { currentTarget }
-    , m_target { target }
-    , m_closedShadowDepth { closedShadowDepth }
-    , m_currentTargetIsInShadowTree { is<Node>(currentTarget) && downcast<Node>(*currentTarget).isInShadowTree() }
-{
-    ASSERT(!isUnreachableNode(m_target.get()));
-}
-
 EventContext::~EventContext() = default;
 
 void EventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const
@@ -51,82 +43,76 @@
 {
     event.setTarget(m_target.get());
     event.setCurrentTarget(m_currentTarget.get(), m_currentTargetIsInShadowTree);
-    // FIXME: Consider merging handleLocalEvents and fireEventListeners.
-    if (m_node)
-        m_node->handleLocalEvents(event, phase);
-    else
-        m_currentTarget->fireEventListeners(event, phase);
-}
 
-bool EventContext::isMouseOrFocusEventContext() const
-{
-    return false;
-}
+    if (m_relatedTarget) {
+        ASSERT(m_type == Type::MouseOrFocus);
+        event.setRelatedTarget(m_relatedTarget.get());
+    }
 
-bool EventContext::isTouchEventContext() const
-{
-    return false;
-}
+#if ENABLE(TOUCH_EVENTS)
+    if (m_type == Type::Touch) {
 
-MouseOrFocusEventContext::MouseOrFocusEventContext(Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth)
-    : EventContext(&node, currentTarget, target, closedShadowDepth)
-{
-}
+#if ASSERT_ENABLED
+        auto checkReachability = [&](const Ref<TouchList>& touchList) {
+            size_t length = touchList->length();
+            for (size_t i = 0; i < length; ++i)
+                ASSERT(!isUnreachableNode(downcast<Node>(touchList->item(i)->target())));
+        }
+        checkReachability(m_touches);
+        checkReachability(m_targetTouches);
+        checkReachability(m_changedTouches);
+#endif
 
-MouseOrFocusEventContext::~MouseOrFocusEventContext() = default;
+        auto& touchEvent = downcast<TouchEvent>(event);
+        touchEvent.setTouches(m_touches.get());
+        touchEvent.setTargetTouches(m_targetTouches.get());
+        touchEvent.setChangedTouches(m_changedTouches.get());
+    }
+#endif
 
-void MouseOrFocusEventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const
-{
-    if (m_relatedTarget)
-        event.setRelatedTarget(m_relatedTarget.get());
-    EventContext::handleLocalEvents(event, phase);
-}
+    if (!m_node || UNLIKELY(m_type == Type::Window)) {
+        m_currentTarget->fireEventListeners(event, phase);
+        return;
+    }
 
-bool MouseOrFocusEventContext::isMouseOrFocusEventContext() const
-{
-    return true;
-}
+    if (UNLIKELY(m_contextNodeIsFormElement)) {
+        ASSERT(is<HTMLFormElement>(*m_node));
+        if ((event.type() == eventNames().submitEvent || event.type() == eventNames().resetEvent)
+            && event.eventPhase() != Event::CAPTURING_PHASE && event.target() != m_node && is<Node>(event.target())) {
+            event.stopPropagation();
+            return;
+        }
+    }
 
-#if ENABLE(TOUCH_EVENTS)
+    if (!m_node->hasEventTargetData())
+        return;
 
-TouchEventContext::TouchEventContext(Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth)
-    : EventContext(&node, currentTarget, target, closedShadowDepth)
-    , m_touches(TouchList::create())
-    , m_targetTouches(TouchList::create())
-    , m_changedTouches(TouchList::create())
-{
+    // FIXME: Should we deliver wheel events to disabled form controls or not?
+    if (event.isTrusted() && is<Element>(m_node) && downcast<Element>(*m_node).isDisabledFormControl() && event.isMouseEvent() && !event.isWheelEvent())
+        return;
+
+    m_node->fireEventListeners(event, phase);
 }
 
-TouchEventContext::~TouchEventContext() = default;
+#if ENABLE(TOUCH_EVENTS)
 
-void TouchEventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const
+void EventContext::initializeTouchLists()
 {
-    checkReachability(m_touches);
-    checkReachability(m_targetTouches);
-    checkReachability(m_changedTouches);
-    auto& touchEvent = downcast<TouchEvent>(event);
-    touchEvent.setTouches(m_touches.ptr());
-    touchEvent.setTargetTouches(m_targetTouches.ptr());
-    touchEvent.setChangedTouches(m_changedTouches.ptr());
-    EventContext::handleLocalEvents(event, phase);
+    m_touches = TouchList::create();
+    m_targetTouches = TouchList::create();
+    m_changedTouches = TouchList::create();
 }
 
-bool TouchEventContext::isTouchEventContext() const
-{
-    return true;
-}
+#endif // ENABLE(TOUCH_EVENTS)
 
 #if ASSERT_ENABLED
 
-void TouchEventContext::checkReachability(const Ref<TouchList>& touchList) const
+bool EventContext::isUnreachableNode(EventTarget* target) const
 {
-    size_t length = touchList->length();
-    for (size_t i = 0; i < length; ++i)
-        ASSERT(!isUnreachableNode(downcast<Node>(touchList->item(i)->target())));
+    // FIXME: Checks also for SVG elements.
+    return is<Node>(target) && !downcast<Node>(*target).isSVGElement() && m_node->isClosedShadowHidden(downcast<Node>(*target));
 }
 
-#endif // ASSERT_ENABLED
+#endif
 
-#endif // ENABLE(TOUCH_EVENTS)
-
 }

Modified: trunk/Source/WebCore/dom/EventContext.h (273476 => 273477)


--- trunk/Source/WebCore/dom/EventContext.h	2021-02-25 07:32:19 UTC (rev 273476)
+++ trunk/Source/WebCore/dom/EventContext.h	2021-02-25 08:30:59 UTC (rev 273477)
@@ -27,7 +27,7 @@
 
 #pragma once
 
-#include "Node.h"
+#include "HTMLFormElement.h"
 
 namespace WebCore {
 
@@ -38,9 +38,17 @@
 public:
     using EventInvokePhase = EventTarget::EventInvokePhase;
 
-    EventContext(Node*, EventTarget* currentTarget, EventTarget*, int closedShadowDepth);
-    virtual ~EventContext();
+    enum class Type : uint8_t {
+        Normal = 0,
+        MouseOrFocus,
+        Touch,
+        Window,
+    };
 
+    EventContext(Type, Node*, EventTarget* currentTarget, EventTarget* origin, int closedShadowDepth);
+    EventContext(Type, Node&, Node* currentTarget, EventTarget* origin, int closedShadowDepth);
+    ~EventContext();
+
     Node* node() const { return m_node.get(); }
     EventTarget* currentTarget() const { return m_currentTarget.get(); }
     bool isCurrentTargetInShadowTree() const { return m_currentTargetIsInShadowTree; }
@@ -47,14 +55,27 @@
     EventTarget* target() const { return m_target.get(); }
     int closedShadowDepth() const { return m_closedShadowDepth; }
 
-    virtual void handleLocalEvents(Event&, EventInvokePhase) const;
+    void handleLocalEvents(Event&, EventInvokePhase) const;
 
-    virtual bool isMouseOrFocusEventContext() const;
-    virtual bool isTouchEventContext() const;
+    bool isMouseOrFocusEventContext() const { return m_type == Type::MouseOrFocus; }
+    bool isTouchEventContext() const { return m_type == Type::Touch; }
+    bool isWindowContext() const { return m_type == Type::Window; }
 
-    virtual Node* relatedTarget() const { return nullptr; }
+    Node* relatedTarget() const { return m_relatedTarget.get(); }
+    void setRelatedTarget(Node*);
 
-protected:
+#if ENABLE(TOUCH_EVENTS)
+    enum TouchListType { Touches, TargetTouches, ChangedTouches };
+    TouchList& touchList(TouchListType);
+#endif
+
+private:
+    inline EventContext(Type, Node* currentNode, RefPtr<EventTarget>&& currentTarget, EventTarget* origin, int closedShadowDepth, bool currentTargetIsInShadowTree = false);
+
+#if ENABLE(TOUCH_EVENTS)
+    void initializeTouchLists();
+#endif
+
 #if ASSERT_ENABLED
     bool isUnreachableNode(EventTarget*) const;
 #endif
@@ -62,59 +83,49 @@
     RefPtr<Node> m_node;
     RefPtr<EventTarget> m_currentTarget;
     RefPtr<EventTarget> m_target;
+    RefPtr<Node> m_relatedTarget;
+#if ENABLE(TOUCH_EVENTS)
+    RefPtr<TouchList> m_touches;
+    RefPtr<TouchList> m_targetTouches;
+    RefPtr<TouchList> m_changedTouches;
+#endif
     int m_closedShadowDepth { 0 };
     bool m_currentTargetIsInShadowTree { false };
+    bool m_contextNodeIsFormElement { false };
+    Type m_type { Type::Normal };
 };
 
-class MouseOrFocusEventContext final : public EventContext {
-public:
-    MouseOrFocusEventContext(Node&, EventTarget* currentTarget, EventTarget*, int closedShadowDepth);
-    virtual ~MouseOrFocusEventContext();
-
-    Node* relatedTarget() const final { return m_relatedTarget.get(); }
-    void setRelatedTarget(Node*);
-
-private:
-    void handleLocalEvents(Event&, EventInvokePhase) const final;
-    bool isMouseOrFocusEventContext() const final;
-
-    RefPtr<Node> m_relatedTarget;
-};
-
+inline EventContext::EventContext(Type type, Node* node, RefPtr<EventTarget>&& currentTarget, EventTarget* origin, int closedShadowDepth, bool currentTargetIsInShadowTree)
+    : m_node { node }
+    , m_currentTarget { WTFMove(currentTarget) }
+    , m_target { origin }
+    , m_closedShadowDepth { closedShadowDepth }
+    , m_currentTargetIsInShadowTree { currentTargetIsInShadowTree }
+    , m_type { type }
+{
+    ASSERT(!isUnreachableNode(m_target.get()));
 #if ENABLE(TOUCH_EVENTS)
+    if (m_type == Type::Touch)
+        initializeTouchLists();
+#else
+    ASSERT(m_type != Type::Touch);
+#endif
+}
 
-class TouchEventContext final : public EventContext {
-public:
-    TouchEventContext(Node&, EventTarget* currentTarget, EventTarget*, int closedShadowDepth);
-    virtual ~TouchEventContext();
+inline EventContext::EventContext(Type type, Node* node, EventTarget* currentTarget, EventTarget* origin, int closedShadowDepth)
+    : EventContext(type, node, makeRefPtr(currentTarget), origin, closedShadowDepth)
+{
+    ASSERT(!is<Node>(currentTarget));
+}
 
-    enum TouchListType { Touches, TargetTouches, ChangedTouches };
-    TouchList& touchList(TouchListType);
-
-private:
-    void handleLocalEvents(Event&, EventInvokePhase) const final;
-    bool isTouchEventContext() const final;
-
-    void checkReachability(const Ref<TouchList>&) const;
-
-    Ref<TouchList> m_touches;
-    Ref<TouchList> m_targetTouches;
-    Ref<TouchList> m_changedTouches;
-};
-
-#endif // ENABLE(TOUCH_EVENTS)
-
-#if ASSERT_ENABLED
-
-inline bool EventContext::isUnreachableNode(EventTarget* target) const
+// This variant avoids calling EventTarget::ref() which is a virtual function call.
+inline EventContext::EventContext(Type type, Node& node, Node* currentTarget, EventTarget* origin, int closedShadowDepth)
+    : EventContext(type, &node, makeRefPtr(currentTarget), origin, closedShadowDepth, currentTarget && currentTarget->isInShadowTree())
 {
-    // FIXME: Checks also for SVG elements.
-    return is<Node>(target) && !downcast<Node>(*target).isSVGElement() && m_node->isClosedShadowHidden(downcast<Node>(*target));
+    m_contextNodeIsFormElement = is<HTMLFormElement>(node);
 }
 
-#endif
-
-inline void MouseOrFocusEventContext::setRelatedTarget(Node* relatedTarget)
+inline void EventContext::setRelatedTarget(Node* relatedTarget)
 {
     ASSERT(!isUnreachableNode(relatedTarget));
     m_relatedTarget = relatedTarget;
@@ -122,38 +133,20 @@
 
 #if ENABLE(TOUCH_EVENTS)
 
-inline TouchList& TouchEventContext::touchList(TouchListType type)
+inline TouchList& EventContext::touchList(TouchListType type)
 {
     switch (type) {
     case Touches:
-        return m_touches.get();
+        return *m_touches;
     case TargetTouches:
-        return m_targetTouches.get();
+        return *m_targetTouches;
     case ChangedTouches:
-        return m_changedTouches.get();
+        return *m_changedTouches;
     }
     ASSERT_NOT_REACHED();
-    return m_touches.get();
+    return *m_touches;
 }
 
 #endif
 
-#if ENABLE(TOUCH_EVENTS) && !ASSERT_ENABLED
-
-inline void TouchEventContext::checkReachability(const Ref<TouchList>&) const
-{
-}
-
-#endif
-
 } // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::MouseOrFocusEventContext)
-static bool isType(const WebCore::EventContext& context) { return context.isMouseOrFocusEventContext(); }
-SPECIALIZE_TYPE_TRAITS_END()
-
-#if ENABLE(TOUCH_EVENTS)
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::TouchEventContext)
-static bool isType(const WebCore::EventContext& context) { return context.isTouchEventContext(); }
-SPECIALIZE_TYPE_TRAITS_END()
-#endif

Modified: trunk/Source/WebCore/dom/EventDispatcher.cpp (273476 => 273477)


--- trunk/Source/WebCore/dom/EventDispatcher.cpp	2021-02-25 07:32:19 UTC (rev 273476)
+++ trunk/Source/WebCore/dom/EventDispatcher.cpp	2021-02-25 08:30:59 UTC (rev 273477)
@@ -230,9 +230,4 @@
     dispatchEventWithType<EventTarget>(targets, event);
 }
 
-void EventDispatcher::dispatchEvent(const Vector<Element*>& targets, Event& event)
-{
-    dispatchEventWithType<Element>(targets, event);
 }
-
-}

Modified: trunk/Source/WebCore/dom/EventDispatcher.h (273476 => 273477)


--- trunk/Source/WebCore/dom/EventDispatcher.h	2021-02-25 07:32:19 UTC (rev 273476)
+++ trunk/Source/WebCore/dom/EventDispatcher.h	2021-02-25 08:30:59 UTC (rev 273477)
@@ -33,7 +33,6 @@
 
 void dispatchEvent(Node&, Event&);
 void dispatchEvent(const Vector<EventTarget*>&, Event&);
-void dispatchEvent(const Vector<Element*>&, Event&);
 
 void dispatchScopedEvent(Node&, Event&);
 

Modified: trunk/Source/WebCore/dom/EventPath.cpp (273476 => 273477)


--- trunk/Source/WebCore/dom/EventPath.cpp	2021-02-25 07:32:19 UTC (rev 273476)
+++ trunk/Source/WebCore/dom/EventPath.cpp	2021-02-25 08:30:59 UTC (rev 273477)
@@ -35,25 +35,6 @@
 
 namespace WebCore {
 
-class WindowEventContext final : public EventContext {
-public:
-    WindowEventContext(Node&, DOMWindow&, EventTarget&, int closedShadowDepth);
-private:
-    void handleLocalEvents(Event&, EventInvokePhase) const final;
-};
-
-inline WindowEventContext::WindowEventContext(Node& node, DOMWindow& currentTarget, EventTarget& target, int closedShadowDepth)
-    : EventContext(&node, &currentTarget, &target, closedShadowDepth)
-{
-}
-
-void WindowEventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const
-{
-    event.setTarget(m_target.get());
-    event.setCurrentTarget(m_currentTarget.get(), m_currentTargetIsInShadowTree);
-    m_currentTarget->fireEventListeners(event, phase);
-}
-
 static inline bool shouldEventCrossShadowBoundary(Event& event, ShadowRoot& shadowRoot, EventTarget& target)
 {
 #if ENABLE(FULLSCREEN_API) && ENABLE(VIDEO)
@@ -102,8 +83,8 @@
 {
     buildPath(originalTarget, event);
 
-    if (auto* relatedTarget = event.relatedTarget())
-        setRelatedTarget(originalTarget, *relatedTarget);
+    if (auto* relatedTarget = event.relatedTarget(); is<Node>(relatedTarget) && !m_path.isEmpty())
+        setRelatedTarget(originalTarget, downcast<Node>(*relatedTarget));
 
 #if ENABLE(TOUCH_EVENTS)
     if (is<TouchEvent>(event))
@@ -113,22 +94,15 @@
 
 void EventPath::buildPath(Node& originalTarget, Event& event)
 {
-    using MakeEventContext = std::unique_ptr<EventContext> (*)(Node&, EventTarget*, EventTarget*, int closedShadowDepth);
-    MakeEventContext makeEventContext = [] (Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth) {
-        return makeUnique<EventContext>(&node, currentTarget, target, closedShadowDepth);
-    };
-    if (is<MouseEvent>(event) || event.isFocusEvent()) {
-        makeEventContext = [] (Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth) -> std::unique_ptr<EventContext> {
-            return makeUnique<MouseOrFocusEventContext>(node, currentTarget, target, closedShadowDepth);
-        };
-    }
+    EventContext::Type contextType = [&]() {
+        if (is<MouseEvent>(event) || event.isFocusEvent())
+            return EventContext::Type::MouseOrFocus;
 #if ENABLE(TOUCH_EVENTS)
-    if (is<TouchEvent>(event)) {
-        makeEventContext = [] (Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth) -> std::unique_ptr<EventContext> {
-            return makeUnique<TouchEventContext>(node, currentTarget, target, closedShadowDepth);
-        };
-    }
+        if (is<TouchEvent>(event))
+            return EventContext::Type::Touch;
 #endif
+        return EventContext::Type::Normal;
+    }();
 
     Node* node = nodeOrHostIfPseudoElement(&originalTarget);
     Node* target = node ? eventTargetRespectingTargetRules(*node) : nullptr;
@@ -137,7 +111,7 @@
     // They could be negative for nodes outside the shadow tree of the target node.
     while (node) {
         while (node) {
-            m_path.append(makeEventContext(*node, eventTargetRespectingTargetRules(*node), target, closedShadowDepth));
+            m_path.append(EventContext { contextType, *node, eventTargetRespectingTargetRules(*node), target, closedShadowDepth });
 
             if (is<ShadowRoot>(*node))
                 break;
@@ -149,14 +123,13 @@
                     ASSERT(target);
                     if (target) {
                         if (auto* window = downcast<Document>(*node).domWindow())
-                            m_path.append(makeUnique<WindowEventContext>(*node, *window, *target, closedShadowDepth));
+                            m_path.append(EventContext { EventContext::Type::Window, node, window, target, closedShadowDepth });
                     }
                 }
                 return;
             }
 
-            auto* shadowRootOfParent = parent->shadowRoot();
-            if (UNLIKELY(shadowRootOfParent)) {
+            if (auto* shadowRootOfParent = parent->shadowRoot(); UNLIKELY(shadowRootOfParent)) {
                 if (auto* assignedSlot = shadowRootOfParent->findAssignedSlot(*node)) {
                     if (shadowRootOfParent->mode() != ShadowRootMode::Open)
                         closedShadowDepth++;
@@ -179,23 +152,20 @@
     }
 }
 
-void EventPath::setRelatedTarget(Node& origin, EventTarget& relatedTarget)
+void EventPath::setRelatedTarget(Node& origin, Node& relatedNode)
 {
-    if (!is<Node>(relatedTarget) || m_path.isEmpty())
-        return;
+    RelatedNodeRetargeter retargeter(relatedNode, *m_path[0].node());
 
-    auto& relatedNode = downcast<Node>(relatedTarget);
-    RelatedNodeRetargeter retargeter(relatedNode, *m_path[0]->node());
-
     bool originIsRelatedTarget = &origin == &relatedNode;
     Node& rootNodeInOriginTreeScope = origin.treeScope().rootNode();
     TreeScope* previousTreeScope = nullptr;
     size_t originalEventPathSize = m_path.size();
     for (unsigned contextIndex = 0; contextIndex < originalEventPathSize; contextIndex++) {
-        auto& ambgiousContext = *m_path[contextIndex];
-        if (!is<MouseOrFocusEventContext>(ambgiousContext))
+        auto& context = m_path[contextIndex];
+        if (!context.isMouseOrFocusEventContext()) {
+            ASSERT(context.isWindowContext());
             continue;
-        auto& context = downcast<MouseOrFocusEventContext>(ambgiousContext);
+        }
 
         Node& currentTarget = *context.node();
         TreeScope& currentTreeScope = currentTarget.treeScope();
@@ -221,30 +191,31 @@
 
 #if ENABLE(TOUCH_EVENTS)
 
-void EventPath::retargetTouch(TouchEventContext::TouchListType type, const Touch& touch)
+void EventPath::retargetTouch(EventContext::TouchListType type, const Touch& touch)
 {
     auto* eventTarget = touch.target();
     if (!is<Node>(eventTarget))
         return;
 
-    RelatedNodeRetargeter retargeter(downcast<Node>(*eventTarget), *m_path[0]->node());
+    RelatedNodeRetargeter retargeter(downcast<Node>(*eventTarget), *m_path[0].node());
     TreeScope* previousTreeScope = nullptr;
     for (auto& context : m_path) {
-        Node& currentTarget = *context->node();
+        Node& currentTarget = *context.node();
         TreeScope& currentTreeScope = currentTarget.treeScope();
         if (UNLIKELY(previousTreeScope && &currentTreeScope != previousTreeScope))
             retargeter.moveToNewTreeScope(previousTreeScope, currentTreeScope);
 
-        if (is<TouchEventContext>(*context)) {
+        if (context.isTouchEventContext()) {
             Node* currentRelatedNode = retargeter.currentNode(currentTarget);
-            downcast<TouchEventContext>(*context).touchList(type).append(touch.cloneWithNewTarget(currentRelatedNode));
-        }
+            context.touchList(type).append(touch.cloneWithNewTarget(currentRelatedNode));
+        } else
+            ASSERT(context.isWindowContext());
 
         previousTreeScope = &currentTreeScope;
     }
 }
 
-void EventPath::retargetTouchList(TouchEventContext::TouchListType type, const TouchList* list)
+void EventPath::retargetTouchList(EventContext::TouchListType type, const TouchList* list)
 {
     for (unsigned i = 0, length = list ? list->length() : 0; i < length; ++i)
         retargetTouch(type, *list->item(i));
@@ -252,9 +223,9 @@
 
 void EventPath::retargetTouchLists(const TouchEvent& event)
 {
-    retargetTouchList(TouchEventContext::Touches, event.touches());
-    retargetTouchList(TouchEventContext::TargetTouches, event.targetTouches());
-    retargetTouchList(TouchEventContext::ChangedTouches, event.changedTouches());
+    retargetTouchList(EventContext::TouchListType::Touches, event.touches());
+    retargetTouchList(EventContext::TouchListType::TargetTouches, event.targetTouches());
+    retargetTouchList(EventContext::TouchListType::ChangedTouches, event.changedTouches());
 }
 
 #endif
@@ -271,10 +242,10 @@
     path.reserveInitialCapacity(pathSize);
 
     auto currentTargetIndex = m_path.findMatching([&target] (auto& context) {
-        return context->currentTarget() == &target;
+        return context.currentTarget() == &target;
     });
     RELEASE_ASSERT(currentTargetIndex != notFound);
-    auto currentTargetDepth = m_path[currentTargetIndex]->closedShadowDepth();
+    auto currentTargetDepth = m_path[currentTargetIndex].closedShadowDepth();
 
     auto appendTargetWithLesserDepth = [&path] (const EventContext& currentContext, int& currentDepthAllowed) {
         auto depth = currentContext.closedShadowDepth();
@@ -290,34 +261,23 @@
     auto currentDepthAllowed = currentTargetDepth;
     auto i = currentTargetIndex;
     do {
-        appendTargetWithLesserDepth(*m_path[i], currentDepthAllowed);
+        appendTargetWithLesserDepth(m_path[i], currentDepthAllowed);
     } while (i--);
     path.reverse();
 
     currentDepthAllowed = currentTargetDepth;
     for (auto i = currentTargetIndex + 1; i < pathSize; ++i)
-        appendTargetWithLesserDepth(*m_path[i], currentDepthAllowed);
-    
+        appendTargetWithLesserDepth(m_path[i], currentDepthAllowed);
+
     return path;
 }
 
-EventPath::EventPath(const Vector<Element*>& targets)
-{
-    // FIXME: This function seems wrong. Why are we not firing events in the closed shadow trees?
-    for (auto* target : targets) {
-        ASSERT(target);
-        Node* origin = *targets.begin();
-        if (!target->isClosedShadowHidden(*origin))
-            m_path.append(makeUnique<EventContext>(target, target, origin, 0));
-    }
-}
-
 EventPath::EventPath(const Vector<EventTarget*>& targets)
 {
     for (auto* target : targets) {
         ASSERT(target);
         ASSERT(!is<Node>(target));
-        m_path.append(makeUnique<EventContext>(nullptr, target, *targets.begin(), 0));
+        m_path.append(EventContext { EventContext::Type::Normal, nullptr, target, *targets.begin(), 0 });
     }
 }
 

Modified: trunk/Source/WebCore/dom/EventPath.h (273476 => 273477)


--- trunk/Source/WebCore/dom/EventPath.h	2021-02-25 07:32:19 UTC (rev 273476)
+++ trunk/Source/WebCore/dom/EventPath.h	2021-02-25 08:30:59 UTC (rev 273477)
@@ -35,12 +35,11 @@
 public:
     EventPath(Node& origin, Event&);
     explicit EventPath(const Vector<EventTarget*>&);
-    explicit EventPath(const Vector<Element*>&);
 
     bool isEmpty() const { return m_path.isEmpty(); }
     size_t size() const { return m_path.size(); }
-    const EventContext& contextAt(size_t i) const { return *m_path[i]; }
-    EventContext& contextAt(size_t i) { return *m_path[i]; }
+    const EventContext& contextAt(size_t i) const { return m_path[i]; }
+    EventContext& contextAt(size_t i) { return m_path[i]; }
 
     Vector<EventTarget*> computePathUnclosedToTarget(const EventTarget&) const;
 
@@ -48,15 +47,15 @@
 
 private:
     void buildPath(Node& origin, Event&);
-    void setRelatedTarget(Node& origin, EventTarget&);
+    void setRelatedTarget(Node& origin, Node&);
 
 #if ENABLE(TOUCH_EVENTS)
-    void retargetTouch(TouchEventContext::TouchListType, const Touch&);
-    void retargetTouchList(TouchEventContext::TouchListType, const TouchList*);
+    void retargetTouch(EventContext::TouchListType, const Touch&);
+    void retargetTouchList(EventContext::TouchListType, const TouchList*);
     void retargetTouchLists(const TouchEvent&);
 #endif
 
-    Vector<std::unique_ptr<EventContext>, 32> m_path;
+    Vector<EventContext, 16> m_path;
 };
 
 inline Node* EventPath::eventTargetRespectingTargetRules(Node& referenceNode)

Modified: trunk/Source/WebCore/dom/Node.cpp (273476 => 273477)


--- trunk/Source/WebCore/dom/Node.cpp	2021-02-25 07:32:19 UTC (rev 273476)
+++ trunk/Source/WebCore/dom/Node.cpp	2021-02-25 08:30:59 UTC (rev 273477)
@@ -2364,18 +2364,6 @@
     }
 }
 
-void Node::handleLocalEvents(Event& event, EventInvokePhase phase)
-{
-    if (!hasEventTargetData())
-        return;
-
-    // FIXME: Should we deliver wheel events to disabled form controls or not?
-    if (is<Element>(*this) && downcast<Element>(*this).isDisabledFormControl() && event.isTrusted() && event.isMouseEvent() && !event.isWheelEvent())
-        return;
-
-    fireEventListeners(event, phase);
-}
-
 void Node::dispatchScopedEvent(Event& event)
 {
     EventDispatcher::dispatchScopedEvent(*this, event);

Modified: trunk/Source/WebCore/dom/Node.h (273476 => 273477)


--- trunk/Source/WebCore/dom/Node.h	2021-02-25 07:32:19 UTC (rev 273476)
+++ trunk/Source/WebCore/dom/Node.h	2021-02-25 08:30:59 UTC (rev 273477)
@@ -453,8 +453,6 @@
 
     void dispatchScopedEvent(Event&);
 
-    virtual void handleLocalEvents(Event&, EventInvokePhase);
-
     void dispatchSubtreeModifiedEvent();
     void dispatchDOMActivateEvent(Event& underlyingClickEvent);
 

Modified: trunk/Source/WebCore/html/HTMLFormElement.cpp (273476 => 273477)


--- trunk/Source/WebCore/html/HTMLFormElement.cpp	2021-02-25 07:32:19 UTC (rev 273476)
+++ trunk/Source/WebCore/html/HTMLFormElement.cpp	2021-02-25 08:30:59 UTC (rev 273477)
@@ -149,15 +149,6 @@
     HTMLElement::removedFromAncestor(removalType, oldParentOfRemovedTree);
 }
 
-void HTMLFormElement::handleLocalEvents(Event& event, EventInvokePhase phase)
-{
-    if (event.eventPhase() != Event::CAPTURING_PHASE && is<Node>(event.target()) && event.target() != this && (event.type() == eventNames().submitEvent || event.type() == eventNames().resetEvent)) {
-        event.stopPropagation();
-        return;
-    }
-    HTMLElement::handleLocalEvents(event, phase);
-}
-
 unsigned HTMLFormElement::length() const
 {
     unsigned length = 0;

Modified: trunk/Source/WebCore/html/HTMLFormElement.h (273476 => 273477)


--- trunk/Source/WebCore/html/HTMLFormElement.h	2021-02-25 07:32:19 UTC (rev 273476)
+++ trunk/Source/WebCore/html/HTMLFormElement.h	2021-02-25 08:30:59 UTC (rev 273477)
@@ -131,8 +131,6 @@
     void removedFromAncestor(RemovalType, ContainerNode&) final;
     void finishParsingChildren() final;
 
-    void handleLocalEvents(Event&, EventInvokePhase) final;
-
     void parseAttribute(const QualifiedName&, const AtomString&) final;
     bool isURLAttribute(const Attribute&) const final;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to