Changeset 273477 in webkit
- Timestamp:
- Feb 25, 2021, 12:30:59 AM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 11 edited
-
ChangeLog (modified) (1 diff)
-
dom/EventContext.cpp (modified) (2 diffs)
-
dom/EventContext.h (modified) (6 diffs)
-
dom/EventDispatcher.cpp (modified) (1 diff)
-
dom/EventDispatcher.h (modified) (1 diff)
-
dom/EventPath.cpp (modified) (16 diffs)
-
dom/EventPath.h (modified) (2 diffs)
-
dom/Node.cpp (modified) (1 diff)
-
dom/Node.h (modified) (1 diff)
-
html/HTMLFormElement.cpp (modified) (1 diff)
-
html/HTMLFormElement.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r273474 r273477 1 2021-02-25 Ryosuke Niwa <rniwa@webkit.org> 2 3 Avoid heap allocation for EventContexts 4 https://bugs.webkit.org/show_bug.cgi?id=222095 5 <rdar://problem/74586915> 6 7 Reviewed by Simon Fraser. 8 9 This patch merges all subclasses of EventContext into itself to avoid heap allocation for each 10 EventContext in EventPath::m_path. It also merges Node::handleLocalEvents into EventContext's 11 handleLocalEvents to avoid the extra virtual function call. 12 13 No new tests since there should be no observable behavioral differences. 14 15 * dom/EventContext.cpp: 16 (WebCore::EventContext::EventContext): Moved to the header to be inlined. 17 (WebCore::EventContext::handleLocalEvents const): Merged handleLocalEvents of HTMLFormElement 18 and Node. Moved the code to handle related target and touch targets from MouseOrFocusEventContext 19 and TouchEventContext as they have been merged into this class. Also special case dispatching 20 an event on window to preserve the behavior of WindowEventContext. 21 (WebCore::EventContext::initializeTouchLists): Added. Creates TouchList objects. 22 (WebCore::EventContext::isUnreachableNode const): Moved from the header. 23 (WebCore::EventContext::isMouseOrFocusEventContext const): Deleted. 24 (WebCore::EventContext::isTouchEventContext const): Deleted. 25 (WebCore::MouseOrFocusEventContext::MouseOrFocusEventContext): Deleted. 26 (WebCore::MouseOrFocusEventContext::handleLocalEvents const): Deleted. 27 (WebCore::MouseOrFocusEventContext::isMouseOrFocusEventContext const): Deleted. 28 (WebCore::TouchEventContext::TouchEventContext): Deleted. 29 (WebCore::TouchEventContext::handleLocalEvents const): Deleted. 30 (WebCore::TouchEventContext::isTouchEventContext const): Deleted. 31 (WebCore::TouchEventContext::checkReachability const): Deleted. Merged into handleLocalEvents. 32 * dom/EventContext.h: 33 (WebCore::EventContext::isMouseOrFocusEventContext const): Now simply checks m_type. 34 (WebCore::EventContext::isTouchEventContext const): Ditto. 35 (WebCore::EventContext::isWindowContext const): Ditto. 36 (WebCore::EventContext::relatedTarget const): Moved from MouseOrFocusEventContext. 37 (WebCore::EventContext::setRelatedTarget): Ditto. 38 (WebCore::EventContext::touchList): Moved from TouchEventContext. 39 (WebCore::m_contextNodeIsFormElement): Added. Caching this state here instead of checking it at 40 every event context during dispatching in EventContext::handleLocalEvents seems to be important 41 to get a speed up in Intel processors. Apple silicons don't seem to be affected by this. 42 (WebCore::m_type): Added. 43 (WebCore::MouseOrFocusEventContext): Deleted. 44 (WebCore::MouseOrFocusEventContext::relatedTarget const): Deleted. 45 (WebCore::TouchEventContext): Deleted. 46 (WebCore::EventContext::EventContext): Moved from cpp file to be inlined here. 47 (WebCore::EventContext::isUnreachableNode const): Moved into cpp as this is only used for 48 asserting shadow DOM related conditions. 49 (WebCore::EventContext::touchList): Renamed from TouchEventContext::touchList. 50 (isType): Deleted. 51 * dom/EventDispatcher.cpp: 52 (WebCore::EventDispatcher::dispatchEvent): Deleted the variant that takes a vector of elements 53 since it's not used anywhere. 54 * dom/EventDispatcher.h: 55 * dom/EventPath.cpp: 56 (WebCore::WindowEventContext): Deleted. 57 (WebCore::EventPath::EventPath): Avoid calling setRelatedTarget if related target is not a node 58 or the path is empty. These were early return conditions in setRelatedTarget before this patch. 59 (WebCore::EventPath::buildPath): Always create EventContext. Dramatically simplifies the code. 60 (WebCore::EventPath::setRelatedTarget): Moved the early exit to EventPath::EventPath. 61 (WebCore::EventPath::retargetTouch): 62 (WebCore::EventPath::retargetTouchList): 63 (WebCore::EventPath::retargetTouchLists): 64 (WebCore::EventPath::EventPath): Deleted the variant which takes a vector of elements as it's 65 not used anywhere. 66 * dom/EventPath.h: 67 (WebCore::EventPath::contextAt const): 68 (WebCore::EventPath::contextAt): 69 (WebCore::EventPath::m_path): Now allocates EventContext in place. The size of the inline buffer 70 has been reduced to 16 entries for EventContext from 32 entries for std::unique_ptr<EventContext> 71 since the former is considerably larger than the latter. 72 * dom/Node.cpp: 73 (WebCore::Node::handleLocalEvents): Deleted. Merged into EventContext::handleLocalEvents. 74 * dom/Node.h: 75 * html/HTMLFormElement.cpp: 76 (WebCore::HTMLFormElement::handleLocalEvents): Ditto. 77 * html/HTMLFormElement.h: 78 1 79 2021-02-24 Ryosuke Niwa <rniwa@webkit.org> 2 80 -
trunk/Source/WebCore/dom/EventContext.cpp
r269546 r273477 29 29 #include "EventContext.h" 30 30 31 #include "DOMWindow.h" 31 32 #include "Document.h" 32 33 #include "FocusEvent.h" 34 #include "HTMLFormElement.h" 33 35 #include "MouseEvent.h" 34 36 #include "TouchEvent.h" 35 37 36 38 namespace WebCore { 37 38 EventContext::EventContext(Node* node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth)39 : m_node { node }40 , m_currentTarget { currentTarget }41 , m_target { target }42 , m_closedShadowDepth { closedShadowDepth }43 , m_currentTargetIsInShadowTree { is<Node>(currentTarget) && downcast<Node>(*currentTarget).isInShadowTree() }44 {45 ASSERT(!isUnreachableNode(m_target.get()));46 }47 39 48 40 EventContext::~EventContext() = default; … … 52 44 event.setTarget(m_target.get()); 53 45 event.setCurrentTarget(m_currentTarget.get(), m_currentTargetIsInShadowTree); 54 // FIXME: Consider merging handleLocalEvents and fireEventListeners. 55 if (m_node) 56 m_node->handleLocalEvents(event, phase); 57 else 46 47 if (m_relatedTarget) { 48 ASSERT(m_type == Type::MouseOrFocus); 49 event.setRelatedTarget(m_relatedTarget.get()); 50 } 51 52 #if ENABLE(TOUCH_EVENTS) 53 if (m_type == Type::Touch) { 54 55 #if ASSERT_ENABLED 56 auto checkReachability = [&](const Ref<TouchList>& touchList) { 57 size_t length = touchList->length(); 58 for (size_t i = 0; i < length; ++i) 59 ASSERT(!isUnreachableNode(downcast<Node>(touchList->item(i)->target()))); 60 } 61 checkReachability(m_touches); 62 checkReachability(m_targetTouches); 63 checkReachability(m_changedTouches); 64 #endif 65 66 auto& touchEvent = downcast<TouchEvent>(event); 67 touchEvent.setTouches(m_touches.get()); 68 touchEvent.setTargetTouches(m_targetTouches.get()); 69 touchEvent.setChangedTouches(m_changedTouches.get()); 70 } 71 #endif 72 73 if (!m_node || UNLIKELY(m_type == Type::Window)) { 58 74 m_currentTarget->fireEventListeners(event, phase); 59 } 75 return; 76 } 60 77 61 bool EventContext::isMouseOrFocusEventContext() const 62 { 63 return false; 64 } 78 if (UNLIKELY(m_contextNodeIsFormElement)) { 79 ASSERT(is<HTMLFormElement>(*m_node)); 80 if ((event.type() == eventNames().submitEvent || event.type() == eventNames().resetEvent) 81 && event.eventPhase() != Event::CAPTURING_PHASE && event.target() != m_node && is<Node>(event.target())) { 82 event.stopPropagation(); 83 return; 84 } 85 } 65 86 66 bool EventContext::isTouchEventContext() const 67 { 68 return false; 69 } 87 if (!m_node->hasEventTargetData()) 88 return; 70 89 71 MouseOrFocusEventContext::MouseOrFocusEventContext(Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth) 72 : EventContext(&node, currentTarget, target, closedShadowDepth) 73 { 74 } 90 // FIXME: Should we deliver wheel events to disabled form controls or not? 91 if (event.isTrusted() && is<Element>(m_node) && downcast<Element>(*m_node).isDisabledFormControl() && event.isMouseEvent() && !event.isWheelEvent()) 92 return; 75 93 76 MouseOrFocusEventContext::~MouseOrFocusEventContext() = default; 77 78 void MouseOrFocusEventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const 79 { 80 if (m_relatedTarget) 81 event.setRelatedTarget(m_relatedTarget.get()); 82 EventContext::handleLocalEvents(event, phase); 83 } 84 85 bool MouseOrFocusEventContext::isMouseOrFocusEventContext() const 86 { 87 return true; 94 m_node->fireEventListeners(event, phase); 88 95 } 89 96 90 97 #if ENABLE(TOUCH_EVENTS) 91 98 92 TouchEventContext::TouchEventContext(Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth) 93 : EventContext(&node, currentTarget, target, closedShadowDepth) 94 , m_touches(TouchList::create()) 95 , m_targetTouches(TouchList::create()) 96 , m_changedTouches(TouchList::create()) 99 void EventContext::initializeTouchLists() 97 100 { 101 m_touches = TouchList::create(); 102 m_targetTouches = TouchList::create(); 103 m_changedTouches = TouchList::create(); 98 104 } 99 105 100 TouchEventContext::~TouchEventContext() = default; 101 102 void TouchEventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const 103 { 104 checkReachability(m_touches); 105 checkReachability(m_targetTouches); 106 checkReachability(m_changedTouches); 107 auto& touchEvent = downcast<TouchEvent>(event); 108 touchEvent.setTouches(m_touches.ptr()); 109 touchEvent.setTargetTouches(m_targetTouches.ptr()); 110 touchEvent.setChangedTouches(m_changedTouches.ptr()); 111 EventContext::handleLocalEvents(event, phase); 112 } 113 114 bool TouchEventContext::isTouchEventContext() const 115 { 116 return true; 117 } 106 #endif // ENABLE(TOUCH_EVENTS) 118 107 119 108 #if ASSERT_ENABLED 120 109 121 void TouchEventContext::checkReachability(const Ref<TouchList>& touchList) const110 bool EventContext::isUnreachableNode(EventTarget* target) const 122 111 { 123 size_t length = touchList->length(); 124 for (size_t i = 0; i < length; ++i) 125 ASSERT(!isUnreachableNode(downcast<Node>(touchList->item(i)->target()))); 112 // FIXME: Checks also for SVG elements. 113 return is<Node>(target) && !downcast<Node>(*target).isSVGElement() && m_node->isClosedShadowHidden(downcast<Node>(*target)); 126 114 } 127 115 128 #endif // ASSERT_ENABLED 129 130 #endif // ENABLE(TOUCH_EVENTS) 116 #endif 131 117 132 118 } -
trunk/Source/WebCore/dom/EventContext.h
r269546 r273477 28 28 #pragma once 29 29 30 #include " Node.h"30 #include "HTMLFormElement.h" 31 31 32 32 namespace WebCore { … … 39 39 using EventInvokePhase = EventTarget::EventInvokePhase; 40 40 41 EventContext(Node*, EventTarget* currentTarget, EventTarget*, int closedShadowDepth); 42 virtual ~EventContext(); 41 enum class Type : uint8_t { 42 Normal = 0, 43 MouseOrFocus, 44 Touch, 45 Window, 46 }; 47 48 EventContext(Type, Node*, EventTarget* currentTarget, EventTarget* origin, int closedShadowDepth); 49 EventContext(Type, Node&, Node* currentTarget, EventTarget* origin, int closedShadowDepth); 50 ~EventContext(); 43 51 44 52 Node* node() const { return m_node.get(); } … … 48 56 int closedShadowDepth() const { return m_closedShadowDepth; } 49 57 50 v irtual void handleLocalEvents(Event&, EventInvokePhase) const;58 void handleLocalEvents(Event&, EventInvokePhase) const; 51 59 52 virtual bool isMouseOrFocusEventContext() const; 53 virtual bool isTouchEventContext() const; 60 bool isMouseOrFocusEventContext() const { return m_type == Type::MouseOrFocus; } 61 bool isTouchEventContext() const { return m_type == Type::Touch; } 62 bool isWindowContext() const { return m_type == Type::Window; } 54 63 55 virtual Node* relatedTarget() const { return nullptr; } 64 Node* relatedTarget() const { return m_relatedTarget.get(); } 65 void setRelatedTarget(Node*); 56 66 57 protected: 67 #if ENABLE(TOUCH_EVENTS) 68 enum TouchListType { Touches, TargetTouches, ChangedTouches }; 69 TouchList& touchList(TouchListType); 70 #endif 71 72 private: 73 inline EventContext(Type, Node* currentNode, RefPtr<EventTarget>&& currentTarget, EventTarget* origin, int closedShadowDepth, bool currentTargetIsInShadowTree = false); 74 75 #if ENABLE(TOUCH_EVENTS) 76 void initializeTouchLists(); 77 #endif 78 58 79 #if ASSERT_ENABLED 59 80 bool isUnreachableNode(EventTarget*) const; … … 63 84 RefPtr<EventTarget> m_currentTarget; 64 85 RefPtr<EventTarget> m_target; 86 RefPtr<Node> m_relatedTarget; 87 #if ENABLE(TOUCH_EVENTS) 88 RefPtr<TouchList> m_touches; 89 RefPtr<TouchList> m_targetTouches; 90 RefPtr<TouchList> m_changedTouches; 91 #endif 65 92 int m_closedShadowDepth { 0 }; 66 93 bool m_currentTargetIsInShadowTree { false }; 94 bool m_contextNodeIsFormElement { false }; 95 Type m_type { Type::Normal }; 67 96 }; 68 97 69 class MouseOrFocusEventContext final : public EventContext { 70 public: 71 MouseOrFocusEventContext(Node&, EventTarget* currentTarget, EventTarget*, int closedShadowDepth); 72 virtual ~MouseOrFocusEventContext(); 73 74 Node* relatedTarget() const final { return m_relatedTarget.get(); } 75 void setRelatedTarget(Node*); 76 77 private: 78 void handleLocalEvents(Event&, EventInvokePhase) const final; 79 bool isMouseOrFocusEventContext() const final; 80 81 RefPtr<Node> m_relatedTarget; 82 }; 83 98 inline EventContext::EventContext(Type type, Node* node, RefPtr<EventTarget>&& currentTarget, EventTarget* origin, int closedShadowDepth, bool currentTargetIsInShadowTree) 99 : m_node { node } 100 , m_currentTarget { WTFMove(currentTarget) } 101 , m_target { origin } 102 , m_closedShadowDepth { closedShadowDepth } 103 , m_currentTargetIsInShadowTree { currentTargetIsInShadowTree } 104 , m_type { type } 105 { 106 ASSERT(!isUnreachableNode(m_target.get())); 84 107 #if ENABLE(TOUCH_EVENTS) 85 86 class TouchEventContext final : public EventContext { 87 public: 88 TouchEventContext(Node&, EventTarget* currentTarget, EventTarget*, int closedShadowDepth); 89 virtual ~TouchEventContext(); 90 91 enum TouchListType { Touches, TargetTouches, ChangedTouches }; 92 TouchList& touchList(TouchListType); 93 94 private: 95 void handleLocalEvents(Event&, EventInvokePhase) const final; 96 bool isTouchEventContext() const final; 97 98 void checkReachability(const Ref<TouchList>&) const; 99 100 Ref<TouchList> m_touches; 101 Ref<TouchList> m_targetTouches; 102 Ref<TouchList> m_changedTouches; 103 }; 104 105 #endif // ENABLE(TOUCH_EVENTS) 106 107 #if ASSERT_ENABLED 108 109 inline bool EventContext::isUnreachableNode(EventTarget* target) const 110 { 111 // FIXME: Checks also for SVG elements. 112 return is<Node>(target) && !downcast<Node>(*target).isSVGElement() && m_node->isClosedShadowHidden(downcast<Node>(*target)); 108 if (m_type == Type::Touch) 109 initializeTouchLists(); 110 #else 111 ASSERT(m_type != Type::Touch); 112 #endif 113 113 } 114 114 115 #endif 115 inline EventContext::EventContext(Type type, Node* node, EventTarget* currentTarget, EventTarget* origin, int closedShadowDepth) 116 : EventContext(type, node, makeRefPtr(currentTarget), origin, closedShadowDepth) 117 { 118 ASSERT(!is<Node>(currentTarget)); 119 } 116 120 117 inline void MouseOrFocusEventContext::setRelatedTarget(Node* relatedTarget) 121 // This variant avoids calling EventTarget::ref() which is a virtual function call. 122 inline EventContext::EventContext(Type type, Node& node, Node* currentTarget, EventTarget* origin, int closedShadowDepth) 123 : EventContext(type, &node, makeRefPtr(currentTarget), origin, closedShadowDepth, currentTarget && currentTarget->isInShadowTree()) 124 { 125 m_contextNodeIsFormElement = is<HTMLFormElement>(node); 126 } 127 128 inline void EventContext::setRelatedTarget(Node* relatedTarget) 118 129 { 119 130 ASSERT(!isUnreachableNode(relatedTarget)); … … 123 134 #if ENABLE(TOUCH_EVENTS) 124 135 125 inline TouchList& TouchEventContext::touchList(TouchListType type)136 inline TouchList& EventContext::touchList(TouchListType type) 126 137 { 127 138 switch (type) { 128 139 case Touches: 129 return m_touches.get();140 return *m_touches; 130 141 case TargetTouches: 131 return m_targetTouches.get();142 return *m_targetTouches; 132 143 case ChangedTouches: 133 return m_changedTouches.get();144 return *m_changedTouches; 134 145 } 135 146 ASSERT_NOT_REACHED(); 136 return m_touches.get(); 137 } 138 139 #endif 140 141 #if ENABLE(TOUCH_EVENTS) && !ASSERT_ENABLED 142 143 inline void TouchEventContext::checkReachability(const Ref<TouchList>&) const 144 { 147 return *m_touches; 145 148 } 146 149 … … 148 151 149 152 } // namespace WebCore 150 151 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::MouseOrFocusEventContext)152 static bool isType(const WebCore::EventContext& context) { return context.isMouseOrFocusEventContext(); }153 SPECIALIZE_TYPE_TRAITS_END()154 155 #if ENABLE(TOUCH_EVENTS)156 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::TouchEventContext)157 static bool isType(const WebCore::EventContext& context) { return context.isTouchEventContext(); }158 SPECIALIZE_TYPE_TRAITS_END()159 #endif -
trunk/Source/WebCore/dom/EventDispatcher.cpp
r269789 r273477 231 231 } 232 232 233 void EventDispatcher::dispatchEvent(const Vector<Element*>& targets, Event& event) 234 { 235 dispatchEventWithType<Element>(targets, event); 236 } 237 238 } 233 } -
trunk/Source/WebCore/dom/EventDispatcher.h
r228827 r273477 34 34 void dispatchEvent(Node&, Event&); 35 35 void dispatchEvent(const Vector<EventTarget*>&, Event&); 36 void dispatchEvent(const Vector<Element*>&, Event&);37 36 38 37 void dispatchScopedEvent(Node&, Event&); -
trunk/Source/WebCore/dom/EventPath.cpp
r269500 r273477 36 36 namespace WebCore { 37 37 38 class WindowEventContext final : public EventContext {39 public:40 WindowEventContext(Node&, DOMWindow&, EventTarget&, int closedShadowDepth);41 private:42 void handleLocalEvents(Event&, EventInvokePhase) const final;43 };44 45 inline WindowEventContext::WindowEventContext(Node& node, DOMWindow& currentTarget, EventTarget& target, int closedShadowDepth)46 : EventContext(&node, ¤tTarget, &target, closedShadowDepth)47 {48 }49 50 void WindowEventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const51 {52 event.setTarget(m_target.get());53 event.setCurrentTarget(m_currentTarget.get(), m_currentTargetIsInShadowTree);54 m_currentTarget->fireEventListeners(event, phase);55 }56 57 38 static inline bool shouldEventCrossShadowBoundary(Event& event, ShadowRoot& shadowRoot, EventTarget& target) 58 39 { … … 103 84 buildPath(originalTarget, event); 104 85 105 if (auto* relatedTarget = event.relatedTarget() )106 setRelatedTarget(originalTarget, *relatedTarget);86 if (auto* relatedTarget = event.relatedTarget(); is<Node>(relatedTarget) && !m_path.isEmpty()) 87 setRelatedTarget(originalTarget, downcast<Node>(*relatedTarget)); 107 88 108 89 #if ENABLE(TOUCH_EVENTS) … … 114 95 void EventPath::buildPath(Node& originalTarget, Event& event) 115 96 { 116 using MakeEventContext = std::unique_ptr<EventContext> (*)(Node&, EventTarget*, EventTarget*, int closedShadowDepth); 117 MakeEventContext makeEventContext = [] (Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth) { 118 return makeUnique<EventContext>(&node, currentTarget, target, closedShadowDepth); 119 }; 120 if (is<MouseEvent>(event) || event.isFocusEvent()) { 121 makeEventContext = [] (Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth) -> std::unique_ptr<EventContext> { 122 return makeUnique<MouseOrFocusEventContext>(node, currentTarget, target, closedShadowDepth); 123 }; 124 } 97 EventContext::Type contextType = [&]() { 98 if (is<MouseEvent>(event) || event.isFocusEvent()) 99 return EventContext::Type::MouseOrFocus; 125 100 #if ENABLE(TOUCH_EVENTS) 126 if (is<TouchEvent>(event)) { 127 makeEventContext = [] (Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth) -> std::unique_ptr<EventContext> { 128 return makeUnique<TouchEventContext>(node, currentTarget, target, closedShadowDepth); 129 }; 130 } 101 if (is<TouchEvent>(event)) 102 return EventContext::Type::Touch; 131 103 #endif 104 return EventContext::Type::Normal; 105 }(); 132 106 133 107 Node* node = nodeOrHostIfPseudoElement(&originalTarget); … … 138 112 while (node) { 139 113 while (node) { 140 m_path.append( makeEventContext(*node, eventTargetRespectingTargetRules(*node), target, closedShadowDepth));114 m_path.append(EventContext { contextType, *node, eventTargetRespectingTargetRules(*node), target, closedShadowDepth }); 141 115 142 116 if (is<ShadowRoot>(*node)) … … 150 124 if (target) { 151 125 if (auto* window = downcast<Document>(*node).domWindow()) 152 m_path.append( makeUnique<WindowEventContext>(*node, *window, *target, closedShadowDepth));126 m_path.append(EventContext { EventContext::Type::Window, node, window, target, closedShadowDepth }); 153 127 } 154 128 } … … 156 130 } 157 131 158 auto* shadowRootOfParent = parent->shadowRoot(); 159 if (UNLIKELY(shadowRootOfParent)) { 132 if (auto* shadowRootOfParent = parent->shadowRoot(); UNLIKELY(shadowRootOfParent)) { 160 133 if (auto* assignedSlot = shadowRootOfParent->findAssignedSlot(*node)) { 161 134 if (shadowRootOfParent->mode() != ShadowRootMode::Open) … … 180 153 } 181 154 182 void EventPath::setRelatedTarget(Node& origin, EventTarget& relatedTarget) 183 { 184 if (!is<Node>(relatedTarget) || m_path.isEmpty()) 185 return; 186 187 auto& relatedNode = downcast<Node>(relatedTarget); 188 RelatedNodeRetargeter retargeter(relatedNode, *m_path[0]->node()); 155 void EventPath::setRelatedTarget(Node& origin, Node& relatedNode) 156 { 157 RelatedNodeRetargeter retargeter(relatedNode, *m_path[0].node()); 189 158 190 159 bool originIsRelatedTarget = &origin == &relatedNode; … … 193 162 size_t originalEventPathSize = m_path.size(); 194 163 for (unsigned contextIndex = 0; contextIndex < originalEventPathSize; contextIndex++) { 195 auto& ambgiousContext = *m_path[contextIndex]; 196 if (!is<MouseOrFocusEventContext>(ambgiousContext)) 164 auto& context = m_path[contextIndex]; 165 if (!context.isMouseOrFocusEventContext()) { 166 ASSERT(context.isWindowContext()); 197 167 continue; 198 auto& context = downcast<MouseOrFocusEventContext>(ambgiousContext);168 } 199 169 200 170 Node& currentTarget = *context.node(); … … 222 192 #if ENABLE(TOUCH_EVENTS) 223 193 224 void EventPath::retargetTouch( TouchEventContext::TouchListType type, const Touch& touch)194 void EventPath::retargetTouch(EventContext::TouchListType type, const Touch& touch) 225 195 { 226 196 auto* eventTarget = touch.target(); … … 228 198 return; 229 199 230 RelatedNodeRetargeter retargeter(downcast<Node>(*eventTarget), *m_path[0] ->node());200 RelatedNodeRetargeter retargeter(downcast<Node>(*eventTarget), *m_path[0].node()); 231 201 TreeScope* previousTreeScope = nullptr; 232 202 for (auto& context : m_path) { 233 Node& currentTarget = *context ->node();203 Node& currentTarget = *context.node(); 234 204 TreeScope& currentTreeScope = currentTarget.treeScope(); 235 205 if (UNLIKELY(previousTreeScope && ¤tTreeScope != previousTreeScope)) 236 206 retargeter.moveToNewTreeScope(previousTreeScope, currentTreeScope); 237 207 238 if ( is<TouchEventContext>(*context)) {208 if (context.isTouchEventContext()) { 239 209 Node* currentRelatedNode = retargeter.currentNode(currentTarget); 240 downcast<TouchEventContext>(*context).touchList(type).append(touch.cloneWithNewTarget(currentRelatedNode)); 241 } 210 context.touchList(type).append(touch.cloneWithNewTarget(currentRelatedNode)); 211 } else 212 ASSERT(context.isWindowContext()); 242 213 243 214 previousTreeScope = ¤tTreeScope; … … 245 216 } 246 217 247 void EventPath::retargetTouchList( TouchEventContext::TouchListType type, const TouchList* list)218 void EventPath::retargetTouchList(EventContext::TouchListType type, const TouchList* list) 248 219 { 249 220 for (unsigned i = 0, length = list ? list->length() : 0; i < length; ++i) … … 253 224 void EventPath::retargetTouchLists(const TouchEvent& event) 254 225 { 255 retargetTouchList( TouchEventContext::Touches, event.touches());256 retargetTouchList( TouchEventContext::TargetTouches, event.targetTouches());257 retargetTouchList( TouchEventContext::ChangedTouches, event.changedTouches());226 retargetTouchList(EventContext::TouchListType::Touches, event.touches()); 227 retargetTouchList(EventContext::TouchListType::TargetTouches, event.targetTouches()); 228 retargetTouchList(EventContext::TouchListType::ChangedTouches, event.changedTouches()); 258 229 } 259 230 … … 272 243 273 244 auto currentTargetIndex = m_path.findMatching([&target] (auto& context) { 274 return context ->currentTarget() == ⌖245 return context.currentTarget() == ⌖ 275 246 }); 276 247 RELEASE_ASSERT(currentTargetIndex != notFound); 277 auto currentTargetDepth = m_path[currentTargetIndex] ->closedShadowDepth();248 auto currentTargetDepth = m_path[currentTargetIndex].closedShadowDepth(); 278 249 279 250 auto appendTargetWithLesserDepth = [&path] (const EventContext& currentContext, int& currentDepthAllowed) { … … 291 262 auto i = currentTargetIndex; 292 263 do { 293 appendTargetWithLesserDepth( *m_path[i], currentDepthAllowed);264 appendTargetWithLesserDepth(m_path[i], currentDepthAllowed); 294 265 } while (i--); 295 266 path.reverse(); … … 297 268 currentDepthAllowed = currentTargetDepth; 298 269 for (auto i = currentTargetIndex + 1; i < pathSize; ++i) 299 appendTargetWithLesserDepth( *m_path[i], currentDepthAllowed);300 270 appendTargetWithLesserDepth(m_path[i], currentDepthAllowed); 271 301 272 return path; 302 }303 304 EventPath::EventPath(const Vector<Element*>& targets)305 {306 // FIXME: This function seems wrong. Why are we not firing events in the closed shadow trees?307 for (auto* target : targets) {308 ASSERT(target);309 Node* origin = *targets.begin();310 if (!target->isClosedShadowHidden(*origin))311 m_path.append(makeUnique<EventContext>(target, target, origin, 0));312 }313 273 } 314 274 … … 318 278 ASSERT(target); 319 279 ASSERT(!is<Node>(target)); 320 m_path.append( makeUnique<EventContext>(nullptr, target, *targets.begin(), 0));280 m_path.append(EventContext { EventContext::Type::Normal, nullptr, target, *targets.begin(), 0 }); 321 281 } 322 282 } -
trunk/Source/WebCore/dom/EventPath.h
r253923 r273477 36 36 EventPath(Node& origin, Event&); 37 37 explicit EventPath(const Vector<EventTarget*>&); 38 explicit EventPath(const Vector<Element*>&);39 38 40 39 bool isEmpty() const { return m_path.isEmpty(); } 41 40 size_t size() const { return m_path.size(); } 42 const EventContext& contextAt(size_t i) const { return *m_path[i]; }43 EventContext& contextAt(size_t i) { return *m_path[i]; }41 const EventContext& contextAt(size_t i) const { return m_path[i]; } 42 EventContext& contextAt(size_t i) { return m_path[i]; } 44 43 45 44 Vector<EventTarget*> computePathUnclosedToTarget(const EventTarget&) const; … … 49 48 private: 50 49 void buildPath(Node& origin, Event&); 51 void setRelatedTarget(Node& origin, EventTarget&);50 void setRelatedTarget(Node& origin, Node&); 52 51 53 52 #if ENABLE(TOUCH_EVENTS) 54 void retargetTouch( TouchEventContext::TouchListType, const Touch&);55 void retargetTouchList( TouchEventContext::TouchListType, const TouchList*);53 void retargetTouch(EventContext::TouchListType, const Touch&); 54 void retargetTouchList(EventContext::TouchListType, const TouchList*); 56 55 void retargetTouchLists(const TouchEvent&); 57 56 #endif 58 57 59 Vector< std::unique_ptr<EventContext>, 32> m_path;58 Vector<EventContext, 16> m_path; 60 59 }; 61 60 -
trunk/Source/WebCore/dom/Node.cpp
r271806 r273477 2365 2365 } 2366 2366 2367 void Node::handleLocalEvents(Event& event, EventInvokePhase phase)2368 {2369 if (!hasEventTargetData())2370 return;2371 2372 // FIXME: Should we deliver wheel events to disabled form controls or not?2373 if (is<Element>(*this) && downcast<Element>(*this).isDisabledFormControl() && event.isTrusted() && event.isMouseEvent() && !event.isWheelEvent())2374 return;2375 2376 fireEventListeners(event, phase);2377 }2378 2379 2367 void Node::dispatchScopedEvent(Event& event) 2380 2368 { -
trunk/Source/WebCore/dom/Node.h
r273474 r273477 454 454 void dispatchScopedEvent(Event&); 455 455 456 virtual void handleLocalEvents(Event&, EventInvokePhase);457 458 456 void dispatchSubtreeModifiedEvent(); 459 457 void dispatchDOMActivateEvent(Event& underlyingClickEvent); -
trunk/Source/WebCore/html/HTMLFormElement.cpp
r270931 r273477 150 150 } 151 151 152 void HTMLFormElement::handleLocalEvents(Event& event, EventInvokePhase phase)153 {154 if (event.eventPhase() != Event::CAPTURING_PHASE && is<Node>(event.target()) && event.target() != this && (event.type() == eventNames().submitEvent || event.type() == eventNames().resetEvent)) {155 event.stopPropagation();156 return;157 }158 HTMLElement::handleLocalEvents(event, phase);159 }160 161 152 unsigned HTMLFormElement::length() const 162 153 { -
trunk/Source/WebCore/html/HTMLFormElement.h
r259513 r273477 132 132 void finishParsingChildren() final; 133 133 134 void handleLocalEvents(Event&, EventInvokePhase) final;135 136 134 void parseAttribute(const QualifiedName&, const AtomString&) final; 137 135 bool isURLAttribute(const Attribute&) const final;
Note:
See TracChangeset
for help on using the changeset viewer.