Line data Source code
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 : #include "XULSliderAccessible.h"
7 :
8 : #include "nsAccessibilityService.h"
9 : #include "Role.h"
10 : #include "States.h"
11 :
12 : #include "nsIFrame.h"
13 : #include "mozilla/dom/Element.h"
14 : #include "mozilla/FloatingPoint.h"
15 :
16 : using namespace mozilla::a11y;
17 :
18 : ////////////////////////////////////////////////////////////////////////////////
19 : // XULSliderAccessible
20 : ////////////////////////////////////////////////////////////////////////////////
21 :
22 0 : XULSliderAccessible::
23 0 : XULSliderAccessible(nsIContent* aContent, DocAccessible* aDoc) :
24 0 : AccessibleWrap(aContent, aDoc)
25 : {
26 0 : mStateFlags |= eHasNumericValue | eNoXBLKids;
27 0 : }
28 :
29 : // Accessible
30 :
31 : role
32 0 : XULSliderAccessible::NativeRole()
33 : {
34 0 : return roles::SLIDER;
35 : }
36 :
37 : uint64_t
38 0 : XULSliderAccessible::NativeInteractiveState() const
39 : {
40 0 : if (NativelyUnavailable())
41 0 : return states::UNAVAILABLE;
42 :
43 0 : nsIContent* sliderElm = GetSliderElement();
44 0 : if (sliderElm) {
45 0 : nsIFrame* frame = sliderElm->GetPrimaryFrame();
46 0 : if (frame && frame->IsFocusable())
47 0 : return states::FOCUSABLE;
48 : }
49 :
50 0 : return 0;
51 : }
52 :
53 : bool
54 0 : XULSliderAccessible::NativelyUnavailable() const
55 : {
56 0 : return mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
57 0 : nsGkAtoms::_true, eCaseMatters);
58 : }
59 :
60 : void
61 0 : XULSliderAccessible::Value(nsString& aValue)
62 : {
63 0 : GetSliderAttr(nsGkAtoms::curpos, aValue);
64 0 : }
65 :
66 : uint8_t
67 0 : XULSliderAccessible::ActionCount()
68 : {
69 0 : return 1;
70 : }
71 :
72 : void
73 0 : XULSliderAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
74 : {
75 0 : aName.Truncate();
76 0 : if (aIndex == 0)
77 0 : aName.AssignLiteral("activate");
78 0 : }
79 :
80 : bool
81 0 : XULSliderAccessible::DoAction(uint8_t aIndex)
82 : {
83 0 : if (aIndex != 0)
84 0 : return false;
85 :
86 0 : nsIContent* sliderElm = GetSliderElement();
87 0 : if (sliderElm)
88 0 : DoCommand(sliderElm);
89 :
90 0 : return true;
91 : }
92 :
93 : double
94 0 : XULSliderAccessible::MaxValue() const
95 : {
96 0 : double value = AccessibleWrap::MaxValue();
97 0 : return IsNaN(value) ? GetSliderAttr(nsGkAtoms::maxpos) : value;
98 : }
99 :
100 : double
101 0 : XULSliderAccessible::MinValue() const
102 : {
103 0 : double value = AccessibleWrap::MinValue();
104 0 : return IsNaN(value) ? GetSliderAttr(nsGkAtoms::minpos) : value;
105 : }
106 :
107 : double
108 0 : XULSliderAccessible::Step() const
109 : {
110 0 : double value = AccessibleWrap::Step();
111 0 : return IsNaN(value) ? GetSliderAttr(nsGkAtoms::increment) : value;
112 : }
113 :
114 : double
115 0 : XULSliderAccessible::CurValue() const
116 : {
117 0 : double value = AccessibleWrap::CurValue();
118 0 : return IsNaN(value) ? GetSliderAttr(nsGkAtoms::curpos) : value;
119 : }
120 :
121 : bool
122 0 : XULSliderAccessible::SetCurValue(double aValue)
123 : {
124 0 : if (AccessibleWrap::SetCurValue(aValue))
125 0 : return true;
126 :
127 0 : return SetSliderAttr(nsGkAtoms::curpos, aValue);
128 : }
129 :
130 : // Utils
131 :
132 : nsIContent*
133 0 : XULSliderAccessible::GetSliderElement() const
134 : {
135 0 : if (!mSliderNode) {
136 : // XXX: we depend on anonymous content.
137 0 : mSliderNode = mContent->OwnerDoc()->
138 0 : GetAnonymousElementByAttribute(mContent, nsGkAtoms::anonid,
139 0 : NS_LITERAL_STRING("slider"));
140 : }
141 :
142 0 : return mSliderNode;
143 : }
144 :
145 : nsresult
146 0 : XULSliderAccessible::GetSliderAttr(nsIAtom* aName, nsAString& aValue) const
147 : {
148 0 : aValue.Truncate();
149 :
150 0 : if (IsDefunct())
151 0 : return NS_ERROR_FAILURE;
152 :
153 0 : nsIContent* sliderElm = GetSliderElement();
154 0 : if (sliderElm)
155 0 : sliderElm->GetAttr(kNameSpaceID_None, aName, aValue);
156 :
157 0 : return NS_OK;
158 : }
159 :
160 : nsresult
161 0 : XULSliderAccessible::SetSliderAttr(nsIAtom* aName, const nsAString& aValue)
162 : {
163 0 : if (IsDefunct())
164 0 : return NS_ERROR_FAILURE;
165 :
166 0 : nsIContent* sliderElm = GetSliderElement();
167 0 : if (sliderElm)
168 0 : sliderElm->SetAttr(kNameSpaceID_None, aName, aValue, true);
169 :
170 0 : return NS_OK;
171 : }
172 :
173 : double
174 0 : XULSliderAccessible::GetSliderAttr(nsIAtom* aName) const
175 : {
176 0 : nsAutoString attrValue;
177 0 : nsresult rv = GetSliderAttr(aName, attrValue);
178 0 : if (NS_FAILED(rv))
179 0 : return UnspecifiedNaN<double>();
180 :
181 0 : nsresult error = NS_OK;
182 0 : double value = attrValue.ToDouble(&error);
183 0 : return NS_FAILED(error) ? UnspecifiedNaN<double>() : value;
184 : }
185 :
186 : bool
187 0 : XULSliderAccessible::SetSliderAttr(nsIAtom* aName, double aValue)
188 : {
189 0 : nsAutoString value;
190 0 : value.AppendFloat(aValue);
191 :
192 0 : return NS_SUCCEEDED(SetSliderAttr(aName, value));
193 : }
194 :
195 :
196 : ////////////////////////////////////////////////////////////////////////////////
197 : // XULThumbAccessible
198 : ////////////////////////////////////////////////////////////////////////////////
199 :
200 0 : XULThumbAccessible::
201 0 : XULThumbAccessible(nsIContent* aContent, DocAccessible* aDoc) :
202 0 : AccessibleWrap(aContent, aDoc)
203 : {
204 0 : }
205 :
206 : ////////////////////////////////////////////////////////////////////////////////
207 : // XULThumbAccessible: Accessible
208 :
209 : role
210 0 : XULThumbAccessible::NativeRole()
211 : {
212 0 : return roles::INDICATOR;
213 : }
214 :
|