Bug 1251743 - ARIA owns reallocation may insert a child at wrong index, r=yzen

This commit is contained in:
Alexander Surkov 2016-03-01 14:35:01 -05:00
parent d4d25316b8
commit 6647b0c3d8
2 changed files with 71 additions and 1 deletions

View File

@ -2029,6 +2029,7 @@ DocAccessible::DoARIAOwnsRelocation(Accessible* aOwner)
MoveChild(child, insertIdx);
children->InsertElementAt(arrayIdx, child);
arrayIdx++;
insertIdx = child->IndexInParent() + 1;
} else if (SeizeChild(aOwner, child, insertIdx)) {
children->InsertElementAt(arrayIdx, child);
@ -2055,6 +2056,12 @@ DocAccessible::SeizeChild(Accessible* aNewParent, Accessible* aChild,
int32_t oldIdxInParent = aChild->IndexInParent();
#ifdef A11Y_LOG
logging::TreeInfo("aria owns seize child", 0,
"old parent", oldParent, "new parent", aNewParent,
"child", aChild, nullptr);
#endif
RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(oldParent);
RefPtr<AccMutationEvent> hideEvent = new AccHideEvent(aChild, false);
reorderEvent->AddSubMutationEvent(hideEvent);
@ -2070,6 +2077,11 @@ DocAccessible::SeizeChild(Accessible* aNewParent, Accessible* aChild,
isReinserted = aNewParent->InsertChildAt(aIdxInParent, aChild);
}
#ifdef A11Y_LOG
logging::TreeInfo("aria owns seize child: new parent tree after",
logging::eVerbose, aNewParent);
#endif
if (!isReinserted) {
AutoTreeMutation mut(oldParent);
oldParent->InsertChildAt(oldIdxInParent, aChild);
@ -2108,10 +2120,20 @@ DocAccessible::MoveChild(Accessible* aChild, int32_t aIdxInParent)
RefPtr<AccMutationEvent> hideEvent = new AccHideEvent(aChild, false);
reorderEvent->AddSubMutationEvent(hideEvent);
#ifdef A11Y_LOG
logging::TreeInfo("aria owns move child", 0,
"parent", parent, "child", aChild, nullptr);
#endif
AutoTreeMutation mut(parent);
parent->MoveChild(aIdxInParent, aChild);
aChild->SetRelocated(true);
#ifdef A11Y_LOG
logging::TreeInfo("aria owns move child: parent tree after",
logging::eVerbose, parent);
#endif
FireDelayedEvent(hideEvent);
RefPtr<AccMutationEvent> showEvent = new AccShowEvent(aChild);

View File

@ -441,12 +441,44 @@
}
}
function rearrangeARIAOwns(aContainer, aAttr, aIdList, aRoleList)
{
this.eventSeq = [];
for (var id of aIdList) {
this.eventSeq.push(new invokerChecker(EVENT_HIDE, getNode(id)));
this.eventSeq.push(new invokerChecker(EVENT_SHOW, getNode(id)));
}
this.eventSeq.push(new invokerChecker(EVENT_REORDER, getNode(aContainer)));
this.invoke = function rearrangeARIAOwns_invoke()
{
getNode(aContainer).setAttribute("aria-owns", aAttr);
}
this.finalCheck = function rearrangeARIAOwns_finalCheck()
{
var tree = { SECTION: [ ] };
for (var role of aRoleList) {
var ch = {};
ch[role] = [];
tree["SECTION"].push(ch);
}
testAccessibleTree(aContainer, tree);
}
this.getID = function rearrangeARIAOwns_getID()
{
return `Rearrange @aria-owns attribute to '${aAttr}'`;
}
}
////////////////////////////////////////////////////////////////////////////
// Test
////////////////////////////////////////////////////////////////////////////
//gA11yEventDumpToConsole = true;
//enableLogging("tree"); // debug stuff
//enableLogging("tree,verbose"); // debug stuff
var gQueue = null;
@ -474,6 +506,16 @@
// test4
gQueue.push(new showHiddenElement());
// test5
gQueue.push(new rearrangeARIAOwns(
"t5_container", "t5_checkbox t5_radio t5_button",
[ "t5_checkbox", "t5_radio", "t5_button" ],
[ "CHECKBUTTON", "RADIOBUTTON", "PUSHBUTTON" ]));
gQueue.push(new rearrangeARIAOwns(
"t5_container", "t5_radio t5_button t5_checkbox",
[ "t5_radio", "t5_button" ],
[ "RADIOBUTTON", "PUSHBUTTON", "CHECKBUTTON" ]));
gQueue.invoke(); // SimpleTest.finish() will be called in the end
}
@ -515,6 +557,12 @@
<div id="t4_child1" style="display:none" role="checkbox"></div>
<div id="t4_child2" role="radio"></div>
</div>
<div id="t5_container">
<div role="button" id="t5_button"></div>
<div role="checkbox" id="t5_checkbox"></div>
<div role="radio" id="t5_radio"></div>
</div>
</body>
</html>