Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/blink_ax_tree_source.h" | 5 #include "content/renderer/accessibility/blink_ax_tree_source.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 using blink::WebNode; | 48 using blink::WebNode; |
| 49 using blink::WebPlugin; | 49 using blink::WebPlugin; |
| 50 using blink::WebPluginContainer; | 50 using blink::WebPluginContainer; |
| 51 using blink::WebVector; | 51 using blink::WebVector; |
| 52 using blink::WebView; | 52 using blink::WebView; |
| 53 | 53 |
| 54 namespace content { | 54 namespace content { |
| 55 | 55 |
| 56 namespace { | 56 namespace { |
| 57 | 57 |
| 58 void AddIntListAttributeFromWebObjects(ui::AXIntListAttribute attr, | |
| 59 WebVector<WebAXObject> objects, | |
| 60 AXContentNodeData* dst) { | |
| 61 std::vector<int32_t> ids; | |
| 62 for (size_t i = 0; i < objects.size(); i++) | |
| 63 ids.push_back(objects[i].axID()); | |
| 64 if (!ids.empty()) | |
| 65 dst->AddIntListAttribute(attr, ids); | |
| 66 } | |
| 67 | |
| 68 class SparseAttributeMap : public blink::WebAXSparseAttributeMap { | |
|
aboxhall
2017/01/10 05:59:59
The name "SparseAttributeMap" is confusing me a bi
dmazzoni
2017/01/12 03:36:24
Done.
| |
| 69 public: | |
| 70 SparseAttributeMap(AXContentNodeData* dst) : dst_(dst) {} | |
| 71 ~SparseAttributeMap() override {} | |
| 72 | |
| 73 private: | |
| 74 AXContentNodeData* dst_; | |
| 75 | |
| 76 void addBoolAttribute(blink::WebAXBoolAttribute attribute, | |
| 77 bool value) override { | |
| 78 switch (attribute) { | |
| 79 case blink::WebAXBoolAttribute::AriaModal: | |
| 80 // TODO(dmazzoni): implement aria-modal. http://crbug.com/644766 | |
| 81 break; | |
| 82 default: | |
| 83 NOTREACHED(); | |
| 84 } | |
| 85 } | |
| 86 | |
| 87 void addStringAttribute(blink::WebAXStringAttribute attribute, | |
| 88 const blink::WebString& value) override { | |
| 89 switch (attribute) { | |
| 90 case blink::WebAXStringAttribute::AriaKeyShortcuts: | |
| 91 // TODO(dmazzoni): implement aria-keyshortcuts. http://crbug.com/644766 | |
| 92 break; | |
| 93 case blink::WebAXStringAttribute::AriaRoleDescription: | |
| 94 // TODO(dmazzoni): implement aria-roledescription. | |
| 95 // http://crbug.com/644766 | |
| 96 break; | |
| 97 default: | |
| 98 NOTREACHED(); | |
| 99 } | |
| 100 } | |
| 101 | |
| 102 void addObjectAttribute(blink::WebAXObjectAttribute attribute, | |
| 103 const blink::WebAXObject& value) override { | |
| 104 switch (attribute) { | |
| 105 case blink::WebAXObjectAttribute::AriaActiveDescendant: | |
| 106 dst_->AddIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, value.axID()); | |
| 107 break; | |
| 108 case blink::WebAXObjectAttribute::AriaErrorMessage: | |
| 109 // TODO | |
|
aboxhall
2017/01/10 05:59:59
Any chance we could add these values in the follow
dmazzoni
2017/01/12 03:36:24
Sure. I'll pull the new attributes into a middle c
| |
| 110 break; | |
| 111 default: | |
| 112 NOTREACHED(); | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 void addObjectVectorAttribute( | |
| 117 blink::WebAXObjectVectorAttribute attribute, | |
| 118 const blink::WebVector<WebAXObject>& value) override { | |
| 119 switch (attribute) { | |
| 120 case blink::WebAXObjectVectorAttribute::AriaControls: | |
| 121 AddIntListAttributeFromWebObjects(ui::AX_ATTR_CONTROLS_IDS, value, | |
| 122 dst_); | |
| 123 break; | |
| 124 case blink::WebAXObjectVectorAttribute::AriaDetails: | |
| 125 // TODO | |
| 126 break; | |
| 127 case blink::WebAXObjectVectorAttribute::AriaFlowTo: | |
| 128 AddIntListAttributeFromWebObjects(ui::AX_ATTR_FLOWTO_IDS, value, dst_); | |
| 129 break; | |
| 130 default: | |
| 131 NOTREACHED(); | |
| 132 } | |
| 133 } | |
| 134 }; | |
| 135 | |
| 58 WebAXObject ParentObjectUnignored(WebAXObject child) { | 136 WebAXObject ParentObjectUnignored(WebAXObject child) { |
| 59 WebAXObject parent = child.parentObject(); | 137 WebAXObject parent = child.parentObject(); |
| 60 while (!parent.isDetached() && parent.accessibilityIsIgnored()) | 138 while (!parent.isDetached() && parent.accessibilityIsIgnored()) |
| 61 parent = parent.parentObject(); | 139 parent = parent.parentObject(); |
| 62 return parent; | 140 return parent; |
| 63 } | 141 } |
| 64 | 142 |
| 65 // Returns true if |ancestor| is the first unignored parent of |child|, | 143 // Returns true if |ancestor| is the first unignored parent of |child|, |
| 66 // which means that when walking up the parent chain from |child|, | 144 // which means that when walking up the parent chain from |child|, |
| 67 // |ancestor| is the *first* ancestor that isn't marked as | 145 // |ancestor| is the *first* ancestor that isn't marked as |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 102 return "slider"; | 180 return "slider"; |
| 103 case ui::AX_ROLE_TIME: | 181 case ui::AX_ROLE_TIME: |
| 104 return "time"; | 182 return "time"; |
| 105 default: | 183 default: |
| 106 break; | 184 break; |
| 107 } | 185 } |
| 108 | 186 |
| 109 return std::string(); | 187 return std::string(); |
| 110 } | 188 } |
| 111 | 189 |
| 112 void AddIntListAttributeFromWebObjects(ui::AXIntListAttribute attr, | |
| 113 WebVector<WebAXObject> objects, | |
| 114 AXContentNodeData* dst) { | |
| 115 std::vector<int32_t> ids; | |
| 116 for(size_t i = 0; i < objects.size(); i++) | |
| 117 ids.push_back(objects[i].axID()); | |
| 118 if (ids.size() > 0) | |
| 119 dst->AddIntListAttribute(attr, ids); | |
| 120 } | |
| 121 | |
| 122 } // namespace | 190 } // namespace |
| 123 | 191 |
| 124 ScopedFreezeBlinkAXTreeSource::ScopedFreezeBlinkAXTreeSource( | 192 ScopedFreezeBlinkAXTreeSource::ScopedFreezeBlinkAXTreeSource( |
| 125 BlinkAXTreeSource* tree_source) | 193 BlinkAXTreeSource* tree_source) |
| 126 : tree_source_(tree_source) { | 194 : tree_source_(tree_source) { |
| 127 tree_source_->Freeze(); | 195 tree_source_->Freeze(); |
| 128 } | 196 } |
| 129 | 197 |
| 130 ScopedFreezeBlinkAXTreeSource::~ScopedFreezeBlinkAXTreeSource() { | 198 ScopedFreezeBlinkAXTreeSource::~ScopedFreezeBlinkAXTreeSource() { |
| 131 tree_source_->Thaw(); | 199 tree_source_->Thaw(); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 WebFloatRect bounds_in_container; | 385 WebFloatRect bounds_in_container; |
| 318 SkMatrix44 container_transform; | 386 SkMatrix44 container_transform; |
| 319 src.getRelativeBounds( | 387 src.getRelativeBounds( |
| 320 offset_container, bounds_in_container, container_transform); | 388 offset_container, bounds_in_container, container_transform); |
| 321 dst->location = bounds_in_container; | 389 dst->location = bounds_in_container; |
| 322 if (!container_transform.isIdentity()) | 390 if (!container_transform.isIdentity()) |
| 323 dst->transform = base::WrapUnique(new gfx::Transform(container_transform)); | 391 dst->transform = base::WrapUnique(new gfx::Transform(container_transform)); |
| 324 if (!offset_container.isDetached()) | 392 if (!offset_container.isDetached()) |
| 325 dst->offset_container_id = offset_container.axID(); | 393 dst->offset_container_id = offset_container.axID(); |
| 326 | 394 |
| 395 SparseAttributeMap sparse_map(dst); | |
| 396 src.getSparseAXAttributes(sparse_map); | |
| 397 | |
| 327 blink::WebAXNameFrom nameFrom; | 398 blink::WebAXNameFrom nameFrom; |
| 328 blink::WebVector<blink::WebAXObject> nameObjects; | 399 blink::WebVector<blink::WebAXObject> nameObjects; |
| 329 blink::WebString web_name = src.name(nameFrom, nameObjects); | 400 blink::WebString web_name = src.name(nameFrom, nameObjects); |
| 330 if (!web_name.isEmpty()) { | 401 if (!web_name.isEmpty()) { |
| 331 dst->AddStringAttribute(ui::AX_ATTR_NAME, web_name.utf8()); | 402 dst->AddStringAttribute(ui::AX_ATTR_NAME, web_name.utf8()); |
| 332 dst->AddIntAttribute(ui::AX_ATTR_NAME_FROM, AXNameFromFromBlink(nameFrom)); | 403 dst->AddIntAttribute(ui::AX_ATTR_NAME_FROM, AXNameFromFromBlink(nameFrom)); |
| 333 AddIntListAttributeFromWebObjects( | 404 AddIntListAttributeFromWebObjects( |
| 334 ui::AX_ATTR_LABELLEDBY_IDS, nameObjects, dst); | 405 ui::AX_ATTR_LABELLEDBY_IDS, nameObjects, dst); |
| 335 } | 406 } |
| 336 | 407 |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 748 WebAXObject child = src.childAt(i); | 819 WebAXObject child = src.childAt(i); |
| 749 std::vector<int32_t> indirect_child_ids; | 820 std::vector<int32_t> indirect_child_ids; |
| 750 if (!is_iframe && !child.isDetached() && !IsParentUnignoredOf(src, child)) | 821 if (!is_iframe && !child.isDetached() && !IsParentUnignoredOf(src, child)) |
| 751 indirect_child_ids.push_back(child.axID()); | 822 indirect_child_ids.push_back(child.axID()); |
| 752 if (indirect_child_ids.size() > 0) { | 823 if (indirect_child_ids.size() > 0) { |
| 753 dst->AddIntListAttribute( | 824 dst->AddIntListAttribute( |
| 754 ui::AX_ATTR_INDIRECT_CHILD_IDS, indirect_child_ids); | 825 ui::AX_ATTR_INDIRECT_CHILD_IDS, indirect_child_ids); |
| 755 } | 826 } |
| 756 } | 827 } |
| 757 | 828 |
| 758 WebVector<WebAXObject> controls; | |
| 759 if (src.ariaControls(controls)) | |
| 760 AddIntListAttributeFromWebObjects(ui::AX_ATTR_CONTROLS_IDS, controls, dst); | |
| 761 | |
| 762 WebVector<WebAXObject> flowTo; | |
| 763 if (src.ariaFlowTo(flowTo)) | |
| 764 AddIntListAttributeFromWebObjects(ui::AX_ATTR_FLOWTO_IDS, flowTo, dst); | |
| 765 | |
| 766 if (src.isScrollableContainer()) { | 829 if (src.isScrollableContainer()) { |
| 767 const gfx::Point& scrollOffset = src.getScrollOffset(); | 830 const gfx::Point& scrollOffset = src.getScrollOffset(); |
| 768 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X, scrollOffset.x()); | 831 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X, scrollOffset.x()); |
| 769 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y, scrollOffset.y()); | 832 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y, scrollOffset.y()); |
| 770 | 833 |
| 771 const gfx::Point& minScrollOffset = src.minimumScrollOffset(); | 834 const gfx::Point& minScrollOffset = src.minimumScrollOffset(); |
| 772 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MIN, minScrollOffset.x()); | 835 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_X_MIN, minScrollOffset.x()); |
| 773 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MIN, minScrollOffset.y()); | 836 dst->AddIntAttribute(ui::AX_ATTR_SCROLL_Y_MIN, minScrollOffset.y()); |
| 774 | 837 |
| 775 const gfx::Point& maxScrollOffset = src.maximumScrollOffset(); | 838 const gfx::Point& maxScrollOffset = src.maximumScrollOffset(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 796 return WebAXObject(); | 859 return WebAXObject(); |
| 797 | 860 |
| 798 WebDocument document = render_frame_->GetWebFrame()->document(); | 861 WebDocument document = render_frame_->GetWebFrame()->document(); |
| 799 if (!document.isNull()) | 862 if (!document.isNull()) |
| 800 return document.accessibilityObject(); | 863 return document.accessibilityObject(); |
| 801 | 864 |
| 802 return WebAXObject(); | 865 return WebAXObject(); |
| 803 } | 866 } |
| 804 | 867 |
| 805 } // namespace content | 868 } // namespace content |
| OLD | NEW |