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, ¤tTarget, &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 && ¤tTreeScope != 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 = ¤tTreeScope;
}
}
-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() == ⌖
+ return context.currentTarget() == ⌖
});
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;