OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |