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