Bug 1489139 - Ensure unbound generated content doesn't remain in the active chain. r=smaug

This reuses the same code path that was added in bug 1461299 for NAC, but for
generated content as well. DestroyAnonymousContent notifies to the ESM.

Also, remove the NativeAnonymousContentRemoved bit about <svg:use> since it's no
longer NAC.

Differential Revision: https://phabricator.services.mozilla.com/D5575
This commit is contained in:
Emilio Cobos Álvarez 2018-09-11 21:18:04 +02:00
parent 28b1389ea7
commit 673ea6eb31
6 changed files with 44 additions and 13 deletions

View File

@ -5378,9 +5378,7 @@ EventStateManager::RemoveNodeFromChainIfNeeded(EventStates aState,
void
EventStateManager::NativeAnonymousContentRemoved(nsIContent* aContent)
{
// FIXME(bug 1450250): <svg:use> is nasty.
MOZ_ASSERT(aContent->IsRootOfNativeAnonymousSubtree() ||
aContent->GetParentNode()->IsSVGElement(nsGkAtoms::use));
MOZ_ASSERT(aContent->IsRootOfNativeAnonymousSubtree());
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_HOVER, aContent, false);
RemoveNodeFromChainIfNeeded(NS_EVENT_STATE_ACTIVE, aContent, false);
}

View File

@ -211,3 +211,4 @@ support-files = file_bug1484371.html
[test_hover_mouseleave.html]
[test_slotted_mouse_event.html]
[test_slotted_text_click.html]
[test_unbound_before_in_active_chain.html]

View File

@ -0,0 +1,38 @@
<!doctype html>
<title>Test for bug 1489139: Unbound generated content in the active chain</title>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<style>
#target, #target::before {
width: 200px;
height: 200px;
}
#target::before {
content: " ";
display: block;
background: green;
}
#target:active::before {
content: "";
background: red;
}
</style>
Should see a green square after clicking.
<div id="target"></div>
<script>
SimpleTest.waitForExplicitFinish();
onload = function() {
let target = document.getElementById("target");
requestAnimationFrame(() => {
synthesizeMouseAtPoint(100, 100, { type: "mousedown" })
ok(target.matches(":active"), "Should have been clicked");
requestAnimationFrame(() => {
synthesizeMouseAtPoint(100, 100, { type: "mouseup" })
ok(!target.matches(':active'), "Should stop matching :active afterwards");
SimpleTest.finish();
});
});
}
</script>

View File

@ -815,7 +815,7 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData)
// aPostDestroyData to unbind it after frame destruction is done.
if (HasAnyStateBits(NS_FRAME_GENERATED_CONTENT) &&
mContent->IsRootOfNativeAnonymousSubtree()) {
aPostDestroyData.AddGeneratedContent(mContent.forget());
aPostDestroyData.AddAnonymousContent(mContent.forget());
}
}

View File

@ -57,14 +57,11 @@ namespace layout {
PostFrameDestroyData(const PostFrameDestroyData&) = delete;
PostFrameDestroyData() = default;
AutoTArray<RefPtr<nsIContent>, 50> mAnonymousContent;
AutoTArray<RefPtr<nsIContent>, 50> mGeneratedContent;
void AddAnonymousContent(already_AddRefed<nsIContent>&& aContent) {
AutoTArray<RefPtr<nsIContent>, 100> mAnonymousContent;
void AddAnonymousContent(already_AddRefed<nsIContent>&& aContent)
{
mAnonymousContent.AppendElement(aContent);
}
void AddGeneratedContent(already_AddRefed<nsIContent>&& aContent) {
mGeneratedContent.AppendElement(aContent);
}
};
} // namespace layout
} // namespace mozilla

View File

@ -659,9 +659,6 @@ public:
for (auto& content : mozilla::Reversed(mData.mAnonymousContent)) {
nsIFrame::DestroyAnonymousContent(mPresContext, content.forget());
}
for (auto& content : mozilla::Reversed(mData.mGeneratedContent)) {
content->UnbindFromTree();
}
}
nsPresContext* mPresContext;
PostDestroyData mData;