tor-browser

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

AccessibleNode.h (8336B)


      1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
      2 /* vim: set ts=2 et sw=2 tw=40: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef A11Y_AOM_ACCESSIBLENODE_H
      8 #define A11Y_AOM_ACCESSIBLENODE_H
      9 
     10 #include "nsTHashMap.h"
     11 #include "nsRefPtrHashtable.h"
     12 #include "nsWrapperCache.h"
     13 #include "mozilla/dom/BindingDeclarations.h"
     14 #include "mozilla/dom/DOMString.h"
     15 #include "mozilla/dom/Nullable.h"
     16 
     17 class nsINode;
     18 
     19 namespace mozilla {
     20 
     21 class ErrorResult;
     22 
     23 namespace a11y {
     24 class LocalAccessible;
     25 }
     26 
     27 namespace dom {
     28 
     29 class DOMStringList;
     30 struct ParentObject;
     31 
     32 #define ANODE_ENUM(name) e##name,
     33 
     34 #define ANODE_FUNC(typeName, type, name)                    \
     35  dom::Nullable<type> Get##name() {                         \
     36    return GetProperty(AOM##typeName##Property::e##name);   \
     37  }                                                         \
     38                                                            \
     39  void Set##name(const dom::Nullable<type>& a##name) {      \
     40    SetProperty(AOM##typeName##Property::e##name, a##name); \
     41  }
     42 
     43 #define ANODE_STRING_FUNC(name)                              \
     44  void Get##name(nsAString& a##name) {                       \
     45    return GetProperty(AOMStringProperty::e##name, a##name); \
     46  }                                                          \
     47                                                             \
     48  void Set##name(const nsAString& a##name) {                 \
     49    SetProperty(AOMStringProperty::e##name, a##name);        \
     50  }
     51 
     52 #define ANODE_RELATION_FUNC(name)                       \
     53  already_AddRefed<AccessibleNode> Get##name() {        \
     54    return GetProperty(AOMRelationProperty::e##name);   \
     55  }                                                     \
     56                                                        \
     57  void Set##name(AccessibleNode* a##name) {             \
     58    SetProperty(AOMRelationProperty::e##name, a##name); \
     59  }
     60 
     61 #define ANODE_PROPS(typeName, type, ...)            \
     62  enum class AOM##typeName##Property{               \
     63      MOZ_FOR_EACH(ANODE_ENUM, (), (__VA_ARGS__))}; \
     64  MOZ_FOR_EACH(ANODE_FUNC, (typeName, type, ), (__VA_ARGS__))
     65 
     66 #define ANODE_STRING_PROPS(...)                 \
     67  enum class AOMStringProperty {                \
     68    MOZ_FOR_EACH(ANODE_ENUM, (), (__VA_ARGS__)) \
     69  };                                            \
     70  MOZ_FOR_EACH(ANODE_STRING_FUNC, (), (__VA_ARGS__))
     71 
     72 #define ANODE_RELATION_PROPS(...)               \
     73  enum class AOMRelationProperty {              \
     74    MOZ_FOR_EACH(ANODE_ENUM, (), (__VA_ARGS__)) \
     75  };                                            \
     76  MOZ_FOR_EACH(ANODE_RELATION_FUNC, (), (__VA_ARGS__))
     77 
     78 #define ANODE_ACCESSOR_MUTATOR(typeName, type, defVal)                      \
     79  nsTHashMap<nsUint32HashKey, type> m##typeName##Properties;                \
     80                                                                            \
     81  dom::Nullable<type> GetProperty(AOM##typeName##Property aProperty) {      \
     82    type value = defVal;                                                    \
     83    if (m##typeName##Properties.Get(static_cast<int>(aProperty), &value)) { \
     84      return dom::Nullable<type>(value);                                    \
     85    }                                                                       \
     86    return dom::Nullable<type>();                                           \
     87  }                                                                         \
     88                                                                            \
     89  void SetProperty(AOM##typeName##Property aProperty,                       \
     90                   const dom::Nullable<type>& aValue) {                     \
     91    if (aValue.IsNull()) {                                                  \
     92      m##typeName##Properties.Remove(static_cast<int>(aProperty));          \
     93    } else {                                                                \
     94      m##typeName##Properties.InsertOrUpdate(static_cast<int>(aProperty),   \
     95                                             aValue.Value());               \
     96    }                                                                       \
     97  }
     98 
     99 class AccessibleNode : public nsISupports, public nsWrapperCache {
    100 public:
    101  explicit AccessibleNode(nsINode* aNode);
    102 
    103  NS_DECL_CYCLE_COLLECTING_ISUPPORTS;
    104  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(AccessibleNode);
    105 
    106  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
    107  dom::ParentObject GetParentObject() const;
    108 
    109  void GetComputedRole(nsAString& aRole);
    110  void GetStates(nsTArray<nsString>& aStates);
    111  void GetAttributes(nsTArray<nsString>& aAttributes);
    112  nsINode* GetDOMNode();
    113 
    114  bool Is(const Sequence<nsString>& aFlavors);
    115  bool Has(const Sequence<nsString>& aAttributes);
    116  void Get(JSContext* cx, const nsAString& aAttribute,
    117           JS::MutableHandle<JS::Value> aValue, ErrorResult& aRv);
    118 
    119  static bool IsAOMEnabled(JSContext*, JSObject*);
    120 
    121  ANODE_STRING_PROPS(Autocomplete, Checked, Current, HasPopUp, Invalid,
    122                     KeyShortcuts, Label, Live, Orientation, Placeholder,
    123                     Pressed, Relevant, Role, RoleDescription, Sort, ValueText)
    124 
    125  ANODE_PROPS(Boolean, bool, Atomic, Busy, Disabled, Expanded, Hidden, Modal,
    126              Multiline, Multiselectable, ReadOnly, Required, Selected)
    127 
    128  ANODE_PROPS(UInt, uint32_t, ColIndex, ColSpan, Level, PosInSet, RowIndex,
    129              RowSpan)
    130 
    131  ANODE_PROPS(Int, int32_t, ColCount, RowCount, SetSize)
    132 
    133  ANODE_PROPS(Double, double, ValueMax, ValueMin, ValueNow)
    134 
    135  ANODE_RELATION_PROPS(ActiveDescendant, Details, ErrorMessage)
    136 
    137 protected:
    138  AccessibleNode(const AccessibleNode& aCopy) = delete;
    139  AccessibleNode& operator=(const AccessibleNode& aCopy) = delete;
    140  virtual ~AccessibleNode();
    141 
    142  void GetProperty(AOMStringProperty aProperty, nsAString& aRetval) {
    143    nsString data;
    144    if (!mStringProperties.Get(static_cast<int>(aProperty), &data)) {
    145      SetDOMStringToNull(data);
    146    }
    147    aRetval = data;
    148  }
    149 
    150  void SetProperty(AOMStringProperty aProperty, const nsAString& aValue) {
    151    if (DOMStringIsNull(aValue)) {
    152      mStringProperties.Remove(static_cast<int>(aProperty));
    153    } else {
    154      nsString value(aValue);
    155      mStringProperties.InsertOrUpdate(static_cast<int>(aProperty), value);
    156    }
    157  }
    158 
    159  dom::Nullable<bool> GetProperty(AOMBooleanProperty aProperty) {
    160    int num = static_cast<int>(aProperty);
    161    if (mBooleanProperties & (1U << (2 * num))) {
    162      bool data = static_cast<bool>(mBooleanProperties & (1U << (2 * num + 1)));
    163      return dom::Nullable<bool>(data);
    164    }
    165    return dom::Nullable<bool>();
    166  }
    167 
    168  void SetProperty(AOMBooleanProperty aProperty,
    169                   const dom::Nullable<bool>& aValue) {
    170    int num = static_cast<int>(aProperty);
    171    if (aValue.IsNull()) {
    172      mBooleanProperties &= ~(1U << (2 * num));
    173    } else {
    174      mBooleanProperties |= (1U << (2 * num));
    175      mBooleanProperties =
    176          (aValue.Value() ? mBooleanProperties | (1U << (2 * num + 1))
    177                          : mBooleanProperties & ~(1U << (2 * num + 1)));
    178    }
    179  }
    180 
    181  ANODE_ACCESSOR_MUTATOR(Double, double, 0.0)
    182  ANODE_ACCESSOR_MUTATOR(Int, int32_t, 0)
    183  ANODE_ACCESSOR_MUTATOR(UInt, uint32_t, 0)
    184 
    185  already_AddRefed<AccessibleNode> GetProperty(AOMRelationProperty aProperty) {
    186    return mRelationProperties.Get(static_cast<int>(aProperty));
    187  }
    188 
    189  void SetProperty(AOMRelationProperty aProperty, AccessibleNode* aValue) {
    190    if (!aValue) {
    191      mRelationProperties.Remove(static_cast<int>(aProperty));
    192    } else {
    193      mRelationProperties.InsertOrUpdate(static_cast<int>(aProperty),
    194                                         RefPtr{aValue});
    195    }
    196  }
    197 
    198  // The 2k'th bit indicates whether the k'th boolean property is used(1) or
    199  // not(0) and 2k+1'th bit contains the property's value(1:true, 0:false)
    200  uint32_t mBooleanProperties;
    201  nsRefPtrHashtable<nsUint32HashKey, AccessibleNode> mRelationProperties;
    202  nsTHashMap<nsUint32HashKey, nsString> mStringProperties;
    203 
    204  RefPtr<a11y::LocalAccessible> mIntl;
    205  RefPtr<nsINode> mDOMNode;
    206  RefPtr<dom::DOMStringList> mStates;
    207 };
    208 
    209 }  // namespace dom
    210 }  // namespace mozilla
    211 
    212 #endif  // A11Y_JSAPI_ACCESSIBLENODE