Bug 1515186 - Always calculate group position for all children of an accessible after a tree mutation, r=Jamie

Previously, if we had children a, b, c, and d, then removed b, the group position for c and d would potentially be marked as dirty, but a would not. This caused the check for the availability of previous group info to return outdated information.

This patch now always forces the update of all children's group position when a children move has occurred, since it potentially affects all the children, not just the ones after it. In addition, accGroupInfo::Update() now checks if the previous and next siblings that are being used as shortcuts have dirty group info, and are being used only if they do not.

Differential Revision: https://phabricator.services.mozilla.com/D16059

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Marco Zehe 2019-01-10 05:59:01 +00:00
parent d9173f8644
commit b4ebbe90ae
5 changed files with 93 additions and 3 deletions

View File

@ -59,7 +59,7 @@ void AccGroupInfo::Update() {
// If the previous item in the group has calculated group information then
// build group information for this item based on found one.
if (sibling->mBits.groupInfo) {
if (sibling->mBits.groupInfo && !sibling->HasDirtyGroupInfo()) {
mPosInSet += sibling->mBits.groupInfo->mPosInSet;
mParent = sibling->mBits.groupInfo->mParent;
mSetSize = sibling->mBits.groupInfo->mSetSize;
@ -93,7 +93,7 @@ void AccGroupInfo::Update() {
// If the next item in the group has calculated group information then
// build group information for this item based on found one.
if (sibling->mBits.groupInfo) {
if (sibling->mBits.groupInfo && !sibling->HasDirtyGroupInfo()) {
mParent = sibling->mBits.groupInfo->mParent;
mSetSize = sibling->mBits.groupInfo->mSetSize;
return;

View File

@ -103,6 +103,9 @@ void TreeMutation::Done() {
for (uint32_t idx = mStartIdx; idx < length; idx++) {
mParent->mChildren[idx]->mInt.mIndexOfEmbeddedChild = -1;
}
for (uint32_t idx = 0; idx < length; idx++) {
mParent->mChildren[idx]->mStateFlags |= Accessible::eGroupInfoDirty;
}

View File

@ -2150,10 +2150,13 @@ void Accessible::MoveChild(uint32_t aNewIndex, Accessible* aChild) {
for (uint32_t idx = startIdx; idx <= endIdx; idx++) {
mChildren[idx]->mIndexInParent = idx;
mChildren[idx]->mStateFlags |= eGroupInfoDirty;
mChildren[idx]->mInt.mIndexOfEmbeddedChild = -1;
}
for (uint32_t idx = 0; idx < mChildren.Length(); idx++) {
mChildren[idx]->mStateFlags |= eGroupInfoDirty;
}
RefPtr<AccShowEvent> showEvent = new AccShowEvent(aChild);
DebugOnly<bool> added = mDoc->Controller()->QueueMutationEvent(showEvent);
MOZ_ASSERT(added);

View File

@ -4,6 +4,7 @@ support-files =
[test_dpub_aria_xml-roles.html]
[test_graphics_aria_xml-roles.html]
[test_listbox.html]
[test_obj.html]
[test_obj_css.html]
[test_obj_css.xul]

View File

@ -0,0 +1,83 @@
<html>
<head>
<title>Listbox group attribute tests</title>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../attributes.js"></script>
<script type="application/javascript"
src="../events.js"></script>
<script type="application/javascript">
async function doTest() {
// First test the whole lot.
testGroupAttrs("a", 1, 6);
testGroupAttrs("b", 2, 6);
testGroupAttrs("c", 3, 6);
testGroupAttrs("d", 4, 6);
testGroupAttrs("e", 5, 6);
testGroupAttrs("f", 6, 6);
// Remove c, reducing the set to 5.
let listbox = getAccessible("listbox");
let updated = waitForEventPromise(EVENT_REORDER, listbox);
c.remove();
await updated;
testGroupAttrs("a", 1, 5);
testGroupAttrs("b", 2, 5);
testGroupAttrs("d", 3, 5);
testGroupAttrs("e", 4, 5);
testGroupAttrs("f", 5, 5);
// Now, remove the first element.
updated = waitForEventPromise(EVENT_REORDER, listbox);
a.remove();
await updated;
testGroupAttrs("b", 1, 4);
testGroupAttrs("d", 2, 4);
testGroupAttrs("e", 3, 4);
testGroupAttrs("f", 4, 4);
// Remove the last item.
updated = waitForEventPromise(EVENT_REORDER, listbox);
f.remove();
await updated;
testGroupAttrs("b", 1, 3);
testGroupAttrs("d", 2, 3);
testGroupAttrs("e", 3, 3);
// Finally, remove the middle item.
updated = waitForEventPromise(EVENT_REORDER, listbox);
d.remove();
await updated;
testGroupAttrs("b", 1, 2);
testGroupAttrs("e", 2, 2);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<!-- Group information updated after removal of list items, bug 1515186 -->
<div id="listbox" role="listbox">
<div id="a" role="option">Option a</div>
<div id="b" role="option">Option b</div>
<div id="c" role="option">Option c</div>
<div id="d" role="option">Option d</div>
<div id="e" role="option">Option e</div>
<div id="f" role="option">Option f</div>
</div>
</body>
</html>