mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1461299: Make ESM not point to unbound NAC in the hover / active chain. r=smaug
MozReview-Commit-ID: 8mL7Yv3TwQM
This commit is contained in:
parent
f4898626f9
commit
cf0ce82b71
@ -5368,6 +5368,51 @@ EventStateManager::ResetLastOverForContent(
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EventStateManager::RemoveNodeFromChainIfNeeded(EventStates aState,
|
||||
nsIContent* aContentRemoved)
|
||||
{
|
||||
MOZ_ASSERT(aState == NS_EVENT_STATE_HOVER || aState == NS_EVENT_STATE_ACTIVE);
|
||||
if (!aContentRemoved->IsElement() ||
|
||||
!aContentRemoved->AsElement()->State().HasState(aState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent>& leaf =
|
||||
aState == NS_EVENT_STATE_HOVER ? mHoverContent : mActiveContent;
|
||||
|
||||
MOZ_ASSERT(leaf);
|
||||
// XBL Likes to unbind content without notifying, thus the
|
||||
// NODE_IS_ANONYMOUS_ROOT check...
|
||||
MOZ_ASSERT(nsContentUtils::ContentIsFlattenedTreeDescendantOf(
|
||||
leaf, aContentRemoved) ||
|
||||
leaf->SubtreeRoot()->HasFlag(NODE_IS_ANONYMOUS_ROOT));
|
||||
|
||||
nsIContent* newLeaf = aContentRemoved->GetFlattenedTreeParent();
|
||||
MOZ_ASSERT_IF(newLeaf,
|
||||
newLeaf->IsElement() &&
|
||||
newLeaf->AsElement()->State().HasState(aState));
|
||||
if (aContentRemoved->IsRootOfNativeAnonymousSubtree()) {
|
||||
// We don't update the removed content's state here, since removing NAC
|
||||
// happens from layout and we don't really want to notify at that point or
|
||||
// what not.
|
||||
//
|
||||
// Also, NAC is not observable and NAC being removed will go away soon.
|
||||
leaf = newLeaf;
|
||||
} else {
|
||||
SetContentState(newLeaf, aState);
|
||||
}
|
||||
MOZ_ASSERT(leaf == newLeaf);
|
||||
}
|
||||
|
||||
void
|
||||
EventStateManager::NativeAnonymousContentRemoved(nsIContent* aContent)
|
||||
{
|
||||
MOZ_ASSERT(aContent->IsRootOfAnonymousSubtree());
|
||||
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_HOVER, aContent);
|
||||
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_ACTIVE, aContent);
|
||||
}
|
||||
|
||||
void
|
||||
EventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
|
||||
{
|
||||
@ -5392,29 +5437,8 @@ EventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
|
||||
if (fm)
|
||||
fm->ContentRemoved(aDocument, aContent);
|
||||
|
||||
if (aContent->IsElement() &&
|
||||
aContent->AsElement()->State().HasState(NS_EVENT_STATE_HOVER)) {
|
||||
MOZ_ASSERT(mHoverContent);
|
||||
// XBL Likes to unbind content without notifying, thus the
|
||||
// NODE_IS_ANONYMOUS_ROOT check...
|
||||
MOZ_ASSERT(nsContentUtils::ContentIsFlattenedTreeDescendantOf(mHoverContent,
|
||||
aContent) ||
|
||||
mHoverContent->SubtreeRoot()->HasFlag(NODE_IS_ANONYMOUS_ROOT));
|
||||
// Since hover is hierarchical, set the current hover to the
|
||||
// content's parent node.
|
||||
SetContentState(aContent->GetFlattenedTreeParent(), NS_EVENT_STATE_HOVER);
|
||||
}
|
||||
|
||||
if (aContent->IsElement() &&
|
||||
aContent->AsElement()->State().HasState(NS_EVENT_STATE_ACTIVE)) {
|
||||
MOZ_ASSERT(mActiveContent);
|
||||
MOZ_ASSERT(nsContentUtils::ContentIsFlattenedTreeDescendantOf(mActiveContent,
|
||||
aContent) ||
|
||||
mHoverContent->SubtreeRoot()->HasFlag(NODE_IS_ANONYMOUS_ROOT));
|
||||
// Active is hierarchical, so set the current active to the
|
||||
// content's parent node.
|
||||
SetContentState(aContent->GetFlattenedTreeParent(), NS_EVENT_STATE_ACTIVE);
|
||||
}
|
||||
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_HOVER, aContent);
|
||||
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_ACTIVE, aContent);
|
||||
|
||||
if (sDragOverContent &&
|
||||
sDragOverContent->OwnerDoc() == aContent->OwnerDoc() &&
|
||||
|
@ -148,6 +148,8 @@ public:
|
||||
* affect the return value.
|
||||
*/
|
||||
bool SetContentState(nsIContent* aContent, EventStates aState);
|
||||
|
||||
void NativeAnonymousContentRemoved(nsIContent* aAnonContent);
|
||||
void ContentRemoved(nsIDocument* aDocument, nsIContent* aContent);
|
||||
|
||||
bool EventStatusOK(WidgetGUIEvent* aEvent);
|
||||
@ -1087,6 +1089,13 @@ protected:
|
||||
void HandleQueryContentEvent(WidgetQueryContentEvent* aEvent);
|
||||
|
||||
private:
|
||||
// Removes a node from the :hover / :active chain if needed, notifying if the
|
||||
// node is not a NAC subtree.
|
||||
//
|
||||
// Only meant to be called from ContentRemoved and
|
||||
// NativeAnonymousContentRemoved.
|
||||
void RemoveNodeFromChainIfNeeded(EventStates aState,
|
||||
nsIContent* aContentRemoved);
|
||||
|
||||
bool IsEventOutsideDragThreshold(WidgetInputEvent* aEvent) const;
|
||||
|
||||
|
@ -259,14 +259,6 @@ nsFrameManager::RestoreFrameState(nsIFrame* aFrame,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameManager::DestroyAnonymousContent(already_AddRefed<nsIContent> aContent)
|
||||
{
|
||||
if (nsCOMPtr<nsIContent> content = aContent) {
|
||||
content->UnbindFromTree();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameManager::AddSizeOfIncludingThis(nsWindowSizes& aSizes) const
|
||||
{
|
||||
|
@ -93,8 +93,6 @@ public:
|
||||
|
||||
void RestoreFrameStateFor(nsIFrame* aFrame, nsILayoutHistoryState* aState);
|
||||
|
||||
void DestroyAnonymousContent(already_AddRefed<nsIContent> aContent);
|
||||
|
||||
void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const;
|
||||
|
||||
protected:
|
||||
|
@ -246,8 +246,10 @@ nsReflowStatus::UpdateTruncated(const ReflowInput& aReflowInput,
|
||||
nsIFrame::DestroyAnonymousContent(nsPresContext* aPresContext,
|
||||
already_AddRefed<nsIContent>&& aContent)
|
||||
{
|
||||
aPresContext->PresShell()->FrameConstructor()
|
||||
->DestroyAnonymousContent(Move(aContent));
|
||||
if (nsCOMPtr<nsIContent> content = aContent) {
|
||||
aPresContext->EventStateManager()->NativeAnonymousContentRemoved(content);
|
||||
content->UnbindFromTree();
|
||||
}
|
||||
}
|
||||
|
||||
// Formerly the nsIFrameDebug interface
|
||||
|
Loading…
Reference in New Issue
Block a user