| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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", |
| 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 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 for (unsigned i = 0; i < size; ++i) { | 1050 for (unsigned i = 0; i < size; ++i) { |
| 987 String roleName = roleVector[i]; | 1051 String roleName = roleVector[i]; |
| 988 role = roleMap->get(roleName); | 1052 role = roleMap->get(roleName); |
| 989 if (role) | 1053 if (role) |
| 990 return role; | 1054 return role; |
| 991 } | 1055 } |
| 992 | 1056 |
| 993 return role; | 1057 return role; |
| 994 } | 1058 } |
| 995 | 1059 |
| 1060 bool AXObject::isInsideFocusableElementOrARIAWidget(const Node& node) |
| 1061 { |
| 1062 const Node* curNode = &node; |
| 1063 do { |
| 1064 if (curNode->isElementNode()) { |
| 1065 const Element* element = toElement(curNode); |
| 1066 if (element->isFocusable()) |
| 1067 return true; |
| 1068 String role = element->getAttribute("role"); |
| 1069 if (!role.isEmpty() && AXObject::includesARIAWidgetRole(role)) |
| 1070 return true; |
| 1071 if (hasInteractiveARIAAttribute(*element)) |
| 1072 return true; |
| 1073 } |
| 1074 curNode = curNode->parentNode(); |
| 1075 } while (curNode && !isHTMLBodyElement(node)); |
| 1076 return false; |
| 1077 } |
| 1078 |
| 1079 bool AXObject::hasInteractiveARIAAttribute(const Element& element) |
| 1080 { |
| 1081 for (size_t i = 0; i < WTF_ARRAY_LENGTH(ariaInteractiveWidgetAttributes); ++
i) { |
| 1082 const char* attribute = ariaInteractiveWidgetAttributes[i]; |
| 1083 if (element.hasAttribute(attribute)) { |
| 1084 return true; |
| 1085 } |
| 1086 } |
| 1087 return false; |
| 1088 } |
| 1089 |
| 1090 bool AXObject::includesARIAWidgetRole(const String& role) |
| 1091 { |
| 1092 static const HashSet<String, CaseFoldingHash>* roleSet = createARIARoleWidge
tSet(); |
| 1093 |
| 1094 Vector<String> roleVector; |
| 1095 role.split(' ', roleVector); |
| 1096 unsigned size = roleVector.size(); |
| 1097 for (unsigned i = 0; i < size; ++i) { |
| 1098 String roleName = roleVector[i]; |
| 1099 if (roleSet->contains(roleName)) |
| 1100 return true; |
| 1101 } |
| 1102 return false; |
| 1103 } |
| 1104 |
| 996 AccessibilityRole AXObject::buttonRoleType() const | 1105 AccessibilityRole AXObject::buttonRoleType() const |
| 997 { | 1106 { |
| 998 // If aria-pressed is present, then it should be exposed as a toggle button. | 1107 // If aria-pressed is present, then it should be exposed as a toggle button. |
| 999 // http://www.w3.org/TR/wai-aria/states_and_properties#aria-pressed | 1108 // http://www.w3.org/TR/wai-aria/states_and_properties#aria-pressed |
| 1000 if (ariaPressedIsPresent()) | 1109 if (ariaPressedIsPresent()) |
| 1001 return ToggleButtonRole; | 1110 return ToggleButtonRole; |
| 1002 if (ariaHasPopup()) | 1111 if (ariaHasPopup()) |
| 1003 return PopUpButtonRole; | 1112 return PopUpButtonRole; |
| 1004 // We don't contemplate RadioButtonRole, as it depends on the input | 1113 // We don't contemplate RadioButtonRole, as it depends on the input |
| 1005 // type. | 1114 // type. |
| 1006 | 1115 |
| 1007 return ButtonRole; | 1116 return ButtonRole; |
| 1008 } | 1117 } |
| 1009 | 1118 |
| 1010 const AtomicString& AXObject::roleName(AccessibilityRole role) | 1119 const AtomicString& AXObject::roleName(AccessibilityRole role) |
| 1011 { | 1120 { |
| 1012 static const Vector<AtomicString>* roleNameVector = createRoleNameVector(); | 1121 static const Vector<AtomicString>* roleNameVector = createRoleNameVector(); |
| 1013 | 1122 |
| 1014 return roleNameVector->at(role); | 1123 return roleNameVector->at(role); |
| 1015 } | 1124 } |
| 1016 | 1125 |
| 1017 } // namespace blink | 1126 } // namespace blink |
| OLD | NEW |