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 // NOTE: alphabetically ordered
7
8 #include "FormControlAccessible.h"
9 #include "Role.h"
10
11 #include "mozilla/FloatingPoint.h"
12 #include "nsIDOMHTMLFormElement.h"
13 #include "nsIDOMXULElement.h"
14 #include "nsIDOMXULControlElement.h"
15
16 using namespace mozilla::a11y;
17
18 ////////////////////////////////////////////////////////////////////////////////
19 // ProgressMeterAccessible
20 ////////////////////////////////////////////////////////////////////////////////
21
22 template class mozilla::a11y::ProgressMeterAccessible<1>;
23 template class mozilla::a11y::ProgressMeterAccessible<100>;
24
25 ////////////////////////////////////////////////////////////////////////////////
26 // Accessible
27
28 template<int Max>
29 role
NativeRole()30 ProgressMeterAccessible<Max>::NativeRole()
31 {
32 return roles::PROGRESSBAR;
33 }
34
35 template<int Max>
36 uint64_t
NativeState()37 ProgressMeterAccessible<Max>::NativeState()
38 {
39 uint64_t state = LeafAccessible::NativeState();
40
41 // An undetermined progressbar (i.e. without a value) has a mixed state.
42 nsAutoString attrValue;
43 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue);
44
45 if (attrValue.IsEmpty())
46 state |= states::MIXED;
47
48 return state;
49 }
50
51 ////////////////////////////////////////////////////////////////////////////////
52 // ProgressMeterAccessible<Max>: Widgets
53
54 template<int Max>
55 bool
IsWidget() const56 ProgressMeterAccessible<Max>::IsWidget() const
57 {
58 return true;
59 }
60
61 ////////////////////////////////////////////////////////////////////////////////
62 // ProgressMeterAccessible<Max>: Value
63
64 template<int Max>
65 void
Value(nsString & aValue)66 ProgressMeterAccessible<Max>::Value(nsString& aValue)
67 {
68 LeafAccessible::Value(aValue);
69 if (!aValue.IsEmpty())
70 return;
71
72 double maxValue = MaxValue();
73 if (IsNaN(maxValue) || maxValue == 0)
74 return;
75
76 double curValue = CurValue();
77 if (IsNaN(curValue))
78 return;
79
80 // Treat the current value bigger than maximum as 100%.
81 double percentValue = (curValue < maxValue) ?
82 (curValue / maxValue) * 100 : 100;
83
84 aValue.AppendFloat(percentValue);
85 aValue.Append('%');
86 }
87
88 template<int Max>
89 double
MaxValue() const90 ProgressMeterAccessible<Max>::MaxValue() const
91 {
92 double value = LeafAccessible::MaxValue();
93 if (!IsNaN(value))
94 return value;
95
96 nsAutoString strValue;
97 if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::max, strValue)) {
98 nsresult result = NS_OK;
99 value = strValue.ToDouble(&result);
100 if (NS_SUCCEEDED(result))
101 return value;
102 }
103
104 return Max;
105 }
106
107 template<int Max>
108 double
MinValue() const109 ProgressMeterAccessible<Max>::MinValue() const
110 {
111 double value = LeafAccessible::MinValue();
112 return IsNaN(value) ? 0 : value;
113 }
114
115 template<int Max>
116 double
Step() const117 ProgressMeterAccessible<Max>::Step() const
118 {
119 double value = LeafAccessible::Step();
120 return IsNaN(value) ? 0 : value;
121 }
122
123 template<int Max>
124 double
CurValue() const125 ProgressMeterAccessible<Max>::CurValue() const
126 {
127 double value = LeafAccessible::CurValue();
128 if (!IsNaN(value))
129 return value;
130
131 nsAutoString attrValue;
132 if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue))
133 return UnspecifiedNaN<double>();
134
135 nsresult error = NS_OK;
136 value = attrValue.ToDouble(&error);
137 return NS_FAILED(error) ? UnspecifiedNaN<double>() : value;
138 }
139
140 template<int Max>
141 bool
SetCurValue(double aValue)142 ProgressMeterAccessible<Max>::SetCurValue(double aValue)
143 {
144 return false; // progress meters are readonly.
145 }
146
147 ////////////////////////////////////////////////////////////////////////////////
148 // RadioButtonAccessible
149 ////////////////////////////////////////////////////////////////////////////////
150
151 RadioButtonAccessible::
RadioButtonAccessible(nsIContent * aContent,DocAccessible * aDoc)152 RadioButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) :
153 LeafAccessible(aContent, aDoc)
154 {
155 }
156
157 uint8_t
ActionCount()158 RadioButtonAccessible::ActionCount()
159 {
160 return 1;
161 }
162
163 void
ActionNameAt(uint8_t aIndex,nsAString & aName)164 RadioButtonAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
165 {
166 if (aIndex == eAction_Click)
167 aName.AssignLiteral("select");
168 }
169
170 bool
DoAction(uint8_t aIndex)171 RadioButtonAccessible::DoAction(uint8_t aIndex)
172 {
173 if (aIndex != eAction_Click)
174 return false;
175
176 DoCommand();
177 return true;
178 }
179
180 role
NativeRole()181 RadioButtonAccessible::NativeRole()
182 {
183 return roles::RADIOBUTTON;
184 }
185
186 ////////////////////////////////////////////////////////////////////////////////
187 // RadioButtonAccessible: Widgets
188
189 bool
IsWidget() const190 RadioButtonAccessible::IsWidget() const
191 {
192 return true;
193 }
194