Bug 457166 - Conversation links in GMail Inbox do not expose an action, cannot be activated by screen readers, r=marcoz, aaronlev

This commit is contained in:
Alexander Surkov 2008-10-08 20:54:58 +08:00
parent 0b44649c8c
commit ee8c4eb982
7 changed files with 724 additions and 190 deletions

View File

@ -60,119 +60,511 @@ static const nsStateMapEntry kEndEntry = {nsnull, 0, 0}; // To fill in array of
nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
{
{"alert", nsIAccessibleRole::ROLE_ALERT, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"alertdialog", nsIAccessibleRole::ROLE_ALERT, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
{"application", nsIAccessibleRole::ROLE_APPLICATION, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"article", nsIAccessibleRole::ROLE_DOCUMENT, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"button", nsIAccessibleRole::ROLE_PUSHBUTTON, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_pressed, kBoolState, nsIAccessibleStates::STATE_PRESSED},
{&nsAccessibilityAtoms::aria_pressed, "mixed", nsIAccessibleStates::STATE_MIXED}, kEndEntry},
{"checkbox", nsIAccessibleRole::ROLE_CHECKBUTTON, eNameOkFromChildren, eNoValue, 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},
{"columnheader", nsIAccessibleRole::ROLE_COLUMNHEADER, eNameOkFromChildren, eNoValue, 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},
{"combobox", nsIAccessibleRole::ROLE_COMBOBOX, eNameLabelOrTitle, eHasValueMinMax,
nsIAccessibleStates::STATE_COLLAPSED | nsIAccessibleStates::STATE_HASPOPUP,
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED}, kEndEntry},
{"description", nsIAccessibleRole::ROLE_TEXT_CONTAINER, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
{"dialog", nsIAccessibleRole::ROLE_DIALOG, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"document", nsIAccessibleRole::ROLE_DOCUMENT, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"grid", nsIAccessibleRole::ROLE_TABLE, eNameLabelOrTitle, eNoValue, nsIAccessibleStates::STATE_FOCUSABLE,
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
{"gridcell", nsIAccessibleRole::ROLE_CELL, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
{&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},
{"group", nsIAccessibleRole::ROLE_GROUPING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"heading", nsIAccessibleRole::ROLE_HEADING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"img", nsIAccessibleRole::ROLE_GRAPHIC, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"label", nsIAccessibleRole::ROLE_LABEL, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
{"link", nsIAccessibleRole::ROLE_LINK, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_LINKED, kEndEntry},
{"list", nsIAccessibleRole::ROLE_LIST, eNameLabelOrTitle, eNoValue, nsIAccessibleStates::STATE_READONLY,
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
{"listbox", nsIAccessibleRole::ROLE_LISTBOX, eNameLabelOrTitle, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
{"listitem", nsIAccessibleRole::ROLE_LISTITEM, eNameOkFromChildren, eNoValue, 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},
{"math", nsIAccessibleRole::ROLE_FLAT_EQUATION, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"menu", nsIAccessibleRole::ROLE_MENUPOPUP, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"menubar", nsIAccessibleRole::ROLE_MENUBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"menuitem", nsIAccessibleRole::ROLE_MENUITEM, eNameOkFromChildren, eNoValue, 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},
{"menuitemcheckbox", nsIAccessibleRole::ROLE_CHECK_MENU_ITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED}, kEndEntry},
{"menuitemradio", nsIAccessibleRole::ROLE_RADIO_MENU_ITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED }, kEndEntry},
{"option", nsIAccessibleRole::ROLE_OPTION, eNameOkFromChildren, eNoValue, 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},
{"presentation", nsIAccessibleRole::ROLE_NOTHING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"progressbar", nsIAccessibleRole::ROLE_PROGRESSBAR, eNameLabelOrTitle, eHasValueMinMax, nsIAccessibleStates::STATE_READONLY, kEndEntry},
{"radio", nsIAccessibleRole::ROLE_RADIOBUTTON, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED}, kEndEntry},
{"radiogroup", nsIAccessibleRole::ROLE_GROUPING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"region", nsIAccessibleRole::ROLE_PANE, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"row", nsIAccessibleRole::ROLE_ROW, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED}, kEndEntry},
{"rowheader", nsIAccessibleRole::ROLE_ROWHEADER, eNameOkFromChildren, eNoValue, 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},
{"section", nsIAccessibleRole::ROLE_SECTION, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"separator", nsIAccessibleRole::ROLE_SEPARATOR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"slider", nsIAccessibleRole::ROLE_SLIDER, eNameLabelOrTitle, eHasValueMinMax, kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
{"spinbutton", nsIAccessibleRole::ROLE_SPINBUTTON, eNameLabelOrTitle, eHasValueMinMax, kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
{"status", nsIAccessibleRole::ROLE_STATUSBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"tab", nsIAccessibleRole::ROLE_PAGETAB, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
{"tablist", nsIAccessibleRole::ROLE_PAGETABLIST, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"tabpanel", nsIAccessibleRole::ROLE_PROPERTYPAGE, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"textbox", nsIAccessibleRole::ROLE_ENTRY, eNameLabelOrTitle, eNoValue, 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},
{"toolbar", nsIAccessibleRole::ROLE_TOOLBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"tooltip", nsIAccessibleRole::ROLE_TOOLTIP, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
{"tree", nsIAccessibleRole::ROLE_OUTLINE, eNameLabelOrTitle, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
{"treegrid", nsIAccessibleRole::ROLE_TREE_TABLE, eNameLabelOrTitle, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
{"treeitem", nsIAccessibleRole::ROLE_OUTLINEITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
{&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},},
{
"alert",
nsIAccessibleRole::ROLE_ALERT,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"alertdialog",
nsIAccessibleRole::ROLE_ALERT,
eNameOkFromChildren,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"application",
nsIAccessibleRole::ROLE_APPLICATION,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"article",
nsIAccessibleRole::ROLE_DOCUMENT,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"button",
nsIAccessibleRole::ROLE_PUSHBUTTON,
eNameOkFromChildren,
eNoValue,
eClickAction,
kNoReqStates,
{&nsAccessibilityAtoms::aria_pressed, kBoolState, nsIAccessibleStates::STATE_PRESSED},
{&nsAccessibilityAtoms::aria_pressed, "mixed", nsIAccessibleStates::STATE_MIXED},
kEndEntry
},
{
"checkbox",
nsIAccessibleRole::ROLE_CHECKBUTTON,
eNameOkFromChildren,
eNoValue,
eCheckUncheckAction,
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
},
{
"columnheader",
nsIAccessibleRole::ROLE_COLUMNHEADER,
eNameOkFromChildren,
eNoValue,
eNoAction,
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
},
{
"combobox",
nsIAccessibleRole::ROLE_COMBOBOX,
eNameLabelOrTitle,
eHasValueMinMax,
eOpenCloseAction,
nsIAccessibleStates::STATE_COLLAPSED | nsIAccessibleStates::STATE_HASPOPUP,
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
kEndEntry
},
{
"description",
nsIAccessibleRole::ROLE_TEXT_CONTAINER,
eNameOkFromChildren,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"dialog",
nsIAccessibleRole::ROLE_DIALOG,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"document",
nsIAccessibleRole::ROLE_DOCUMENT,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"grid",
nsIAccessibleRole::ROLE_TABLE,
eNameLabelOrTitle,
eNoValue,
eNoAction,
nsIAccessibleStates::STATE_FOCUSABLE,
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
},
{
"gridcell",
nsIAccessibleRole::ROLE_CELL,
eNameOkFromChildren,
eNoValue,
eNoAction,
kNoReqStates,
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
{&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
},
{
"group",
nsIAccessibleRole::ROLE_GROUPING,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"heading",
nsIAccessibleRole::ROLE_HEADING,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"img",
nsIAccessibleRole::ROLE_GRAPHIC,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"label",
nsIAccessibleRole::ROLE_LABEL,
eNameOkFromChildren,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"link",
nsIAccessibleRole::ROLE_LINK,
eNameOkFromChildren,
eNoValue,
eJumpAction,
nsIAccessibleStates::STATE_LINKED,
kEndEntry
},
{
"list",
nsIAccessibleRole::ROLE_LIST,
eNameLabelOrTitle,
eNoValue,
eNoAction,
nsIAccessibleStates::STATE_READONLY,
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
},
{
"listbox",
nsIAccessibleRole::ROLE_LISTBOX,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
},
{
"listitem",
nsIAccessibleRole::ROLE_LISTITEM,
eNameOkFromChildren,
eNoValue,
eNoAction, // XXX: should depend on state, parent accessible
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
},
{
"math",
nsIAccessibleRole::ROLE_FLAT_EQUATION,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"menu",
nsIAccessibleRole::ROLE_MENUPOPUP,
eNameLabelOrTitle,
eNoValue,
eNoAction, // XXX: technically accessibles of menupopup role haven't
// any action, but menu can be open or close.
kNoReqStates,
kEndEntry
},
{
"menubar",
nsIAccessibleRole::ROLE_MENUBAR,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"menuitem",
nsIAccessibleRole::ROLE_MENUITEM,
eNameOkFromChildren,
eNoValue,
eClickAction,
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
},
{
"menuitemcheckbox",
nsIAccessibleRole::ROLE_CHECK_MENU_ITEM,
eNameOkFromChildren,
eNoValue,
eClickAction,
nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED},
kEndEntry
},
{
"menuitemradio",
nsIAccessibleRole::ROLE_RADIO_MENU_ITEM,
eNameOkFromChildren,
eNoValue,
eClickAction,
nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
kEndEntry
},
{
"option",
nsIAccessibleRole::ROLE_OPTION,
eNameOkFromChildren,
eNoValue,
eSelectAction,
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
},
{
"presentation",
nsIAccessibleRole::ROLE_NOTHING,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"progressbar",
nsIAccessibleRole::ROLE_PROGRESSBAR,
eNameLabelOrTitle,
eHasValueMinMax,
eNoAction,
nsIAccessibleStates::STATE_READONLY,
kEndEntry
},
{
"radio",
nsIAccessibleRole::ROLE_RADIOBUTTON,
eNameOkFromChildren,
eNoValue,
eSelectAction,
kNoReqStates,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED},
kEndEntry
},
{
"radiogroup",
nsIAccessibleRole::ROLE_GROUPING,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"region",
nsIAccessibleRole::ROLE_PANE,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"row",
nsIAccessibleRole::ROLE_ROW,
eNameOkFromChildren,
eNoValue,
eNoAction,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
kEndEntry
},
{
"rowheader",
nsIAccessibleRole::ROLE_ROWHEADER,
eNameOkFromChildren,
eNoValue,
eNoAction,
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
},
{
"section",
nsIAccessibleRole::ROLE_SECTION,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"separator",
nsIAccessibleRole::ROLE_SEPARATOR,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"slider",
nsIAccessibleRole::ROLE_SLIDER,
eNameLabelOrTitle,
eHasValueMinMax,
eNoAction,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
},
{
"spinbutton",
nsIAccessibleRole::ROLE_SPINBUTTON,
eNameLabelOrTitle,
eHasValueMinMax,
eNoAction,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
},
{
"status",
nsIAccessibleRole::ROLE_STATUSBAR,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"tab",
nsIAccessibleRole::ROLE_PAGETAB,
eNameOkFromChildren,
eNoValue,
eSwitchAction,
kNoReqStates,
kEndEntry
},
{
"tablist",
nsIAccessibleRole::ROLE_PAGETABLIST,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"tabpanel",
nsIAccessibleRole::ROLE_PROPERTYPAGE,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"textbox",
nsIAccessibleRole::ROLE_ENTRY,
eNameLabelOrTitle,
eNoValue,
eActivateAction,
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
},
{
"toolbar",
nsIAccessibleRole::ROLE_TOOLBAR,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"tooltip",
nsIAccessibleRole::ROLE_TOOLTIP,
eNameOkFromChildren,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
},
{
"tree",
nsIAccessibleRole::ROLE_OUTLINE,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
},
{
"treegrid",
nsIAccessibleRole::ROLE_TREE_TABLE,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
},
{
"treeitem",
nsIAccessibleRole::ROLE_OUTLINEITEM,
eNameOkFromChildren,
eNoValue,
eActivateAction, // XXX: should expose second 'expand/collapse' action based
// on states
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
{&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},
},
};
PRUint32 nsARIAMap::gWAIRoleMapLength = NS_ARRAY_LENGTH(nsARIAMap::gWAIRoleMap);
@ -182,6 +574,7 @@ nsRoleMapEntry nsARIAMap::gLandmarkRoleMap = {
nsIAccessibleRole::ROLE_NOTHING,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
};
@ -191,6 +584,7 @@ nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
nsIAccessibleRole::ROLE_NOTHING,
eNameLabelOrTitle,
eNoValue,
eNoAction,
kNoReqStates,
kEndEntry
};

View File

@ -70,6 +70,19 @@ enum EValueRule
eHasValueMinMax // Supports value, min and max from aria-valuenow, aria-valuemin and aria-valuemax
};
// Should we expose action based on the ARIA role?
enum EActionRule
{
eNoAction,
eActivateAction,
eClickAction,
eCheckUncheckAction,
eJumpAction,
eOpenCloseAction,
eSelectAction,
eSwitchAction
};
// Used for an nsStateMapEntry if a given state attribute supports "true" and "false"
#define kBoolState 0
@ -99,7 +112,10 @@ struct nsRoleMapEntry
// Value mapping rule: how to compute nsIAccessible value
EValueRule valueRule;
// Action mapping rule, how to expose nsIAccessible action
EActionRule actionRule;
// Automatic state mapping rule: always include in nsIAccessibleStates
PRUint32 state; // or kNoReqStates if no nsIAccessibleStates are automatic for this role.

View File

@ -2775,7 +2775,7 @@ NS_IMETHODIMP nsAccessible::GetRole(PRUint32 *aRole)
return NS_OK;
}
/* PRUint8 getAccNumActions (); */
// readonly attribute PRUint8 numActions
NS_IMETHODIMP
nsAccessible::GetNumActions(PRUint8 *aNumActions)
{
@ -2785,23 +2785,11 @@ nsAccessible::GetNumActions(PRUint8 *aNumActions)
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIContent> content = GetRoleContent(mDOMNode);
if (!content)
PRUint32 actionRule = GetActionRule(State(this));
if (actionRule == eNoAction)
return NS_OK;
// Check if it's a simple xlink.
if (nsAccUtils::IsXLink(content)) {
*aNumActions = 1;
return NS_OK;
}
// Has registered 'click' event handler.
PRBool isOnclick = nsAccUtils::HasListener(content,
NS_LITERAL_STRING("click"));
if (isOnclick)
*aNumActions = 1;
*aNumActions = 1;
return NS_OK;
}
@ -2817,26 +2805,49 @@ nsAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
if (IsDefunct())
return NS_ERROR_FAILURE;
// Check if it's a simple xlink.
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
if (nsAccUtils::IsXLink(content)) {
aName.AssignLiteral("jump");
return NS_OK;
}
PRUint32 states = State(this);
PRUint32 actionRule = GetActionRule(states);
// Has registered 'click' event handler.
PRBool isOnclick = nsAccUtils::HasListener(content,
NS_LITERAL_STRING("click"));
if (isOnclick) {
aName.AssignLiteral("click");
return NS_OK;
switch (actionRule) {
case eActivateAction:
aName.AssignLiteral("activate");
return NS_OK;
case eClickAction:
aName.AssignLiteral("click");
return NS_OK;
case eCheckUncheckAction:
if (states & nsIAccessibleStates::STATE_CHECKED)
aName.AssignLiteral("uncheck");
else
aName.AssignLiteral("check");
return NS_OK;
case eJumpAction:
aName.AssignLiteral("jump");
return NS_OK;
case eOpenCloseAction:
if (states & nsIAccessibleStates::STATE_COLLAPSED)
aName.AssignLiteral("open");
else
aName.AssignLiteral("close");
return NS_OK;
case eSelectAction:
aName.AssignLiteral("select");
return NS_OK;
case eSwitchAction:
aName.AssignLiteral("switch");
return NS_OK;
}
return NS_ERROR_INVALID_ARG;
}
/* DOMString getActionDescription (in PRUint8 index); */
// AString getActionDescription(in PRUint8 index)
NS_IMETHODIMP
nsAccessible::GetActionDescription(PRUint8 aIndex, nsAString& aDescription)
{
@ -2848,7 +2859,7 @@ nsAccessible::GetActionDescription(PRUint8 aIndex, nsAString& aDescription)
return GetTranslatedString(name, aDescription);
}
/* void doAction (in PRUint8 index); */
// void doAction(in PRUint8 index)
NS_IMETHODIMP
nsAccessible::DoAction(PRUint8 aIndex)
{
@ -2858,19 +2869,10 @@ nsAccessible::DoAction(PRUint8 aIndex)
if (IsDefunct())
return NS_ERROR_FAILURE;
PRBool doAction = PR_FALSE;
// Check if it's a simple xlink.
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
if (nsAccUtils::IsXLink(content))
doAction = PR_TRUE;
// Has registered 'click' event handler.
if (!doAction)
doAction = nsAccUtils::HasListener(content, NS_LITERAL_STRING("click"));
if (doAction)
if (GetActionRule(State(this)) != eNoAction) {
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
return DoCommand(content);
}
return NS_ERROR_INVALID_ARG;
}
@ -3674,6 +3676,31 @@ nsAccessible::GetAttrValue(nsIAtom *aProperty, double *aValue)
return result;
}
PRUint32
nsAccessible::GetActionRule(PRUint32 aStates)
{
if (aStates & nsIAccessibleStates::STATE_UNAVAILABLE)
return eNoAction;
// Check if it's simple xlink.
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
if (nsAccUtils::IsXLink(content))
return eJumpAction;
// Has registered 'click' event handler.
PRBool isOnclick = nsAccUtils::HasListener(content,
NS_LITERAL_STRING("click"));
if (isOnclick)
return eClickAction;
// Get an action based on ARIA role.
if (mRoleMapEntry)
return mRoleMapEntry->actionRule;
return eNoAction;
}
PRBool nsAccessible::MustPrune(nsIAccessible *aAccessible)
{
PRUint32 role = Role(aAccessible);

View File

@ -259,6 +259,14 @@ protected:
*/
nsresult GetAttrValue(nsIAtom *aAriaProperty, double *aValue);
/**
* Return the action rule based on ARIA enum constants EActionRule
* (see nsARIAMap.h). Used by GetNumActions() and GetActionName().
*
* @param aStates [in] states of the accessible
*/
PRUint32 GetActionRule(PRUint32 aStates);
/**
* Fires platform accessible event. It's notification method only. It does
* change nothing on Gecko side. Mostly you should use

View File

@ -1,19 +1,3 @@
////////////////////////////////////////////////////////////////////////////////
// General
const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval;
const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;
var gAccRetrieval = null;
function initialize()
{
gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(nsIAccessibleRetrieval);
}
addLoadEvent(initialize);
////////////////////////////////////////////////////////////////////////////////
// Event constants
@ -38,33 +22,27 @@ function testActions(aArray, aIndex)
return;
}
var ID = aArray[aIndex].ID;
var accOrElmOrID = aArray[aIndex].ID;
var actionName = aArray[aIndex].actionName;
var events = aArray[aIndex].events;
var elm = document.getElementById(ID);
if (!elm) {
ok(false, "There is no element with ID " + ID);
SimpleTest.finish();
return null;
}
var elmObj = {};
var acc = getAccessible(accOrElmOrID, null, elmObj);
var elm = elmObj.value;
var acc = null;
try {
acc = gAccRetrieval.getAccessibleFor(elm);
} catch(e) {
}
var isThereActions = acc.numActions > 0;
ok(isThereActions,
"No actions on the accessible for " + accOrElmOrID);
if (!acc) {
ok(false, "There is no accessible for " + ID);
if (!isThereActions) {
SimpleTest.finish();
return null;
return; // Stop test.
}
is(acc.getActionName(0), actionName,
"Wrong action name of the accessible for " + ID);
"Wrong action name of the accessible for " + accOrElmOrID);
gEventHandler.initialize(ID, elm, events);
gEventHandler.initialize(accOrElmOrID, elm, events);
acc.doAction(0);

View File

@ -10,6 +10,9 @@
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/nsIAccessible_actions.js"></script>
@ -21,6 +24,76 @@
ID: "clickable",
actionName: "click",
events: CLICK_EVENTS
},
{
ID: "button",
actionName: "click",
events: CLICK_EVENTS
},
{
ID: "checkbox_unchecked",
actionName: "check",
events: CLICK_EVENTS
},
{
ID: "checkbox_checked",
actionName: "uncheck",
events: CLICK_EVENTS
},
{
ID: "combobox_collapsed",
actionName: "open",
events: CLICK_EVENTS
},
{
ID: "combobox_expanded",
actionName: "close",
events: CLICK_EVENTS
},
{
ID: "link",
actionName: "jump",
events: CLICK_EVENTS
},
{
ID: "menuitem",
actionName: "click",
events: CLICK_EVENTS
},
{
ID: "menuitemcheckbox",
actionName: "click",
events: CLICK_EVENTS
},
{
ID: "menuitemradio",
actionName: "click",
events: CLICK_EVENTS
},
{
ID: "option",
actionName: "select",
events: CLICK_EVENTS
},
{
ID: "radio",
actionName: "select",
events: CLICK_EVENTS
},
{
ID: "tab",
actionName: "switch",
events: CLICK_EVENTS
},
{
ID: "textbox",
actionName: "activate",
events: CLICK_EVENTS
},
{
ID: "treeitem",
actionName: "activate",
events: CLICK_EVENTS
}
];
testActions(actionsArray);
@ -45,5 +118,40 @@
<div id="clickable" onclick="">Clickable text</div>
<div id="button" role="button">Button</span>
<div id="checkbox_unchecked" role="checkbox">Checkbox</span>
<div id="checkbox_checked" role="checkbox" aria-checked="true">Checkbox</span>
<div id="combobox_collapsed" role="combobox">
<div id="option" role="option">Option of collapsed combobox</div>
</div>
<div id="combobox_expanded" role="combobox" aria-expanded="true">
<div role="option">Option of expanded combobox</div>
</div>
<div id="link" role="link">Link</div>
<div role="menu">
<div id="menuitem" role="menuitem">Menuitem</div>
<div id="menuitemcheckbox" role="menuitemcheckbox">Menuitem checkbox</div>
<div id="menuitemradio" role="menuitemradio">Menuitem radio</div>
</div>
<div role="radiogroup">
<div id="radio" role="radio">Radio</div>
</div>
<div role="tablist">
<div id="tab" role="tab">Tab</div>
</div>
<div id="textbox" role="textbox">Textbox</div>
<div role="tree">
<div id="treeitem" role="treeitem">Treeitem</div>
</div>
</body>
</html>

View File

@ -13,6 +13,9 @@
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js" />
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/nsIAccessible_actions.js" />