Bug 1693411: Make sure an a11y node is removed when visibility: hidden is set but the layout frame is reconstructed; e.g. position: fixed. r=eeejay

Differential Revision: https://phabricator.services.mozilla.com/D105934
This commit is contained in:
James Teh 2021-02-23 01:48:15 +00:00
parent ac04bdcbeb
commit 7050157edf
2 changed files with 55 additions and 0 deletions

View File

@ -1584,6 +1584,18 @@ bool DocAccessible::PruneOrInsertSubtree(nsIContent* aRoot) {
// We schedule it for reinsertion. For example, a slotted element
// can change its slot attribute to a different slot.
insert = true;
// If the frame is invisible, remove it.
// Normally, layout sends explicit a11y notifications for visibility
// changes (see SendA11yNotifications in RestyleManager). However, if a
// visibility change also reconstructs the frame, we must handle it here.
if (frame && !frame->StyleVisibility()->IsVisible()) {
ContentRemoved(aRoot);
// There might be visible descendants, so we want to walk the subtree.
// However, we know we don't want to reinsert this node, so we set insert
// to false.
insert = false;
}
} else {
// If there is no current accessible, and the node has a frame, or is
// display:contents, schedule it for insertion.

View File

@ -341,6 +341,40 @@
is(getAccessible("c14").name, "one two three", "subtree has correct order");
}
// Ensure that a node is removed when visibility: hidden is set but the
// layout frame is reconstructed; e.g. because of position: fixed. Also
// ensure that visible children aren't clobbered.
async function visibilityHiddenWithReframe() {
let msg = "visibilityHiddenWithReframe";
info(msg);
testAccessibleTree("c15", { SECTION: [ // c15
{ SECTION: [ // c15_inner
{ TEXT_LEAF: [] }, // Text
{ PARAGRAPH: [
{ TEXT_LEAF: [] } // Para
] },
{ HEADING: [ // c15_visible
{ TEXT_LEAF: [] } // Visible
] }, // c15_visible
] } // c15_inner
] });
let events = waitForOrderedEvents([
[EVENT_HIDE, "c15_inner"],
[EVENT_SHOW, "c15_visible"],
[EVENT_REORDER, "c15"],
], msg);
getNode("c15_inner").style = "visibility: hidden; position: fixed;";
await events;
testAccessibleTree("c15", { SECTION: [ // c15
{ HEADING: [ // c15_visible
{ TEXT_LEAF: [] } // Visible
] }, // c15_visible
] });
}
async function doTest() {
await hideDivFromInsideSpan();
@ -369,6 +403,9 @@
await testCSSGeneratedContentRemovedFromButton();
await testSlack();
await visibilityHiddenWithReframe();
SimpleTest.finish();
}
@ -448,6 +485,12 @@
</div>
</div>
<div id="c15"><div id="c15_inner">
Text
<p>Para</p>
<h1 id="c15_visible" style="visibility: visible;">Visible</h1>
</div></div>
<div id="eventdump"></div>
</body>
</html>