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