Commit 7050e61a authored by Aaron Leventhal's avatar Aaron Leventhal Committed by Commit Bot

Support details-roles object attribute hint

Bug: 1006767
Change-Id: I9665b2e1c935bece54e92d94a327071128f3efb7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2032788
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#738714}
parent 53a70319
...@@ -537,6 +537,7 @@ const char* const ATK_OBJECT_ATTRIBUTES[] = { ...@@ -537,6 +537,7 @@ const char* const ATK_OBJECT_ATTRIBUTES[] = {
"container-live", "container-live",
"container-relevant", "container-relevant",
"current", "current",
"details-roles",
"display", "display",
"dropeffect", "dropeffect",
"explicit-name", "explicit-name",
......
...@@ -563,6 +563,11 @@ IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityAriaDetails) { ...@@ -563,6 +563,11 @@ IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityAriaDetails) {
RunAriaTest(FILE_PATH_LITERAL("aria-details.html")); RunAriaTest(FILE_PATH_LITERAL("aria-details.html"));
} }
IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest,
AccessibilityAriaDetailsRoles) {
RunAriaTest(FILE_PATH_LITERAL("aria-details-roles.html"));
}
IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityAriaDialog) { IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityAriaDialog) {
RunAriaTest(FILE_PATH_LITERAL("aria-dialog.html")); RunAriaTest(FILE_PATH_LITERAL("aria-dialog.html"));
} }
......
#<skip -- Some bots do not map details/details-for>
[document web]
++[section]
++++[entry] selectable-text details
++[paragraph] details-for
++++[static] name='Details'
++[paragraph]
++++[static] name='This '
++++[section] details
++++++[static] name='text'
++++[static] name=' has details'
++[panel] details-for
++++[static] name='Text details'
++[image] name='Image details' details-for
[document web]
++[section] name='comment' details-roles:comment
++[section] name='comment-group' details-roles:comment
++[section] name='comment-region' details-roles:comment
++[section] name='comment-section' details-roles:*
++[section] name='definition' details-roles:definition
++[section] name='doc-endnote' details-roles:doc-endnote
++[section] name='doc-footnote' details-roles:doc-footnote
++[section] name='many' details-roles:comment definition doc-footnote
++[section]
++++[static] name='x'
++[panel]
++++[heading] name='heading'
++++++[static] name='heading'
++++[panel]
++++++[section]
++++++++[static] name='x'
++[landmark]
++++[section]
++++++[static] name='x'
++[section]
++++[section]
++++++[static] name='x'
++[description value]
++++[static] name='x'
++[list item]
++++[static] name='x'
++[footnote]
++++[static] name='x'
ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE
++IA2_ROLE_SECTION name='comment' details-roles:comment
++IA2_ROLE_SECTION name='comment-group' details-roles:comment
++IA2_ROLE_SECTION name='comment-region' details-roles:comment
++IA2_ROLE_SECTION name='comment-section' details-roles:*
++IA2_ROLE_SECTION name='definition' details-roles:definition
++IA2_ROLE_SECTION name='doc-endnote' details-roles:doc-endnote
++IA2_ROLE_SECTION name='doc-footnote' details-roles:doc-footnote
++IA2_ROLE_SECTION name='many' details-roles:comment definition doc-footnote
++IA2_ROLE_COMMENT
++++ROLE_SYSTEM_STATICTEXT name='x'
++ROLE_SYSTEM_GROUPING
++++IA2_ROLE_HEADING name='heading'
++++++ROLE_SYSTEM_STATICTEXT name='heading'
++++ROLE_SYSTEM_GROUPING
++++++IA2_ROLE_COMMENT
++++++++ROLE_SYSTEM_STATICTEXT name='x'
++IA2_ROLE_LANDMARK
++++IA2_ROLE_COMMENT
++++++ROLE_SYSTEM_STATICTEXT name='x'
++IA2_ROLE_SECTION
++++IA2_ROLE_COMMENT
++++++ROLE_SYSTEM_STATICTEXT name='x'
++IA2_ROLE_PARAGRAPH READONLY
++++ROLE_SYSTEM_STATICTEXT name='x'
++ROLE_SYSTEM_LISTITEM
++++ROLE_SYSTEM_STATICTEXT name='x'
++IA2_ROLE_FOOTNOTE
++++ROLE_SYSTEM_STATICTEXT name='x'
\ No newline at end of file
<!--
@WIN-ALLOW:details-roles:*
@AURALINUX-ALLOW:details-roles:*
@AURALINUX-DENY:details
@AURALINUX-DENY:details-for
@AURALINUX-DENY:last-defined
-->
<!-- details-roles=comment when pointing to a group or region with comments -->
<div aria-details="comment" aria-label="comment"></div>
<div aria-details="comment-group" aria-label="comment-group"></div>
<div aria-details="comment-region" aria-label="comment-region"></div>
<div aria-details="comment-section" aria-label="comment-section"></div>
<div aria-details="definition" aria-label="definition"></div>
<div aria-details="doc-endnote" aria-label="doc-endnote"></div>
<div aria-details="doc-footnote" aria-label="doc-footnote"></div>
<div aria-details="comment-group comment definition doc-footnote" aria-label="many"></div>
<div id="comment" role="comment">x</div>
<div id="comment-group" role="group">
<h1>heading</h1>
<div role="group">
<div role="comment">x</div>
</div>
</div>
<div id="comment-region" role="region">
<div role="comment">x</div>
</div>
<div id="comment-section" role="section">
<div role="comment">x</div>
</div>
<div id="definition" role="definition">x</div>
<div id="doc-endnote" role="doc-endnote">x</div>
<div id="doc-footnote" role="doc-footnote">x</div>
...@@ -2893,8 +2893,10 @@ struct AtkIntListRelation { ...@@ -2893,8 +2893,10 @@ struct AtkIntListRelation {
static AtkIntListRelation kIntListRelations[] = { static AtkIntListRelation kIntListRelations[] = {
{ax::mojom::IntListAttribute::kControlsIds, ATK_RELATION_CONTROLLER_FOR, {ax::mojom::IntListAttribute::kControlsIds, ATK_RELATION_CONTROLLER_FOR,
ATK_RELATION_CONTROLLED_BY}, ATK_RELATION_CONTROLLED_BY},
#if defined(ATK_226)
{ax::mojom::IntListAttribute::kDetailsIds, ATK_RELATION_DETAILS, {ax::mojom::IntListAttribute::kDetailsIds, ATK_RELATION_DETAILS,
ATK_RELATION_DETAILS_FOR}, ATK_RELATION_DETAILS_FOR},
#endif
{ax::mojom::IntListAttribute::kDescribedbyIds, ATK_RELATION_DESCRIBED_BY, {ax::mojom::IntListAttribute::kDescribedbyIds, ATK_RELATION_DESCRIBED_BY,
ATK_RELATION_DESCRIPTION_FOR}, ATK_RELATION_DESCRIPTION_FOR},
{ax::mojom::IntListAttribute::kFlowtoIds, ATK_RELATION_FLOWS_TO, {ax::mojom::IntListAttribute::kFlowtoIds, ATK_RELATION_FLOWS_TO,
......
...@@ -29,6 +29,31 @@ namespace { ...@@ -29,6 +29,31 @@ namespace {
// A function to call when focus changes, for testing only. // A function to call when focus changes, for testing only.
base::LazyInstance<std::map<ax::mojom::Event, base::RepeatingClosure>>:: base::LazyInstance<std::map<ax::mojom::Event, base::RepeatingClosure>>::
DestructorAtExit g_on_notify_event_for_testing; DestructorAtExit g_on_notify_event_for_testing;
// Check for descendant comment, using limited depth first search.
bool FindDescendantRoleWithMaxDepth(AXPlatformNodeBase* node,
ax::mojom::Role descendant_role,
int max_depth,
int max_children_to_check) {
if (node->GetData().role == descendant_role)
return true;
if (max_depth <= 1)
return false;
int num_children_to_check =
std::min(node->GetChildCount(), max_children_to_check);
for (int index = 0; index < num_children_to_check; index++) {
auto* child = static_cast<AXPlatformNodeBase*>(
AXPlatformNode::FromNativeViewAccessible(node->ChildAtIndex(index)));
if (child &&
FindDescendantRoleWithMaxDepth(child, descendant_role, max_depth - 1,
max_children_to_check)) {
return true;
}
}
return false;
}
} // namespace } // namespace
const base::char16 AXPlatformNodeBase::kEmbeddedCharacter = L'\xfffc'; const base::char16 AXPlatformNodeBase::kEmbeddedCharacter = L'\xfffc';
...@@ -1124,6 +1149,10 @@ void AXPlatformNodeBase::ComputeAttributes(PlatformAttributeList* attributes) { ...@@ -1124,6 +1149,10 @@ void AXPlatformNodeBase::ComputeAttributes(PlatformAttributeList* attributes) {
GetData().GetHtmlAttribute("type", &type)) { GetData().GetHtmlAttribute("type", &type)) {
AddAttributeToList("text-input-type", type, attributes); AddAttributeToList("text-input-type", type, attributes);
} }
std::string details_roles = ComputeDetailsRoles();
if (!details_roles.empty())
AddAttributeToList("details-roles", details_roles, attributes);
} }
void AXPlatformNodeBase::AddAttributeToList( void AXPlatformNodeBase::AddAttributeToList(
...@@ -1906,4 +1935,57 @@ void AXPlatformNodeBase::SanitizeTextAttributeValue(const std::string& input, ...@@ -1906,4 +1935,57 @@ void AXPlatformNodeBase::SanitizeTextAttributeValue(const std::string& input,
DCHECK(output); DCHECK(output);
} }
std::string AXPlatformNodeBase::ComputeDetailsRoles() const {
const std::vector<int32_t>& details_ids =
GetIntListAttribute(ax::mojom::IntListAttribute::kDetailsIds);
if (details_ids.empty())
return std::string();
std::set<std::string> details_roles_set;
for (int id : details_ids) {
AXPlatformNodeBase* detail_object =
static_cast<AXPlatformNodeBase*>(delegate_->GetFromNodeID(id));
if (!detail_object)
continue;
switch (detail_object->GetData().role) {
case ax::mojom::Role::kComment:
details_roles_set.insert("comment");
break;
case ax::mojom::Role::kDefinition:
details_roles_set.insert("definition");
break;
case ax::mojom::Role::kDocEndnote:
details_roles_set.insert("doc-endnote");
break;
case ax::mojom::Role::kDocFootnote:
details_roles_set.insert("doc-footnote");
break;
case ax::mojom::Role::kGroup:
case ax::mojom::Role::kRegion: {
// These should still report comment if there are comments inside them.
constexpr int kMaxChildrenToCheck = 8;
constexpr int kMaxDepthToCheck = 4;
if (FindDescendantRoleWithMaxDepth(
detail_object, ax::mojom::Role::kComment, kMaxDepthToCheck,
kMaxChildrenToCheck)) {
details_roles_set.insert("comment");
break;
}
FALLTHROUGH;
}
default:
// Use * to indicate some other role.
details_roles_set.insert("*");
break;
}
}
// Create space delimited list of types. The set will not be large, as there
// are not very many possible types.
std::vector<std::string> details_roles_vector(details_roles_set.begin(),
details_roles_set.end());
return base::JoinString(details_roles_vector, " ");
}
} // namespace ui } // namespace ui
...@@ -427,6 +427,9 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode { ...@@ -427,6 +427,9 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode {
size_t index, size_t index,
bool is_indexed_from_end = false); bool is_indexed_from_end = false);
// Compute value for object attribute details-roles on aria-details nodes.
std::string ComputeDetailsRoles() const;
DISALLOW_COPY_AND_ASSIGN(AXPlatformNodeBase); DISALLOW_COPY_AND_ASSIGN(AXPlatformNodeBase);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment