1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
4 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is mozilla.org code.
19 * The Initial Developer of the Original Code is IBM Corporation
20 * Portions created by the Initial Developer are Copyright (C) 2007
21 * the Initial Developer. All Rights Reserved.
24 * Aaron Leventhal <aleventh@us.ibm.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #include "nsARIAMap.h"
41 #include "nsIAccessibleRole.h"
42 #include "nsIAccessibleStates.h"
45 * This list of WAI-defined roles are currently hardcoded.
46 * Eventually we will most likely be loading an RDF resource that contains this information
47 * Using RDF will also allow for role extensibility. See bug 280138.
49 * Definition of nsRoleMapEntry and nsStateMapEntry contains comments explaining this table.
51 * When no nsIAccessibleRole enum mapping exists for an ARIA role, the
52 * role will be exposed via the object attribute "xml-roles".
53 * In addition, in MSAA, the unmapped role will also be exposed as a BSTR string role.
55 * There are no nsIAccessibleRole enums for the following landmark roles:
56 * banner, contentinfo, main, navigation, note, search, secondary, seealso, breadcrumbs
59 static const nsStateMapEntry kEndEntry
= {nsnull
, 0, 0}; // To fill in array of state mappings
61 nsRoleMapEntry
nsARIAMap::gWAIRoleMap
[] =
65 nsIAccessibleRole::ROLE_ALERT
,
73 nsIAccessibleRole::ROLE_ALERT
,
81 nsIAccessibleRole::ROLE_APPLICATION
,
89 nsIAccessibleRole::ROLE_DOCUMENT
,
97 nsIAccessibleRole::ROLE_PUSHBUTTON
,
101 {&nsAccessibilityAtoms::aria_pressed
, kBoolState
, nsIAccessibleStates::STATE_PRESSED
},
102 {&nsAccessibilityAtoms::aria_pressed
, "mixed", nsIAccessibleStates::STATE_MIXED
},
107 nsIAccessibleRole::ROLE_CHECKBUTTON
,
110 nsIAccessibleStates::STATE_CHECKABLE
,
111 {&nsAccessibilityAtoms::aria_checked
, kBoolState
, nsIAccessibleStates::STATE_CHECKED
},
112 {&nsAccessibilityAtoms::aria_checked
, "mixed", nsIAccessibleStates::STATE_MIXED
},
113 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
118 nsIAccessibleRole::ROLE_COLUMNHEADER
,
122 {&nsAccessibilityAtoms::aria_selected
, kBoolState
, nsIAccessibleStates::STATE_SELECTED
| nsIAccessibleStates::STATE_SELECTABLE
},
123 {&nsAccessibilityAtoms::aria_selected
, "false", nsIAccessibleStates::STATE_SELECTABLE
},
124 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
129 nsIAccessibleRole::ROLE_COMBOBOX
,
132 nsIAccessibleStates::STATE_COLLAPSED
| nsIAccessibleStates::STATE_HASPOPUP
,
133 // Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
134 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
135 {&nsAccessibilityAtoms::aria_expanded
, kBoolState
, nsIAccessibleStates::STATE_EXPANDED
},
140 nsIAccessibleRole::ROLE_TEXT_CONTAINER
,
148 nsIAccessibleRole::ROLE_DIALOG
,
156 nsIAccessibleRole::ROLE_DOCUMENT
,
164 nsIAccessibleRole::ROLE_TABLE
,
167 nsIAccessibleStates::STATE_FOCUSABLE
,
168 {&nsAccessibilityAtoms::aria_multiselectable
, kBoolState
, nsIAccessibleStates::STATE_MULTISELECTABLE
| nsIAccessibleStates::STATE_EXTSELECTABLE
},
169 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
174 nsIAccessibleRole::ROLE_CELL
,
178 {&nsAccessibilityAtoms::aria_expanded
, kBoolState
, nsIAccessibleStates::STATE_EXPANDED
},
179 {&nsAccessibilityAtoms::aria_expanded
, "false", nsIAccessibleStates::STATE_COLLAPSED
},
180 {&nsAccessibilityAtoms::aria_selected
, kBoolState
, nsIAccessibleStates::STATE_SELECTED
| nsIAccessibleStates::STATE_SELECTABLE
},
181 {&nsAccessibilityAtoms::aria_selected
, "false", nsIAccessibleStates::STATE_SELECTABLE
},
182 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
187 nsIAccessibleRole::ROLE_GROUPING
,
195 nsIAccessibleRole::ROLE_HEADING
,
203 nsIAccessibleRole::ROLE_GRAPHIC
,
211 nsIAccessibleRole::ROLE_LABEL
,
219 nsIAccessibleRole::ROLE_LINK
,
222 nsIAccessibleStates::STATE_LINKED
,
227 nsIAccessibleRole::ROLE_LIST
,
230 nsIAccessibleStates::STATE_READONLY
,
231 {&nsAccessibilityAtoms::aria_multiselectable
, kBoolState
, nsIAccessibleStates::STATE_MULTISELECTABLE
| nsIAccessibleStates::STATE_EXTSELECTABLE
},
236 nsIAccessibleRole::ROLE_LISTBOX
,
240 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
241 {&nsAccessibilityAtoms::aria_multiselectable
, kBoolState
, nsIAccessibleStates::STATE_MULTISELECTABLE
| nsIAccessibleStates::STATE_EXTSELECTABLE
},
246 nsIAccessibleRole::ROLE_LISTITEM
,
248 eNoAction
, // XXX: should depend on state, parent accessible
249 nsIAccessibleStates::STATE_READONLY
,
250 {&nsAccessibilityAtoms::aria_selected
, kBoolState
, nsIAccessibleStates::STATE_SELECTED
| nsIAccessibleStates::STATE_SELECTABLE
},
251 {&nsAccessibilityAtoms::aria_selected
, "false", nsIAccessibleStates::STATE_SELECTABLE
},
252 {&nsAccessibilityAtoms::aria_checked
, kBoolState
, nsIAccessibleStates::STATE_CHECKED
| nsIAccessibleStates::STATE_CHECKABLE
},
253 {&nsAccessibilityAtoms::aria_checked
, "mixed", nsIAccessibleStates::STATE_MIXED
| nsIAccessibleStates::STATE_CHECKABLE
},
254 {&nsAccessibilityAtoms::aria_checked
, "false", nsIAccessibleStates::STATE_CHECKABLE
},
259 nsIAccessibleRole::ROLE_FLAT_EQUATION
,
267 nsIAccessibleRole::ROLE_MENUPOPUP
,
269 eNoAction
, // XXX: technically accessibles of menupopup role haven't
270 // any action, but menu can be open or close.
276 nsIAccessibleRole::ROLE_MENUBAR
,
284 nsIAccessibleRole::ROLE_MENUITEM
,
288 {&nsAccessibilityAtoms::aria_checked
, kBoolState
, nsIAccessibleStates::STATE_CHECKED
| nsIAccessibleStates::STATE_CHECKABLE
},
289 {&nsAccessibilityAtoms::aria_checked
, "mixed", nsIAccessibleStates::STATE_MIXED
| nsIAccessibleStates::STATE_CHECKABLE
},
290 {&nsAccessibilityAtoms::aria_checked
, "false", nsIAccessibleStates::STATE_CHECKABLE
},
295 nsIAccessibleRole::ROLE_CHECK_MENU_ITEM
,
298 nsIAccessibleStates::STATE_CHECKABLE
,
299 {&nsAccessibilityAtoms::aria_checked
, kBoolState
, nsIAccessibleStates::STATE_CHECKED
},
300 {&nsAccessibilityAtoms::aria_checked
, "mixed", nsIAccessibleStates::STATE_MIXED
},
305 nsIAccessibleRole::ROLE_RADIO_MENU_ITEM
,
308 nsIAccessibleStates::STATE_CHECKABLE
,
309 {&nsAccessibilityAtoms::aria_checked
, kBoolState
, nsIAccessibleStates::STATE_CHECKED
},
314 nsIAccessibleRole::ROLE_OPTION
,
318 {&nsAccessibilityAtoms::aria_selected
, kBoolState
, nsIAccessibleStates::STATE_SELECTED
| nsIAccessibleStates::STATE_SELECTABLE
},
319 {&nsAccessibilityAtoms::aria_selected
, "false", nsIAccessibleStates::STATE_SELECTABLE
},
320 {&nsAccessibilityAtoms::aria_checked
, kBoolState
, nsIAccessibleStates::STATE_CHECKED
| nsIAccessibleStates::STATE_CHECKABLE
},
321 {&nsAccessibilityAtoms::aria_checked
, "mixed", nsIAccessibleStates::STATE_MIXED
| nsIAccessibleStates::STATE_CHECKABLE
},
322 {&nsAccessibilityAtoms::aria_checked
, "false", nsIAccessibleStates::STATE_CHECKABLE
},
327 nsIAccessibleRole::ROLE_NOTHING
,
335 nsIAccessibleRole::ROLE_PROGRESSBAR
,
338 nsIAccessibleStates::STATE_READONLY
,
343 nsIAccessibleRole::ROLE_RADIOBUTTON
,
347 {&nsAccessibilityAtoms::aria_checked
, kBoolState
, nsIAccessibleStates::STATE_CHECKED
},
352 nsIAccessibleRole::ROLE_GROUPING
,
360 nsIAccessibleRole::ROLE_PANE
,
368 nsIAccessibleRole::ROLE_ROW
,
372 {&nsAccessibilityAtoms::aria_selected
, kBoolState
, nsIAccessibleStates::STATE_SELECTED
| nsIAccessibleStates::STATE_SELECTABLE
},
373 {&nsAccessibilityAtoms::aria_selected
, "false", nsIAccessibleStates::STATE_SELECTABLE
},
374 {&nsAccessibilityAtoms::aria_expanded
, kBoolState
, nsIAccessibleStates::STATE_EXPANDED
},
375 {&nsAccessibilityAtoms::aria_expanded
, "false", nsIAccessibleStates::STATE_COLLAPSED
},
380 nsIAccessibleRole::ROLE_ROWHEADER
,
384 {&nsAccessibilityAtoms::aria_selected
, kBoolState
, nsIAccessibleStates::STATE_SELECTED
| nsIAccessibleStates::STATE_SELECTABLE
},
385 {&nsAccessibilityAtoms::aria_selected
, "false", nsIAccessibleStates::STATE_SELECTABLE
},
386 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
391 nsIAccessibleRole::ROLE_SECTION
,
399 nsIAccessibleRole::ROLE_SEPARATOR
,
407 nsIAccessibleRole::ROLE_SLIDER
,
411 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
416 nsIAccessibleRole::ROLE_SPINBUTTON
,
420 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
425 nsIAccessibleRole::ROLE_STATUSBAR
,
433 nsIAccessibleRole::ROLE_PAGETAB
,
441 nsIAccessibleRole::ROLE_PAGETABLIST
,
449 nsIAccessibleRole::ROLE_PROPERTYPAGE
,
457 nsIAccessibleRole::ROLE_ENTRY
,
461 // Manually map EXT_STATE_SINGLE_LINE and EXT_STATE_MULTI_LINE FROM aria-multiline
462 // Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
463 {&nsAccessibilityAtoms::aria_autocomplete
, "list", nsIAccessibleStates::STATE_HASPOPUP
},
464 {&nsAccessibilityAtoms::aria_autocomplete
, "both", nsIAccessibleStates::STATE_HASPOPUP
},
465 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
470 nsIAccessibleRole::ROLE_TOOLBAR
,
478 nsIAccessibleRole::ROLE_TOOLTIP
,
486 nsIAccessibleRole::ROLE_OUTLINE
,
490 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
491 {&nsAccessibilityAtoms::aria_multiselectable
, kBoolState
, nsIAccessibleStates::STATE_MULTISELECTABLE
| nsIAccessibleStates::STATE_EXTSELECTABLE
},
496 nsIAccessibleRole::ROLE_TREE_TABLE
,
500 {&nsAccessibilityAtoms::aria_readonly
, kBoolState
, nsIAccessibleStates::STATE_READONLY
},
501 {&nsAccessibilityAtoms::aria_multiselectable
, kBoolState
, nsIAccessibleStates::STATE_MULTISELECTABLE
| nsIAccessibleStates::STATE_EXTSELECTABLE
},
506 nsIAccessibleRole::ROLE_OUTLINEITEM
,
508 eActivateAction
, // XXX: should expose second 'expand/collapse' action based
511 {&nsAccessibilityAtoms::aria_selected
, kBoolState
, nsIAccessibleStates::STATE_SELECTED
| nsIAccessibleStates::STATE_SELECTABLE
},
512 {&nsAccessibilityAtoms::aria_selected
, "false", nsIAccessibleStates::STATE_SELECTABLE
},
513 {&nsAccessibilityAtoms::aria_expanded
, kBoolState
, nsIAccessibleStates::STATE_EXPANDED
},
514 {&nsAccessibilityAtoms::aria_expanded
, "false", nsIAccessibleStates::STATE_COLLAPSED
},
515 {&nsAccessibilityAtoms::aria_checked
, kBoolState
, nsIAccessibleStates::STATE_CHECKED
| nsIAccessibleStates::STATE_CHECKABLE
},
516 {&nsAccessibilityAtoms::aria_checked
, "mixed", nsIAccessibleStates::STATE_MIXED
| nsIAccessibleStates::STATE_CHECKABLE
},
517 {&nsAccessibilityAtoms::aria_checked
, "false", nsIAccessibleStates::STATE_CHECKABLE
},
521 PRUint32
nsARIAMap::gWAIRoleMapLength
= NS_ARRAY_LENGTH(nsARIAMap::gWAIRoleMap
);
523 nsRoleMapEntry
nsARIAMap::gLandmarkRoleMap
= {
525 nsIAccessibleRole::ROLE_NOTHING
,
532 nsRoleMapEntry
nsARIAMap::gEmptyRoleMap
= {
534 nsIAccessibleRole::ROLE_NOTHING
,
543 * The following state rules are applied to any accessible element,
544 * whether there is an ARIA role or not:
546 nsStateMapEntry
nsARIAMap::gWAIUnivStateMap
[] = {
547 {&nsAccessibilityAtoms::aria_required
, kBoolState
, nsIAccessibleStates::STATE_REQUIRED
},
548 {&nsAccessibilityAtoms::aria_invalid
, kBoolState
, nsIAccessibleStates::STATE_INVALID
},
549 {&nsAccessibilityAtoms::aria_haspopup
, kBoolState
, nsIAccessibleStates::STATE_HASPOPUP
},
550 {&nsAccessibilityAtoms::aria_busy
, "true", nsIAccessibleStates::STATE_BUSY
},
551 {&nsAccessibilityAtoms::aria_busy
, "error", nsIAccessibleStates::STATE_INVALID
},
552 {&nsAccessibilityAtoms::aria_disabled
, kBoolState
, nsIAccessibleStates::STATE_UNAVAILABLE
},