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

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

Issue 2589273002: Add sparse accessibility attribute interface to Blink (Closed)
Patch Set: Renamed 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 {
haraken 2017/01/18 23:40:00 Add USING_FAST_MALLOC().
dmazzoni 2017/01/21 00:16:35 Done.
75 public:
76 virtual void Run(const AXObject*,
77 AXSparseAttributeClient&,
78 const AtomicString& value) = 0;
79 };
80
81 class BoolAttributeSetter : public SparseAttributeSetter {
82 public:
83 BoolAttributeSetter(AXBoolAttribute attribute) : m_attribute(attribute) {}
84
85 private:
86 AXBoolAttribute m_attribute;
87
88 void Run(const AXObject* obj,
89 AXSparseAttributeClient& attributeMap,
90 const AtomicString& value) override {
91 attributeMap.addBoolAttribute(m_attribute,
92 equalIgnoringCase(value, "true"));
93 }
94 };
95
96 class StringAttributeSetter : public SparseAttributeSetter {
97 public:
98 StringAttributeSetter(AXStringAttribute attribute) : m_attribute(attribute) {}
99
100 private:
101 AXStringAttribute m_attribute;
102
103 void Run(const AXObject* obj,
104 AXSparseAttributeClient& attributeMap,
105 const AtomicString& value) override {
106 attributeMap.addStringAttribute(m_attribute, value);
107 }
108 };
109
110 class ObjectAttributeSetter : public SparseAttributeSetter {
111 public:
112 ObjectAttributeSetter(AXObjectAttribute attribute) : m_attribute(attribute) {}
113
114 private:
115 AXObjectAttribute m_attribute;
116
117 void Run(const AXObject* obj,
118 AXSparseAttributeClient& attributeMap,
119 const AtomicString& value) override {
120 if (value.isNull() || value.isEmpty())
121 return;
122
123 Node* node = obj->getNode();
124 if (!node || !node->isElementNode())
125 return;
126 Element* target = toElement(node)->treeScope().getElementById(value);
127 if (!target)
128 return;
129 AXObject* axTarget = obj->axObjectCache().getOrCreate(target);
130 if (axTarget)
131 attributeMap.addObjectAttribute(m_attribute, axTarget);
132 }
133 };
134
135 class ObjectVectorAttributeSetter : public SparseAttributeSetter {
136 public:
137 ObjectVectorAttributeSetter(AXObjectVectorAttribute attribute)
138 : m_attribute(attribute) {}
139
140 private:
141 AXObjectVectorAttribute m_attribute;
142
143 void Run(const AXObject* obj,
144 AXSparseAttributeClient& attributeMap,
145 const AtomicString& value) override {
146 Node* node = obj->getNode();
147 if (!node || !node->isElementNode())
148 return;
149
150 String attributeValue = value.getString();
151 if (attributeValue.isEmpty())
152 return;
153
154 attributeValue.simplifyWhiteSpace();
155 Vector<String> ids;
156 attributeValue.split(' ', ids);
157 if (ids.isEmpty())
158 return;
159
160 HeapVector<Member<AXObject>> objects;
161 TreeScope& scope = node->treeScope();
162 for (const auto& id : ids) {
163 if (Element* idElement = scope.getElementById(AtomicString(id))) {
164 AXObject* axIdElement = obj->axObjectCache().getOrCreate(idElement);
165 if (axIdElement && !axIdElement->accessibilityIsIgnored())
166 objects.append(axIdElement);
167 }
168 }
169
170 attributeMap.addObjectVectorAttribute(m_attribute, objects);
171 }
172 };
173
174 typedef HashMap<QualifiedName, SparseAttributeSetter*>
175 AXSparseAttributeSetterMap;
dcheng 2017/01/19 23:02:44 Nit: prefer using AXSpareAttributeSetterMap = Hash
dmazzoni 2017/01/21 00:16:35 Done.
176
177 static AXSparseAttributeSetterMap& GetSparseAttributeSetterMap() {
178 // Use a map from attribute name to properties of that attribute.
179 // That way we only need to iterate over the list of attributes once,
180 // rather than calling getAttribute() once for each possible obscure
181 // accessibility attribute.
182 DEFINE_STATIC_LOCAL(AXSparseAttributeSetterMap, axSparseAttributeSetterMap,
183 ());
184 if (axSparseAttributeSetterMap.isEmpty()) {
185 axSparseAttributeSetterMap.set(
186 aria_activedescendantAttr,
187 new ObjectAttributeSetter(AXObjectAttribute::AriaActiveDescendant));
188 axSparseAttributeSetterMap.set(
189 aria_controlsAttr,
190 new ObjectVectorAttributeSetter(AXObjectVectorAttribute::AriaControls));
191 axSparseAttributeSetterMap.set(
192 aria_flowtoAttr,
193 new ObjectVectorAttributeSetter(AXObjectVectorAttribute::AriaFlowTo));
194 }
195 return axSparseAttributeSetterMap;
196 }
197
73 AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& axObjectCache) 198 AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& axObjectCache)
74 : AXObject(axObjectCache), 199 : AXObject(axObjectCache),
75 m_ariaRole(UnknownRole), 200 m_ariaRole(UnknownRole),
76 m_childrenDirty(false), 201 m_childrenDirty(false),
77 #if ENABLE(ASSERT) 202 #if ENABLE(ASSERT)
78 m_initialized(false), 203 m_initialized(false),
79 #endif 204 #endif
80 m_node(node) { 205 m_node(node) {
81 } 206 }
82 207
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 m_initialized = true; 871 m_initialized = true;
747 #endif 872 #endif
748 m_role = determineAccessibilityRole(); 873 m_role = determineAccessibilityRole();
749 } 874 }
750 875
751 void AXNodeObject::detach() { 876 void AXNodeObject::detach() {
752 AXObject::detach(); 877 AXObject::detach();
753 m_node = nullptr; 878 m_node = nullptr;
754 } 879 }
755 880
881 void AXNodeObject::getSparseAXAttributes(
882 AXSparseAttributeClient& sparseAttributeClient) const {
883 Node* node = this->getNode();
884 if (!node || !node->isElementNode())
885 return;
886
887 AXSparseAttributeSetterMap& axSparseAttributeSetterMap =
888 GetSparseAttributeSetterMap();
889 AttributeCollection attributes = toElement(node)->attributesWithoutUpdate();
890 for (const Attribute& attr : attributes) {
891 SparseAttributeSetter* setter = axSparseAttributeSetterMap.get(attr.name());
892 if (setter)
893 setter->Run(this, sparseAttributeClient, attr.value());
894 }
895 }
896
756 bool AXNodeObject::isAnchor() const { 897 bool AXNodeObject::isAnchor() const {
757 return !isNativeImage() && isLink(); 898 return !isNativeImage() && isLink();
758 } 899 }
759 900
760 bool AXNodeObject::isControl() const { 901 bool AXNodeObject::isControl() const {
761 Node* node = this->getNode(); 902 Node* node = this->getNode();
762 if (!node) 903 if (!node)
763 return false; 904 return false;
764 905
765 return ((node->isElementNode() && toElement(node)->isFormControlElement()) || 906 return ((node->isElementNode() && toElement(node)->isFormControlElement()) ||
(...skipping 2129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2895 return String(); 3036 return String();
2896 return toTextControlElement(node)->strippedPlaceholder(); 3037 return toTextControlElement(node)->strippedPlaceholder();
2897 } 3038 }
2898 3039
2899 DEFINE_TRACE(AXNodeObject) { 3040 DEFINE_TRACE(AXNodeObject) {
2900 visitor->trace(m_node); 3041 visitor->trace(m_node);
2901 AXObject::trace(visitor); 3042 AXObject::trace(visitor);
2902 } 3043 }
2903 3044
2904 } // namespace blink 3045 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698