void EventPath::setRelatedTarget(Node& origin, EventTarget& relatedTarget) { UNUSED_PARAM(origin); Node* relatedNode = relatedTarget.toNode(); if (!relatedNode || m_path.isEmpty()) return; RelatedNodeRetargeter retargeter(*relatedNode, downcast<MouseOrFocusEventContext>(*m_path[0]).node()->treeScope()); bool originIsRelatedTarget = &origin == relatedNode; // FIXME: We should add a new flag on Event instead. bool shouldTrimEventPath = m_event.type() == eventNames().mouseoverEvent || m_event.type() == eventNames().mousemoveEvent || m_event.type() == eventNames().mouseoutEvent; Node& rootNodeInOriginTreeScope = origin.treeScope().rootNode(); TreeScope* previousTreeScope = nullptr; size_t originalEventPathSize = m_path.size(); for (unsigned contextIndex = 0; contextIndex < originalEventPathSize; contextIndex++) { auto& context = downcast<MouseOrFocusEventContext>(*m_path[contextIndex]); TreeScope& currentTreeScope = context.node()->treeScope(); if (UNLIKELY(previousTreeScope && ¤tTreeScope != previousTreeScope)) retargeter.moveToNewTreeScope(previousTreeScope, currentTreeScope); Node* currentRelatedNode = retargeter.currentNode(currentTreeScope); if (UNLIKELY(shouldTrimEventPath && !originIsRelatedTarget && context.target() == currentRelatedNode)) { m_path.shrink(contextIndex); break; } context.setRelatedTarget(currentRelatedNode); if (UNLIKELY(shouldTrimEventPath && originIsRelatedTarget && context.node() == &rootNodeInOriginTreeScope)) { m_path.shrink(contextIndex + 1); break; } previousTreeScope = ¤tTreeScope; } }
void EventPath::setRelatedTarget(Node& origin, EventTarget& relatedTarget) { Node* relatedNode = relatedTarget.toNode(); if (!relatedNode || m_path.isEmpty()) return; RelatedNodeRetargeter retargeter(*relatedNode, *m_path[0]->node()); bool originIsRelatedTarget = &origin == relatedNode; bool relatedTargetScoped = m_event.relatedTargetScoped(); Node& rootNodeInOriginTreeScope = origin.treeScope().rootNode(); TreeScope* previousTreeScope = nullptr; size_t originalEventPathSize = m_path.size(); for (unsigned contextIndex = 0; contextIndex < originalEventPathSize; contextIndex++) { auto& context = downcast<MouseOrFocusEventContext>(*m_path[contextIndex]); Node& currentTarget = *context.node(); TreeScope& currentTreeScope = currentTarget.treeScope(); if (UNLIKELY(previousTreeScope && ¤tTreeScope != previousTreeScope)) retargeter.moveToNewTreeScope(previousTreeScope, currentTreeScope); Node* currentRelatedNode = retargeter.currentNode(currentTarget); if (UNLIKELY(relatedTargetScoped && !originIsRelatedTarget && context.target() == currentRelatedNode)) { m_path.shrink(contextIndex); break; } context.setRelatedTarget(currentRelatedNode); if (UNLIKELY(relatedTargetScoped && originIsRelatedTarget && context.node() == &rootNodeInOriginTreeScope)) { m_path.shrink(contextIndex + 1); break; } previousTreeScope = ¤tTreeScope; } }
void EventPath::retargetTouch(TouchEventContext::TouchListType touchListType, const Touch& touch) { EventTarget* eventTarget = touch.target(); if (!eventTarget) return; Node* targetNode = eventTarget->toNode(); if (!targetNode) return; RelatedNodeRetargeter retargeter(*targetNode, *m_path[0]->node()); TreeScope* previousTreeScope = nullptr; for (auto& context : m_path) { Node& currentTarget = *context->node(); TreeScope& currentTreeScope = currentTarget.treeScope(); if (UNLIKELY(previousTreeScope && ¤tTreeScope != previousTreeScope)) retargeter.moveToNewTreeScope(previousTreeScope, currentTreeScope); Node* currentRelatedNode = retargeter.currentNode(currentTarget); downcast<TouchEventContext>(*context).touchList(touchListType)->append(touch.cloneWithNewTarget(currentRelatedNode)); previousTreeScope = ¤tTreeScope; } }