1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Netscape Public License
6
* Version 1.1 (the "License"); you may not use this file except in
7
* compliance with the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/NPL/
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
15
* The Original Code is mozilla.org code.
17
* The Initial Developer of the Original Code is
18
* Netscape Communications Corporation.
19
* Portions created by the Initial Developer are Copyright (C) 1998
20
* the Initial Developer. All Rights Reserved.
22
* Original Author: John Gaunt (jgaunt@netscape.com)
24
* Aaron Leventhal (aaronl@netscape.com)
25
* Kyle Yuan (kyle.yuan@sun.com)
27
* Alternatively, the contents of this file may be used under the terms of
28
* either the GNU General Public License Version 2 or later (the "GPL"), or
29
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30
* in which case the provisions of the GPL or the LGPL are applicable instead
31
* of those above. If you wish to allow use of your version of this file only
32
* under the terms of either the GPL or the LGPL, and not to allow others to
33
* use your version of this file under the terms of the NPL, indicate your
34
* decision by deleting the provisions above and replace them with the notice
35
* and other provisions required by the GPL or the LGPL. If you do not delete
36
* the provisions above, a recipient may use your version of this file under
37
* the terms of any one of the NPL, the GPL or the LGPL.
39
* ***** END LICENSE BLOCK ***** */
41
// NOTE: alphabetically ordered
42
#include "nsXULFormControlAccessible.h"
43
#include "nsIDOMXULButtonElement.h"
44
#include "nsIDOMXULCheckboxElement.h"
45
#include "nsIDOMXULMenuListElement.h"
46
#include "nsIDOMXULSelectCntrlItemEl.h"
47
#include "nsAccessibleTreeWalker.h"
50
* XUL Button: can contain arbitrary HTML content
57
// Don't inherit from nsFormControlAccessible - it doesn't allow children and a button can have a dropmarker child
58
nsXULButtonAccessible::nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
59
nsAccessibleWrap(aNode, aShell)
63
NS_IMETHODIMP nsXULButtonAccessible::GetName(nsAString& aResult)
65
return GetXULName(aResult);
69
* Only one actions available
71
NS_IMETHODIMP nsXULButtonAccessible::GetNumActions(PRUint8 *_retval)
73
*_retval = eSingle_Action;
78
* Return the name of our only action
80
NS_IMETHODIMP nsXULButtonAccessible::GetActionName(PRUint8 index, nsAString& _retval)
82
if (index == eAction_Click) {
83
nsAccessible::GetTranslatedString(NS_LITERAL_STRING("press"), _retval);
86
return NS_ERROR_INVALID_ARG;
90
* Tell the button to do it's action
92
NS_IMETHODIMP nsXULButtonAccessible::DoAction(PRUint8 index)
95
nsCOMPtr<nsIDOMXULElement> buttonElement(do_QueryInterface(mDOMNode));
98
buttonElement->Click();
101
return NS_ERROR_FAILURE;
103
return NS_ERROR_INVALID_ARG;
107
* We are a pushbutton
109
NS_IMETHODIMP nsXULButtonAccessible::GetRole(PRUint32 *_retval)
111
*_retval = ROLE_PUSHBUTTON;
116
* Possible states: focused, focusable, unavailable(disabled)
118
NS_IMETHODIMP nsXULButtonAccessible::GetState(PRUint32 *_retval)
120
// get focus and disable status from base class
121
nsAccessible::GetState(_retval);
123
PRBool disabled = PR_FALSE;
124
nsCOMPtr<nsIDOMXULControlElement> xulFormElement(do_QueryInterface(mDOMNode));
125
if (xulFormElement) {
126
xulFormElement->GetDisabled(&disabled);
128
*_retval |= STATE_UNAVAILABLE;
130
*_retval |= STATE_FOCUSABLE;
133
// Buttons can be checked -- they simply appear pressed in rather than checked
134
nsCOMPtr<nsIDOMXULButtonElement> xulButtonElement(do_QueryInterface(mDOMNode));
135
if (xulButtonElement) {
136
PRBool checked = PR_FALSE;
137
PRInt32 checkState = 0;
138
xulButtonElement->GetChecked(&checked);
140
*_retval |= STATE_PRESSED;
141
xulButtonElement->GetCheckState(&checkState);
142
if (checkState == nsIDOMXULButtonElement::CHECKSTATE_MIXED)
143
*_retval |= STATE_MIXED;
147
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
148
NS_ASSERTION(element, "No nsIDOMElement for button node!");
149
PRBool isDefault = PR_FALSE;
150
element->HasAttribute(NS_LITERAL_STRING("default"), &isDefault) ;
152
*_retval |= STATE_DEFAULT;
158
* Perhaps 1 child - if there's a <dropmarker>
160
NS_IMETHODIMP nsXULButtonAccessible::GetFirstChild(nsIAccessible **aResult)
163
nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE);
164
walker.GetLastChild();
166
// If the anonymous tree walker can find accessible children,
167
// and the last one is a push button, then use it as the only accessible
168
// child -- because this is the scenario where we have a dropmarker child
170
if (walker.mState.accessible) {
172
if (NS_SUCCEEDED(walker.mState.accessible->GetRole(&role)) && role == ROLE_PUSHBUTTON) {
173
mFirstChild = walker.mState.accessible;
174
nsCOMPtr<nsPIAccessible> privChildAcc = do_QueryInterface(mFirstChild);
175
privChildAcc->SetNextSibling(nsnull);
180
mAccChildCount = (mFirstChild != nsnull);
181
NS_IF_ADDREF(*aResult = mFirstChild);
185
NS_IMETHODIMP nsXULButtonAccessible::GetLastChild(nsIAccessible **aResult)
187
return GetFirstChild(aResult);
190
NS_IMETHODIMP nsXULButtonAccessible::GetChildCount(PRInt32 *aResult)
192
nsCOMPtr<nsIAccessible> accessible;
193
GetFirstChild(getter_AddRefs(accessible));
194
*aResult = mAccChildCount;
200
* XUL Dropmarker: can contain arbitrary HTML content
204
* Default Constructor
206
nsXULDropmarkerAccessible::nsXULDropmarkerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
207
nsFormControlAccessible(aNode, aShell)
212
* Only one actions available
214
NS_IMETHODIMP nsXULDropmarkerAccessible::GetNumActions(PRUint8 *aResult)
216
*aResult = eSingle_Action;
220
PRBool nsXULDropmarkerAccessible::DropmarkerOpen(PRBool aToggleOpen)
222
PRBool isOpen = PR_FALSE;
224
nsCOMPtr<nsIDOMNode> parentButtonNode;
225
mDOMNode->GetParentNode(getter_AddRefs(parentButtonNode));
226
nsCOMPtr<nsIDOMXULButtonElement> parentButtonElement(do_QueryInterface(parentButtonNode));
228
if (parentButtonElement) {
229
parentButtonElement->GetOpen(&isOpen);
231
parentButtonElement->SetOpen(!isOpen);
234
nsCOMPtr<nsIDOMXULMenuListElement> parentMenuListElement(do_QueryInterface(parentButtonNode));
235
if (parentMenuListElement) {
236
parentMenuListElement->GetOpen(&isOpen);
238
parentMenuListElement->SetOpen(!isOpen);
246
* Return the name of our only action
248
NS_IMETHODIMP nsXULDropmarkerAccessible::GetActionName(PRUint8 index, nsAString& aResult)
250
if (index == eAction_Click) {
251
if (DropmarkerOpen(PR_FALSE))
252
aResult = NS_LITERAL_STRING("close");
254
aResult = NS_LITERAL_STRING("open");
258
return NS_ERROR_INVALID_ARG;
262
* Tell the Dropmarker to do it's action
264
NS_IMETHODIMP nsXULDropmarkerAccessible::DoAction(PRUint8 index)
266
if (index == eAction_Click) {
267
DropmarkerOpen(PR_TRUE); // Reverse the open attribute
270
return NS_ERROR_INVALID_ARG;
274
* We are a pushbutton
276
NS_IMETHODIMP nsXULDropmarkerAccessible::GetRole(PRUint32 *aResult)
278
*aResult = ROLE_PUSHBUTTON;
282
NS_IMETHODIMP nsXULDropmarkerAccessible::GetState(PRUint32 *aResult)
286
if (DropmarkerOpen(PR_FALSE))
287
*aResult = STATE_PRESSED;
297
* Default Constructor
299
nsXULCheckboxAccessible::nsXULCheckboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
300
nsFormControlAccessible(aNode, aShell)
305
* We are a CheckButton
307
NS_IMETHODIMP nsXULCheckboxAccessible::GetRole(PRUint32 *_retval)
309
*_retval = ROLE_CHECKBUTTON;
314
* Only one action available
316
NS_IMETHODIMP nsXULCheckboxAccessible::GetNumActions(PRUint8 *_retval)
318
*_retval = eSingle_Action;
323
* Return the name of our only action
325
NS_IMETHODIMP nsXULCheckboxAccessible::GetActionName(PRUint8 index, nsAString& _retval)
327
if (index == eAction_Click) {
332
if (state & STATE_CHECKED)
333
_retval = NS_LITERAL_STRING("uncheck");
335
_retval = NS_LITERAL_STRING("check");
339
return NS_ERROR_INVALID_ARG;
343
* Tell the checkbox to do its only action -- check( or uncheck) itself
345
NS_IMETHODIMP nsXULCheckboxAccessible::DoAction(PRUint8 index)
347
if (index == eAction_Click) {
348
nsCOMPtr<nsIDOMXULElement> xulCheckboxElement(do_QueryInterface(mDOMNode));
349
if (xulCheckboxElement) {
350
xulCheckboxElement->Click();
353
return NS_ERROR_FAILURE;
355
return NS_ERROR_INVALID_ARG;
359
* Possible states: focused, focusable, unavailable(disabled), checked
361
NS_IMETHODIMP nsXULCheckboxAccessible::GetState(PRUint32 *_retval)
363
// Get focus and disable status from base class
364
nsFormControlAccessible::GetState(_retval);
366
// Determine Checked state
367
nsCOMPtr<nsIDOMXULCheckboxElement> xulCheckboxElement(do_QueryInterface(mDOMNode));
368
if (xulCheckboxElement) {
369
PRBool checked = PR_FALSE;
370
xulCheckboxElement->GetChecked(&checked);
372
*_retval |= STATE_CHECKED;
373
PRInt32 checkState = 0;
374
xulCheckboxElement->GetCheckState(&checkState);
375
if (checkState == nsIDOMXULCheckboxElement::CHECKSTATE_MIXED)
376
*_retval |= STATE_MIXED;
387
nsXULGroupboxAccessible::nsXULGroupboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
388
nsAccessibleWrap(aNode, aShell)
392
NS_IMETHODIMP nsXULGroupboxAccessible::GetRole(PRUint32 *_retval)
394
*_retval = ROLE_GROUPING;
398
NS_IMETHODIMP nsXULGroupboxAccessible::GetState(PRUint32 *_retval)
400
// Groupbox doesn't support any states!
406
NS_IMETHODIMP nsXULGroupboxAccessible::GetName(nsAString& _retval)
408
_retval.Assign(NS_LITERAL_STRING("")); // Default name is blank
410
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
412
nsCOMPtr<nsIDOMNodeList> captions;
413
element->GetElementsByTagName(NS_LITERAL_STRING("caption"), getter_AddRefs(captions));
415
nsCOMPtr<nsIDOMNode> captionNode;
416
captions->Item(0, getter_AddRefs(captionNode));
418
element = do_QueryInterface(captionNode);
419
NS_ASSERTION(element, "No nsIDOMElement for caption node!");
420
element->GetAttribute(NS_LITERAL_STRING("label"), _retval) ;
430
NS_IMPL_ISUPPORTS_INHERITED0(nsXULProgressMeterAccessible, nsFormControlAccessible)
432
nsXULProgressMeterAccessible::nsXULProgressMeterAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
433
nsFormControlAccessible(aNode, aShell)
437
NS_IMETHODIMP nsXULProgressMeterAccessible::GetRole(PRUint32 *_retval)
439
*_retval = ROLE_PROGRESSBAR;
444
* No states supported for progressmeter
446
NS_IMETHODIMP nsXULProgressMeterAccessible::GetState(PRUint32 *_retval)
452
NS_IMETHODIMP nsXULProgressMeterAccessible::GetValue(nsAString& _retval)
454
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
455
NS_ASSERTION(element, "No element for DOM node!");
456
element->GetAttribute(NS_LITERAL_STRING("value"), _retval);
457
if (!_retval.IsEmpty() && _retval.Last() != '%')
458
_retval.Append(NS_LITERAL_STRING("%"));
467
nsXULRadioButtonAccessible::nsXULRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
468
nsRadioButtonAccessible(aNode, aShell)
472
/** Our only action is to click */
473
NS_IMETHODIMP nsXULRadioButtonAccessible::DoAction(PRUint8 index)
475
if (index == eAction_Click) {
476
nsCOMPtr<nsIDOMXULElement> radioButton(do_QueryInterface(mDOMNode));
478
radioButton->Click();
482
return NS_ERROR_INVALID_ARG;
485
/** We are Focusable and can be Checked and focused */
486
NS_IMETHODIMP nsXULRadioButtonAccessible::GetState(PRUint32 *_retval)
488
nsFormControlAccessible::GetState(_retval);
489
PRBool selected = PR_FALSE; // Radio buttons can be selected
491
nsCOMPtr<nsIDOMXULSelectControlItemElement> radioButton(do_QueryInterface(mDOMNode));
493
radioButton->GetSelected(&selected);
496
*_retval |= STATE_CHECKED;
497
// If our parent radio group is focused, then consider this radio button focused
498
nsCOMPtr<nsIDOMNode> parentNode;
499
mDOMNode->GetParentNode(getter_AddRefs(parentNode));
501
nsCOMPtr<nsIDOMNode> focusedNode;
502
GetFocusedNode(mDOMNode, getter_AddRefs(focusedNode));
503
if (focusedNode == parentNode)
504
*_retval |= STATE_FOCUSED;
512
* This gets the parent of the RadioGroup (our grandparent) and sets it
513
* as our parent, for future calls.
515
NS_IMETHODIMP nsXULRadioButtonAccessible::GetParent(nsIAccessible ** aParent)
518
nsCOMPtr<nsIAccessible> tempParent;
519
nsAccessible::GetParent(getter_AddRefs(tempParent));
521
tempParent->GetParent(getter_AddRefs(mParent));
523
NS_ASSERTION(mParent,"Whoa! This RadioButtonAcc doesn't have a parent! Better find out why.");
531
* The Radio Group proxies for the Radio Buttons themselves. The Group gets
532
* focus whereas the Buttons do not. So we only have an accessible object for
533
* this for the purpose of getting the proper RadioButton. Need this here to
534
* avoid circular reference problems when navigating the accessible tree and
535
* for getting to the radiobuttons.
539
nsXULRadioGroupAccessible::nsXULRadioGroupAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
540
nsAccessibleWrap(aNode, aShell)
544
NS_IMETHODIMP nsXULRadioGroupAccessible::GetRole(PRUint32 *_retval)
546
*_retval = ROLE_GROUPING;
550
NS_IMETHODIMP nsXULRadioGroupAccessible::GetState(PRUint32 *_retval)
552
// The radio group is not focusable.
553
// Sometimes the focus controller will report that it is focused.
554
// That means that the actual selected radio button should be considered focused
555
nsAccessible::GetState(_retval);
556
*_retval &= ~(STATE_FOCUSABLE | STATE_FOCUSED);
560
* XUL StatusBar: can contain arbitrary HTML content
564
* Default Constructor
566
nsXULStatusBarAccessible::nsXULStatusBarAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
567
nsAccessibleWrap(aNode, aShell)
574
NS_IMETHODIMP nsXULStatusBarAccessible::GetRole(PRUint32 *_retval)
576
*_retval = ROLE_STATUSBAR;
580
NS_IMETHODIMP nsXULStatusBarAccessible::GetState(PRUint32 *_retval)
582
*_retval = 0; // no special state flags for status bar
590
nsXULToolbarAccessible::nsXULToolbarAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
591
nsAccessibleWrap(aNode, aShell)
595
NS_IMETHODIMP nsXULToolbarAccessible::GetRole(PRUint32 *_retval)
597
*_retval = ROLE_TOOLBAR;
601
NS_IMETHODIMP nsXULToolbarAccessible::GetState(PRUint32 *_retval)
603
nsAccessible::GetState(_retval);
604
*_retval &= ~STATE_FOCUSABLE; // toolbar is not focusable
609
* XUL Toolbar Separator
612
nsXULToolbarSeparatorAccessible::nsXULToolbarSeparatorAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
613
nsLeafAccessible(aNode, aShell)
617
NS_IMETHODIMP nsXULToolbarSeparatorAccessible::GetRole(PRUint32 *_retval)
619
*_retval = ROLE_SEPARATOR;
623
NS_IMETHODIMP nsXULToolbarSeparatorAccessible::GetState(PRUint32 *_retval)
625
*_retval = 0; // no special state flags for toolbar separator