From df40116d6fde6ce6e94a01a2d64fbef23ce8e8a5 Mon Sep 17 00:00:00 2001 From: Eitan Isaacson Date: Wed, 28 Aug 2019 23:02:19 +0000 Subject: [PATCH] Bug 1572829 - Remove explicit children too when node has a shadow root. r=Jamie Differential Revision: https://phabricator.services.mozilla.com/D43488 --HG-- extra : moz-landing-system : lando --- accessible/generic/DocAccessible.cpp | 14 ++++++++++++++ .../treeupdate/test_delayed_removal.html | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/accessible/generic/DocAccessible.cpp b/accessible/generic/DocAccessible.cpp index 50532ceb7527..ada2c38f5b96 100644 --- a/accessible/generic/DocAccessible.cpp +++ b/accessible/generic/DocAccessible.cpp @@ -2001,6 +2001,20 @@ void DocAccessible::ContentRemoved(nsIContent* aContentNode) { while (nsIContent* childNode = iter.GetNextChild()) { ContentRemoved(childNode); } + + // If this node has a shadow root, remove its explicit children too. + // The host node may be removed after the shadow root was attached, and + // before we asynchronously prune the light DOM and construct the shadow DOM. + // If this is a case where the node does not have its own accessible, we will + // not recurse into its current children, so we need to use an + // ExplicitChildIterator in order to get its accessible children in the light + // DOM, since they are not accessible anymore via AllChildrenIterator. + if (aContentNode->GetShadowRoot()) { + dom::ExplicitChildIterator iter = dom::ExplicitChildIterator(aContentNode); + while (nsIContent* childNode = iter.GetNextChild()) { + ContentRemoved(childNode); + } + } } bool DocAccessible::RelocateARIAOwnedIfNeeded(nsIContent* aElement) { diff --git a/accessible/tests/mochitest/treeupdate/test_delayed_removal.html b/accessible/tests/mochitest/treeupdate/test_delayed_removal.html index e82e8df70952..800911c005f9 100644 --- a/accessible/tests/mochitest/treeupdate/test_delayed_removal.html +++ b/accessible/tests/mochitest/treeupdate/test_delayed_removal.html @@ -183,6 +183,18 @@ ] }); } + // Bug 1572829 + async function removeShadowRootHost() { + info("removeShadowRootHost"); + document.body.offsetTop; // Flush layout. + + let event = waitForEvent(EVENT_REORDER, "c9", "removeShadowRootHost"); + getNode("c9").firstElementChild.attachShadow({mode: "open"}); + getNode("c9").firstElementChild.replaceWith(""); + + await event; + } + async function doTest() { await hideDivFromInsideSpan(); @@ -200,6 +212,8 @@ await removeRelocatedWhenDomAncestorHidden(); + await removeShadowRootHost(); + SimpleTest.finish(); } @@ -249,6 +263,10 @@ +
+
a
+
+