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

Side by Side Diff: Source/modules/accessibility/AXObject.cpp

Issue 885163002: [Contextual Search] Check for ARIA widget roles. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Cleaup usage of Web wrappers. Created 5 years, 10 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) 2008, 2009, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2008, 2009, 2011 Apple 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 22 matching lines...) Expand all
33 #include "core/editing/VisibleUnits.h" 33 #include "core/editing/VisibleUnits.h"
34 #include "core/editing/htmlediting.h" 34 #include "core/editing/htmlediting.h"
35 #include "core/frame/LocalFrame.h" 35 #include "core/frame/LocalFrame.h"
36 #include "core/frame/Settings.h" 36 #include "core/frame/Settings.h"
37 #include "core/layout/LayoutTheme.h" 37 #include "core/layout/LayoutTheme.h"
38 #include "core/rendering/RenderListItem.h" 38 #include "core/rendering/RenderListItem.h"
39 #include "core/rendering/RenderView.h" 39 #include "core/rendering/RenderView.h"
40 #include "modules/accessibility/AXObjectCacheImpl.h" 40 #include "modules/accessibility/AXObjectCacheImpl.h"
41 #include "platform/UserGestureIndicator.h" 41 #include "platform/UserGestureIndicator.h"
42 #include "platform/text/PlatformLocale.h" 42 #include "platform/text/PlatformLocale.h"
43 #include "wtf/HashSet.h"
43 #include "wtf/StdLibExtras.h" 44 #include "wtf/StdLibExtras.h"
44 #include "wtf/text/WTFString.h" 45 #include "wtf/text/WTFString.h"
45 46
46 using blink::WebLocalizedString; 47 using blink::WebLocalizedString;
47 48
48 namespace blink { 49 namespace blink {
49 50
50 using namespace HTMLNames; 51 using namespace HTMLNames;
51 52
52 namespace { 53 namespace {
53 typedef HashMap<String, AccessibilityRole, CaseFoldingHash> ARIARoleMap; 54 typedef HashMap<String, AccessibilityRole, CaseFoldingHash> ARIARoleMap;
55 typedef HashSet<String, CaseFoldingHash> ARIAWidgetSet;
54 56
55 struct RoleEntry { 57 struct RoleEntry {
56 const char* ariaRole; 58 const char* ariaRole;
57 AccessibilityRole webcoreRole; 59 AccessibilityRole webcoreRole;
58 }; 60 };
59 61
60 const RoleEntry roles[] = { 62 const RoleEntry roles[] = {
61 { "alert", AlertRole }, 63 { "alert", AlertRole },
62 { "alertdialog", AlertDialogRole }, 64 { "alertdialog", AlertDialogRole },
63 { "application", ApplicationRole }, 65 { "application", ApplicationRole },
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 152
151 for (size_t i = 0; i < WTF_ARRAY_LENGTH(roles); ++i) 153 for (size_t i = 0; i < WTF_ARRAY_LENGTH(roles); ++i)
152 (*roleNameVector)[roles[i].webcoreRole] = AtomicString(roles[i].ariaRole ); 154 (*roleNameVector)[roles[i].webcoreRole] = AtomicString(roles[i].ariaRole );
153 155
154 for (size_t i = 0; i < WTF_ARRAY_LENGTH(reverseRoles); ++i) 156 for (size_t i = 0; i < WTF_ARRAY_LENGTH(reverseRoles); ++i)
155 (*roleNameVector)[reverseRoles[i].webcoreRole] = AtomicString(reverseRol es[i].ariaRole); 157 (*roleNameVector)[reverseRoles[i].webcoreRole] = AtomicString(reverseRol es[i].ariaRole);
156 158
157 return roleNameVector; 159 return roleNameVector;
158 } 160 }
159 161
162 const char* ariaWidgets[] = {
163 // From http://www.w3.org/TR/wai-aria/roles#widget_roles
164 "alert",
165 "alertdialog",
166 "button",
167 "checkbox",
168 "dialog",
169 "gridcell",
170 "link",
171 "log",
172 "marquee",
173 "menuitem",
174 "menuitemcheckbox",
175 "menuitemradio",
176 "option",
177 "progressbar",
178 "radio",
179 "scrollbar",
180 "slider",
181 "spinbutton",
182 "status",
183 "tab",
184 "tabpanel",
185 "textbox",
186 "timer",
187 "tooltip",
188 "treeitem",
189 // Composite user interface widgets. This list is also from w3.org site ref rerenced above.
190 "combobox",
191 "grid",
192 "listbox",
193 "menu",
194 "menubar",
195 "radiogroup",
196 "tablist",
197 "tree",
198 "treegrid"
199 };
200
201 static ARIAWidgetSet* createARIARoleWidgetSet()
202 {
203 ARIAWidgetSet* widgetSet = new HashSet<String, CaseFoldingHash>();
204 for (size_t i = 0; i < WTF_ARRAY_LENGTH(ariaWidgets); ++i)
205 widgetSet->add(String(ariaWidgets[i]));
206 return widgetSet;
207 }
208
209 const char* ariaInteractiveWidgetAttributes[] = {
210 // These attributes implicitly indicate the given widget is interactive.
211 // From http://www.w3.org/TR/wai-aria/states_and_properties#attrs_widgets
212 "aria-activedescendant",
213 "aria-checked",
214 "aria-controls",
215 "aria-disabled", // If it's disabled, it can be made interactive.
216 "aria-expanded",
217 "aria-haspopup", // Interactive only if this attribute has a value of "true" .
218 "aria-multiselectable",
219 "aria-pressed",
220 "aria-required",
221 "aria-selected"
222 };
223
160 } // namespace 224 } // namespace
161 225
162 AXObject::AXObject(AXObjectCacheImpl* axObjectCache) 226 AXObject::AXObject(AXObjectCacheImpl* axObjectCache)
163 : m_id(0) 227 : m_id(0)
164 , m_haveChildren(false) 228 , m_haveChildren(false)
165 , m_role(UnknownRole) 229 , m_role(UnknownRole)
166 , m_lastKnownIsIgnoredValue(DefaultBehavior) 230 , m_lastKnownIsIgnoredValue(DefaultBehavior)
167 , m_detached(false) 231 , m_detached(false)
168 , m_parent(0) 232 , m_parent(0)
169 , m_lastModificationCount(-1) 233 , m_lastModificationCount(-1)
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 for (unsigned i = 0; i < size; ++i) { 1026 for (unsigned i = 0; i < size; ++i) {
963 String roleName = roleVector[i]; 1027 String roleName = roleVector[i];
964 role = roleMap->get(roleName); 1028 role = roleMap->get(roleName);
965 if (role) 1029 if (role)
966 return role; 1030 return role;
967 } 1031 }
968 1032
969 return role; 1033 return role;
970 } 1034 }
971 1035
1036 bool AXObject::isInsideFocusableElementOrARIAWidget(const Node& node)
1037 {
1038 const Node* curNode = &node;
1039 do {
1040 if (curNode->isElementNode()) {
1041 const Element* element = toElement(curNode);
1042 if (element->isFocusable())
1043 return true;
1044 String role = element->getAttribute("role");
1045 if (!role.isEmpty() && AXObject::includesARIAWidgetRole(role))
1046 return true;
1047 if (hasInteractiveARIAAttribute(*element))
1048 return true;
1049 }
1050 curNode = curNode->parentNode();
1051 } while (curNode && !isHTMLBodyElement(node));
1052 return false;
1053 }
1054
1055 bool AXObject::hasInteractiveARIAAttribute(const Element& element)
1056 {
1057 for (size_t i = 0; i < WTF_ARRAY_LENGTH(ariaInteractiveWidgetAttributes); ++ i) {
1058 const char* attribute = ariaInteractiveWidgetAttributes[i];
1059 if (element.hasAttribute(attribute)) {
1060 if (!strcmp("aria-haspopup", attribute))
dmazzoni 2015/02/10 07:40:54 Why are you special-casing aria-haspopup? Since yo
Donn Denman 2015/02/24 23:37:52 Makes sense -- done. It looked to me like this wa
1061 return element.getAttribute(attribute) == "true";
1062 return true;
1063 }
1064 }
1065 return false;
1066 }
1067
1068 bool AXObject::includesARIAWidgetRole(const String& role)
1069 {
1070 static const HashSet<String, CaseFoldingHash>* roleSet = createARIARoleWidge tSet();
1071
1072 Vector<String> roleVector;
1073 role.split(' ', roleVector);
1074 unsigned size = roleVector.size();
1075 for (unsigned i = 0; i < size; ++i) {
1076 String roleName = roleVector[i];
1077 if (roleSet->contains(roleName))
1078 return true;
1079 }
1080 return false;
1081 }
1082
972 AccessibilityRole AXObject::buttonRoleType() const 1083 AccessibilityRole AXObject::buttonRoleType() const
973 { 1084 {
974 // If aria-pressed is present, then it should be exposed as a toggle button. 1085 // If aria-pressed is present, then it should be exposed as a toggle button.
975 // http://www.w3.org/TR/wai-aria/states_and_properties#aria-pressed 1086 // http://www.w3.org/TR/wai-aria/states_and_properties#aria-pressed
976 if (ariaPressedIsPresent()) 1087 if (ariaPressedIsPresent())
977 return ToggleButtonRole; 1088 return ToggleButtonRole;
978 if (ariaHasPopup()) 1089 if (ariaHasPopup())
979 return PopUpButtonRole; 1090 return PopUpButtonRole;
980 // We don't contemplate RadioButtonRole, as it depends on the input 1091 // We don't contemplate RadioButtonRole, as it depends on the input
981 // type. 1092 // type.
982 1093
983 return ButtonRole; 1094 return ButtonRole;
984 } 1095 }
985 1096
986 const AtomicString& AXObject::roleName(AccessibilityRole role) 1097 const AtomicString& AXObject::roleName(AccessibilityRole role)
987 { 1098 {
988 static const Vector<AtomicString>* roleNameVector = createRoleNameVector(); 1099 static const Vector<AtomicString>* roleNameVector = createRoleNameVector();
989 1100
990 return roleNameVector->at(role); 1101 return roleNameVector->at(role);
991 } 1102 }
992 1103
993 } // namespace blink 1104 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698