1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Mozilla Foundation.
19 : * Portions created by the Initial Developer are Copyright (C) 2007
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Alexander Surkov <surkov.alexander@gmail.com> (original author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "nsXULSliderAccessible.h"
40 :
41 : #include "nsAccessibilityService.h"
42 : #include "Role.h"
43 : #include "States.h"
44 :
45 : #include "nsIDOMDocument.h"
46 : #include "nsIDOMDocumentXBL.h"
47 : #include "nsIFrame.h"
48 :
49 : using namespace mozilla::a11y;
50 :
51 : ////////////////////////////////////////////////////////////////////////////////
52 : // nsXULSliderAccessible
53 : ////////////////////////////////////////////////////////////////////////////////
54 :
55 0 : nsXULSliderAccessible::
56 : nsXULSliderAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
57 0 : nsAccessibleWrap(aContent, aDoc)
58 : {
59 0 : }
60 :
61 : // nsISupports
62 :
63 0 : NS_IMPL_ISUPPORTS_INHERITED1(nsXULSliderAccessible,
64 : nsAccessibleWrap,
65 : nsIAccessibleValue)
66 :
67 : // nsAccessible
68 :
69 : role
70 0 : nsXULSliderAccessible::NativeRole()
71 : {
72 0 : return roles::SLIDER;
73 : }
74 :
75 : PRUint64
76 0 : nsXULSliderAccessible::NativeState()
77 : {
78 0 : PRUint64 states = nsAccessibleWrap::NativeState();
79 :
80 0 : nsCOMPtr<nsIContent> sliderContent(GetSliderNode());
81 0 : NS_ENSURE_STATE(sliderContent);
82 :
83 0 : nsIFrame *frame = sliderContent->GetPrimaryFrame();
84 0 : if (frame && frame->IsFocusable())
85 0 : states |= states::FOCUSABLE;
86 :
87 0 : if (FocusMgr()->IsFocused(this))
88 0 : states |= states::FOCUSED;
89 :
90 0 : return states;
91 : }
92 :
93 : // nsIAccessible
94 :
95 : NS_IMETHODIMP
96 0 : nsXULSliderAccessible::GetValue(nsAString& aValue)
97 : {
98 0 : return GetSliderAttr(nsGkAtoms::curpos, aValue);
99 : }
100 :
101 : PRUint8
102 0 : nsXULSliderAccessible::ActionCount()
103 : {
104 0 : return 1;
105 : }
106 :
107 : NS_IMETHODIMP
108 0 : nsXULSliderAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
109 : {
110 0 : aName.Truncate();
111 :
112 0 : NS_ENSURE_ARG(aIndex == 0);
113 :
114 0 : aName.AssignLiteral("activate");
115 0 : return NS_OK;
116 : }
117 :
118 : NS_IMETHODIMP
119 0 : nsXULSliderAccessible::DoAction(PRUint8 aIndex)
120 : {
121 0 : NS_ENSURE_ARG(aIndex == 0);
122 :
123 0 : nsCOMPtr<nsIContent> sliderContent(GetSliderNode());
124 0 : NS_ENSURE_STATE(sliderContent);
125 :
126 0 : DoCommand(sliderContent);
127 0 : return NS_OK;
128 : }
129 :
130 : // nsIAccessibleValue
131 :
132 : NS_IMETHODIMP
133 0 : nsXULSliderAccessible::GetMaximumValue(double *aValue)
134 : {
135 0 : nsresult rv = nsAccessibleWrap::GetMaximumValue(aValue);
136 :
137 : // ARIA redefined maximum value.
138 0 : if (rv != NS_OK_NO_ARIA_VALUE)
139 0 : return rv;
140 :
141 0 : return GetSliderAttr(nsGkAtoms::maxpos, aValue);
142 : }
143 :
144 : NS_IMETHODIMP
145 0 : nsXULSliderAccessible::GetMinimumValue(double *aValue)
146 : {
147 0 : nsresult rv = nsAccessibleWrap::GetMinimumValue(aValue);
148 :
149 : // ARIA redefined minmum value.
150 0 : if (rv != NS_OK_NO_ARIA_VALUE)
151 0 : return rv;
152 :
153 0 : return GetSliderAttr(nsGkAtoms::minpos, aValue);
154 : }
155 :
156 : NS_IMETHODIMP
157 0 : nsXULSliderAccessible::GetMinimumIncrement(double *aValue)
158 : {
159 0 : nsresult rv = nsAccessibleWrap::GetMinimumIncrement(aValue);
160 :
161 : // ARIA redefined minimum increment value.
162 0 : if (rv != NS_OK_NO_ARIA_VALUE)
163 0 : return rv;
164 :
165 0 : return GetSliderAttr(nsGkAtoms::increment, aValue);
166 : }
167 :
168 : NS_IMETHODIMP
169 0 : nsXULSliderAccessible::GetCurrentValue(double *aValue)
170 : {
171 0 : nsresult rv = nsAccessibleWrap::GetCurrentValue(aValue);
172 :
173 : // ARIA redefined current value.
174 0 : if (rv != NS_OK_NO_ARIA_VALUE)
175 0 : return rv;
176 :
177 0 : return GetSliderAttr(nsGkAtoms::curpos, aValue);
178 : }
179 :
180 : NS_IMETHODIMP
181 0 : nsXULSliderAccessible::SetCurrentValue(double aValue)
182 : {
183 0 : nsresult rv = nsAccessibleWrap::SetCurrentValue(aValue);
184 :
185 : // ARIA redefined current value.
186 0 : if (rv != NS_OK_NO_ARIA_VALUE)
187 0 : return rv;
188 :
189 0 : return SetSliderAttr(nsGkAtoms::curpos, aValue);
190 : }
191 :
192 : bool
193 0 : nsXULSliderAccessible::CanHaveAnonChildren()
194 : {
195 : // Do not allow anonymous xul:slider be accessible.
196 0 : return false;
197 : }
198 :
199 : // Utils
200 :
201 : already_AddRefed<nsIContent>
202 0 : nsXULSliderAccessible::GetSliderNode()
203 : {
204 0 : if (IsDefunct())
205 0 : return nsnull;
206 :
207 0 : if (!mSliderNode) {
208 0 : nsCOMPtr<nsIDOMDocumentXBL> xblDoc(do_QueryInterface(mContent->OwnerDoc()));
209 0 : if (!xblDoc)
210 0 : return nsnull;
211 :
212 : // XXX: we depend on anonymous content.
213 0 : nsCOMPtr<nsIDOMElement> domElm(do_QueryInterface(mContent));
214 0 : if (!domElm)
215 0 : return nsnull;
216 :
217 0 : xblDoc->GetAnonymousElementByAttribute(domElm, NS_LITERAL_STRING("anonid"),
218 0 : NS_LITERAL_STRING("slider"),
219 0 : getter_AddRefs(mSliderNode));
220 : }
221 :
222 0 : nsIContent *sliderNode = nsnull;
223 0 : nsresult rv = CallQueryInterface(mSliderNode, &sliderNode);
224 0 : return NS_FAILED(rv) ? nsnull : sliderNode;
225 : }
226 :
227 : nsresult
228 0 : nsXULSliderAccessible::GetSliderAttr(nsIAtom *aName, nsAString& aValue)
229 : {
230 0 : aValue.Truncate();
231 :
232 0 : if (IsDefunct())
233 0 : return NS_ERROR_FAILURE;
234 :
235 0 : nsCOMPtr<nsIContent> sliderNode(GetSliderNode());
236 0 : NS_ENSURE_STATE(sliderNode);
237 :
238 0 : sliderNode->GetAttr(kNameSpaceID_None, aName, aValue);
239 0 : return NS_OK;
240 : }
241 :
242 : nsresult
243 0 : nsXULSliderAccessible::SetSliderAttr(nsIAtom *aName, const nsAString& aValue)
244 : {
245 0 : if (IsDefunct())
246 0 : return NS_ERROR_FAILURE;
247 :
248 0 : nsCOMPtr<nsIContent> sliderNode(GetSliderNode());
249 0 : NS_ENSURE_STATE(sliderNode);
250 :
251 0 : sliderNode->SetAttr(kNameSpaceID_None, aName, aValue, true);
252 0 : return NS_OK;
253 : }
254 :
255 : nsresult
256 0 : nsXULSliderAccessible::GetSliderAttr(nsIAtom *aName, double *aValue)
257 : {
258 0 : NS_ENSURE_ARG_POINTER(aValue);
259 0 : *aValue = 0;
260 :
261 0 : nsAutoString attrValue;
262 0 : nsresult rv = GetSliderAttr(aName, attrValue);
263 0 : NS_ENSURE_SUCCESS(rv, rv);
264 :
265 : // Return zero value if there is no attribute or its value is empty.
266 0 : if (attrValue.IsEmpty())
267 0 : return NS_OK;
268 :
269 0 : PRInt32 error = NS_OK;
270 0 : double value = attrValue.ToDouble(&error);
271 0 : if (NS_SUCCEEDED(error))
272 0 : *aValue = value;
273 :
274 0 : return NS_OK;
275 : }
276 :
277 : nsresult
278 0 : nsXULSliderAccessible::SetSliderAttr(nsIAtom *aName, double aValue)
279 : {
280 0 : nsAutoString value;
281 0 : value.AppendFloat(aValue);
282 :
283 0 : return SetSliderAttr(aName, value);
284 : }
285 :
286 :
287 : ////////////////////////////////////////////////////////////////////////////////
288 : // nsXULThumbAccessible
289 : ////////////////////////////////////////////////////////////////////////////////
290 :
291 0 : nsXULThumbAccessible::
292 : nsXULThumbAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
293 0 : nsAccessibleWrap(aContent, aDoc)
294 : {
295 0 : }
296 :
297 : ////////////////////////////////////////////////////////////////////////////////
298 : // nsXULThumbAccessible: nsAccessible
299 :
300 : role
301 0 : nsXULThumbAccessible::NativeRole()
302 : {
303 0 : return roles::INDICATOR;
304 : }
305 :
|