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

Side by Side Diff: third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp

Issue 2589273002: Add sparse accessibility attribute interface to Blink (Closed)
Patch Set: Address feedback Created 3 years, 11 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012, Google Inc. All rights reserved. 2 * Copyright (C) 2012, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 14 matching lines...) Expand all
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29 #include "modules/accessibility/AXNodeObject.h" 29 #include "modules/accessibility/AXNodeObject.h"
30 30
31 #include "core/InputTypeNames.h" 31 #include "core/InputTypeNames.h"
32 #include "core/dom/DocumentUserGestureToken.h" 32 #include "core/dom/DocumentUserGestureToken.h"
33 #include "core/dom/Element.h" 33 #include "core/dom/Element.h"
34 #include "core/dom/NodeTraversal.h" 34 #include "core/dom/NodeTraversal.h"
35 #include "core/dom/QualifiedName.h"
35 #include "core/dom/Text.h" 36 #include "core/dom/Text.h"
36 #include "core/dom/shadow/FlatTreeTraversal.h" 37 #include "core/dom/shadow/FlatTreeTraversal.h"
37 #include "core/editing/EditingUtilities.h" 38 #include "core/editing/EditingUtilities.h"
38 #include "core/editing/markers/DocumentMarkerController.h" 39 #include "core/editing/markers/DocumentMarkerController.h"
39 #include "core/frame/FrameView.h" 40 #include "core/frame/FrameView.h"
40 #include "core/html/HTMLDListElement.h" 41 #include "core/html/HTMLDListElement.h"
41 #include "core/html/HTMLFieldSetElement.h" 42 #include "core/html/HTMLFieldSetElement.h"
42 #include "core/html/HTMLFrameElementBase.h" 43 #include "core/html/HTMLFrameElementBase.h"
43 #include "core/html/HTMLImageElement.h" 44 #include "core/html/HTMLImageElement.h"
44 #include "core/html/HTMLInputElement.h" 45 #include "core/html/HTMLInputElement.h"
(...skipping 18 matching lines...) Expand all
63 #include "core/svg/SVGElement.h" 64 #include "core/svg/SVGElement.h"
64 #include "modules/accessibility/AXObjectCacheImpl.h" 65 #include "modules/accessibility/AXObjectCacheImpl.h"
65 #include "platform/UserGestureIndicator.h" 66 #include "platform/UserGestureIndicator.h"
66 #include "platform/text/PlatformLocale.h" 67 #include "platform/text/PlatformLocale.h"
67 #include "wtf/text/StringBuilder.h" 68 #include "wtf/text/StringBuilder.h"
68 69
69 namespace blink { 70 namespace blink {
70 71
71 using namespace HTMLNames; 72 using namespace HTMLNames;
72 73
74 class SparseAttributeSetter {
75 USING_FAST_MALLOC(SparseAttributeSetter);
76
77 public:
78 virtual void run(const AXObject&,
79 AXSparseAttributeClient&,
80 const AtomicString& value) = 0;
81 };
82
83 class BoolAttributeSetter : public SparseAttributeSetter {
84 public:
85 BoolAttributeSetter(AXBoolAttribute attribute) : m_attribute(attribute) {}
86
87 private:
88 AXBoolAttribute m_attribute;
89
90 void run(const AXObject& obj,
91 AXSparseAttributeClient& attributeMap,
92 const AtomicString& value) override {
93 attributeMap.addBoolAttribute(m_attribute,
94 equalIgnoringCase(value, "true"));
95 }
96 };
97
98 class StringAttributeSetter : public SparseAttributeSetter {
99 public:
100 StringAttributeSetter(AXStringAttribute attribute) : m_attribute(attribute) {}
101
102 private:
103 AXStringAttribute m_attribute;
104
105 void run(const AXObject& obj,
106 AXSparseAttributeClient& attributeMap,
107 const AtomicString& value) override {
108 attributeMap.addStringAttribute(m_attribute, value);
109 }
110 };
111
112 class ObjectAttributeSetter : public SparseAttributeSetter {
113 public:
114 ObjectAttributeSetter(AXObjectAttribute attribute) : m_attribute(attribute) {}
115
116 private:
117 AXObjectAttribute m_attribute;
118
119 void run(const AXObject& obj,
120 AXSparseAttributeClient& attributeMap,
121 const AtomicString& value) override {
122 if (value.isNull() || value.isEmpty())
123 return;
124
125 Node* node = obj.getNode();
126 if (!node || !node->isElementNode())
127 return;
128 Element* target = toElement(node)->treeScope().getElementById(value);
129 if (!target)
130 return;
131 AXObject* axTarget = obj.axObjectCache().getOrCreate(target);
132 if (axTarget)
133 attributeMap.addObjectAttribute(m_attribute, *axTarget);
134 }
135 };
136
137 class ObjectVectorAttributeSetter : public SparseAttributeSetter {
138 public:
139 ObjectVectorAttributeSetter(AXObjectVectorAttribute attribute)
140 : m_attribute(attribute) {}
141
142 private:
143 AXObjectVectorAttribute m_attribute;
144
145 void run(const AXObject& obj,
146 AXSparseAttributeClient& attributeMap,
147 const AtomicString& value) override {
148 Node* node = obj.getNode();
149 if (!node || !node->isElementNode())
150 return;
151
152 String attributeValue = value.getString();
153 if (attributeValue.isEmpty())
154 return;
155
156 attributeValue.simplifyWhiteSpace();
157 Vector<String> ids;
158 attributeValue.split(' ', ids);
159 if (ids.isEmpty())
160 return;
161
162 HeapVector<Member<AXObject>> objects;
163 TreeScope& scope = node->treeScope();
164 for (const auto& id : ids) {
165 if (Element* idElement = scope.getElementById(AtomicString(id))) {
166 AXObject* axIdElement = obj.axObjectCache().getOrCreate(idElement);
167 if (axIdElement && !axIdElement->accessibilityIsIgnored())
168 objects.append(axIdElement);
169 }
170 }
171
172 attributeMap.addObjectVectorAttribute(m_attribute, objects);
173 }
174 };
175
176 using AXSparseAttributeSetterMap =
177 HashMap<QualifiedName, SparseAttributeSetter*>;
178
179 static AXSparseAttributeSetterMap& getSparseAttributeSetterMap() {
180 // Use a map from attribute name to properties of that attribute.
181 // That way we only need to iterate over the list of attributes once,
182 // rather than calling getAttribute() once for each possible obscure
183 // accessibility attribute.
184 DEFINE_STATIC_LOCAL(AXSparseAttributeSetterMap, axSparseAttributeSetterMap,
185 ());
186 if (axSparseAttributeSetterMap.isEmpty()) {
187 axSparseAttributeSetterMap.set(
188 aria_activedescendantAttr,
189 new ObjectAttributeSetter(AXObjectAttribute::AriaActiveDescendant));
190 axSparseAttributeSetterMap.set(
191 aria_controlsAttr,
192 new ObjectVectorAttributeSetter(AXObjectVectorAttribute::AriaControls));
193 axSparseAttributeSetterMap.set(
194 aria_flowtoAttr,
195 new ObjectVectorAttributeSetter(AXObjectVectorAttribute::AriaFlowTo));
196 }
197 return axSparseAttributeSetterMap;
198 }
199
73 AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& axObjectCache) 200 AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& axObjectCache)
74 : AXObject(axObjectCache), 201 : AXObject(axObjectCache),
75 m_ariaRole(UnknownRole), 202 m_ariaRole(UnknownRole),
76 m_childrenDirty(false), 203 m_childrenDirty(false),
77 #if ENABLE(ASSERT) 204 #if ENABLE(ASSERT)
78 m_initialized(false), 205 m_initialized(false),
79 #endif 206 #endif
80 m_node(node) { 207 m_node(node) {
81 } 208 }
82 209
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 m_initialized = true; 873 m_initialized = true;
747 #endif 874 #endif
748 m_role = determineAccessibilityRole(); 875 m_role = determineAccessibilityRole();
749 } 876 }
750 877
751 void AXNodeObject::detach() { 878 void AXNodeObject::detach() {
752 AXObject::detach(); 879 AXObject::detach();
753 m_node = nullptr; 880 m_node = nullptr;
754 } 881 }
755 882
883 void AXNodeObject::getSparseAXAttributes(
884 AXSparseAttributeClient& sparseAttributeClient) const {
885 Node* node = this->getNode();
886 if (!node || !node->isElementNode())
887 return;
888
889 AXSparseAttributeSetterMap& axSparseAttributeSetterMap =
890 getSparseAttributeSetterMap();
891 AttributeCollection attributes = toElement(node)->attributesWithoutUpdate();
892 for (const Attribute& attr : attributes) {
893 SparseAttributeSetter* setter = axSparseAttributeSetterMap.get(attr.name());
894 if (setter)
895 setter->run(*this, sparseAttributeClient, attr.value());
896 }
897 }
898
756 bool AXNodeObject::isAnchor() const { 899 bool AXNodeObject::isAnchor() const {
757 return !isNativeImage() && isLink(); 900 return !isNativeImage() && isLink();
758 } 901 }
759 902
760 bool AXNodeObject::isControl() const { 903 bool AXNodeObject::isControl() const {
761 Node* node = this->getNode(); 904 Node* node = this->getNode();
762 if (!node) 905 if (!node)
763 return false; 906 return false;
764 907
765 return ((node->isElementNode() && toElement(node)->isFormControlElement()) || 908 return ((node->isElementNode() && toElement(node)->isFormControlElement()) ||
(...skipping 2129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2895 return String(); 3038 return String();
2896 return toTextControlElement(node)->strippedPlaceholder(); 3039 return toTextControlElement(node)->strippedPlaceholder();
2897 } 3040 }
2898 3041
2899 DEFINE_TRACE(AXNodeObject) { 3042 DEFINE_TRACE(AXNodeObject) {
2900 visitor->trace(m_node); 3043 visitor->trace(m_node);
2901 AXObject::trace(visitor); 3044 AXObject::trace(visitor);
2902 } 3045 }
2903 3046
2904 } // namespace blink 3047 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698