Issue #2135 - Bug 1413102 (Follow-up): Ignore current target because of shadow DOM retargeting

Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1466581
This commit is contained in:
FranklinDM 2023-03-04 02:23:31 +08:00 • committed by roytam1
commit 1bb2009f61
3 changed files with 18 additions and 4 deletions

View file

@ -995,7 +995,7 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
// Step 4. // Step 4.
// "If target is relatedTarget and target is not event's // "If target is relatedTarget and target is not event's
// relatedTarget, then return true." // relatedTarget, then return true."
aVisitor.IgnoreCurrentTarget(); aVisitor.IgnoreCurrentTargetBecauseOfShadowDOMRetargeting();
// Old code relies on mTarget to point to the first element which // Old code relies on mTarget to point to the first element which
// was not added to the event target chain because of mCanHandle // was not added to the event target chain because of mCanHandle
// being false, but in Shadow DOM case mTarget really should // being false, but in Shadow DOM case mTarget really should
@ -1034,7 +1034,7 @@ nsIContent::GetEventTargetParent(EventChainPreVisitor& aVisitor)
// Step 11.5 // Step 11.5
// "Otherwise, if parent and relatedTarget are identical, then set // "Otherwise, if parent and relatedTarget are identical, then set
// parent to null." // parent to null."
aVisitor.IgnoreCurrentTarget(); aVisitor.IgnoreCurrentTargetBecauseOfShadowDOMRetargeting();
// Old code relies on mTarget to point to the first element which // Old code relies on mTarget to point to the first element which
// was not added to the event target chain because of mCanHandle // was not added to the event target chain because of mCanHandle
// being false, but in Shadow DOM case mTarget really should // being false, but in Shadow DOM case mTarget really should

View file

@ -872,6 +872,7 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
preVisitor.mTargetInKnownToBeHandledScope = preVisitor.mEvent->mTarget; preVisitor.mTargetInKnownToBeHandledScope = preVisitor.mEvent->mTarget;
topEtci = parentEtci; topEtci = parentEtci;
} else { } else {
bool ignoreBecauseOfShadowDOM = preVisitor.mIgnoreBecauseOfShadowDOM;
nsCOMPtr<nsINode> disabledTarget = do_QueryInterface(parentTarget); nsCOMPtr<nsINode> disabledTarget = do_QueryInterface(parentTarget);
parentEtci = MayRetargetToChromeIfCanNotHandleEvent(chain, parentEtci = MayRetargetToChromeIfCanNotHandleEvent(chain,
preVisitor, preVisitor,
@ -882,7 +883,11 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
preVisitor.mTargetInKnownToBeHandledScope = preVisitor.mEvent->mTarget; preVisitor.mTargetInKnownToBeHandledScope = preVisitor.mEvent->mTarget;
EventTargetChainItem* item = EventTargetChainItem* item =
EventTargetChainItem::GetFirstCanHandleEventTarget(chain); EventTargetChainItem::GetFirstCanHandleEventTarget(chain);
item->SetNewTarget(parentTarget); if (!ignoreBecauseOfShadowDOM) {
// If we ignored the target because of Shadow DOM retargeting, we
// shouldn't treat the target to be in the event path at all.
item->SetNewTarget(parentTarget);
}
topEtci = parentEtci; topEtci = parentEtci;
continue; continue;
} }

View file

@ -128,6 +128,7 @@ public:
, mParentIsSlotInClosedTree(false) , mParentIsSlotInClosedTree(false)
, mParentIsChromeHandler(false) , mParentIsChromeHandler(false)
, mRelatedTargetRetargetedInCurrentScope(false) , mRelatedTargetRetargetedInCurrentScope(false)
, mIgnoreBecauseOfShadowDOM(false)
, mParentTarget(nullptr) , mParentTarget(nullptr)
, mEventTargetAtParent(nullptr) , mEventTargetAtParent(nullptr)
, mRetargetedRelatedTarget(nullptr) , mRetargetedRelatedTarget(nullptr)
@ -151,6 +152,7 @@ public:
// Note, we don't clear mRelatedTargetRetargetedInCurrentScope explicitly, // Note, we don't clear mRelatedTargetRetargetedInCurrentScope explicitly,
// since it is used during event path creation to indicate whether // since it is used during event path creation to indicate whether
// relatedTarget may need to be retargeted. // relatedTarget may need to be retargeted.
mIgnoreBecauseOfShadowDOM = false;
mParentTarget = nullptr; mParentTarget = nullptr;
mEventTargetAtParent = nullptr; mEventTargetAtParent = nullptr;
mRetargetedRelatedTarget = nullptr; mRetargetedRelatedTarget = nullptr;
@ -169,9 +171,10 @@ public:
} }
} }
void IgnoreCurrentTarget() void IgnoreCurrentTargetBecauseOfShadowDOMRetargeting()
{ {
mCanHandle = false; mCanHandle = false;
mIgnoreBecauseOfShadowDOM = true;
SetParentTarget(nullptr, false); SetParentTarget(nullptr, false);
mEventTargetAtParent = nullptr; mEventTargetAtParent = nullptr;
} }
@ -251,6 +254,12 @@ public:
*/ */
bool mRelatedTargetRetargetedInCurrentScope; bool mRelatedTargetRetargetedInCurrentScope;
/**
* True if Shadow DOM relatedTarget retargeting causes the current item
* to not show up in the event path.
*/
bool mIgnoreBecauseOfShadowDOM;
private: private:
/** /**
* Parent item in the event target chain. * Parent item in the event target chain.