ARIAMap.h (11671B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:expandtab:shiftwidth=2:tabstop=2: 3 */ 4 /* This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 8 #ifndef mozilla_a11y_aria_ARIAMap_h_ 9 #define mozilla_a11y_aria_ARIAMap_h_ 10 11 #include "ARIAStateMap.h" 12 #include "mozilla/a11y/AccTypes.h" 13 #include "mozilla/a11y/DocAccessible.h" 14 #include "mozilla/a11y/Role.h" 15 16 #include "nsAtom.h" 17 #include "nsIContent.h" 18 #include "nsTHashSet.h" 19 20 class nsINode; 21 22 namespace mozilla::dom { 23 class Element; 24 } 25 26 //////////////////////////////////////////////////////////////////////////////// 27 // Value constants 28 29 /** 30 * Used to define if role requires to expose Value interface. 31 */ 32 enum EValueRule { 33 /** 34 * Value interface isn't exposed. 35 */ 36 eNoValue, 37 38 /** 39 * Value interface is implemented, supports value, min and max from 40 * aria-valuenow, aria-valuemin and aria-valuemax. 41 */ 42 eHasValueMinMax, 43 44 /** 45 * Value interface is implemented, but only if the element is focusable. 46 * For instance, in ARIA 1.1 the ability for authors to create adjustable 47 * splitters was provided by supporting the value interface on separators 48 * that are focusable. Non-focusable separators expose no value information. 49 */ 50 eHasValueMinMaxIfFocusable 51 }; 52 53 //////////////////////////////////////////////////////////////////////////////// 54 // Action constants 55 56 /** 57 * Used to define if the role requires to expose action. 58 */ 59 enum EActionRule { 60 eNoAction, 61 eActivateAction, 62 eClickAction, 63 ePressAction, 64 eCheckUncheckAction, 65 eExpandAction, 66 eJumpAction, 67 eOpenCloseAction, 68 eSelectAction, 69 eSortAction, 70 eSwitchAction 71 }; 72 73 //////////////////////////////////////////////////////////////////////////////// 74 // Live region constants 75 76 /** 77 * Used to define if role exposes default value of aria-live attribute. 78 */ 79 enum ELiveAttrRule { 80 eNoLiveAttr, 81 eOffLiveAttr, 82 ePoliteLiveAttr, 83 eAssertiveLiveAttr 84 }; 85 86 //////////////////////////////////////////////////////////////////////////////// 87 // Role constants 88 89 /** 90 * ARIA role overrides role from native markup. 91 */ 92 const bool kUseMapRole = true; 93 94 /** 95 * ARIA role doesn't override the role from native markup. 96 */ 97 const bool kUseNativeRole = false; 98 99 //////////////////////////////////////////////////////////////////////////////// 100 // ARIA attribute characteristic masks 101 102 /** 103 * This mask indicates the attribute should not be exposed as an object 104 * attribute via the catch-all logic in Accessible::Attributes(). 105 * This means it either isn't mean't to be exposed as an object attribute, or 106 * that it should, but is already handled in other code. 107 */ 108 const uint8_t ATTR_BYPASSOBJ = 0x1 << 0; 109 const uint8_t ATTR_BYPASSOBJ_IF_FALSE = 0x1 << 1; 110 111 /** 112 * This mask indicates the attribute is expected to have an NMTOKEN or bool 113 * value. (See for example usage in Accessible::Attributes()) 114 */ 115 const uint8_t ATTR_VALTOKEN = 0x1 << 2; 116 117 /** 118 * Indicate the attribute is global state or property (refer to 119 * http://www.w3.org/TR/wai-aria/states_and_properties#global_states). 120 */ 121 const uint8_t ATTR_GLOBAL = 0x1 << 3; 122 123 /** 124 * Indicates that the attribute should have an integer value. 125 */ 126 const uint8_t ATTR_VALINT = 0x1 << 4; 127 128 /** 129 * Indicates that the attribute can have reflected elements. 130 */ 131 const uint8_t ATTR_REFLECT_ELEMENTS = 0x1 << 5; 132 133 //////////////////////////////////////////////////////////////////////////////// 134 // State map entry 135 136 /** 137 * Used in nsRoleMapEntry.state if no nsIAccessibleStates are automatic for 138 * a given role. 139 */ 140 #define kNoReqStates 0 141 142 //////////////////////////////////////////////////////////////////////////////// 143 // Role map entry 144 145 /** 146 * For each ARIA role, this maps the nsIAccessible information. 147 */ 148 struct nsRoleMapEntry { 149 /** 150 * Return true if matches to the given ARIA role. 151 */ 152 bool Is(nsAtom* aARIARole) const { return roleAtom == aARIARole; } 153 154 /** 155 * Return true if ARIA role has the given accessible type. 156 */ 157 bool IsOfType(mozilla::a11y::AccGenericType aType) const { 158 return accTypes & aType; 159 } 160 161 /** 162 * Return ARIA role. 163 */ 164 const nsDependentAtomString ARIARoleString() const { 165 return nsDependentAtomString(roleAtom); 166 } 167 168 // ARIA role: string representation such as "button" 169 nsStaticAtom* const roleAtom; 170 171 // Role mapping rule: maps to enum Role 172 mozilla::a11y::role role; 173 174 // Role rule: whether to use mapped role or native semantics 175 bool roleRule; 176 177 // Value mapping rule: how to compute accessible value 178 EValueRule valueRule; 179 180 // Action mapping rule, how to expose accessible action 181 EActionRule actionRule; 182 183 // 'live' and 'container-live' object attributes mapping rule: how to expose 184 // these object attributes if ARIA 'live' attribute is missed. 185 ELiveAttrRule liveAttRule; 186 187 // LocalAccessible types this role belongs to. 188 uint32_t accTypes; 189 190 // Automatic state mapping rule: always include in states 191 uint64_t state; // or kNoReqStates if no default state for this role 192 193 // ARIA properties supported for this role (in other words, the aria-foo 194 // attribute to accessible states mapping rules). 195 // Currently you cannot have unlimited mappings, because 196 // a variable sized array would not allow the use of 197 // C++'s struct initialization feature. 198 mozilla::a11y::aria::EStateRule attributeMap1; 199 mozilla::a11y::aria::EStateRule attributeMap2; 200 mozilla::a11y::aria::EStateRule attributeMap3; 201 mozilla::a11y::aria::EStateRule attributeMap4; 202 }; 203 204 //////////////////////////////////////////////////////////////////////////////// 205 // ARIA map 206 207 /** 208 * These provide the mappings for WAI-ARIA roles, states and properties using 209 * the structs defined in this file and ARIAStateMap files. 210 */ 211 namespace mozilla { 212 namespace a11y { 213 class AccAttributes; 214 215 namespace aria { 216 217 /** 218 * Empty role map entry. Used by accessibility service to create an accessible 219 * if the accessible can't use role of used accessible class. For example, 220 * it is used for table cells that aren't contained by table. 221 */ 222 extern nsRoleMapEntry gEmptyRoleMap; 223 224 /** 225 * Constants for the role map entry index to indicate that the role map entry 226 * isn't in sWAIRoleMaps, but rather is a special entry: nullptr, 227 * gEmptyRoleMap, and sLandmarkRoleMap 228 */ 229 const uint8_t NO_ROLE_MAP_ENTRY_INDEX = UINT8_MAX - 2; 230 const uint8_t EMPTY_ROLE_MAP_ENTRY_INDEX = UINT8_MAX - 1; 231 const uint8_t LANDMARK_ROLE_MAP_ENTRY_INDEX = UINT8_MAX; 232 233 /** 234 * Get the role map entry for a given DOM node. This will use the first 235 * ARIA role if the role attribute provides a space delimited list of roles. 236 * 237 * @param aEl [in] the DOM node to get the role map entry for 238 * @return a pointer to the role map entry for the ARIA role, or nullptr 239 * if none 240 */ 241 const nsRoleMapEntry* GetRoleMap(dom::Element* aEl); 242 243 /* 244 * Get the role map entry pointer's index for a given DOM node, skipping any 245 * given roles. This will use the first valid ARIA role if the role attribute 246 * provides a space delimited list of roles, excluding any given roles. 247 * 248 * @param aRoleAttrValue [in] the string value of the aria role(s) 249 * @param aRolesToSkip [in] the roles to skip when searching the role string 250 * @return the index of the pointer to the role map entry for the 251 * ARIA role, or NO_ROLE_MAP_ENTRY_INDEX if none 252 */ 253 uint8_t GetFirstValidRoleMapIndexExcluding( 254 const nsString& aRoleAttrValue, 255 std::initializer_list<nsStaticAtom*> aRolesToSkip); 256 257 /** 258 * Get the role map entry pointer's index for a given DOM node. This will use 259 * the first ARIA role if the role attribute provides a space delimited list of 260 * roles. 261 * 262 * @param aEl [in] the DOM node to get the role map entry for 263 * @return the index of the pointer to the role map entry for the ARIA 264 * role, or NO_ROLE_MAP_ENTRY_INDEX if none 265 */ 266 uint8_t GetRoleMapIndex(dom::Element* aEl); 267 268 /** 269 * Get the role map entry pointer for a given role map entry index. 270 * 271 * @param aRoleMapIndex [in] the role map index to get the role map entry 272 * pointer for 273 * @return a pointer to the role map entry for the ARIA role, 274 * or nullptr, if none 275 */ 276 const nsRoleMapEntry* GetRoleMapFromIndex(uint8_t aRoleMapIndex); 277 278 /** 279 * Get the role map entry index for a given role map entry pointer. If the role 280 * map entry is within sWAIRoleMaps, return the index within that array, 281 * otherwise return one of the special index constants listed above. 282 * 283 * @param aRoleMap [in] the role map entry pointer to get the index for 284 * @return the index of the pointer to the role map entry, or 285 * NO_ROLE_MAP_ENTRY_INDEX if none 286 */ 287 uint8_t GetIndexFromRoleMap(const nsRoleMapEntry* aRoleMap); 288 289 /** 290 * Determine whether a role map entry index is valid. 291 */ 292 bool IsRoleMapIndexValid(uint8_t aRoleMapIndex); 293 294 /** 295 * Return accessible state from ARIA universal states applied to the given 296 * element. 297 */ 298 uint64_t UniversalStatesFor(dom::Element* aElement); 299 300 /** 301 * Get the ARIA attribute characteristics for a given ARIA attribute. 302 * 303 * @param aAtom ARIA attribute 304 * @return A bitflag representing the attribute characteristics 305 * (see above for possible bit masks, prefixed "ATTR_") 306 */ 307 uint8_t AttrCharacteristicsFor(nsAtom* aAtom); 308 309 /** 310 * Return true if the element has defined aria-hidden 311 * and should not be ignored per ShouldIgnoreARIAHidden. 312 */ 313 bool IsValidARIAHidden(nsIContent* aContent); 314 315 /** 316 * This function calls into the function above. It verifies the validity 317 * of any `aria-hidden` specified on the given Doc Accessible's 318 * mContent, as well as on the root element of mContent's owner 319 * doc. 320 */ 321 bool IsValidARIAHidden(DocAccessible* aDocAcc); 322 323 /** 324 * Return true if the element should render its subtree 325 * regardless of the presence of aria-hidden. 326 */ 327 bool ShouldIgnoreARIAHidden(nsIContent* aContent); 328 329 /** 330 * Get the role map entry for a given ARIA role. 331 */ 332 const nsRoleMapEntry* GetRoleMap(const nsStaticAtom* aAriaRole); 333 334 /** 335 * Represents a simple enumerator for iterating through ARIA attributes 336 * exposed as object attributes on a given accessible. 337 */ 338 class AttrIterator { 339 public: 340 explicit AttrIterator(nsIContent* aContent); 341 342 bool Next(); 343 344 nsAtom* AttrName() const; 345 346 void AttrValue(nsAString& aAttrValue) const; 347 348 /** 349 * Expose this ARIA attribute in a specified AccAttributes. The appropriate 350 * type will be used for the attribute; e.g. an atom for a token value. 351 */ 352 bool ExposeAttr(AccAttributes* aTargetAttrs) const; 353 354 private: 355 AttrIterator() = delete; 356 AttrIterator(const AttrIterator&) = delete; 357 AttrIterator& operator=(const AttrIterator&) = delete; 358 359 dom::Element* mElement; 360 361 bool mIteratingDefaults; 362 nsTHashSet<RefPtr<nsAtom>> mOverriddenAttrs; 363 364 const AttrArray* mAttrs; 365 uint32_t mAttrIdx; 366 uint32_t mAttrCount; 367 RefPtr<nsAtom> mAttrAtom; 368 uint8_t mAttrCharacteristics; 369 }; 370 371 class AttrWithCharacteristicsIterator { 372 public: 373 explicit AttrWithCharacteristicsIterator(uint8_t aCharacteristics) 374 : mIdx(-1), mCharacteristics(aCharacteristics) {} 375 376 bool Next(); 377 378 nsStaticAtom* AttrName() const; 379 380 private: 381 AttrWithCharacteristicsIterator() = delete; 382 AttrWithCharacteristicsIterator(const AttrWithCharacteristicsIterator&) = 383 delete; 384 AttrWithCharacteristicsIterator& operator=( 385 const AttrWithCharacteristicsIterator&) = delete; 386 387 int32_t mIdx; 388 uint8_t mCharacteristics; 389 }; 390 391 } // namespace aria 392 } // namespace a11y 393 } // namespace mozilla 394 395 #endif