tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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