EventPath::EventPath(Node& targetNode, Event& event) { bool inDocument = targetNode.inDocument(); bool isSVGElement = targetNode.isSVGElement(); bool isMouseOrFocusEvent = event.isMouseEvent() || event.isFocusEvent(); #if ENABLE(TOUCH_EVENTS) bool isTouchEvent = event.isTouchEvent(); #endif EventTarget* target = 0; Node* node = nodeOrHostIfPseudoElement(&targetNode); while (node) { if (!target || !isSVGElement) // FIXME: This code doesn't make sense once we've climbed out of the SVG subtree in a HTML document. target = &eventTargetRespectingTargetRules(*node); for (; node; node = node->parentNode()) { EventTarget& currentTarget = eventTargetRespectingTargetRules(*node); if (isMouseOrFocusEvent) m_path.append(std::make_unique<MouseOrFocusEventContext>(node, ¤tTarget, target)); #if ENABLE(TOUCH_EVENTS) else if (isTouchEvent) m_path.append(std::make_unique<TouchEventContext>(node, ¤tTarget, target)); #endif else m_path.append(std::make_unique<EventContext>(node, ¤tTarget, target)); if (!inDocument) return; if (node->isShadowRoot()) break; } if (!node || !shouldEventCrossShadowBoundary(event, *toShadowRoot(node), *target)) return; node = toShadowRoot(node)->hostElement(); } }
EventPath::EventPath(Node& originalTarget, Event& event) : m_event(event) { bool isMouseOrFocusEvent = event.isMouseEvent() || event.isFocusEvent(); #if ENABLE(TOUCH_EVENTS) bool isTouchEvent = event.isTouchEvent(); #endif Node* node = nodeOrHostIfPseudoElement(&originalTarget); Node* target = node ? eventTargetRespectingTargetRules(*node) : nullptr; while (node) { while (node) { EventTarget* currentTarget = eventTargetRespectingTargetRules(*node); if (isMouseOrFocusEvent) m_path.append(std::make_unique<MouseOrFocusEventContext>(node, currentTarget, target)); #if ENABLE(TOUCH_EVENTS) else if (isTouchEvent) m_path.append(std::make_unique<TouchEventContext>(node, currentTarget, target)); #endif else m_path.append(std::make_unique<EventContext>(node, currentTarget, target)); if (is<ShadowRoot>(*node)) break; ContainerNode* parent = node->parentNode(); if (!parent) return; #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) if (ShadowRoot* shadowRootOfParent = parent->shadowRoot()) { if (auto* assignedSlot = shadowRootOfParent->findAssignedSlot(*node)) { // node is assigned to a slot. Continue dispatching the event at this slot. parent = assignedSlot; } } #endif node = parent; } bool exitingShadowTreeOfTarget = &target->treeScope() == &node->treeScope(); ShadowRoot& shadowRoot = downcast<ShadowRoot>(*node); if (!shouldEventCrossShadowBoundary(event, shadowRoot, originalTarget)) return; node = shadowRoot.host(); if (exitingShadowTreeOfTarget) target = eventTargetRespectingTargetRules(*node); } }
EventPath::EventPath(Node& originalTarget, Event& event) : m_event(event) { #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) Vector<EventTarget*, 16> targetStack; #endif bool isMouseOrFocusEvent = event.isMouseEvent() || event.isFocusEvent(); #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS) bool isTouchEvent = event.isTouchEvent(); #endif EventTarget* target = nullptr; Node* node = nodeOrHostIfPseudoElement(&originalTarget); while (node) { if (!target) target = eventTargetRespectingTargetRules(*node); ContainerNode* parent; for (; node; node = parent) { EventTarget* currentTarget = eventTargetRespectingTargetRules(*node); if (isMouseOrFocusEvent) m_path.append(std::make_unique<MouseOrFocusEventContext>(node, currentTarget, target)); #if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS) else if (isTouchEvent) m_path.append(std::make_unique<TouchEventContext>(node, currentTarget, target)); #endif else m_path.append(std::make_unique<EventContext>(node, currentTarget, target)); if (is<ShadowRoot>(*node)) break; parent = node->parentNode(); if (!parent) return; #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) if (ShadowRoot* shadowRootOfParent = parent->shadowRoot()) { if (auto* assignedSlot = shadowRootOfParent->findAssignedSlot(*node)) { // node is assigned to a slot. Continue dispatching the event at this slot. targetStack.append(target); parent = assignedSlot; target = assignedSlot; } } #endif node = parent; } ShadowRoot& shadowRoot = downcast<ShadowRoot>(*node); // At a shadow root. Continue dispatching the event at the shadow host. #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) if (!targetStack.isEmpty()) { // Move target back to a descendant of the shadow host if the event did not originate in this shadow tree or its inner shadow trees. target = targetStack.last(); targetStack.removeLast(); ASSERT(shadowRoot.host()->contains(target->toNode())); } else #endif target = nullptr; if (!shouldEventCrossShadowBoundary(event, shadowRoot, originalTarget)) return; node = shadowRoot.host(); } }