1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef MOZILLA_A11Y_HTMLFormControlAccessible_H_ 7 #define MOZILLA_A11Y_HTMLFormControlAccessible_H_ 8 9 #include "FormControlAccessible.h" 10 #include "HyperTextAccessibleWrap.h" 11 #include "nsAccUtils.h" 12 #include "Relation.h" 13 14 namespace mozilla { 15 class TextEditor; 16 namespace a11y { 17 18 /** 19 * Accessible for HTML input@type="radio" element. 20 */ 21 class HTMLRadioButtonAccessible : public RadioButtonAccessible { 22 public: HTMLRadioButtonAccessible(nsIContent * aContent,DocAccessible * aDoc)23 HTMLRadioButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) 24 : RadioButtonAccessible(aContent, aDoc) { 25 // Ignore "RadioStateChange" DOM event in lieu of document observer 26 // state change notification. 27 mStateFlags |= eIgnoreDOMUIEvent; 28 } 29 30 // Accessible 31 virtual uint64_t NativeState() const override; 32 virtual void GetPositionAndSizeInternal(int32_t* aPosInSet, 33 int32_t* aSetSize) override; 34 virtual Relation RelationByType(RelationType aType) const override; 35 36 private: 37 Relation ComputeGroupAttributes(int32_t* aPosInSet, int32_t* aSetSize) const; 38 }; 39 40 /** 41 * Accessible for HTML input@type="button", @type="submit", @type="image" 42 * and HTML button elements. 43 */ 44 class HTMLButtonAccessible : public HyperTextAccessibleWrap { 45 public: 46 enum { eAction_Click = 0 }; 47 48 HTMLButtonAccessible(nsIContent* aContent, DocAccessible* aDoc); 49 50 // Accessible 51 virtual mozilla::a11y::role NativeRole() const override; 52 virtual uint64_t State() override; 53 virtual uint64_t NativeState() const override; 54 55 // ActionAccessible 56 virtual uint8_t ActionCount() const override; 57 virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override; 58 virtual bool DoAction(uint8_t aIndex) const override; 59 60 // Widgets 61 virtual bool IsWidget() const override; 62 63 protected: 64 // Accessible 65 virtual ENameValueFlag NativeName(nsString& aName) const override; 66 }; 67 68 /** 69 * Accessible for HTML input@type="text", input@type="password", textarea and 70 * other HTML text controls. 71 */ 72 class HTMLTextFieldAccessible : public HyperTextAccessibleWrap { 73 public: 74 enum { eAction_Click = 0 }; 75 76 HTMLTextFieldAccessible(nsIContent* aContent, DocAccessible* aDoc); 77 78 NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLTextFieldAccessible, 79 HyperTextAccessibleWrap) 80 81 // HyperTextAccessible 82 MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual already_AddRefed<TextEditor> GetEditor() 83 const override; 84 85 // Accessible 86 virtual void Value(nsString& aValue) const override; 87 virtual void ApplyARIAState(uint64_t* aState) const override; 88 virtual mozilla::a11y::role NativeRole() const override; 89 virtual uint64_t NativeState() const override; 90 virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() override; 91 92 // ActionAccessible 93 virtual uint8_t ActionCount() const override; 94 virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override; 95 virtual bool DoAction(uint8_t aIndex) const override; 96 97 // Widgets 98 virtual bool IsWidget() const override; 99 virtual Accessible* ContainerWidget() const override; 100 101 protected: ~HTMLTextFieldAccessible()102 virtual ~HTMLTextFieldAccessible() {} 103 104 // Accessible 105 virtual ENameValueFlag NativeName(nsString& aName) const override; 106 107 /** 108 * Return a widget element this input is part of, for example, search-textbox. 109 * 110 * FIXME: This should probably be renamed. 111 */ BindingOrWidgetParent()112 nsIContent* BindingOrWidgetParent() const { 113 if (auto* el = mContent->GetClosestNativeAnonymousSubtreeRootParent()) { 114 return el; 115 } 116 // XUL search-textbox custom element 117 return Elm()->Closest(NS_LITERAL_STRING("search-textbox"), IgnoreErrors()); 118 } 119 }; 120 121 /** 122 * Accessible for input@type="file" element. 123 */ 124 class HTMLFileInputAccessible : public HyperTextAccessibleWrap { 125 public: 126 HTMLFileInputAccessible(nsIContent* aContent, DocAccessible* aDoc); 127 128 // Accessible 129 virtual mozilla::a11y::role NativeRole() const override; 130 virtual nsresult HandleAccEvent(AccEvent* aAccEvent) override; 131 virtual Accessible* CurrentItem() const override; 132 }; 133 134 /** 135 * Used for HTML input@type="number". 136 */ 137 class HTMLSpinnerAccessible final : public HTMLTextFieldAccessible { 138 public: HTMLSpinnerAccessible(nsIContent * aContent,DocAccessible * aDoc)139 HTMLSpinnerAccessible(nsIContent* aContent, DocAccessible* aDoc) 140 : HTMLTextFieldAccessible(aContent, aDoc) { 141 mStateFlags |= eHasNumericValue; 142 } 143 144 // Accessible 145 virtual mozilla::a11y::role NativeRole() const override; 146 virtual void Value(nsString& aValue) const override; 147 148 virtual double MaxValue() const override; 149 virtual double MinValue() const override; 150 virtual double CurValue() const override; 151 virtual double Step() const override; 152 virtual bool SetCurValue(double aValue) override; 153 }; 154 155 /** 156 * Used for input@type="range" element. 157 */ 158 class HTMLRangeAccessible : public LeafAccessible { 159 public: HTMLRangeAccessible(nsIContent * aContent,DocAccessible * aDoc)160 HTMLRangeAccessible(nsIContent* aContent, DocAccessible* aDoc) 161 : LeafAccessible(aContent, aDoc) { 162 mStateFlags |= eHasNumericValue; 163 } 164 165 // Accessible 166 virtual void Value(nsString& aValue) const override; 167 virtual mozilla::a11y::role NativeRole() const override; 168 169 // Value 170 virtual double MaxValue() const override; 171 virtual double MinValue() const override; 172 virtual double CurValue() const override; 173 virtual double Step() const override; 174 virtual bool SetCurValue(double aValue) override; 175 176 // Widgets 177 virtual bool IsWidget() const override; 178 }; 179 180 /** 181 * Accessible for HTML fieldset element. 182 */ 183 class HTMLGroupboxAccessible : public HyperTextAccessibleWrap { 184 public: 185 HTMLGroupboxAccessible(nsIContent* aContent, DocAccessible* aDoc); 186 187 // Accessible 188 virtual mozilla::a11y::role NativeRole() const override; 189 virtual Relation RelationByType(RelationType aType) const override; 190 191 protected: 192 // Accessible 193 virtual ENameValueFlag NativeName(nsString& aName) const override; 194 195 // HTMLGroupboxAccessible 196 nsIContent* GetLegend() const; 197 }; 198 199 /** 200 * Accessible for HTML legend element. 201 */ 202 class HTMLLegendAccessible : public HyperTextAccessibleWrap { 203 public: 204 HTMLLegendAccessible(nsIContent* aContent, DocAccessible* aDoc); 205 206 // Accessible 207 virtual Relation RelationByType(RelationType aType) const override; 208 }; 209 210 /** 211 * Accessible for HTML5 figure element. 212 */ 213 class HTMLFigureAccessible : public HyperTextAccessibleWrap { 214 public: 215 HTMLFigureAccessible(nsIContent* aContent, DocAccessible* aDoc); 216 217 // Accessible 218 virtual Relation RelationByType(RelationType aType) const override; 219 220 protected: 221 // Accessible 222 virtual ENameValueFlag NativeName(nsString& aName) const override; 223 224 // HTMLLegendAccessible 225 nsIContent* Caption() const; 226 }; 227 228 /** 229 * Accessible for HTML5 figcaption element. 230 */ 231 class HTMLFigcaptionAccessible : public HyperTextAccessibleWrap { 232 public: 233 HTMLFigcaptionAccessible(nsIContent* aContent, DocAccessible* aDoc); 234 235 // Accessible 236 virtual Relation RelationByType(RelationType aType) const override; 237 }; 238 239 /** 240 * Used for HTML form element. 241 */ 242 class HTMLFormAccessible : public HyperTextAccessibleWrap { 243 public: HTMLFormAccessible(nsIContent * aContent,DocAccessible * aDoc)244 HTMLFormAccessible(nsIContent* aContent, DocAccessible* aDoc) 245 : HyperTextAccessibleWrap(aContent, aDoc) {} 246 247 NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLFormAccessible, 248 HyperTextAccessibleWrap) 249 250 // Accessible 251 virtual nsAtom* LandmarkRole() const override; 252 virtual a11y::role NativeRole() const override; 253 254 protected: 255 virtual ~HTMLFormAccessible() = default; 256 }; 257 258 /** 259 * Accessible for HTML progress element. 260 */ 261 262 class HTMLProgressAccessible : public LeafAccessible { 263 public: HTMLProgressAccessible(nsIContent * aContent,DocAccessible * aDoc)264 HTMLProgressAccessible(nsIContent* aContent, DocAccessible* aDoc) 265 : LeafAccessible(aContent, aDoc) { 266 // Ignore 'ValueChange' DOM event in lieu of @value attribute change 267 // notifications. 268 mStateFlags |= eHasNumericValue | eIgnoreDOMUIEvent; 269 mType = eProgressType; 270 } 271 272 // Accessible 273 virtual void Value(nsString& aValue) const override; 274 virtual mozilla::a11y::role NativeRole() const override; 275 virtual uint64_t NativeState() const override; 276 277 // Value 278 virtual double MaxValue() const override; 279 virtual double MinValue() const override; 280 virtual double CurValue() const override; 281 virtual double Step() const override; 282 virtual bool SetCurValue(double aValue) override; 283 284 // Widgets 285 virtual bool IsWidget() const override; 286 287 protected: ~HTMLProgressAccessible()288 virtual ~HTMLProgressAccessible() {} 289 }; 290 291 /** 292 * Accessible for HTML date/time inputs. 293 */ 294 template <a11y::role R> 295 class HTMLDateTimeAccessible : public AccessibleWrap { 296 public: HTMLDateTimeAccessible(nsIContent * aContent,DocAccessible * aDoc)297 HTMLDateTimeAccessible(nsIContent* aContent, DocAccessible* aDoc) 298 : AccessibleWrap(aContent, aDoc) {} 299 NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLDateTimeAccessible,AccessibleWrap)300 NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLDateTimeAccessible, AccessibleWrap) 301 302 // Accessible 303 virtual mozilla::a11y::role NativeRole() const override { return R; } NativeAttributes()304 virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() 305 override { 306 nsCOMPtr<nsIPersistentProperties> attributes = 307 AccessibleWrap::NativeAttributes(); 308 // Unfortunately, an nsStaticAtom can't be passed as a 309 // template argument, so fetch the type from the DOM. 310 nsAutoString type; 311 if (mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::type, 312 type)) { 313 nsAccUtils::SetAccAttr(attributes, nsGkAtoms::textInputType, type); 314 } 315 return attributes.forget(); 316 } 317 318 // Widgets IsWidget()319 virtual bool IsWidget() const override { return true; } 320 321 protected: ~HTMLDateTimeAccessible()322 virtual ~HTMLDateTimeAccessible() {} 323 }; 324 325 } // namespace a11y 326 } // namespace mozilla 327 328 #endif 329