Bug 499653 - unify ARIA state attributes mapping rules, r=marcoz, davidb

This commit is contained in:
Alexander Surkov 2009-06-25 10:12:38 +08:00
Родитель 001473948e
Коммит 2f5a7e0689
12 изменённых файлов: 881 добавлений и 351 удалений

Просмотреть файл

@ -54,9 +54,7 @@
*
* There are no nsIAccessibleRole enums for the following landmark roles:
* banner, contentinfo, main, navigation, note, search, secondary, seealso, breadcrumbs
*/
static const nsStateMapEntry kEndEntry = {nsnull, 0, 0}; // To fill in array of state mappings
*/
nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
{
@ -67,8 +65,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"alertdialog",
@ -77,8 +74,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"application",
@ -87,8 +83,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"article",
@ -97,8 +92,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_READONLY,
kEndEntry
nsIAccessibleStates::STATE_READONLY
},
{
"button",
@ -108,9 +102,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eClickAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_pressed, kBoolState, nsIAccessibleStates::STATE_PRESSED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_pressed, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
kEndEntry
eARIAPressed
},
{
"checkbox",
@ -119,11 +111,9 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eCheckUncheckAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
kNoReqStates,
eARIACheckableMixed,
eARIAReadonly
},
{
"columnheader",
@ -133,10 +123,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eSortAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIASelected,
eARIAReadonly
},
{
"combobox",
@ -146,9 +134,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eOpenCloseAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_COLLAPSED | nsIAccessibleStates::STATE_HASPOPUP,
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIAAutoComplete,
eARIAReadonly
},
{
"dialog",
@ -157,8 +144,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"document",
@ -167,8 +153,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_READONLY,
kEndEntry
nsIAccessibleStates::STATE_READONLY
},
{
"grid",
@ -178,9 +163,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_FOCUSABLE,
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIAMultiSelectable,
eARIAReadonly
},
{
"gridcell",
@ -190,10 +174,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIASelected,
eARIAReadonly
},
{
"group",
@ -202,8 +184,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"heading",
@ -212,8 +193,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"img",
@ -222,8 +202,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"label",
@ -232,8 +211,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"link",
@ -242,8 +220,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eJumpAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_LINKED,
kEndEntry
nsIAccessibleStates::STATE_LINKED
},
{
"list",
@ -253,8 +230,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_READONLY,
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
eARIAMultiSelectable
},
{
"listbox",
@ -264,9 +240,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
eARIAMultiSelectable,
eARIAReadonly
},
{
"listitem",
@ -276,12 +251,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction, // XXX: should depend on state, parent accessible
eNoLiveAttr,
nsIAccessibleStates::STATE_READONLY,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
kEndEntry
eARIASelected,
eARIACheckedMixed
},
{
"log",
@ -290,8 +261,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
ePoliteLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"marquee",
@ -300,8 +270,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eOffLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"math",
@ -310,8 +279,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"menu",
@ -321,8 +289,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction, // XXX: technically accessibles of menupopup role haven't
// any action, but menu can be open or close.
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"menubar",
@ -331,8 +298,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"menuitem",
@ -342,10 +308,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eClickAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
kEndEntry
eARIACheckedMixed
},
{
"menuitemcheckbox",
@ -354,10 +317,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eClickAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED},
kEndEntry
kNoReqStates,
eARIACheckableMixed
},
{
"menuitemradio",
@ -366,9 +327,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eClickAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
kEndEntry
kNoReqStates,
eARIACheckableBool
},
{
"option",
@ -378,12 +338,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eSelectAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
kEndEntry
eARIASelected,
eARIACheckedMixed
},
{
"presentation",
@ -392,8 +348,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"progressbar",
@ -402,8 +357,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eHasValueMinMax,
eNoAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_READONLY,
kEndEntry
nsIAccessibleStates::STATE_READONLY
},
{
"radio",
@ -412,9 +366,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eSelectAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED},
kEndEntry
kNoReqStates,
eARIACheckableBool
},
{
"radiogroup",
@ -423,8 +376,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"region",
@ -433,8 +385,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"row",
@ -444,9 +395,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
kEndEntry
eARIASelected
},
{
"rowheader",
@ -456,10 +405,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eSortAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIASelected,
eARIAReadonly
},
{
"section",
@ -468,8 +415,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"separator",
@ -478,8 +424,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"slider",
@ -489,8 +434,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIAReadonly
},
{
"spinbutton",
@ -500,8 +444,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIAReadonly
},
{
"status",
@ -510,8 +453,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
ePoliteLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"tab",
@ -520,8 +462,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eSwitchAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"tablist",
@ -530,8 +471,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
ePoliteLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"tabpanel",
@ -540,8 +480,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"textbox",
@ -551,12 +490,9 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eActivateAction,
eNoLiveAttr,
kNoReqStates,
// Manually map EXT_STATE_SINGLE_LINE and EXT_STATE_MULTI_LINE FROM aria-multiline
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
{&nsAccessibilityAtoms::aria_autocomplete, "list", nsIAccessibleStates::STATE_HASPOPUP},
{&nsAccessibilityAtoms::aria_autocomplete, "both", nsIAccessibleStates::STATE_HASPOPUP},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIAAutoComplete,
eARIAMultiline,
eARIAReadonlyOrEditable
},
{
"timer",
@ -565,8 +501,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eOffLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"toolbar",
@ -575,8 +510,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"tooltip",
@ -585,8 +519,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"tree",
@ -596,9 +529,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
eARIAReadonly,
eARIAMultiSelectable
},
{
"treegrid",
@ -608,9 +540,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
eARIAReadonly,
eARIAMultiSelectable
},
{
"treeitem",
@ -621,12 +552,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
// on states
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
kEndEntry
eARIASelected,
eARIACheckedMixed
}
};
@ -639,8 +566,7 @@ nsRoleMapEntry nsARIAMap::gLandmarkRoleMap = {
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
};
nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
@ -650,8 +576,89 @@ nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
};
nsStateMapEntry nsARIAMap::gWAIStateMap[] = {
// eARIANone
nsStateMapEntry(),
// eARIAAutoComplete
nsStateMapEntry(&nsAccessibilityAtoms::aria_autocomplete,
"inline", 0, nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION,
"list", nsIAccessibleStates::STATE_HASPOPUP, nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION,
"both", nsIAccessibleStates::STATE_HASPOPUP, nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION),
// eARIABusy
nsStateMapEntry(&nsAccessibilityAtoms::aria_busy,
"true", nsIAccessibleStates::STATE_BUSY, 0,
"error", nsIAccessibleStates::STATE_INVALID, 0),
// eARIACheckableBool
nsStateMapEntry(&nsAccessibilityAtoms::aria_checked, kBoolType,
nsIAccessibleStates::STATE_CHECKABLE,
nsIAccessibleStates::STATE_CHECKED, 0,
0, 0, PR_TRUE),
// eARIACheckableMixed
nsStateMapEntry(&nsAccessibilityAtoms::aria_checked, kMixedType,
nsIAccessibleStates::STATE_CHECKABLE,
nsIAccessibleStates::STATE_CHECKED, 0,
0, 0, PR_TRUE),
// eARIACheckedMixed
nsStateMapEntry(&nsAccessibilityAtoms::aria_checked, kMixedType,
nsIAccessibleStates::STATE_CHECKABLE,
nsIAccessibleStates::STATE_CHECKED, 0),
// eARIADisabled
nsStateMapEntry(&nsAccessibilityAtoms::aria_disabled, kBoolType, 0,
nsIAccessibleStates::STATE_UNAVAILABLE, 0),
// eARIAExpanded
nsStateMapEntry(&nsAccessibilityAtoms::aria_expanded, kBoolType, 0,
nsIAccessibleStates::STATE_EXPANDED, 0,
nsIAccessibleStates::STATE_COLLAPSED, 0),
// eARIAHasPopup
nsStateMapEntry(&nsAccessibilityAtoms::aria_haspopup, kBoolType, 0,
nsIAccessibleStates::STATE_HASPOPUP, 0),
// eARIAInvalid
nsStateMapEntry(&nsAccessibilityAtoms::aria_invalid, kBoolType, 0,
nsIAccessibleStates::STATE_INVALID, 0),
// eARIAMultiline
nsStateMapEntry(&nsAccessibilityAtoms::aria_multiline, kBoolType, 0,
0, nsIAccessibleStates::EXT_STATE_MULTI_LINE,
0, nsIAccessibleStates::EXT_STATE_SINGLE_LINE, PR_TRUE),
// eARIAMultiSelectable
nsStateMapEntry(&nsAccessibilityAtoms::aria_multiselectable, kBoolType, 0,
nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE, 0),
// eARIAPressed
nsStateMapEntry(&nsAccessibilityAtoms::aria_pressed, kMixedType,
nsIAccessibleStates::STATE_CHECKABLE,
nsIAccessibleStates::STATE_PRESSED, 0),
// eARIAReadonly
nsStateMapEntry(&nsAccessibilityAtoms::aria_readonly, kBoolType, 0,
nsIAccessibleStates::STATE_READONLY, 0),
// eARIAReadonlyOrEditable
nsStateMapEntry(&nsAccessibilityAtoms::aria_readonly, kBoolType, 0,
nsIAccessibleStates::STATE_READONLY, 0,
0, nsIAccessibleStates::EXT_STATE_EDITABLE, PR_TRUE),
// eARIARequired
nsStateMapEntry(&nsAccessibilityAtoms::aria_required, kBoolType, 0,
nsIAccessibleStates::STATE_REQUIRED, 0),
// eARIASelected
nsStateMapEntry(&nsAccessibilityAtoms::aria_selected, kBoolType,
nsIAccessibleStates::STATE_SELECTABLE,
nsIAccessibleStates::STATE_SELECTED, 0)
};
/**
@ -659,16 +666,14 @@ nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
* The following state rules are applied to any accessible element,
* whether there is an ARIA role or not:
*/
nsStateMapEntry nsARIAMap::gWAIUnivStateMap[] = {
{&nsAccessibilityAtoms::aria_required, kBoolState, nsIAccessibleStates::STATE_REQUIRED},
{&nsAccessibilityAtoms::aria_invalid, kBoolState, nsIAccessibleStates::STATE_INVALID},
{&nsAccessibilityAtoms::aria_haspopup, kBoolState, nsIAccessibleStates::STATE_HASPOPUP},
{&nsAccessibilityAtoms::aria_busy, "true", nsIAccessibleStates::STATE_BUSY},
{&nsAccessibilityAtoms::aria_busy, "error", nsIAccessibleStates::STATE_INVALID},
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
kEndEntry
eStateMapEntryID nsARIAMap::gWAIUnivStateMap[] = {
eARIARequired,
eARIAInvalid,
eARIAHasPopup,
eARIABusy,
eARIADisabled,
eARIAExpanded,
eARIANone
};
@ -709,3 +714,144 @@ nsAttributeCharacteristics nsARIAMap::gWAIUnivAttrMap[] = {
};
PRUint32 nsARIAMap::gWAIUnivAttrMapLength = NS_ARRAY_LENGTH(nsARIAMap::gWAIUnivAttrMap);
////////////////////////////////////////////////////////////////////////////////
// nsStateMapEntry
nsStateMapEntry:: nsStateMapEntry(nsIAtom **aAttrName, eStateValueType aType,
PRUint32 aPermanentState,
PRUint32 aTrueState, PRUint32 aTrueExtraState,
PRUint32 aFalseState, PRUint32 aFalseExtraState,
PRBool aDefinedIfAbsent) :
attributeName(aAttrName), isToken(PR_TRUE), permanentState(aPermanentState)
{
value1 = "false";
state1 = aFalseState;
extraState1 = aFalseExtraState;
if (aType == kMixedType) {
value2 = "mixed";
state2 = nsIAccessibleStates::STATE_MIXED;
extraState2 = 0;
}
defaultState = aTrueState;
defaultExtraState = aTrueExtraState;
definedIfAbsent = aDefinedIfAbsent;
}
nsStateMapEntry::nsStateMapEntry(nsIAtom **aAttrName,
const char *aValue1,
PRUint32 aState1, PRUint32 aExtraState1,
const char *aValue2,
PRUint32 aState2, PRUint32 aExtraState2,
const char *aValue3,
PRUint32 aState3, PRUint32 aExtraState3) :
attributeName(aAttrName), isToken(PR_FALSE), permanentState(0),
value1(aValue1), state1(aState1), extraState1(aExtraState1),
value2(aValue2), state2(aState2), extraState2(aExtraState2),
value3(aValue3), state3(aState3), extraState3(aExtraState3),
defaultState(0), defaultExtraState(0), definedIfAbsent(PR_FALSE)
{
}
PRBool
nsStateMapEntry::MapToStates(nsIContent *aContent,
PRUint32 *aState, PRUint32 *aExtraState,
eStateMapEntryID aStateMapEntryID)
{
// Return true if we should continue.
if (aStateMapEntryID == eARIANone)
return PR_FALSE;
const nsStateMapEntry& entry = nsARIAMap::gWAIStateMap[aStateMapEntryID];
if (entry.isToken) {
// If attribute is considered as defined when it's absent then let's act
// attribute value is "false" supposedly.
PRBool hasAttr = aContent->HasAttr(kNameSpaceID_None, *entry.attributeName);
if (entry.definedIfAbsent && !hasAttr) {
if (entry.permanentState)
*aState |= entry.permanentState;
if (entry.state1)
*aState |= entry.state1;
if (aExtraState && entry.extraState1)
*aExtraState |= entry.extraState1;
return PR_TRUE;
}
// We only have attribute state mappings for NMTOKEN (and boolean) based
// ARIA attributes. According to spec, a value of "undefined" is to be
// treated equivalent to "", or the absence of the attribute. We bail out
// for this case here.
// Note: If this method happens to be called with a non-token based
// attribute, for example: aria-label="" or aria-label="undefined", we will
// bail out and not explore a state mapping, which is safe.
if (!hasAttr ||
aContent->AttrValueIs(kNameSpaceID_None, *entry.attributeName,
nsAccessibilityAtoms::_empty, eCaseMatters) ||
aContent->AttrValueIs(kNameSpaceID_None, *entry.attributeName,
nsAccessibilityAtoms::_undefined, eCaseMatters)) {
if (entry.permanentState)
*aState &= ~entry.permanentState;
return PR_TRUE;
}
if (entry.permanentState)
*aState |= entry.permanentState;
}
nsAutoString attrValue;
if (!aContent->GetAttr(kNameSpaceID_None, *entry.attributeName, attrValue))
return PR_TRUE;
// Apply states for matched value. If no values was matched then apply default
// states.
PRBool applyDefaultStates = PR_TRUE;
if (entry.value1) {
if (attrValue.EqualsASCII(entry.value1)) {
applyDefaultStates = PR_FALSE;
if (entry.state1)
*aState |= entry.state1;
if (aExtraState && entry.extraState1)
*aExtraState |= entry.extraState1;
} else if (entry.value2) {
if (attrValue.EqualsASCII(entry.value2)) {
applyDefaultStates = PR_FALSE;
if (entry.state2)
*aState |= entry.state2;
if (aExtraState && entry.extraState2)
*aExtraState |= entry.extraState2;
} else if (entry.value3) {
if (attrValue.EqualsASCII(entry.value3)) {
applyDefaultStates = PR_FALSE;
if (entry.state3)
*aState |= entry.state3;
if (aExtraState && entry.extraState3)
*aExtraState |= entry.extraState3;
}
}
}
}
if (applyDefaultStates) {
if (entry.defaultState)
*aState |= entry.defaultState;
if (entry.defaultExtraState && aExtraState)
*aExtraState |= entry.defaultExtraState;
}
return PR_TRUE;
}

Просмотреть файл

@ -43,14 +43,35 @@
#include "prtypes.h"
#include "nsAccessibilityAtoms.h"
// Is nsIAccessible value supported for this role or not?
#include "nsIContent.h"
////////////////////////////////////////////////////////////////////////////////
// Value constants
/**
* Used to define if role requires to expose nsIAccessibleValue.
*/
enum EValueRule
{
/**
* nsIAccessibleValue isn't exposed.
*/
eNoValue,
eHasValueMinMax // Supports value, min and max from aria-valuenow, aria-valuemin and aria-valuemax
/**
* nsIAccessibleValue is implemented, supports value, min and max from
* aria-valuenow, aria-valuemin and aria-valuemax.
*/
eHasValueMinMax
};
// Should we expose action based on the ARIA role?
////////////////////////////////////////////////////////////////////////////////
// Action constants
/**
* Used to define if the role requires to expose action.
*/
enum EActionRule
{
eNoAction,
@ -65,6 +86,13 @@ enum EActionRule
eSwitchAction
};
////////////////////////////////////////////////////////////////////////////////
// Live region constants
/**
* Used to define if role exposes default value of aria-live attribute.
*/
enum ELiveAttrRule
{
eNoLiveAttr,
@ -72,11 +100,23 @@ enum ELiveAttrRule
ePoliteLiveAttr
};
// Role mapping rule
////////////////////////////////////////////////////////////////////////////////
// Role constants
/**
* ARIA role overrides role from native markup.
*/
const PRBool kUseMapRole = PR_TRUE;
/**
* ARIA role doesn't override the role from native markup.
*/
const PRBool kUseNativeRole = PR_FALSE;
// ARIA attribute characteristic masks, grow as needed
////////////////////////////////////////////////////////////////////////////////
// ARIA attribute characteristic masks
/**
* This mask indicates the attribute should not be exposed as an object
@ -92,29 +132,132 @@ const PRUint8 ATTR_BYPASSOBJ = 0x0001;
*/
const PRUint8 ATTR_VALTOKEN = 0x0010;
// Used for an nsStateMapEntry if a given state attribute supports "true" and "false"
#define kBoolState 0
// Used in nsRoleMapEntry.state if no nsIAccessibleStates are automatic for a given role
#define kNoReqStates 0
// For this name and value pair, what is the nsIAccessibleStates mapping.
// nsStateMapEntry.state
struct nsStateMapEntry
{
nsIAtom** attributeName; // nsnull indicates last entry in map
const char* attributeValue; // magic value of kBoolState (0) means supports "true" and "false"
PRUint32 state; // If match, this is the nsIAccessibleStates to map to
};
// Small footprint storage of persistent aria attribute characteristics
/**
* Small footprint storage of persistent aria attribute characteristics.
*/
struct nsAttributeCharacteristics
{
nsIAtom** attributeName;
const PRUint8 characteristics;
};
// For each ARIA role, this maps the nsIAccessible information
////////////////////////////////////////////////////////////////////////////////
// State map entry
/**
* Used in nsRoleMapEntry.state if no nsIAccessibleStates are automatic for
* a given role.
*/
#define kNoReqStates 0
enum eStateValueType
{
kBoolType,
kMixedType
};
/**
* ID for state map entry, used in nsRoleMapEntry.
*/
enum eStateMapEntryID
{
eARIANone,
eARIAAutoComplete,
eARIABusy,
eARIACheckableBool,
eARIACheckableMixed,
eARIACheckedMixed,
eARIADisabled,
eARIAExpanded,
eARIAHasPopup,
eARIAInvalid,
eARIAMultiline,
eARIAMultiSelectable,
eARIAPressed,
eARIAReadonly,
eARIAReadonlyOrEditable,
eARIARequired,
eARIASelected
};
class nsStateMapEntry
{
public:
/**
* Used to create stub.
*/
nsStateMapEntry() {}
/**
* Used for ARIA attributes having boolean or mixed values.
*/
nsStateMapEntry(nsIAtom **aAttrName, eStateValueType aType,
PRUint32 aPermanentState,
PRUint32 aTrueState, PRUint32 aTrueExtraState,
PRUint32 aFalseState = 0, PRUint32 aFalseExtraState = 0,
PRBool aDefinedIfAbsent = PR_FALSE);
/**
* Used for ARIA attributes having enumerated values.
*/
nsStateMapEntry(nsIAtom **aAttrName,
const char *aValue1, PRUint32 aState1, PRUint32 aExtraState1,
const char *aValue2, PRUint32 aState2, PRUint32 aExtraState2,
const char *aValue3 = 0, PRUint32 aState3 = 0,
PRUint32 aExtraState3 = 0);
/**
* Maps ARIA state map pointed by state map entry ID to accessible states.
*
* @param aContent [in] node of the accessible
* @param aState [in/out] accessible states
* @param aExtraState [in/out] accessible extra states
* @param aStateMapEntryID [in] state map entry ID
* @return true if state map entry ID is valid
*/
static PRBool MapToStates(nsIContent *aContent,
PRUint32 *aState, PRUint32 *aExtraState,
eStateMapEntryID aStateMapEntryID);
private:
// ARIA attribute name
nsIAtom** attributeName;
// Indicates if attribute is token (can be undefined)
PRBool isToken;
// State applied always if attribute is defined
PRUint32 permanentState;
// States applied if attribute value is matched to the stored value
const char* value1;
PRUint32 state1;
PRUint32 extraState1;
const char* value2;
PRUint32 state2;
PRUint32 extraState2;
const char* value3;
PRUint32 state3;
PRUint32 extraState3;
// States applied if no stored values above are matched
PRUint32 defaultState;
PRUint32 defaultExtraState;
// Permanent and false states are applied if attribute is absent
PRBool definedIfAbsent;
};
////////////////////////////////////////////////////////////////////////////////
// Role map entry
/**
* For each ARIA role, this maps the nsIAccessible information.
*/
struct nsRoleMapEntry
{
// ARIA role: string representation such as "button"
@ -144,16 +287,15 @@ struct nsRoleMapEntry
// Currently you cannot have unlimited mappings, because
// a variable sized array would not allow the use of
// C++'s struct initialization feature.
nsStateMapEntry attributeMap1;
nsStateMapEntry attributeMap2;
nsStateMapEntry attributeMap3;
nsStateMapEntry attributeMap4;
nsStateMapEntry attributeMap5;
nsStateMapEntry attributeMap6;
nsStateMapEntry attributeMap7;
nsStateMapEntry attributeMap8;
eStateMapEntryID attributeMap1;
eStateMapEntryID attributeMap2;
eStateMapEntryID attributeMap3;
};
////////////////////////////////////////////////////////////////////////////////
// ARIA map
/**
* These are currently initialized (hardcoded) in nsARIAMap.cpp,
* and provide the mappings for WAI-ARIA roles and properties using the
@ -180,11 +322,16 @@ struct nsARIAMap
*/
static nsRoleMapEntry gEmptyRoleMap;
/**
* State map of ARIA state attributes.
*/
static nsStateMapEntry nsARIAMap::gWAIStateMap[];
/**
* State map of ARIA states applied to any accessible not depending on
* the role.
*/
static nsStateMapEntry gWAIUnivStateMap[];
static eStateMapEntryID gWAIUnivStateMap[];
/**
* Map of attribute to attribute characteristics.

Просмотреть файл

@ -1891,45 +1891,6 @@ nsAccessible::GroupPosition(PRInt32 *aGroupLevel,
return NS_OK;
}
PRBool nsAccessible::MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut,
nsStateMapEntry *aStateMapEntry)
{
// Return true if we should continue
if (!aStateMapEntry->attributeName) {
return PR_FALSE; // Stop looking -- no more states
}
// We only have attribute state mappings for NMTOKEN (and boolean) based
// ARIA attributes. According to spec, a value of "undefined" is to be
// treated equivalent to "", or the absence of the attribute. We bail out
// for this case here.
// Note: If this method happens to be called with a non-token based
// attribute, for example: aria-label="" or aria-label="undefined", we will
// bail out and not explore a state mapping, which is safe.
if (!nsAccUtils::HasDefinedARIAToken(aContent, *aStateMapEntry->attributeName)) {
return PR_TRUE;
}
nsAutoString attribValue;
if (aContent->GetAttr(kNameSpaceID_None, *aStateMapEntry->attributeName, attribValue)) {
if (aStateMapEntry->attributeValue == kBoolState) {
// No attribute value map specified in state map entry indicates state cleared
if (attribValue.EqualsLiteral("false") ||
attribValue.EqualsLiteral("mixed")) {
*aStateInOut &= ~aStateMapEntry->state;
}
else {
*aStateInOut |= aStateMapEntry->state;
}
}
else if (NS_ConvertUTF16toUTF8(attribValue).Equals(aStateMapEntry->attributeValue)) {
*aStateInOut |= aStateMapEntry->state;
}
}
return PR_TRUE;
}
NS_IMETHODIMP
nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
{
@ -1947,7 +1908,7 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
NS_ENSURE_A11Y_SUCCESS(rv, rv);
// Apply ARIA states to be sure accessible states will be overriden.
GetARIAState(aState);
GetARIAState(aState, aExtraState);
if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_PAGETAB) {
if (*aState & nsIAccessibleStates::STATE_FOCUSED) {
@ -2019,33 +1980,6 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
rv = GetRole(&role);
NS_ENSURE_SUCCESS(rv, rv);
if (role == nsIAccessibleRole::ROLE_ENTRY ||
role == nsIAccessibleRole::ROLE_COMBOBOX) {
nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
NS_ENSURE_STATE(content);
nsAutoString autocomplete;
if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_autocomplete, autocomplete) &&
(autocomplete.EqualsIgnoreCase("inline") ||
autocomplete.EqualsIgnoreCase("list") ||
autocomplete.EqualsIgnoreCase("both"))) {
*aExtraState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
}
// XXX We can remove this hack once we support RDF-based role & state maps
if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_ENTRY) {
PRBool isMultiLine = content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::aria_multiline,
nsAccessibilityAtoms::_true, eCaseMatters);
*aExtraState |= isMultiLine ? nsIAccessibleStates::EXT_STATE_MULTI_LINE :
nsIAccessibleStates::EXT_STATE_SINGLE_LINE;
if (0 == (*aState & nsIAccessibleStates::STATE_READONLY))
*aExtraState |= nsIAccessibleStates::EXT_STATE_EDITABLE; // Not readonly
else // We're readonly: make sure editable state wasn't set by impl class
*aExtraState &= ~nsIAccessibleStates::EXT_STATE_EDITABLE;
}
}
// For some reasons DOM node may have not a frame. We tract such accessibles
// as invisible.
nsIFrame *frame = GetFrame();
@ -2077,7 +2011,7 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
}
nsresult
nsAccessible::GetARIAState(PRUint32 *aState)
nsAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
{
// Test for universal states first
nsIContent *content = nsCoreUtils::GetRoleContent(mDOMNode);
@ -2086,7 +2020,8 @@ nsAccessible::GetARIAState(PRUint32 *aState)
}
PRUint32 index = 0;
while (MappedAttrState(content, aState, &nsARIAMap::gWAIUnivStateMap[index])) {
while (nsStateMapEntry::MapToStates(content, aState, aExtraState,
nsARIAMap::gWAIUnivStateMap[index])) {
++ index;
}
@ -2126,14 +2061,12 @@ nsAccessible::GetARIAState(PRUint32 *aState)
// Note: the readonly bitflag will be overridden later if content is editable
*aState |= mRoleMapEntry->state;
if (MappedAttrState(content, aState, &mRoleMapEntry->attributeMap1) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap2) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap3) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap4) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap5) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap6) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap7)) {
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap8);
if (nsStateMapEntry::MapToStates(content, aState, aExtraState,
mRoleMapEntry->attributeMap1) &&
nsStateMapEntry::MapToStates(content, aState, aExtraState,
mRoleMapEntry->attributeMap2)) {
nsStateMapEntry::MapToStates(content, aState, aExtraState,
mRoleMapEntry->attributeMap3);
}
return NS_OK;

Просмотреть файл

@ -148,8 +148,9 @@ public:
* method.
*
* @param [in/out] where to fill the states into.
* @param [in/out] where to fill the extra states into
*/
virtual nsresult GetARIAState(PRUint32 *aState);
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
/**
* Returns the accessible name provided by native markup. It doesn't take
@ -279,7 +280,6 @@ public:
}
protected:
PRBool MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut, nsStateMapEntry *aStateMapEntry);
virtual nsIFrame* GetBoundsFrame();
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
PRBool IsVisible(PRBool *aIsOffscreen);

Просмотреть файл

@ -340,16 +340,16 @@ nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
}
nsresult
nsDocAccessible::GetARIAState(PRUint32 *aState)
nsDocAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
{
// Combine with states from outer doc
NS_ENSURE_ARG_POINTER(aState);
nsresult rv = nsAccessible::GetARIAState(aState);
nsresult rv = nsAccessible::GetARIAState(aState, aExtraState);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsAccessible> parent = nsAccUtils::QueryAccessible(mParent);
if (parent) // Allow iframe/frame etc. to have final state override via ARIA
return parent->GetARIAState(aState);
return parent->GetARIAState(aState, aExtraState);
return rv;
}

Просмотреть файл

@ -109,7 +109,7 @@ public:
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsresult GetARIAState(PRUint32 *aState);
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
// nsIAccessibleText

Просмотреть файл

@ -872,6 +872,18 @@ already_AddRefed<nsIDOMNode> nsXULTextFieldAccessible::GetInputField()
return inputField;
}
nsresult
nsXULTextFieldAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
{
nsresult rv = nsHyperTextAccessibleWrap::GetARIAState(aState, aExtraState);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
nsStateMapEntry::MapToStates(content, aState, aExtraState, eARIAAutoComplete);
return NS_OK;
}
nsresult
nsXULTextFieldAccessible::GetStateInternal(PRUint32 *aState,
PRUint32 *aExtraState)

Просмотреть файл

@ -204,6 +204,7 @@ public:
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
// nsAccessible
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual PRBool GetAllowsAnonChildAccessibles();

Просмотреть файл

@ -49,6 +49,7 @@ const nsIPropertyElement = Components.interfaces.nsIPropertyElement;
////////////////////////////////////////////////////////////////////////////////
// States
const STATE_BUSY = nsIAccessibleStates.STATE_BUSY;
const STATE_CHECKED = nsIAccessibleStates.STATE_CHECKED;
const STATE_CHECKABLE = nsIAccessibleStates.STATE_CHECKABLE;
const STATE_COLLAPSED = nsIAccessibleStates.STATE_COLLAPSED;
@ -57,12 +58,14 @@ const STATE_EXTSELECTABLE = nsIAccessibleStates.STATE_EXTSELECTABLE;
const STATE_FOCUSABLE = nsIAccessibleStates.STATE_FOCUSABLE;
const STATE_FOCUSED = nsIAccessibleStates.STATE_FOCUSED;
const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP;
const STATE_INVALID = nsIAccessibleStates.STATE_INVALID;
const STATE_LINKED = nsIAccessibleStates.STATE_LINKED;
const STATE_MIXED = nsIAccessibleStates.STATE_MIXED;
const STATE_MULTISELECTABLE = nsIAccessibleStates.STATE_MULTISELECTABLE;
const STATE_OFFSCREEN = nsIAccessibleStates.STATE_OFFSCREEN;
const STATE_PRESSED = nsIAccessibleStates.STATE_PRESSED;
const STATE_READONLY = nsIAccessibleStates.STATE_READONLY;
const STATE_REQUIRED = nsIAccessibleStates.STATE_REQUIRED;
const STATE_SELECTABLE = nsIAccessibleStates.STATE_SELECTABLE;
const STATE_SELECTED = nsIAccessibleStates.STATE_SELECTED;
const STATE_TRAVERSED = nsIAccessibleStates.STATE_TRAVERSED;
@ -71,9 +74,8 @@ const STATE_UNAVAILABLE = nsIAccessibleStates.STATE_UNAVAILABLE;
const EXT_STATE_EDITABLE = nsIAccessibleStates.EXT_STATE_EDITABLE;
const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE;
const EXT_STATE_HORIZONTAL = nsIAccessibleStates.EXT_STATE_HORIZONTAL;
const EXT_STATE_INVALID = nsIAccessibleStates.STATE_INVALID;
const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
const EXT_STATE_REQUIRED = nsIAccessibleStates.STATE_REQUIRED;
const EXT_STATE_SINGLE_LINE = nsIAccessibleStates.EXT_STATE_SINGLE_LINE;
const EXT_STATE_SUPPORTS_AUTOCOMPLETION =
nsIAccessibleStates.EXT_STATE_SUPPORTS_AUTOCOMPLETION;
@ -108,7 +110,7 @@ function addA11yLoadEvent(aFunc)
var accDoc = getAccessible(document);
var state = {};
accDoc.getState(state, {});
if (state.value & nsIAccessibleStates.STATE_BUSY)
if (state.value & STATE_BUSY)
return waitForDocLoad();
aFunc.call();
@ -326,9 +328,12 @@ function statesToString(aStates, aExtraStates)
var list = gAccRetrieval.getStringStates(aStates, aExtraStates);
var str = "";
for (var index = 0; index < list.length; index++)
for (var index = 0; index < list.length - 1; index++)
str += list.item(index) + ", ";
if (list.length != 0)
str += list.item(index)
return str;
}

Просмотреть файл

@ -1,3 +1,11 @@
////////////////////////////////////////////////////////////////////////////////
// Helper functions for accessible states testing.
//
// requires:
// common.js
//
////////////////////////////////////////////////////////////////////////////////
/**
* Tests the states and extra states of the given accessible.
* Also tests for unwanted states and extra states.
@ -17,55 +25,73 @@ function testStates(aAccOrElmOrID, aState, aExtraState, aAbsentState,
var id = prettyName(aAccOrElmOrID);
is(state & aState, aState,
"wrong state bits for " + id + "!");
// Primary test.
isState(state & aState, aState, false,
"wrong state bits for " + id + "!");
if (aExtraState)
is(extraState & aExtraState, aExtraState,
"wrong extra state bits for " + id + "!");
isState(extraState & aExtraState, aExtraState, true,
"wrong extra state bits for " + id + "!");
if (aAbsentState)
is(state & aAbsentState, 0,
"state bits should not be present in ID " + id + "!");
isState(state & aAbsentState, 0, false,
"state bits should not be present in ID " + id + "!");
if (aAbsentExtraState)
is(extraState & aAbsentExtraState, 0,
"extraState bits should not be present in ID " + id + "!");
isState(extraState & aAbsentExtraState, 0, true,
"extraState bits should not be present in ID " + id + "!");
// Additional test.
// readonly/editable
if (state & STATE_READONLY)
is(extraState & EXT_STATE_EDITABLE, 0,
"Read-only " + id + " cannot be editable!");
isState(extraState & EXT_STATE_EDITABLE, 0, true,
"Read-only " + id + " cannot be editable!");
if (extraState & EXT_STATE_EDITABLE)
is(state & STATE_READONLY, 0,
"Editable " + id + " cannot be readonly!");
isState(state & STATE_READONLY, 0, true,
"Editable " + id + " cannot be readonly!");
// multiline/singleline
if (extraState & EXT_STATE_MULTI_LINE)
isState(extraState & EXT_STATE_SINGLE_LINE, 0, true,
"Multiline " + id + " cannot be singleline!");
if (extraState & EXT_STATE_SINGLE_LINE)
isState(extraState & EXT_STATE_MULTI_LINE, 0, true,
"Singleline " + id + " cannot be multiline!");
// expanded/collapsed/expandable
if (state & STATE_COLLAPSED || state & STATE_EXPANDED)
is(extraState & EXT_STATE_EXPANDABLE, EXT_STATE_EXPANDABLE,
"Collapsed or expanded " + id + " should be expandable!");
isState(extraState & EXT_STATE_EXPANDABLE, EXT_STATE_EXPANDABLE, true,
"Collapsed or expanded " + id + " should be expandable!");
if (state & STATE_COLLAPSED)
is(state & STATE_EXPANDED, 0,
"Collapsed " + id + " cannot be expanded!");
isState(state & STATE_EXPANDED, 0, false,
"Collapsed " + id + " cannot be expanded!");
if (state & STATE_EXPANDED)
is(state & STATE_COLLAPSED, 0,
"Expanded " + id + " cannot be collapsed!");
isState(state & STATE_COLLAPSED, 0, false,
"Expanded " + id + " cannot be collapsed!");
// checked/mixed/checkable
if (state & STATE_CHECKED || state & STATE_MIXED)
is(state & STATE_CHECKABLE, STATE_CHECKABLE,
"Checked or mixed element must be checkable!");
isState(state & STATE_CHECKABLE, STATE_CHECKABLE, false,
"Checked or mixed element must be checkable!");
if (state & STATE_CHECKED)
is(state & STATE_MIXED, 0, "Checked element cannot be state mixed!");
isState(state & STATE_MIXED, 0, false,
"Checked element cannot be state mixed!");
if (state & STATE_MIXED)
is(state & STATE_CHECKED, 0, "Mixed element cannot be state checked!");
isState(state & STATE_CHECKED, 0, false,
"Mixed element cannot be state checked!");
// unavailable
if ((state & STATE_UNAVAILABLE)
&& (getRole(aAccOrElmOrID) != ROLE_GROUPING))
is(state & STATE_FOCUSABLE, STATE_FOCUSABLE,
"Disabled " + id + " must be focusable!");
isState(state & STATE_FOCUSABLE, STATE_FOCUSABLE, false,
"Disabled " + id + " must be focusable!");
}
/**
@ -122,3 +148,31 @@ function getStates(aAccOrElmOrID)
return [state.value, extraState.value];
}
////////////////////////////////////////////////////////////////////////////////
// Private implementation details
/**
* Analogy of SimpleTest.is function used to compare states.
*/
function isState(aState1, aState2, aIsExtraStates, aMsg)
{
if (aState1 == aState2) {
ok(true, aMsg);
return;
}
var got = "0";
if (aState1) {
got = statesToString(aIsExtraStates ? 0 : aState1,
aIsExtraStates ? aState1 : 0);
}
var expected = "0";
if (aState2) {
expected = statesToString(aIsExtraStates ? 0 : aState2,
aIsExtraStates ? aState2 : 0);
}
ok(false, aMsg + "got '" + got + "', expected '" + expected + "'");
}

Просмотреть файл

@ -22,25 +22,25 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452388
<script type="application/javascript">
function doTest()
{
// test (treeitem) selectable and selected states
testStates("treeitem_selected_true", (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_false", STATE_SELECTABLE, 0, STATE_SELECTED);
testStates("treeitem_selected_empty", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_undefined", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_absent", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
// test aria-pressed state mapping to roles PUSHBUTTON vs TOGGLEBUTTON
testRole("button_pressed_true", ROLE_TOGGLE_BUTTON);
testRole("button_pressed_false", ROLE_TOGGLE_BUTTON);
testRole("button_pressed_empty", ROLE_PUSHBUTTON);
testRole("button_pressed_undefined", ROLE_PUSHBUTTON);
testRole("button_pressed_absent", ROLE_PUSHBUTTON);
// test (menuitem) checkable and checked states
testStates("menuitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("menuitem_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_absent", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
// test button aria-pressed states
testStates("button_pressed_true", STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_false", STATE_CHECKABLE, 0, STATE_PRESSED);
testStates("button_pressed_empty", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_undefined", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_absent", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
// test (checkbox) checkable and checked states
testStates("checkbox_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("checkbox_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("checkbox_checked_empty", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("checkbox_checked_undefined", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("checkbox_checked_empty", 0 , 0, STATE_CHECKABLE | STATE_CHECKED);
testStates("checkbox_checked_undefined", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
testStates("checkbox_checked_absent", STATE_CHECKABLE, 0, STATE_CHECKED);
// test native checkbox checked state and aria-checked state (if conflict, native wins)
@ -49,27 +49,124 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452388
testStates("native_checkbox_nativechecked_ariaempty", (STATE_CHECKABLE | STATE_CHECKED));
testStates("native_checkbox_nativechecked_ariaundefined", (STATE_CHECKABLE | STATE_CHECKED));
testStates("native_checkbox_nativechecked_ariaabsent", (STATE_CHECKABLE | STATE_CHECKED));
testStates("native_checkbox_nativeunchecked_ariatrue", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("native_checkbox_nativeunchecked_ariafalse", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("native_checkbox_nativeunchecked_ariaempty", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("native_checkbox_nativeunchecked_ariaundefined", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("native_checkbox_nativeunchecked_ariaabsent", STATE_CHECKABLE, 0, STATE_CHECKED);
// test button aria-pressed states
testStates("button_pressed_true", STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_false", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_empty", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_undefined", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_absent", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
// test aria-pressed state mapping to roles PUSHBUTTON vs TOGGLEBUTTON
testRole("button_pressed_true", ROLE_TOGGLE_BUTTON);
testRole("button_pressed_false", ROLE_TOGGLE_BUTTON);
testRole("button_pressed_empty", ROLE_PUSHBUTTON);
testRole("button_pressed_undefined", ROLE_PUSHBUTTON);
testRole("button_pressed_absent", ROLE_PUSHBUTTON);
// test (checkbox) readonly states
testStates("checkbox_readonly_true", STATE_READONLY);
testStates("checkbox_readonly_false", 0, 0, STATE_READONLY);
testStates("checkbox_readonly_empty", 0, 0, STATE_READONLY);
testStates("checkbox_readonly_undefined", 0, 0, STATE_READONLY);
testStates("checkbox_readonly_absent", 0, 0, STATE_READONLY);
// test (checkbox) required states
testStates("checkbox_required_true", STATE_REQUIRED);
testStates("checkbox_required_false", 0, 0, STATE_REQUIRED);
testStates("checkbox_required_empty", 0, 0, STATE_REQUIRED);
testStates("checkbox_required_undefined", 0, 0, STATE_REQUIRED);
testStates("checkbox_required_absent", 0, 0, STATE_REQUIRED);
// test (checkbox) invalid states
testStates("checkbox_invalid_true", STATE_INVALID);
testStates("checkbox_invalid_false", 0, 0, STATE_INVALID);
testStates("checkbox_invalid_empty", 0, 0, STATE_INVALID);
testStates("checkbox_invalid_undefined", 0, 0, STATE_INVALID);
testStates("checkbox_invalid_absent", 0, 0, STATE_INVALID);
// test (checkbox) disabled states
testStates("checkbox_disabled_true", STATE_UNAVAILABLE);
testStates("checkbox_disabled_false", 0, 0, STATE_UNAVAILABLE);
testStates("checkbox_disabled_empty", 0, 0, STATE_UNAVAILABLE);
testStates("checkbox_disabled_undefined", 0, 0, STATE_UNAVAILABLE);
testStates("checkbox_disabled_absent", 0, 0, STATE_UNAVAILABLE);
// test (listbox) multiselectable states
testStates("listbox_multiselectable_true", STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
testStates("listbox_multiselectable_false", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
testStates("listbox_multiselectable_empty", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
testStates("listbox_multiselectable_undefined", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
testStates("listbox_multiselectable_absent", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
// test (listitem) checkable and checked states
testStates("listitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("listitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("listitem_checked_empty", 0 , 0, STATE_CHECKABLE | STATE_CHECKED);
testStates("listitem_checked_undefined", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
testStates("listitem_checked_absent", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
// test (menuitem) checkable and checked states
testStates("menuitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("menuitem_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_absent", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
// test (menuitemradio) checkable and checked states
testStates("menuitemradio_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitemradio_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("menuitemradio_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitemradio_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitemradio_checked_absent", STATE_CHECKABLE, 0, STATE_CHECKED);
// test (radio) checkable and checked states
testStates("radio_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("radio_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("radio_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("radio_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("radio_checked_absent", STATE_CHECKABLE, 0, STATE_CHECKED);
// test (textbox) multiline states
testStates("textbox_multiline_true", 0, EXT_STATE_MULTI_LINE);
testStates("textbox_multiline_false", 0, EXT_STATE_SINGLE_LINE);
testStates("textbox_multiline_empty", 0, 0, 0, EXT_STATE_SINGLE_LINE | EXT_STATE_MULTI_LINE);
testStates("textbox_multiline_undefined", 0, 0, 0, EXT_STATE_SINGLE_LINE | EXT_STATE_MULTI_LINE);
testStates("textbox_multiline_absent", 0, EXT_STATE_SINGLE_LINE);
// test (textbox) readonly states
testStates("textbox_readonly_true", STATE_READONLY);
testStates("textbox_readonly_false", 0, EXT_STATE_EDITABLE, STATE_READONLY);
testStates("textbox_readonly_empty", 0, 0, STATE_READONLY, EXT_STATE_EDITABLE);
testStates("textbox_readonly_undefined", 0, 0, STATE_READONLY, EXT_STATE_EDITABLE);
testStates("textbox_readonly_absent", 0, EXT_STATE_EDITABLE, STATE_READONLY);
// test native textbox readonly state and aria-readonly state (if conflict, native wins)
testStates("native_textbox_nativereadonly_ariatrue", STATE_READONLY);
testStates("native_textbox_nativereadonly_ariafalse", STATE_READONLY);
testStates("native_textbox_nativereadonly_ariaempty", STATE_READONLY);
testStates("native_textbox_nativereadonly_ariaundefined", STATE_READONLY);
testStates("native_textbox_nativereadonly_ariaabsent", STATE_READONLY);
testStates("native_textbox_nativeeditable_ariatrue", 0, 0, STATE_READONLY);
testStates("native_textbox_nativeeditable_ariafalse", 0, 0, STATE_READONLY);
testStates("native_textbox_nativeeditable_ariaempty", 0, 0, STATE_READONLY);
testStates("native_textbox_nativeeditable_ariaundefined", 0, 0, STATE_READONLY);
testStates("native_textbox_nativeeditable_ariaabsent", 0, 0, STATE_READONLY);
// test (treeitem) selectable and selected states
testStates("treeitem_selected_true", (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_false", STATE_SELECTABLE, 0, STATE_SELECTED);
testStates("treeitem_selected_empty", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_undefined", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_absent", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
// test (treeitem) haspopup states
testStates("treeitem_haspopup_true", STATE_HASPOPUP);
testStates("treeitem_haspopup_false", 0, 0, STATE_HASPOPUP);
testStates("treeitem_haspopup_empty", 0, 0, STATE_HASPOPUP);
testStates("treeitem_haspopup_undefined", 0, 0, STATE_HASPOPUP);
testStates("treeitem_haspopup_absent", 0, 0, STATE_HASPOPUP);
// test (treeitem) expandable and expanded/collapsed states
testStates("treeitem_expanded_true", STATE_EXPANDED, EXT_STATE_EXPANDABLE);
testStates("treeitem_expanded_false", STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
testStates("treeitem_expanded_empty", 0, 0, STATE_EXPANDED | STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
testStates("treeitem_expanded_undefined", 0, 0, STATE_EXPANDED | STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
testStates("treeitem_expanded_absent", 0, 0, STATE_EXPANDED | STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
SimpleTest.finish();
}
@ -79,48 +176,151 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452388
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=452388">Mozilla Bug 452388</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=452388">
Mozilla Bug 452388
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=499653"
title="Unify ARIA state attributes mapping rules">
Mozilla Bug 499653
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="treeitem_selected_true" role="treeitem" aria-selected="true">This treeitem has aria-selected="true" and should get STATE_SELECTABLE. It should also get STATE_SELECTED.</div>
<div id="treeitem_selected_false" role="treeitem" aria-selected="false">This treeitem has aria-selected="false" and should get STATE_SELECTABLE.</div>
<div id="treeitem_selected_empty" role="treeitem" aria-selected="">This treeitem has aria-selected="" and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="treeitem_selected_undefined" role="treeitem" aria-selected="undefined">This treeitem has aria-selected="undefined" and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="treeitem_selected_absent" role="treeitem">This treeitem has <emph>no</emph> aria-selected attribute and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="menuitem_checked_true" role="menuitem" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
<div id="menuitem_checked_false" role="menuitem" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
<div id="menuitem_checked_empty" role="menuitem" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitem_checked_undefined" role="menuitem" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitem_checked_absent" role="menuitem">This menuitem has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="button_pressed_true" role="button" aria-pressed="true">This button has aria-pressed="true" and should get ROLE_TOGGLE_BUTTON. It should also get STATE_PRESSED.</div>
<div id="button_pressed_false" role="button" aria-pressed="false">This button has aria-pressed="false" and should get ROLE_TOGGLE_BUTTON.</div>
<div id="button_pressed_empty" role="button" aria-pressed="">This button has aria-pressed="" and should <emph>not</emph> get ROLE_BUTTON.</div>
<div id="button_pressed_undefined" role="button" aria-pressed="undefined">This button has aria-pressed="undefined" and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
<div id="button_pressed_absent" role="button">This button has <emph>no</emph> aria-pressed attribute and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
<div id="checkbox_checked_true" role="checkbox" aria-checked="true">This checkbox has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
<div id="checkbox_checked_false" role="checkbox" aria-checked="false">This checkbox has aria-checked="false" and should get STATE_CHECKABLE.</div>
<div id="checkbox_checked_empty" role="checkbox" aria-checked="">This checkbox has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="checkbox_checked_undefined" role="checkbox" aria-checked="undefined">This checkbox has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="checkbox_checked_absent" role="checkbox">This checkbox has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="checkbox_checked_absent" role="checkbox">This checkbox has <emph>no</emph> aria-checked attribute and should get STATE_CHECKABLE.</div>
<form action="">
<input id="native_checkbox_nativechecked_ariatrue" type="checkbox" checked="checked" aria-checked="true"/>
<input id="native_checkbox_nativechecked_ariafalse" type="checkbox" checked="checked" aria-checked="false"/>
<input id="native_checkbox_nativechecked_ariaempty" type="checkbox" checked="checked" aria-checked=""/>
<input id="native_checkbox_nativechecked_ariaundefined" type="checkbox" checked="checked" aria-checked="undefined"/>
<input id="native_checkbox_nativechecked_ariaabsent" type="checkbox" checked="checked" aria-checked="false"/>
<input id="native_checkbox_nativechecked_ariaabsent" type="checkbox" checked="checked"/>
<input id="native_checkbox_nativeunchecked_ariatrue" type="checkbox" aria-checked="true"/>
<input id="native_checkbox_nativeunchecked_ariafalse" type="checkbox" aria-checked="false"/>
<input id="native_checkbox_nativeunchecked_ariaempty" type="checkbox" aria-checked=""/>
<input id="native_checkbox_nativeunchecked_ariaundefined" type="checkbox" aria-checked="undefined"/>
<input id="native_checkbox_nativeunchecked_ariaabsent" type="checkbox" aria-checked="false"/>
<input id="native_checkbox_nativeunchecked_ariaabsent" type="checkbox"/>
</form>
<div id="button_pressed_true" role="button" aria-pressed="true">This button has aria-pressed="true" and should get ROLE_TOGGLE_BUTTON. It should also get STATE_PRESSED.</div>
<div id="button_pressed_false" role="button" aria-pressed="false">This button has aria-pressed="false" and should get ROLE_TOGGLE_BUTTON.</div>
<div id="button_pressed_empty" role="button" aria-pressed="">This button has aria-pressed="" and should <emph>not</emph> get ROLE_BUTTON.</div>
<div id="button_pressed_undefined" role="button" aria-pressed="undefined">This button has aria-pressed="undefined" and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
<div id="button_pressed_absent" role="button">This button has <emph>no</emph> aria-pressed attribute and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
<div id="checkbox_readonly_true" role="checkbox" aria-readonly="true">This checkbox has aria-readonly="true" and should get STATE_READONLY.</div>
<div id="checkbox_readonly_false" role="checkbox" aria-readonly="false">This checkbox has aria-readonly="false" and should <emph>not</emph> get STATE_READONLY.</div>
<div id="checkbox_readonly_empty" role="checkbox" aria-readonly="">This checkbox has aria-readonly="" and should <emph>not</emph> get STATE_READONLY.</div>
<div id="checkbox_readonly_undefined" role="checkbox" aria-readonly="undefined">This checkbox has aria-readonly="undefined" and should <emph>not</emph> get STATE_READONLY.</div>
<div id="checkbox_readonly_absent" role="checkbox">This checkbox has <emph>no</emph> aria-readonly attribute and should <emph>not</emph> get STATE_READONLY.</div>
<div id="checkbox_required_true" role="checkbox" aria-required="true">This checkbox has aria-required="true" and should get STATE_REQUIRED.</div>
<div id="checkbox_required_false" role="checkbox" aria-required="false">This checkbox has aria-required="false" and should <emph>not</emph> get STATE_REQUIRED.</div>
<div id="checkbox_required_empty" role="checkbox" aria-required="">This checkbox has aria-required="" and should <emph>not</emph> get STATE_REQUIRED.</div>
<div id="checkbox_required_undefined" role="checkbox" aria-required="undefined">This checkbox has aria-required="undefined" and should <emph>not</emph> get STATE_REQUIRED.</div>
<div id="checkbox_required_absent" role="checkbox">This checkbox has <emph>no</emph> aria-required attribute and should <emph>not</emph> get STATE_REQUIRED.</div>
<div id="checkbox_invalid_true" role="checkbox" aria-invalid="true">This checkbox has aria-invalid="true" and should get STATE_INVALID.</div>
<div id="checkbox_invalid_false" role="checkbox" aria-invalid="false">This checkbox has aria-invalid="false" and should <emph>not</emph> get STATE_INVALID.</div>
<div id="checkbox_invalid_empty" role="checkbox" aria-invalid="">This checkbox has aria-invalid="" and should <emph>not</emph> get STATE_INVALID.</div>
<div id="checkbox_invalid_undefined" role="checkbox" aria-invalid="undefined">This checkbox has aria-invalid="undefined" and should <emph>not</emph> get STATE_INVALID.</div>
<div id="checkbox_invalid_absent" role="checkbox">This checkbox has <emph>no</emph> aria-invalid attribute and should <emph>not</emph> get STATE_INVALID.</div>
<div id="checkbox_disabled_true" role="checkbox" aria-disabled="true" tabindex="0">This checkbox has aria-disabled="true" and should get STATE_DISABLED.</div>
<div id="checkbox_disabled_false" role="checkbox" aria-disabled="false">This checkbox has aria-disabled="false" and should <emph>not</emph> get STATE_DISABLED.</div>
<div id="checkbox_disabled_empty" role="checkbox" aria-disabled="">This checkbox has aria-disabled="" and should <emph>not</emph> get STATE_DISABLED.</div>
<div id="checkbox_disabled_undefined" role="checkbox" aria-disabled="undefined">This checkbox has aria-disabled="undefined" and should <emph>not</emph> get STATE_DISABLED.</div>
<div id="checkbox_disabled_absent" role="checkbox">This checkbox has <emph>no</emph> aria-disabled attribute and should <emph>not</emph> get STATE_DISABLED.</div>
<div id="listbox_multiselectable_true" role="listbox" aria-multiselectable="true">
<div id="listitem_checked_true" role="listitem" aria-checked="true">item</div>
</div>
<div id="listbox_multiselectable_false" role="listbox" aria-multiselectable="false">
<div id="listitem_checked_false" role="listitem" aria-checked="false">item</div>
</div>
<div id="listbox_multiselectable_empty" role="listbox" aria-multiselectable="">
<div id="listitem_checked_empty" role="listitem" aria-checked="">item</div>
</div>
<div id="listbox_multiselectable_undefined" role="listbox" aria-multiselectable="undefined">
<div id="listitem_checked_undefined" role="listitem" aria-checked="undefined">item</div>
</div>
<div id="listbox_multiselectable_absent" role="listbox">
<div id="listitem_checked_absent" role="listitem">item</div>
</div>
<div role="menu">
<div id="menuitem_checked_true" role="menuitem" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
<div id="menuitem_checked_false" role="menuitem" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
<div id="menuitem_checked_empty" role="menuitem" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitem_checked_undefined" role="menuitem" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitem_checked_absent" role="menuitem">This menuitem has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitemradio_checked_true" role="menuitemradio" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
<div id="menuitemradio_checked_false" role="menuitemradio" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
<div id="menuitemradio_checked_empty" role="menuitemradio" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitemradio_checked_undefined" role="menuitemradio" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitemradio_checked_absent" role="menuitemradio">This menuitem has <emph>no</emph> aria-checked attribute but should get STATE_CHECKABLE.</div>
</div>
<div id="radio_checked_true" role="radio" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_CHECKED.</div>
<div id="radio_checked_false" role="radio" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
<div id="radio_checked_empty" role="radio" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="radio_checked_undefined" role="radio" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="radio_checked_absent" role="radio">This menuitem has <emph>no</emph> aria-checked attribute but should get STATE_CHECKABLE.</div>
<div id="textbox_readonly_true" role="textbox" aria-readonly="true"></div>
<div id="textbox_readonly_false" role="textbox" aria-readonly="false"></div>
<div id="textbox_readonly_empty" role="textbox" aria-readonly=""></div>
<div id="textbox_readonly_undefined" role="textbox" aria-readonly="undefined"></div>
<div id="textbox_readonly_absent" role="textbox"></div>
<div id="textbox_multiline_true" role="textbox" aria-multiline="true"></div>
<div id="textbox_multiline_false" role="textbox" aria-multiline="false"></div>
<div id="textbox_multiline_empty" role="textbox" aria-multiline=""></div>
<div id="textbox_multiline_undefined" role="textbox" aria-multiline="undefined"></div>
<div id="textbox_multiline_absent" role="textbox"></div>
<form action="">
<input id="native_textbox_nativereadonly_ariatrue" readonly="readonly" aria-readonly="true"/>
<input id="native_textbox_nativereadonly_ariafalse" readonly="readonly" aria-readonly="false"/>
<input id="native_textbox_nativereadonly_ariaempty" readonly="readonly" aria-readonly=""/>
<input id="native_textbox_nativereadonly_ariaundefined" readonly="readonly" aria-readonly="undefined"/>
<input id="native_textbox_nativereadonly_ariaabsent" readonly="readonly"/>
<input id="native_textbox_nativeeditable_ariatrue" aria-readonly="true"/>
<input id="native_textbox_nativeeditable_ariafalse" aria-readonly="false"/>
<input id="native_textbox_nativeeditable_ariaempty" aria-readonly=""/>
<input id="native_textbox_nativeeditable_ariaundefined" aria-readonly="undefined"/>
<input id="native_textbox_nativeeditable_ariaabsent"/>
</form>
<div role="tree">
<div id="treeitem_selected_true" role="treeitem" aria-selected="true">This treeitem has aria-selected="true" and should get STATE_SELECTABLE. It should also get STATE_SELECTED.</div>
<div id="treeitem_selected_false" role="treeitem" aria-selected="false">This treeitem has aria-selected="false" and should get STATE_SELECTABLE.</div>
<div id="treeitem_selected_empty" role="treeitem" aria-selected="">This treeitem has aria-selected="" and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="treeitem_selected_undefined" role="treeitem" aria-selected="undefined">This treeitem has aria-selected="undefined" and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="treeitem_selected_absent" role="treeitem">This treeitem has <emph>no</emph> aria-selected attribute and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="treeitem_haspopup_true" role="treeitem" aria-haspopup="true">This treeitem has aria-haspopup="true" and should get STATE_HASPOPUP.</div>
<div id="treeitem_haspopup_false" role="treeitem" aria-haspopup="false">This treeitem has aria-haspopup="false" and should get STATE_HASPOPUP.</div>
<div id="treeitem_haspopup_empty" role="treeitem" aria-haspopup="">This treeitem has aria-haspopup="" and should <emph>not</emph> get STATE_HASPOPUP.</div>
<div id="treeitem_haspopup_undefined" role="treeitem" aria-haspopup="undefined">This treeitem has aria-haspopup="undefined" and should <emph>not</emph> get STATE_HASPOPUP.</div>
<div id="treeitem_haspopup_absent" role="treeitem">This treeitem has <emph>no</emph> aria-haspopup attribute and should <emph>not</emph> get STATE_HASPOPUP.</div>
<div id="treeitem_expanded_true" role="treeitem" aria-expanded="true">This treeitem has aria-expanded="true" and should get STATE_EXPANDABLE. It should also get STATE_EXPANDED.</div>
<div id="treeitem_expanded_false" role="treeitem" aria-expanded="false">This treeitem has aria-expanded="false" and should get STATE_EXPANDABLE. It should also get STATE_COLLAPSED.</div>
<div id="treeitem_expanded_empty" role="treeitem" aria-expanded="">This treeitem has aria-expanded="" and should <emph>not</emph> get STATE_EXPANDABLE.</div>
<div id="treeitem_expanded_undefined" role="treeitem" aria-expanded="undefined">This treeitem has aria-expanded="undefined" and should <emph>not</emph> get STATE_EXPANDABLE.</div>
<div id="treeitem_expanded_absent" role="treeitem">This treeitem has <emph>no</emph> aria-expanded attribute and should <emph>not</emph> get STATE_EXPANDABLE.</div>
</div>
</body>
</html>

Просмотреть файл

@ -31,9 +31,24 @@
<script type="application/javascript">
function doTest()
{
// aria_autocomplete
testStates("textbox_autocomplete_inline", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
testStates("textbox_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
testStates("textbox_autocomplete_both", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
testStates("combobox_autocomplete_inline", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
testStates("combobox_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
testStates("combobox_autocomplete_both", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
// aria-busy
testStates("textbox_busy_false", 0, 0, STATE_BUSY);
testStates("textbox_busy_true", STATE_BUSY);
testStates("textbox_busy_error", STATE_INVALID);
// aria-expanded
testStates("combobox", STATE_COLLAPSED);
testStates("combobox_expanded", STATE_EXPANDED);
// tri-state checkbox
var checkboxElem = getNode("check1");
if (checkboxElem) {
testStates(checkboxElem, STATE_CHECKED);
@ -43,6 +58,7 @@
testStates(checkboxElem, STATE_MIXED, 0);
}
// aria-checked
testStates("aria_checked_checkbox", STATE_CHECKED);
testStates("aria_mixed_checkbox", STATE_MIXED);
@ -50,6 +66,7 @@
// disabled, too. See bug 429285.
testStatesInSubtree("group", STATE_UNAVAILABLE);
// offscreen test
testStates("aria_offscreen_textbox", STATE_OFFSCREEN);
SimpleTest.finish();
@ -73,13 +90,28 @@
title="Propagate aria-disabled to descendants">
Mozilla Bug 429285
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=499653"
title="Unify ARIA state attributes mapping rules">
Mozilla Bug 499653
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="combobox" role="combobox">combobox</div>
<div id="textbox_autocomplete_inline" role="textbox" aria-autocomplete="inline"></div>
<div id="textbox_autocomplete_list" role="textbox" aria-autocomplete="list"></div>
<div id="textbox_autocomplete_both" role="textbox" aria-autocomplete="both"></div>
<div id="combobox_autocomplete_inline" role="combobox" aria-autocomplete="inline"></div>
<div id="combobox_autocomplete_list" role="combobox" aria-autocomplete="list"></div>
<div id="combobox_autocomplete_both" role="combobox" aria-autocomplete="both"></div>
<div id="textbox_busy_false" role="textbox" aria-busy="false"></div>
<div id="textbox_busy_true" role="textbox" aria-busy="true"></div>
<div id="textbox_busy_error" role="textbox" aria-busy="error"></div>
<div id="combobox" role="combobox">combobox</div>
<div id="combobox_expanded" role="combobox"
aria-expanded="true">combobox</div>