void EventRetargeter::calculateAdjustedNodes(const Node* node, const Node* relatedNode, EventWithRelatedTargetDispatchBehavior eventWithRelatedTargetDispatchBehavior, EventPath& eventPath, AdjustedNodes& adjustedNodes) { RelatedNodeMap relatedNodeMap; buildRelatedNodeMap(relatedNode, relatedNodeMap); // Synthetic mouse events can have a relatedTarget which is identical to the target. bool targetIsIdenticalToToRelatedTarget = (node == relatedNode); TreeScope* lastTreeScope = 0; Node* adjustedNode = 0; for (EventPath::const_iterator iter = eventPath.begin(); iter < eventPath.end(); ++iter) { TreeScope* scope = (*iter)->node()->treeScope(); if (scope == lastTreeScope) { // Re-use the previous adjustedRelatedTarget if treeScope does not change. Just for the performance optimization. adjustedNodes.append(adjustedNode); } else { adjustedNode = findRelatedNode(scope, relatedNodeMap); adjustedNodes.append(adjustedNode); } lastTreeScope = scope; if (eventWithRelatedTargetDispatchBehavior == DoesNotStopAtBoundary) continue; if (targetIsIdenticalToToRelatedTarget) { if (node->treeScope()->rootNode() == (*iter)->node()) { eventPath.shrink(iter + 1 - eventPath.begin()); break; } } else if ((*iter)->target() == adjustedNode) { // Event dispatching should be stopped here. eventPath.shrink(iter - eventPath.begin()); adjustedNodes.shrink(adjustedNodes.size() - 1); break; } } }
void EventPath::adjustForRelatedTarget(Node* target, EventTarget* relatedTarget) { if (!target) return; if (!relatedTarget) return; Node* relatedNode = relatedTarget->toNode(); if (!relatedNode) return; if (target->document() != relatedNode->document()) return; if (!target->inDocument() || !relatedNode->inDocument()) return; RelatedTargetMap relatedNodeMap; buildRelatedNodeMap(relatedNode, relatedNodeMap); for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i) { TreeScopeEventContext* treeScopeEventContext = m_treeScopeEventContexts[i].get(); EventTarget* adjustedRelatedTarget = findRelatedNode(&treeScopeEventContext->treeScope(), relatedNodeMap); ASSERT(adjustedRelatedTarget); treeScopeEventContext->setRelatedTarget(adjustedRelatedTarget); } shrinkIfNeeded(target, relatedTarget); }
void EventPath::adjustTouchList(const TouchList* touchList, WillBeHeapVector<RawPtrWillBeMember<TouchList>> adjustedTouchList, const WillBeHeapVector<RawPtrWillBeMember<TreeScope>>& treeScopes) { if (!touchList) return; for (size_t i = 0; i < touchList->length(); ++i) { const Touch& touch = *touchList->item(i); RelatedTargetMap relatedNodeMap; buildRelatedNodeMap(*touch.target()->toNode(), relatedNodeMap); for (size_t j = 0; j < treeScopes.size(); ++j) { adjustedTouchList[j]->append(touch.cloneWithNewTarget(findRelatedNode(*treeScopes[j], relatedNodeMap))); } } }
void EventPath::adjustForRelatedTarget(Node& target, EventTarget* relatedTarget) { if (!relatedTarget) return; Node* relatedNode = relatedTarget->toNode(); if (!relatedNode) return; if (target.document() != relatedNode->document()) return; if (!target.inDocument() || !relatedNode->inDocument()) return; RelatedTargetMap relatedNodeMap; buildRelatedNodeMap(*relatedNode, relatedNodeMap); for (const auto& treeScopeEventContext : m_treeScopeEventContexts) { EventTarget* adjustedRelatedTarget = findRelatedNode(treeScopeEventContext->treeScope(), relatedNodeMap); ASSERT(adjustedRelatedTarget); treeScopeEventContext.get()->setRelatedTarget(adjustedRelatedTarget); } shrinkIfNeeded(target, *relatedTarget); }