mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 864224 - Support nested ARIA listitems structured by role='group', r=tbsaunde
This commit is contained in:
parent
937aa4fe6a
commit
321c3993eb
@ -110,52 +110,69 @@ AccGroupInfo::AccGroupInfo(Accessible* aItem, role aRole) :
|
||||
if (IsConceptualParent(aRole, parentRole))
|
||||
mParent = parent;
|
||||
|
||||
// In the case of ARIA tree (not ARIA treegrid) a tree can be arranged by
|
||||
// using ARIA groups to organize levels. In this case the parent of the tree
|
||||
// item will be a group and the previous treeitem of that should be the tree
|
||||
// item parent.
|
||||
if (parentRole != roles::GROUPING || aRole != roles::OUTLINEITEM)
|
||||
// ARIA tree and list can be arranged by using ARIA groups to organize levels.
|
||||
if (parentRole != roles::GROUPING)
|
||||
return;
|
||||
|
||||
Accessible* parentPrevSibling = parent->PrevSibling();
|
||||
if (!parentPrevSibling)
|
||||
return;
|
||||
|
||||
roles::Role parentPrevSiblingRole = parentPrevSibling->Role();
|
||||
if (parentPrevSiblingRole == roles::TEXT_LEAF) {
|
||||
// XXX Sometimes an empty text accessible is in the hierarchy here,
|
||||
// although the text does not appear to be rendered, GetRenderedText()
|
||||
// says that it is so we need to skip past it to find the true
|
||||
// previous sibling.
|
||||
parentPrevSibling = parentPrevSibling->PrevSibling();
|
||||
if (parentPrevSibling)
|
||||
parentPrevSiblingRole = parentPrevSibling->Role();
|
||||
// Way #1 for ARIA tree (not ARIA treegrid): previous sibling of a group is a
|
||||
// parent. In other words the parent of the tree item will be a group and
|
||||
// the previous tree item of the group is a conceptual parent of the tree
|
||||
// item.
|
||||
if (aRole == roles::OUTLINEITEM) {
|
||||
Accessible* parentPrevSibling = parent->PrevSibling();
|
||||
if (parentPrevSibling && parentPrevSibling->Role() == aRole) {
|
||||
mParent = parentPrevSibling;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Previous sibling of parent group is a tree item, this is the
|
||||
// conceptual tree item parent.
|
||||
if (parentPrevSiblingRole == roles::OUTLINEITEM)
|
||||
mParent = parentPrevSibling;
|
||||
// Way #2 for ARIA list and tree: group is a child of an item. In other words
|
||||
// the parent of the item will be a group and containing item of the group is
|
||||
// a conceptual parent of the item.
|
||||
if (aRole == roles::LISTITEM || aRole == roles::OUTLINEITEM) {
|
||||
Accessible* grandParent = parent->Parent();
|
||||
if (grandParent && grandParent->Role() == aRole)
|
||||
mParent = grandParent;
|
||||
}
|
||||
}
|
||||
|
||||
Accessible*
|
||||
AccGroupInfo::FirstItemOf(Accessible* aContainer)
|
||||
{
|
||||
// ARIA trees can be arranged by ARIA groups, otherwise aria-level works.
|
||||
// ARIA tree can be arranged by ARIA groups case #1 (previous sibling of a
|
||||
// group is a parent) or by aria-level.
|
||||
a11y::role containerRole = aContainer->Role();
|
||||
Accessible* item = aContainer->NextSibling();
|
||||
if (item) {
|
||||
if (containerRole == roles::OUTLINEITEM && item->Role() == roles::GROUPING)
|
||||
item = item->FirstChild();
|
||||
|
||||
AccGroupInfo* itemGroupInfo = item->GetGroupInfo();
|
||||
if (itemGroupInfo && itemGroupInfo->ConceptualParent() == aContainer)
|
||||
return item;
|
||||
if (item) {
|
||||
AccGroupInfo* itemGroupInfo = item->GetGroupInfo();
|
||||
if (itemGroupInfo && itemGroupInfo->ConceptualParent() == aContainer)
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
// ARIA list and tree can be arranged by ARIA groups case #2 (group is
|
||||
// a child of an item).
|
||||
item = aContainer->LastChild();
|
||||
if (!item)
|
||||
return nullptr;
|
||||
|
||||
if (item->Role() == roles::GROUPING &&
|
||||
(containerRole == roles::LISTITEM || containerRole == roles::OUTLINEITEM)) {
|
||||
item = item->FirstChild();
|
||||
if (item) {
|
||||
AccGroupInfo* itemGroupInfo = item->GetGroupInfo();
|
||||
if (itemGroupInfo && itemGroupInfo->ConceptualParent() == aContainer)
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise it can be a direct child.
|
||||
item = aContainer->FirstChild();
|
||||
if (item && IsConceptualParent(BaseRole(item->Role()), containerRole))
|
||||
if (IsConceptualParent(BaseRole(item->Role()), containerRole))
|
||||
return item;
|
||||
|
||||
return nullptr;
|
||||
|
@ -2024,7 +2024,8 @@ Accessible::RelationByType(uint32_t aType)
|
||||
|
||||
// This is an ARIA tree or treegrid that doesn't use owns, so we need to
|
||||
// get the parent the hard way.
|
||||
if (mRoleMapEntry && (mRoleMapEntry->role == roles::OUTLINEITEM ||
|
||||
if (mRoleMapEntry && (mRoleMapEntry->role == roles::OUTLINEITEM ||
|
||||
mRoleMapEntry->role == roles::LISTITEM ||
|
||||
mRoleMapEntry->role == roles::ROW)) {
|
||||
rel.AppendTarget(GetGroupInfo()->ConceptualParent());
|
||||
}
|
||||
@ -2055,8 +2056,10 @@ Accessible::RelationByType(uint32_t aType)
|
||||
// also can be organized by groups.
|
||||
if (mRoleMapEntry &&
|
||||
(mRoleMapEntry->role == roles::OUTLINEITEM ||
|
||||
mRoleMapEntry->role == roles::LISTITEM ||
|
||||
mRoleMapEntry->role == roles::ROW ||
|
||||
mRoleMapEntry->role == roles::OUTLINE ||
|
||||
mRoleMapEntry->role == roles::LIST ||
|
||||
mRoleMapEntry->role == roles::TREE_TABLE)) {
|
||||
rel.AppendIter(new ItemIterator(this));
|
||||
}
|
||||
@ -3256,10 +3259,11 @@ Accessible::GetLevelInternal()
|
||||
}
|
||||
|
||||
} else if (role == roles::LISTITEM) {
|
||||
// Expose 'level' attribute on nested lists. We assume nested list is a last
|
||||
// child of listitem of parent list. We don't handle the case when nested
|
||||
// lists have more complex structure, for example when there are accessibles
|
||||
// between parent listitem and nested list.
|
||||
// Expose 'level' attribute on nested lists. We support two hierarchies:
|
||||
// a) list -> listitem -> list -> listitem (nested list is a last child
|
||||
// of listitem of the parent list);
|
||||
// b) list -> listitem -> group -> listitem (nested listitems are contained
|
||||
// by group that is a last child of the parent listitem).
|
||||
|
||||
// Calculate 'level' attribute based on number of parent listitems.
|
||||
level = 0;
|
||||
@ -3269,9 +3273,8 @@ Accessible::GetLevelInternal()
|
||||
|
||||
if (parentRole == roles::LISTITEM)
|
||||
++ level;
|
||||
else if (parentRole != roles::LIST)
|
||||
else if (parentRole != roles::LIST && parentRole != roles::GROUPING)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (level == 0) {
|
||||
@ -3283,8 +3286,11 @@ Accessible::GetLevelInternal()
|
||||
Accessible* sibling = parent->GetChildAt(siblingIdx);
|
||||
|
||||
Accessible* siblingChild = sibling->LastChild();
|
||||
if (siblingChild && siblingChild->Role() == roles::LIST)
|
||||
return 1;
|
||||
if (siblingChild) {
|
||||
roles::Role lastChildRole = siblingChild->Role();
|
||||
if (lastChildRole == roles::LIST || lastChildRole == roles::GROUPING)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
++ level; // level is 1-index based
|
||||
|
@ -68,7 +68,7 @@
|
||||
testGroupAttrs("li9", 3, 3);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ARIA list (nested lists)
|
||||
// ARIA list (nested lists: list -> listitem -> list -> listitem)
|
||||
testGroupAttrs("li10", 1, 3, 1);
|
||||
testGroupAttrs("li11", 2, 3, 1);
|
||||
testGroupAttrs("li12", 3, 3, 1);
|
||||
@ -77,6 +77,15 @@
|
||||
testGroupAttrs("n_li11", 2, 3, 2);
|
||||
testGroupAttrs("n_li12", 3, 3, 2);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ARIA list (nested lists: list -> listitem -> group -> listitem)
|
||||
testGroupAttrs("lgt_li1", 1, 2, 1);
|
||||
testGroupAttrs("lgt_li1_nli1", 1, 2, 2);
|
||||
testGroupAttrs("lgt_li1_nli2", 2, 2, 2);
|
||||
testGroupAttrs("lgt_li2", 2, 2, 1);
|
||||
testGroupAttrs("lgt_li2_nli1", 1, 2, 2);
|
||||
testGroupAttrs("lgt_li2_nli2", 2, 2, 2);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ARIA menu (menuitem, separator, menuitemradio and menuitemcheckbox)
|
||||
testGroupAttrs("menu_item1", 1, 2);
|
||||
@ -110,6 +119,24 @@
|
||||
testGroupAttrs("ti7", 3, 3, 2);
|
||||
testGroupAttrs("ti8", 3, 3, 1);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ARIA tree (tree -> treeitem -> group -> treeitem)
|
||||
testGroupAttrs("tree2_ti1", 1, 2, 1);
|
||||
testGroupAttrs("tree2_ti1a", 1, 2, 2);
|
||||
testGroupAttrs("tree2_ti1b", 2, 2, 2);
|
||||
testGroupAttrs("tree2_ti2", 2, 2, 1);
|
||||
testGroupAttrs("tree2_ti2a", 1, 2, 2);
|
||||
testGroupAttrs("tree2_ti2b", 2, 2, 2);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ARIA tree (tree -> treeitem, group -> treeitem)
|
||||
testGroupAttrs("tree3_ti1", 1, 2, 1);
|
||||
testGroupAttrs("tree3_ti1a", 1, 2, 2);
|
||||
testGroupAttrs("tree3_ti1b", 2, 2, 2);
|
||||
testGroupAttrs("tree3_ti2", 2, 2, 1);
|
||||
testGroupAttrs("tree3_ti2a", 1, 2, 2);
|
||||
testGroupAttrs("tree3_ti2b", 2, 2, 2);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ARIA grid
|
||||
testGroupAttrs("grid_row1", 1, 2);
|
||||
@ -164,6 +191,11 @@
|
||||
title="Expose level for nested lists in HTML">
|
||||
Mozilla Bug 468418
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=864224"
|
||||
title="Support nested ARIA listitems structured by role='group'">
|
||||
Bug 864224
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
@ -228,6 +260,21 @@
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div role="list">
|
||||
<div role="listitem" id="lgt_li1">Item 1
|
||||
<div role="group">
|
||||
<div role="listitem" id="lgt_li1_nli1">Item 1A</div>
|
||||
<div role="listitem" id="lgt_li1_nli2">Item 1B</div>
|
||||
</div>
|
||||
</div>
|
||||
<div role="listitem" id="lgt_li2">Item 2
|
||||
<div role="group">
|
||||
<div role="listitem" id="lgt_li2_nli1">Item 2A</div>
|
||||
<div role="listitem" id="lgt_li2_nli2">Item 2B</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul role="menubar">
|
||||
<li role="menuitem" aria-haspopup="true" id="menu_item1">File
|
||||
<ul role="menu">
|
||||
@ -283,6 +330,34 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<ul role="tree">
|
||||
<li role="treeitem" id="tree2_ti1">Item 1
|
||||
<ul role="group">
|
||||
<li role="treeitem" id="tree2_ti1a">Item 1A</li>
|
||||
<li role="treeitem" id="tree2_ti1b">Item 1B</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li role="treeitem" id="tree2_ti2">Item 2
|
||||
<ul role="group">
|
||||
<li role="treeitem" id="tree2_ti2a">Item 2A</li>
|
||||
<li role="treeitem" id="tree2_ti2b">Item 2B</li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<div role="tree">
|
||||
<div role="treeitem" id="tree3_ti1">Item 1</div>
|
||||
<div role="group">
|
||||
<li role="treeitem" id="tree3_ti1a">Item 1A</li>
|
||||
<li role="treeitem" id="tree3_ti1b">Item 1B</li>
|
||||
</div>
|
||||
<div role="treeitem" id="tree3_ti2">Item 2</div>
|
||||
<div role="group">
|
||||
<div role="treeitem" id="tree3_ti2a">Item 2A</div>
|
||||
<div role="treeitem" id="tree3_ti2b">Item 2B</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table role="grid">
|
||||
<tr role="row" id="grid_row1">
|
||||
<td role="gridcell" id="grid_cell1">cell1</td>
|
||||
|
@ -73,12 +73,20 @@
|
||||
testRelation("treeitem5", RELATION_NODE_CHILD_OF, "treeitem4");
|
||||
testRelation("treeitem6", RELATION_NODE_CHILD_OF, "tree");
|
||||
testRelation("treeitem7", RELATION_NODE_CHILD_OF, "treeitem6");
|
||||
testRelation("tree2_ti1", RELATION_NODE_CHILD_OF, "tree2");
|
||||
testRelation("tree2_ti1a", RELATION_NODE_CHILD_OF, "tree2_ti1");
|
||||
testRelation("tree2_ti1b", RELATION_NODE_CHILD_OF, "tree2_ti1");
|
||||
|
||||
// 'node child of' relation for row role of treegrid
|
||||
testRelation("treegridrow1", RELATION_NODE_CHILD_OF, "treegrid");
|
||||
testRelation("treegridrow2", RELATION_NODE_CHILD_OF, "treegrid");
|
||||
testRelation("treegridrow3", RELATION_NODE_CHILD_OF, "treegridrow2");
|
||||
|
||||
// 'node child of' relation for lists organized by groups
|
||||
testRelation("listitem1", RELATION_NODE_CHILD_OF, "list");
|
||||
testRelation("listitem1.1", RELATION_NODE_CHILD_OF, "listitem1");
|
||||
testRelation("listitem1.2", RELATION_NODE_CHILD_OF, "listitem1");
|
||||
|
||||
// 'node child of' relation for the document having window, returns
|
||||
// direct accessible parent (fixed in bug 419770).
|
||||
var iframeElmObj = {};
|
||||
@ -95,11 +103,20 @@
|
||||
"treeitem5"); // aria-level
|
||||
testRelation("treeitem6", RELATION_NODE_PARENT_OF,
|
||||
"treeitem7"); // // group role
|
||||
testRelation("tree2", RELATION_NODE_PARENT_OF, "tree2_ti1"); // group role
|
||||
testRelation("tree2_ti1", RELATION_NODE_PARENT_OF,
|
||||
["tree2_ti1a", "tree2_ti1b"]); // group role
|
||||
|
||||
testRelation("treegridrow2", RELATION_NODE_PARENT_OF, "treegridrow3");
|
||||
testRelation("treegrid", RELATION_NODE_PARENT_OF,
|
||||
["treegridrow1", "treegridrow2"]);
|
||||
|
||||
// 'node parent of' relation on ARIA list structured by groups
|
||||
testRelation("list", RELATION_NODE_PARENT_OF,
|
||||
"listitem1");
|
||||
testRelation("listitem1", RELATION_NODE_PARENT_OF,
|
||||
[ "listitem1.1", "listitem1.2" ]);
|
||||
|
||||
// aria-controls
|
||||
getAccessible("tab");
|
||||
todo(false,
|
||||
@ -178,6 +195,11 @@
|
||||
title="HTML select options gets relation from containing label">
|
||||
Bug 687393
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=864224"
|
||||
title="Support nested ARIA listitems structured by role='group'">
|
||||
Bug 864224
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
@ -253,6 +275,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul role="tree" id="tree2">
|
||||
<li role="treeitem" id="tree2_ti1">Item 1
|
||||
<ul role="group">
|
||||
<li role="treeitem" id="tree2_ti1a">Item 1A</li>
|
||||
<li role="treeitem" id="tree2_ti1b">Item 1B</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div role="treegrid" id="treegrid">
|
||||
<div role="row" id="treegridrow1">
|
||||
<span role="gridcell">cell1</span><span role="gridcell">cell2</span>
|
||||
@ -265,6 +296,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div role="list" id="list">
|
||||
<div role="listitem" id="listitem1">Item 1
|
||||
<div role="group">
|
||||
<div role="listitem" id="listitem1.1">Item 1A</div>
|
||||
<div role="listitem" id="listitem1.2">Item 1B</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<iframe id="iframe"></iframe>
|
||||
|
||||
<div id="tablist" role="tablist">
|
||||
|
Loading…
Reference in New Issue
Block a user