Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: content/renderer/accessibility/accessibility_node_serializer.cc

Issue 175613002: Include relationship ARIA objects in serialized accessibility tree (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reuse MAYBE(x) for failing android test Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/accessibility/accessibility_node_serializer.h" 5 #include "content/renderer/accessibility/accessibility_node_serializer.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 return "navigation"; 68 return "navigation";
69 case ui::AX_ROLE_REGION: 69 case ui::AX_ROLE_REGION:
70 return "region"; 70 return "region";
71 default: 71 default:
72 break; 72 break;
73 } 73 }
74 74
75 return std::string(); 75 return std::string();
76 } 76 }
77 77
78 void AddIntListAttributeFromWebObjects(ui::AXIntListAttribute attr,
79 WebVector<WebAXObject> objects,
80 ui::AXNodeData* dst) {
81 std::vector<int32> ids;
82 for(size_t i = 0; i < objects.size(); i++)
83 ids.push_back(objects[i].axID());
84 if (ids.size() > 0)
85 dst->AddIntListAttribute(attr, ids);
86 }
87
88
78 } // Anonymous namespace 89 } // Anonymous namespace
79 90
80 void SerializeAccessibilityNode( 91 void SerializeAccessibilityNode(
81 const WebAXObject& src, 92 const WebAXObject& src,
82 ui::AXNodeData* dst) { 93 ui::AXNodeData* dst) {
83 dst->role = AXRoleFromBlink(src.role()); 94 dst->role = AXRoleFromBlink(src.role());
84 dst->state = AXStateFromBlink(src); 95 dst->state = AXStateFromBlink(src);
85 dst->location = src.boundingBoxRect(); 96 dst->location = src.boundingBoxRect();
86 dst->id = src.axID(); 97 dst->id = src.axID();
87 std::string name = base::UTF16ToUTF8(src.title()); 98 std::string name = base::UTF16ToUTF8(src.title());
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 if (src.helpText().length()) 162 if (src.helpText().length())
152 dst->AddStringAttribute(ui::AX_ATTR_HELP, UTF16ToUTF8(src.helpText())); 163 dst->AddStringAttribute(ui::AX_ATTR_HELP, UTF16ToUTF8(src.helpText()));
153 if (src.keyboardShortcut().length()) { 164 if (src.keyboardShortcut().length()) {
154 dst->AddStringAttribute(ui::AX_ATTR_SHORTCUT, 165 dst->AddStringAttribute(ui::AX_ATTR_SHORTCUT,
155 UTF16ToUTF8(src.keyboardShortcut())); 166 UTF16ToUTF8(src.keyboardShortcut()));
156 } 167 }
157 if (!src.titleUIElement().isDetached()) { 168 if (!src.titleUIElement().isDetached()) {
158 dst->AddIntAttribute(ui::AX_ATTR_TITLE_UI_ELEMENT, 169 dst->AddIntAttribute(ui::AX_ATTR_TITLE_UI_ELEMENT,
159 src.titleUIElement().axID()); 170 src.titleUIElement().axID());
160 } 171 }
172 if (!src.ariaActiveDescendant().isDetached()) {
173 dst->AddIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID,
174 src.ariaActiveDescendant().axID());
175 }
176
161 if (!src.url().isEmpty()) 177 if (!src.url().isEmpty())
162 dst->AddStringAttribute(ui::AX_ATTR_URL, src.url().spec()); 178 dst->AddStringAttribute(ui::AX_ATTR_URL, src.url().spec());
163 179
164 if (dst->role == ui::AX_ROLE_HEADING) 180 if (dst->role == ui::AX_ROLE_HEADING)
165 dst->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL, src.headingLevel()); 181 dst->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL, src.headingLevel());
166 else if ((dst->role == ui::AX_ROLE_TREE_ITEM || 182 else if ((dst->role == ui::AX_ROLE_TREE_ITEM ||
167 dst->role == ui::AX_ROLE_ROW) && 183 dst->role == ui::AX_ROLE_ROW) &&
168 src.hierarchicalLevel() > 0) { 184 src.hierarchicalLevel() > 0) {
169 dst->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL, 185 dst->AddIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL,
170 src.hierarchicalLevel()); 186 src.hierarchicalLevel());
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 } 418 }
403 419
404 dst->AddStringAttribute(ui::AX_ATTR_NAME, name); 420 dst->AddStringAttribute(ui::AX_ATTR_NAME, name);
405 421
406 // Add the ids of *indirect* children - those who are children of this node, 422 // Add the ids of *indirect* children - those who are children of this node,
407 // but whose parent is *not* this node. One example is a table 423 // but whose parent is *not* this node. One example is a table
408 // cell, which is a child of both a row and a column. Because the cell's 424 // cell, which is a child of both a row and a column. Because the cell's
409 // parent is the row, the row adds it as a child, and the column adds it 425 // parent is the row, the row adds it as a child, and the column adds it
410 // as an indirect child. 426 // as an indirect child.
411 int child_count = src.childCount(); 427 int child_count = src.childCount();
428 std::vector<int32> indirect_child_ids;
412 for (int i = 0; i < child_count; ++i) { 429 for (int i = 0; i < child_count; ++i) {
413 WebAXObject child = src.childAt(i); 430 WebAXObject child = src.childAt(i);
414 std::vector<int32> indirect_child_ids;
415 if (!is_iframe && !child.isDetached() && !IsParentUnignoredOf(src, child)) 431 if (!is_iframe && !child.isDetached() && !IsParentUnignoredOf(src, child))
416 indirect_child_ids.push_back(child.axID()); 432 indirect_child_ids.push_back(child.axID());
417 if (indirect_child_ids.size() > 0) {
418 dst->AddIntListAttribute(
419 ui::AX_ATTR_INDIRECT_CHILD_IDS, indirect_child_ids);
420 }
421 } 433 }
434 if (indirect_child_ids.size() > 0) {
435 dst->AddIntListAttribute(ui::AX_ATTR_INDIRECT_CHILD_IDS,
436 indirect_child_ids);
437 }
438
439 WebVector<WebAXObject> controls;
440 if (src.ariaControls(controls))
441 AddIntListAttributeFromWebObjects(ui::AX_ATTR_CONTROLS_IDS, controls, dst);
442
443 WebVector<WebAXObject> describedby;
444 if (src.ariaDescribedby(describedby)) {
445 AddIntListAttributeFromWebObjects(
446 ui::AX_ATTR_DESCRIBEDBY_IDS, describedby, dst);
447 }
448
449 WebVector<WebAXObject> flowTo;
450 if (src.ariaFlowTo(flowTo))
451 AddIntListAttributeFromWebObjects(ui::AX_ATTR_FLOWTO_IDS, flowTo, dst);
452
453 WebVector<WebAXObject> labelledby;
454 if (src.ariaLabelledby(labelledby)) {
455 AddIntListAttributeFromWebObjects(
456 ui::AX_ATTR_LABELLEDBY_IDS, labelledby, dst);
457 }
458
459 WebVector<WebAXObject> owns;
460 if (src.ariaOwns(owns))
461 AddIntListAttributeFromWebObjects(ui::AX_ATTR_OWNS_IDS, owns, dst);
422 } 462 }
423 463
424 bool ShouldIncludeChildNode( 464 bool ShouldIncludeChildNode(
425 const WebAXObject& parent, 465 const WebAXObject& parent,
426 const WebAXObject& child) { 466 const WebAXObject& child) {
427 // The child may be invalid due to issues in webkit accessibility code. 467 // The child may be invalid due to issues in webkit accessibility code.
428 // Don't add children that are invalid thus preventing a crash. 468 // Don't add children that are invalid thus preventing a crash.
429 // https://bugs.webkit.org/show_bug.cgi?id=44149 469 // https://bugs.webkit.org/show_bug.cgi?id=44149
430 // TODO(ctguil): We may want to remove this check as webkit stabilizes. 470 // TODO(ctguil): We may want to remove this check as webkit stabilizes.
431 if (child.isDetached()) 471 if (child.isDetached())
432 return false; 472 return false;
433 473
434 // Skip children whose parent isn't this - see indirect_child_ids, above. 474 // Skip children whose parent isn't this - see indirect_child_ids, above.
435 // As an exception, include children of an iframe element. 475 // As an exception, include children of an iframe element.
436 bool is_iframe = false; 476 bool is_iframe = false;
437 WebNode node = parent.node(); 477 WebNode node = parent.node();
438 if (!node.isNull() && node.isElementNode()) { 478 if (!node.isNull() && node.isElementNode()) {
439 WebElement element = node.to<WebElement>(); 479 WebElement element = node.to<WebElement>();
440 is_iframe = (element.tagName() == base::ASCIIToUTF16("IFRAME")); 480 is_iframe = (element.tagName() == base::ASCIIToUTF16("IFRAME"));
441 } 481 }
442 482
443 return (is_iframe || IsParentUnignoredOf(parent, child)); 483 return (is_iframe || IsParentUnignoredOf(parent, child));
444 } 484 }
445 485
446 } // namespace content 486 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698