mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 396632. Don't require namespaces when using ARIA properties in text/html
This commit is contained in:
parent
5796722d5b
commit
4b182e53cc
@ -58,7 +58,7 @@ interface nsIDOMWindow;
|
||||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(6cc11286-e02d-4a8d-960a-e7a61161b230)]
|
||||
[scriptable, uuid(d118c0e9-b5e7-4671-854a-65b4713d9552)]
|
||||
interface nsIAccessibleDocument : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -121,4 +121,27 @@ interface nsIAccessibleDocument : nsISupports
|
||||
* to the document root.
|
||||
*/
|
||||
nsIAccessible getAccessibleInParentChain(in nsIDOMNode aDOMNode);
|
||||
|
||||
/**
|
||||
* A bit flag representing the type of ARIA properties which should be
|
||||
* checked in this document:
|
||||
* either eUnknownPropType, eCheckNamespaced, eCheckHyphenated or eCheckAny
|
||||
*/
|
||||
readonly attribute unsigned long ariaPropTypes;
|
||||
|
||||
/**
|
||||
* Check attributes in the form of:
|
||||
* [someprefix]:[propname] (e.g. aria:live) where ancestor defines:
|
||||
* xmlns:[someprefix]="http://www.w3.org/2005/07/aaa"
|
||||
*/
|
||||
const unsigned long eCheckNamespaced = 1;
|
||||
|
||||
/**
|
||||
* Check hyphenated attributes in the form of aria-[propname].
|
||||
* This is the default in text/html documents.
|
||||
* Can be combined with eCheckNamespaced flag. This may
|
||||
* change during the life of the document, if setAttributeNS()
|
||||
* is used to set an ARIA property.
|
||||
*/
|
||||
const unsigned long eCheckHyphenated = 2;
|
||||
};
|
||||
|
@ -41,15 +41,26 @@
|
||||
#include "nsIAccessibleRole.h"
|
||||
#include "nsIAccessibleStates.h"
|
||||
|
||||
#define ARIA_PROPERTY(atom) &nsAccessibilityAtoms::##atom,
|
||||
nsIAtom** nsARIAMap::gAriaAtomPtrsNS[eAria_none] = {
|
||||
#include "nsAriaPropertyList.h"
|
||||
};
|
||||
#undef ARIA_PROPERTY
|
||||
|
||||
#define ARIA_PROPERTY(atom) &nsAccessibilityAtoms::aria_##atom,
|
||||
nsIAtom** nsARIAMap::gAriaAtomPtrsHyphenated[eAria_none] = {
|
||||
#include "nsAriaPropertyList.h"
|
||||
};
|
||||
#undef ARIA_PROPERTY
|
||||
|
||||
/**
|
||||
* This list of WAI-defined roles are currently hardcoded.
|
||||
* Eventually we will most likely be loading an RDF resource that contains this information
|
||||
* Using RDF will also allow for role extensibility. See bug 280138.
|
||||
*
|
||||
* XXX Should we store attribute names in this table as atoms instead of strings?
|
||||
* Definition of nsRoleMapEntry and nsStateMapEntry contains comments explaining this table.
|
||||
*
|
||||
* When no nsIAccessibleRole neum mapping exists for an ARIA role, the
|
||||
* When no nsIAccessibleRole enum mapping exists for an ARIA role, the
|
||||
* role will be exposed via the object attribute "xml-roles".
|
||||
* In addition, in MSAA, the unmapped role will also be exposed as a BSTR string role.
|
||||
*
|
||||
@ -57,7 +68,7 @@
|
||||
* banner, contentinfo, main, navigation, note, search, secondary, seealso, breadcrumbs
|
||||
*/
|
||||
|
||||
static const nsStateMapEntry kEndEntry = {0, 0, 0}; // To fill in array of state mappings
|
||||
static const nsStateMapEntry kEndEntry = {eAria_none, 0, 0}; // To fill in array of state mappings
|
||||
|
||||
nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
@ -65,141 +76,141 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{"alertdialog", nsIAccessibleRole::ROLE_ALERT, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"application", nsIAccessibleRole::ROLE_APPLICATION, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"button", nsIAccessibleRole::ROLE_PUSHBUTTON, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"pressed", kBoolState, nsIAccessibleStates::STATE_PRESSED},
|
||||
{"pressed", "mixed", nsIAccessibleStates::STATE_MIXED}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_pressed, kBoolState, nsIAccessibleStates::STATE_PRESSED},
|
||||
{eAria_pressed, "mixed", nsIAccessibleStates::STATE_MIXED}, kEndEntry},
|
||||
{"checkbox", nsIAccessibleRole::ROLE_CHECKBUTTON, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED},
|
||||
{"checked", "mixed", nsIAccessibleStates::STATE_MIXED},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED},
|
||||
{eAria_checked, "mixed", nsIAccessibleStates::STATE_MIXED},
|
||||
{eAria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"columnheader", nsIAccessibleRole::ROLE_COLUMNHEADER, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"combobox", nsIAccessibleRole::ROLE_COMBOBOX, eNameLabelOrTitle, eHasValueMinMax,
|
||||
nsIAccessibleStates::STATE_COLLAPSED | nsIAccessibleStates::STATE_HASPOPUP,
|
||||
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aaa:autocomplete
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{"expanded", kBoolState, nsIAccessibleStates::STATE_EXPANDED}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{eAria_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,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
|
||||
{eAria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"gridcell", nsIAccessibleRole::ROLE_CELL, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"expanded", kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{"expanded", "false", nsIAccessibleStates::STATE_COLLAPSED},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{eAria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
|
||||
{eAria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_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,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{"list", nsIAccessibleRole::ROLE_LIST, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{eAria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{eAria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{"listbox", nsIAccessibleRole::ROLE_LIST, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{eAria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{"listitem", nsIAccessibleRole::ROLE_LISTITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{eAria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{eAria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{eAria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{"menu", nsIAccessibleRole::ROLE_MENUPOPUP, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{"menubar", nsIAccessibleRole::ROLE_MENUBAR, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{"menuitem", nsIAccessibleRole::ROLE_MENUITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{eAria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{eAria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{"menuitemcheckbox", nsIAccessibleRole::ROLE_CHECK_MENU_ITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED },
|
||||
{"checked", "mixed", nsIAccessibleStates::STATE_MIXED}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
|
||||
{eAria_checked, "mixed", nsIAccessibleStates::STATE_MIXED}, kEndEntry},
|
||||
{"menuitemradio", nsIAccessibleRole::ROLE_RADIO_MENU_ITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED }, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED }, kEndEntry},
|
||||
{"option", nsIAccessibleRole::ROLE_LISTITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{eAria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{eAria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
|
||||
{"progressbar", nsIAccessibleRole::ROLE_PROGRESSBAR, eNameLabelOrTitle, eHasValueMinMax, nsIAccessibleStates::STATE_READONLY,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{"radio", nsIAccessibleRole::ROLE_RADIOBUTTON, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED}, kEndEntry},
|
||||
{"radiogroup", nsIAccessibleRole::ROLE_GROUPING, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{"region", nsIAccessibleRole::ROLE_PANE, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"row", nsIAccessibleRole::ROLE_ROW, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"expanded", kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{"expanded", "false", nsIAccessibleStates::STATE_COLLAPSED}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{eAria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED}, kEndEntry},
|
||||
{"rowheader", nsIAccessibleRole::ROLE_ROWHEADER, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_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,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"spinbutton", nsIAccessibleRole::ROLE_SPINBUTTON, eNameLabelOrTitle, eHasValueMinMax, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"status", nsIAccessibleRole::ROLE_STATUSBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"tab", nsIAccessibleRole::ROLE_PAGETAB, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, 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 aaa:multiline
|
||||
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aaa:autocomplete
|
||||
{"autocomplete", "list", nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{"autocomplete", "both", nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{"secret", kBoolState, nsIAccessibleStates::STATE_PROTECTED},
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{eAria_autocomplete, "list", nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{eAria_autocomplete, "both", nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{eAria_secret, kBoolState, nsIAccessibleStates::STATE_PROTECTED},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
|
||||
{"toolbar", nsIAccessibleRole::ROLE_TOOLBAR, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
|
||||
{"tooltip", nsIAccessibleRole::ROLE_TOOLTIP, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
|
||||
{"tree", nsIAccessibleRole::ROLE_OUTLINE, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{eAria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{"treegrid", nsIAccessibleRole::ROLE_TREE_TABLE, eNameLabelOrTitle, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"readonly", kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{"multiselectable", kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{eAria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
|
||||
{"treeitem", nsIAccessibleRole::ROLE_OUTLINEITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
|
||||
{"disabled", kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{"selected", kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"selected", "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{"expanded", kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{"expanded", "false", nsIAccessibleStates::STATE_COLLAPSED},
|
||||
{"checked", kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{"checked", "false", nsIAccessibleStates::STATE_CHECKABLE},},
|
||||
{eAria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{eAria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{eAria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{eAria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
|
||||
{eAria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{eAria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{eAria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},},
|
||||
{nsnull, nsIAccessibleRole::ROLE_NOTHING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry} // Last item
|
||||
};
|
||||
|
||||
@ -209,11 +220,11 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
* whether there is an ARIA role or not:
|
||||
*/
|
||||
nsStateMapEntry nsARIAMap::gWAIUnivStateMap[] = {
|
||||
{"required", kBoolState, nsIAccessibleStates::STATE_REQUIRED},
|
||||
{"invalid", kBoolState, nsIAccessibleStates::STATE_INVALID},
|
||||
{"haspopup", kBoolState, nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{"busy", "true", nsIAccessibleStates::STATE_BUSY},
|
||||
{"busy", "error", nsIAccessibleStates::STATE_INVALID},
|
||||
{eAria_required, kBoolState, nsIAccessibleStates::STATE_REQUIRED},
|
||||
{eAria_invalid, kBoolState, nsIAccessibleStates::STATE_INVALID},
|
||||
{eAria_haspopup, kBoolState, nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{eAria_busy, "true", nsIAccessibleStates::STATE_BUSY},
|
||||
{eAria_busy, "error", nsIAccessibleStates::STATE_INVALID},
|
||||
kEndEntry
|
||||
};
|
||||
|
||||
|
@ -41,6 +41,13 @@
|
||||
#define _nsARIAMap_H_
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
|
||||
#define ARIA_PROPERTY(atom) eAria_##atom,
|
||||
enum EAriaProperty {
|
||||
#include "nsAriaPropertyList.h"
|
||||
eAria_none };
|
||||
#undef ARIA_PROPERTY
|
||||
|
||||
// Name mapping rule: can the name be computed from descendants?
|
||||
enum ENameRule
|
||||
@ -79,7 +86,7 @@ enum EValueRule
|
||||
// nsStateMapEntry.state
|
||||
struct nsStateMapEntry
|
||||
{
|
||||
const char* attributeName; // magic value of nsnull means last entry in map
|
||||
EAriaProperty attributeName; // eARIA_none 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
|
||||
};
|
||||
@ -124,6 +131,8 @@ struct nsRoleMapEntry
|
||||
*/
|
||||
struct nsARIAMap
|
||||
{
|
||||
static nsIAtom** gAriaAtomPtrsNS[eAria_none];
|
||||
static nsIAtom** gAriaAtomPtrsHyphenated[eAria_none];
|
||||
static nsRoleMapEntry gWAIRoleMap[];
|
||||
static nsStateMapEntry gWAIUnivStateMap[];
|
||||
};
|
||||
|
74
accessible/src/base/nsARIAPropertyList.h
Normal file
74
accessible/src/base/nsARIAPropertyList.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is IBM Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C)2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Leventhal <aleventh@us.ibm.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// ARIA properties
|
||||
ARIA_PROPERTY(activedescendant)
|
||||
ARIA_PROPERTY(atomic)
|
||||
ARIA_PROPERTY(autocomplete)
|
||||
ARIA_PROPERTY(busy)
|
||||
ARIA_PROPERTY(channel)
|
||||
ARIA_PROPERTY(checked)
|
||||
ARIA_PROPERTY(controls)
|
||||
ARIA_PROPERTY(datatype)
|
||||
ARIA_PROPERTY(describedby)
|
||||
ARIA_PROPERTY(disabled)
|
||||
ARIA_PROPERTY(dropeffect)
|
||||
ARIA_PROPERTY(expanded)
|
||||
ARIA_PROPERTY(flowto)
|
||||
ARIA_PROPERTY(grab)
|
||||
ARIA_PROPERTY(haspopup)
|
||||
ARIA_PROPERTY(invalid)
|
||||
ARIA_PROPERTY(labelledby)
|
||||
ARIA_PROPERTY(level)
|
||||
ARIA_PROPERTY(live)
|
||||
ARIA_PROPERTY(multiline)
|
||||
ARIA_PROPERTY(multiselectable)
|
||||
ARIA_PROPERTY(owns)
|
||||
ARIA_PROPERTY(posinset)
|
||||
ARIA_PROPERTY(pressed)
|
||||
ARIA_PROPERTY(readonly)
|
||||
ARIA_PROPERTY(relevant)
|
||||
ARIA_PROPERTY(required)
|
||||
ARIA_PROPERTY(secret)
|
||||
ARIA_PROPERTY(selected)
|
||||
ARIA_PROPERTY(setsize)
|
||||
ARIA_PROPERTY(sort)
|
||||
ARIA_PROPERTY(valuenow)
|
||||
ARIA_PROPERTY(valuemin)
|
||||
ARIA_PROPERTY(valuemax)
|
@ -140,25 +140,16 @@ ACCESSIBILITY_ATOM(tooltip, "tooltip") // XUL
|
||||
ACCESSIBILITY_ATOM(tr, "tr")
|
||||
ACCESSIBILITY_ATOM(ul, "ul")
|
||||
|
||||
// DHTML accessibility relationship attributes
|
||||
ACCESSIBILITY_ATOM(controls, "controls")
|
||||
ACCESSIBILITY_ATOM(describedby, "describedby")
|
||||
ACCESSIBILITY_ATOM(flowto, "flowto")
|
||||
ACCESSIBILITY_ATOM(labelledby, "labelledby")
|
||||
ACCESSIBILITY_ATOM(owns, "owns")
|
||||
|
||||
// Alphabetical list of attributes
|
||||
ACCESSIBILITY_ATOM(acceltext, "acceltext")
|
||||
ACCESSIBILITY_ATOM(accesskey, "accesskey")
|
||||
ACCESSIBILITY_ATOM(alt, "alt")
|
||||
ACCESSIBILITY_ATOM(anonid, "anonid") // Used for ID's in XBL
|
||||
ACCESSIBILITY_ATOM(autocomplete, "autocomplete") // Used as attribute value too
|
||||
ACCESSIBILITY_ATOM(contenteditable, "contenteditable")
|
||||
ACCESSIBILITY_ATOM(control, "control")
|
||||
ACCESSIBILITY_ATOM(cycles, "cycles") // used for XUL cycler attribute
|
||||
ACCESSIBILITY_ATOM(curpos, "curpos") // XUL
|
||||
ACCESSIBILITY_ATOM(data, "data")
|
||||
ACCESSIBILITY_ATOM(disabled, "disabled")
|
||||
ACCESSIBILITY_ATOM(droppable, "droppable") // XUL combo box
|
||||
ACCESSIBILITY_ATOM(editable, "editable")
|
||||
ACCESSIBILITY_ATOM(_for, "for")
|
||||
@ -168,10 +159,8 @@ ACCESSIBILITY_ATOM(increment, "increment") // XUL
|
||||
ACCESSIBILITY_ATOM(lang, "lang")
|
||||
ACCESSIBILITY_ATOM(maxpos, "maxpos") // XUL
|
||||
ACCESSIBILITY_ATOM(minpos, "minpos") // XUL
|
||||
ACCESSIBILITY_ATOM(multiline, "multiline")
|
||||
ACCESSIBILITY_ATOM(name, "name")
|
||||
ACCESSIBILITY_ATOM(onclick, "onclick")
|
||||
ACCESSIBILITY_ATOM(readonly, "readonly")
|
||||
ACCESSIBILITY_ATOM(src, "src")
|
||||
ACCESSIBILITY_ATOM(summary, "summary")
|
||||
ACCESSIBILITY_ATOM(tabindex, "tabindex")
|
||||
@ -181,31 +170,18 @@ ACCESSIBILITY_ATOM(type, "type")
|
||||
ACCESSIBILITY_ATOM(value, "value")
|
||||
|
||||
// ARIA (DHTML accessibility) attributes
|
||||
ACCESSIBILITY_ATOM(atomic, "atomic")
|
||||
ACCESSIBILITY_ATOM(busy, "busy")
|
||||
ACCESSIBILITY_ATOM(channel, "channel")
|
||||
ACCESSIBILITY_ATOM(activedescendant, "activedescendant")
|
||||
ACCESSIBILITY_ATOM(checked, "checked")
|
||||
ACCESSIBILITY_ATOM(datatype, "datatype")
|
||||
ACCESSIBILITY_ATOM(dropeffect, "dropeffect")
|
||||
ACCESSIBILITY_ATOM(expanded, "expanded")
|
||||
ACCESSIBILITY_ATOM(grab, "grab")
|
||||
ACCESSIBILITY_ATOM(haspopup, "haspopup")
|
||||
ACCESSIBILITY_ATOM(invalid, "invalid")
|
||||
ACCESSIBILITY_ATOM(level, "level")
|
||||
ACCESSIBILITY_ATOM(live, "live")
|
||||
ACCESSIBILITY_ATOM(multiselectable, "multiselectable")
|
||||
ACCESSIBILITY_ATOM(posinset, "posinset")
|
||||
ACCESSIBILITY_ATOM(pressed, "pressed")
|
||||
ACCESSIBILITY_ATOM(relevant, "relevant")
|
||||
ACCESSIBILITY_ATOM(required, "required")
|
||||
// Also add to nsARIAMap.cpp and nsARIAMap.h
|
||||
// ARIA role attribute
|
||||
ACCESSIBILITY_ATOM(role, "role")
|
||||
ACCESSIBILITY_ATOM(secret, "secret")
|
||||
ACCESSIBILITY_ATOM(selected, "selected")
|
||||
ACCESSIBILITY_ATOM(setsize, "setsize")
|
||||
ACCESSIBILITY_ATOM(valuenow, "valuenow") // For DHTML widget values
|
||||
ACCESSIBILITY_ATOM(valuemin, "valuemin")
|
||||
ACCESSIBILITY_ATOM(valuemax, "valuemax")
|
||||
|
||||
// ARIA properties
|
||||
#define ARIA_PROPERTY(atom) ACCESSIBILITY_ATOM(atom, #atom)
|
||||
#include "nsAriaPropertyList.h"
|
||||
#undef ARIA_PROPERTY
|
||||
|
||||
#define ARIA_PROPERTY(atom) ACCESSIBILITY_ATOM(aria_##atom, "aria-"#atom)
|
||||
#include "nsAriaPropertyList.h"
|
||||
#undef ARIA_PROPERTY
|
||||
|
||||
// misc atoms
|
||||
// a form property used to obtain the default label
|
||||
|
@ -1431,22 +1431,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
|
||||
if (!newAcc && content->Tag() != nsAccessibilityAtoms::body && content->GetParent() &&
|
||||
(content->IsFocusable() ||
|
||||
(isHTML && nsAccUtils::HasListener(content, NS_LITERAL_STRING("click"))) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::describedby) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::labelledby) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::flowto) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::controls) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::atomic) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::busy) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::channel) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::datatype) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::dropeffect) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::grab) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::haspopup) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::live) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::relevant) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::required) ||
|
||||
content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::invalid) ||
|
||||
!role.IsEmpty())) {
|
||||
HasUniversalAriaProperty(content, aWeakShell) || !role.IsEmpty())) {
|
||||
// This content is focusable or has an interesting dynamic content accessibility property.
|
||||
// If it's interesting we need it in the accessibility hierarchy so that events or
|
||||
// other accessibles can point to it, or so that it can hold a state, etc.
|
||||
@ -1463,6 +1448,39 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
|
||||
return InitAccessible(newAcc, aAccessible);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccessibilityService::HasUniversalAriaProperty(nsIContent *aContent,
|
||||
nsIWeakReference *aWeakShell)
|
||||
{
|
||||
nsCOMPtr<nsIAccessibleDocument> docAccessible =
|
||||
nsAccessNode::GetDocAccessibleFor(aWeakShell);
|
||||
if (!docAccessible) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Precalculate |ariaPropTypes| so that HasAriaProperty() doesn't have to do that each time
|
||||
PRUint32 ariaPropTypes;
|
||||
docAccessible->GetAriaPropTypes(&ariaPropTypes);
|
||||
|
||||
return nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_atomic, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_busy, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_channel, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_controls, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_datatype, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_describedby, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_dropeffect, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_flowto, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_grab, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_haspopup, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_invalid, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_labelledby, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_live, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_owns, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_relevant, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_required, ariaPropTypes) ||
|
||||
nsAccUtils::HasAriaProperty(aContent, aWeakShell, eAria_sort, ariaPropTypes);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::GetRelevantContentNodeFor(nsIDOMNode *aNode,
|
||||
nsIDOMNode **aRelevantNode)
|
||||
|
@ -119,6 +119,16 @@ private:
|
||||
nsIAccessible **aAccessible);
|
||||
|
||||
static nsAccessibilityService *gAccessibilityService;
|
||||
|
||||
/**
|
||||
* Does this content node have a universal ARIA property set on it?
|
||||
* A universal ARIA property is one that can be defined on any element even if there is no role.
|
||||
*
|
||||
* @param aContent The content node to test
|
||||
* @param aWeakShell A weak reference to the pres shell
|
||||
* @return PR_TRUE if there is a universal ARIA property set on the node
|
||||
*/
|
||||
PRBool HasUniversalAriaProperty(nsIContent *aContent, nsIWeakReference *aWeakShell);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -42,10 +42,14 @@
|
||||
#include "nsPIAccessible.h"
|
||||
#include "nsAccessibleEventData.h"
|
||||
|
||||
#include "nsAccessNode.h"
|
||||
#include "nsARIAMap.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMAbstractView.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentView.h"
|
||||
#include "nsIDOMDocumentXBL.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIDOMXULSelectCntrlEl.h"
|
||||
#include "nsIDOMXULSelectCntrlItemEl.h"
|
||||
@ -410,3 +414,225 @@ nsAccUtils::GetID(nsIContent *aContent, nsAString& aID)
|
||||
nsIAtom *idAttribute = aContent->GetIDAttributeName();
|
||||
return idAttribute ? aContent->GetAttr(kNameSpaceID_None, idAttribute, aID) : PR_FALSE;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsAccUtils::GetAriaPropTypes(nsIContent *aContent, nsIWeakReference *aWeakShell)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aContent);
|
||||
|
||||
PRUint32 ariaPropTypes = 0;
|
||||
|
||||
// Get the doc accessible using the optimsal methodology
|
||||
nsCOMPtr<nsIAccessibleDocument> docAccessible;
|
||||
if (aWeakShell) {
|
||||
docAccessible = nsAccessNode::GetDocAccessibleFor(aWeakShell);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aContent);
|
||||
if (node) {
|
||||
docAccessible = nsAccessNode::GetDocAccessibleFor(node);
|
||||
}
|
||||
}
|
||||
if (docAccessible) {
|
||||
docAccessible->GetAriaPropTypes(&ariaPropTypes);
|
||||
}
|
||||
return ariaPropTypes;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccUtils::HasAriaProperty(nsIContent *aContent, nsIWeakReference *aWeakShell,
|
||||
EAriaProperty aProperty, PRUint32 aAriaPropTypes)
|
||||
{
|
||||
if (!aAriaPropTypes) {
|
||||
// The property types to check for is unknown, get it from the doc accessible
|
||||
aAriaPropTypes = GetAriaPropTypes(aContent, aWeakShell);
|
||||
}
|
||||
|
||||
return ((aAriaPropTypes & nsIAccessibleDocument::eCheckNamespaced) &&
|
||||
aContent->HasAttr(kNameSpaceID_WAIProperties,
|
||||
*nsARIAMap::gAriaAtomPtrsNS[aProperty])) ||
|
||||
((aAriaPropTypes & nsIAccessibleDocument::eCheckHyphenated) &&
|
||||
aContent->HasAttr(kNameSpaceID_None,
|
||||
*nsARIAMap::gAriaAtomPtrsHyphenated[aProperty]));
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccUtils::GetAriaProperty(nsIContent *aContent, nsIWeakReference *aWeakShell,
|
||||
EAriaProperty aProperty, nsAString& aValue,
|
||||
PRUint32 aAriaPropTypes)
|
||||
{
|
||||
aValue.Truncate();
|
||||
if (!aAriaPropTypes) {
|
||||
// The property types to check for is unknown, get it from the doc accessible
|
||||
aAriaPropTypes = GetAriaPropTypes(aContent, aWeakShell);
|
||||
}
|
||||
return ((aAriaPropTypes & nsIAccessibleDocument::eCheckNamespaced) &&
|
||||
aContent->GetAttr(kNameSpaceID_WAIProperties,
|
||||
*nsARIAMap::gAriaAtomPtrsNS[aProperty],
|
||||
aValue)) ||
|
||||
((aAriaPropTypes & nsIAccessibleDocument::eCheckHyphenated) &&
|
||||
aContent->GetAttr(kNameSpaceID_None,
|
||||
*nsARIAMap::gAriaAtomPtrsHyphenated[aProperty],
|
||||
aValue));
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsAccUtils::FindNeighbourPointingToNode(nsIContent *aForNode,
|
||||
EAriaProperty aAriaProperty,
|
||||
nsIAtom *aTagName,
|
||||
nsIAtom *aRelationAttr,
|
||||
PRUint32 aAncestorLevelsToSearch)
|
||||
{
|
||||
NS_ASSERTION(aAriaProperty == eAria_none || !aRelationAttr,
|
||||
"Cannot pass in both an ARIA relation property and an atom relation. Choose one");
|
||||
NS_ASSERTION(aAriaProperty != eAria_none || !aTagName,
|
||||
"Cannot use aTagName with ARIA relation property, because ARIA relations apply to any tag");
|
||||
nsCOMPtr<nsIContent> binding;
|
||||
nsAutoString controlID;
|
||||
if (!nsAccUtils::GetID(aForNode, controlID)) {
|
||||
binding = aForNode->GetBindingParent();
|
||||
if (binding == aForNode)
|
||||
return nsnull;
|
||||
|
||||
aForNode->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::anonid, controlID);
|
||||
if (controlID.IsEmpty())
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Look for label in subtrees of nearby ancestors
|
||||
PRUint32 count = 0;
|
||||
nsIContent *labelContent = nsnull;
|
||||
nsIContent *prevSearched = nsnull;
|
||||
|
||||
while (!labelContent && ++count <= aAncestorLevelsToSearch &&
|
||||
(aForNode = aForNode->GetParent()) != nsnull) {
|
||||
|
||||
if (aForNode == binding) {
|
||||
// When we reach the binding parent, make sure to check
|
||||
// all of its anonymous child subtrees
|
||||
nsCOMPtr<nsIDocument> doc = aForNode->GetCurrentDoc();
|
||||
nsCOMPtr<nsIDOMDocumentXBL> xblDoc(do_QueryInterface(doc));
|
||||
if (!xblDoc)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> nodes;
|
||||
nsCOMPtr<nsIDOMElement> forElm(do_QueryInterface(aForNode));
|
||||
xblDoc->GetAnonymousNodes(forElm, getter_AddRefs(nodes));
|
||||
if (!nodes)
|
||||
return nsnull;
|
||||
|
||||
PRUint32 length;
|
||||
nsresult rv = nodes->GetLength(&length);
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
for (PRUint32 index = 0; index < length && !labelContent; index++) {
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
rv = nodes->Item(index, getter_AddRefs(node));
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
|
||||
if (!content)
|
||||
return nsnull;
|
||||
|
||||
if (content != prevSearched) {
|
||||
labelContent = FindDescendantPointingToID(&controlID, content, aAriaProperty,
|
||||
aRelationAttr, nsnull, aTagName);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
labelContent = FindDescendantPointingToID(&controlID, aForNode, aAriaProperty,
|
||||
aRelationAttr, prevSearched, aTagName);
|
||||
prevSearched = aForNode;
|
||||
}
|
||||
|
||||
return labelContent;
|
||||
}
|
||||
|
||||
// Pass in aAriaProperty = null and aRelationAttr == nsnull if any <label> will do
|
||||
nsIContent*
|
||||
nsAccUtils::FindDescendantPointingToID(const nsString *aId,
|
||||
nsIContent *aLookContent,
|
||||
EAriaProperty aAriaProperty,
|
||||
nsIAtom *aRelationAttr,
|
||||
nsIContent *aExcludeContent,
|
||||
nsIAtom *aTagType)
|
||||
{
|
||||
// Surround id with spaces for search
|
||||
nsCAutoString idWithSpaces(' ');
|
||||
LossyAppendUTF16toASCII(*aId, idWithSpaces);
|
||||
idWithSpaces += ' ';
|
||||
PRUint32 ariaPropTypes = (aAriaProperty == eAria_none) ? 0 :
|
||||
nsAccUtils::GetAriaPropTypes(aLookContent);
|
||||
return FindDescendantPointingToIDImpl(idWithSpaces, aLookContent,
|
||||
aAriaProperty, ariaPropTypes,
|
||||
aRelationAttr, aExcludeContent, aTagType);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsAccUtils::FindDescendantPointingToIDImpl(nsCString& aIdWithSpaces,
|
||||
nsIContent *aLookContent,
|
||||
EAriaProperty aAriaProperty,
|
||||
PRUint32 aAriaPropTypes,
|
||||
nsIAtom *aRelationAttr,
|
||||
nsIContent *aExcludeContent,
|
||||
nsIAtom *aTagType)
|
||||
{
|
||||
if (aAriaProperty != eAria_none) { // Tag ignored for ARIA properties, which can apply to anything
|
||||
nsAutoString idList;
|
||||
if (nsAccUtils::GetAriaProperty(aLookContent, nsnull, aAriaProperty,
|
||||
idList, aAriaPropTypes)) {
|
||||
idList.Insert(' ', 0); // Surround idlist with spaces for search
|
||||
idList.Append(' ');
|
||||
// idList is now a set of id's with spaces around each,
|
||||
// and id also has spaces around it.
|
||||
// If id is a substring of idList then we have a match
|
||||
if (idList.Find(aIdWithSpaces) != -1) {
|
||||
return aLookContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!aTagType || aLookContent->Tag() == aTagType) {
|
||||
// Tag matches
|
||||
if (aRelationAttr) {
|
||||
// Check for ID in the attribute aRelationAttr, which can be a list
|
||||
nsAutoString idList;
|
||||
if (aLookContent->GetAttr(kNameSpaceID_None, aRelationAttr, idList)) {
|
||||
idList.Insert(' ', 0); // Surround idlist with spaces for search
|
||||
idList.Append(' ');
|
||||
// idList is now a set of id's with spaces around each,
|
||||
// and id also has spaces around it.
|
||||
// If id is a substring of idList then we have a match
|
||||
if (idList.Find(aIdWithSpaces) != -1) {
|
||||
return aLookContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aTagType) {
|
||||
// Don't bother to search descendants of an element with matching tag.
|
||||
// That would be like looking for a nested <label> or <description>
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively search descendants for match
|
||||
PRUint32 count = 0;
|
||||
nsIContent *child;
|
||||
nsIContent *labelContent = nsnull;
|
||||
|
||||
while ((child = aLookContent->GetChildAt(count++)) != nsnull) {
|
||||
if (child != aExcludeContent) {
|
||||
labelContent = FindDescendantPointingToIDImpl(aIdWithSpaces, child,
|
||||
aAriaProperty, aAriaPropTypes,
|
||||
aRelationAttr, aExcludeContent, aTagType);
|
||||
if (labelContent) {
|
||||
return labelContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsIAccessible.h"
|
||||
#include "nsARIAMap.h"
|
||||
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIPersistentProperties2.h"
|
||||
@ -48,6 +49,7 @@
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsIAccessibleDocument.h"
|
||||
|
||||
class nsAccUtils
|
||||
{
|
||||
@ -188,6 +190,92 @@ public:
|
||||
* @return PR_TRUE if there is an ID set for this node
|
||||
*/
|
||||
static PRBool GetID(nsIContent *aContent, nsAString& aID);
|
||||
|
||||
/**
|
||||
* Find out what kinds of properties are checked for this content node's document
|
||||
* @param aContent The content node we're going to look for ARIA properties on
|
||||
* @param aWeakShell The presshell for the document we're looking for ARIA properties on (optional optimization)
|
||||
* @return The types of properties checked
|
||||
*/
|
||||
static PRUint32 GetAriaPropTypes(nsIContent *aContent, nsIWeakReference *aWeakShell = nsnull);
|
||||
|
||||
/**
|
||||
* Check for the relevant ARIA property. Can check either for a properly namespaced property,
|
||||
* or a fake hyphenated namespace using "aria-" as a prefix in HTML. Is optimized to only
|
||||
* check for each type when it is possible to exist on a given node.
|
||||
* @param aContent Node to check for property on
|
||||
* @param aWeakShell The current pres shell if known (as an optimization), or nsnull if not known by caller
|
||||
* @param aProperty An enumeration indicating which ARIA property we are checking
|
||||
* @param aAriaPropTypes A bitflag for the property types to check for (namespaced, hyphenated or both), if known by caller
|
||||
* @return PR_TRUE if the property is defined
|
||||
*/
|
||||
static PRBool HasAriaProperty(nsIContent *aContent, nsIWeakReference *aWeakShell,
|
||||
EAriaProperty aProperty,
|
||||
PRUint32 aCheckFlags = 0);
|
||||
|
||||
/**
|
||||
* Get the relevant ARIA property. Can check either for a properly namespaced property,
|
||||
* or a fake hyphenated namespace using "aria-" as a prefix in HTML. Is optimized to only
|
||||
* check for each type when it is possible to exist on a given node.
|
||||
* @param aContent Node to check for property on
|
||||
* @param aWeakShell The current pres shell if known (as an optimization), or nsnull if not known by caller
|
||||
* @param aProperty An enumeration indicating which ARIA property we are checking
|
||||
* @param aValue Where to store the property value
|
||||
* @param aAriaPropTypes A bitflag for the property types to check for (namespaced, hyphenated or both), if known by caller
|
||||
* @return PR_TRUE if the property is defined
|
||||
*/
|
||||
static PRBool GetAriaProperty(nsIContent *aContent, nsIWeakReference *aWeakShell,
|
||||
EAriaProperty aProperty, nsAString& aValue,
|
||||
PRUint32 aCheckFlags = 0);
|
||||
|
||||
/**
|
||||
* Search element in neighborhood of the given element by tag name and
|
||||
* attribute value that equals to ID attribute of the given element.
|
||||
* ID attribute can be either 'id' attribute or 'anonid' if the element is
|
||||
* anonymous.
|
||||
*
|
||||
* @param aAriaProperty - the ARIA property to search for or eAria_none, if aRelationAttr is passed in
|
||||
* @param aForNode - the given element the search is performed for
|
||||
* @param aTagName - tag name of searched element, or nsnull for any -- ignored if aAriaProperty passed in
|
||||
* @param aRelationAttr - attribute name of searched element, ignored if aAriaProperty passed in
|
||||
* @param aAncestorLevelsToSearch - points how is the neighborhood of the
|
||||
* given element big.
|
||||
*/
|
||||
static nsIContent *FindNeighbourPointingToNode(nsIContent *aForNode,
|
||||
EAriaProperty aAriaProperty,
|
||||
nsIAtom *aTagName = nsnull,
|
||||
nsIAtom *aRelationAttr = nsnull,
|
||||
PRUint32 aAncestorLevelsToSearch = 5);
|
||||
|
||||
/**
|
||||
* Search for element that satisfies the requirements in subtree of the given
|
||||
* element. The requirements are tag name, attribute name and value of
|
||||
* attribute.
|
||||
*
|
||||
* @param aId - value of searched attribute
|
||||
* @param aLookContent - element that search is performed inside
|
||||
* @param aAriaProperty - the ARIA property to search for or eAria_none, if aRelationAttr is passed in
|
||||
* @param aRelationAttr - searched attribute-- ignored if aAriaProperty passed in
|
||||
* @param if both aAriaProperty and aRelationAttr are null, then any element with aTagType will do
|
||||
* @param aExcludeContent - element that is skiped for search
|
||||
* @param aTagType - tag name of searched element, by default it is 'label' --
|
||||
* ignored if aAriaProperty passed in
|
||||
*/
|
||||
static nsIContent *FindDescendantPointingToID(const nsString *aId,
|
||||
nsIContent *aLookContent,
|
||||
EAriaProperty aAriaProperty,
|
||||
nsIAtom *aRelationAttr = nsnull,
|
||||
nsIContent *aExcludeContent = nsnull,
|
||||
nsIAtom *aTagType = nsAccessibilityAtoms::label);
|
||||
|
||||
// Helper for FindDescendantPointingToID(), same args
|
||||
static nsIContent *FindDescendantPointingToIDImpl(nsCString& aIdWithSpaces,
|
||||
nsIContent *aLookContent,
|
||||
EAriaProperty aAriaProperty,
|
||||
PRUint32 aAriaPropTypes,
|
||||
nsIAtom *aRelationAttr = nsnull,
|
||||
nsIContent *aExcludeContent = nsnull,
|
||||
nsIAtom *aTagType = nsAccessibilityAtoms::label);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -75,6 +75,7 @@
|
||||
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "prdtoa.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIPrefService.h"
|
||||
@ -197,16 +198,13 @@ nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
}
|
||||
if (HasRoleAttribute(content)) {
|
||||
// If we have an XHTML role attribute present and the
|
||||
// waistate multiselectable attribute not empty or false, then we need
|
||||
// waistate multiselectable attribute is true, then we need
|
||||
// to support nsIAccessibleSelectable
|
||||
// If either attribute (role or multiselectable) change, then we'll
|
||||
// destroy this accessible so that we can follow COM identity rules.
|
||||
static nsIContent::AttrValuesArray strings[] =
|
||||
{&nsAccessibilityAtoms::_empty, &nsAccessibilityAtoms::_false, nsnull};
|
||||
if (content->FindAttrValueIn(kNameSpaceID_WAIProperties ,
|
||||
nsAccessibilityAtoms::multiselectable,
|
||||
strings, eCaseMatters) ==
|
||||
nsIContent::ATTR_VALUE_NO_MATCH) {
|
||||
nsAutoString multiselectable;
|
||||
if (nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_multiselectable, multiselectable) &&
|
||||
multiselectable.EqualsLiteral("true")) {
|
||||
*aInstancePtr = static_cast<nsIAccessibleSelectable*>(this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
@ -303,14 +301,15 @@ NS_IMETHODIMP nsAccessible::GetDescription(nsAString& aDescription)
|
||||
}
|
||||
if (!content->IsNodeOfType(nsINode::eTEXT)) {
|
||||
nsAutoString description;
|
||||
nsresult rv = GetTextFromRelationID(nsAccessibilityAtoms::describedby, description);
|
||||
nsresult rv = GetTextFromRelationID(eAria_describedby, description);
|
||||
if (NS_FAILED(rv)) {
|
||||
PRBool isXUL = content->IsNodeOfType(nsINode::eXUL);
|
||||
if (isXUL) {
|
||||
// Try XUL <description control="[id]">description text</description>
|
||||
nsIContent *descriptionContent =
|
||||
FindNeighbourPointingToNode(content, nsAccessibilityAtoms::description,
|
||||
nsAccessibilityAtoms::control);
|
||||
nsAccUtils::FindNeighbourPointingToNode(content, eAria_none,
|
||||
nsAccessibilityAtoms::description,
|
||||
nsAccessibilityAtoms::control);
|
||||
|
||||
if (descriptionContent) {
|
||||
// We have a description content node
|
||||
@ -1377,10 +1376,24 @@ NS_IMETHODIMP nsAccessible::SetSelected(PRBool aSelect)
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
NS_ASSERTION(content, "Called for dead accessible");
|
||||
|
||||
// For DHTML widgets use WAI namespace
|
||||
PRUint32 nameSpaceID = mRoleMapEntry ? kNameSpaceID_WAIProperties : kNameSpaceID_None;
|
||||
// For ARIA widgets use WAI namespace or hyphenated property, depending on what doc accepts
|
||||
PRUint32 nameSpaceID = kNameSpaceID_None; // Default
|
||||
if (mRoleMapEntry) {
|
||||
if (0 == (nsAccUtils::GetAriaPropTypes(content, mWeakShell) &
|
||||
nsIAccessibleDocument::eCheckNamespaced)) {
|
||||
// No WAI namespaced properties used in this doc, use hyphenated property
|
||||
if (aSelect) {
|
||||
return content->SetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_selected,
|
||||
NS_LITERAL_STRING("true"), PR_TRUE);
|
||||
}
|
||||
return content->UnsetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_selected, PR_TRUE);
|
||||
}
|
||||
nameSpaceID = kNameSpaceID_WAIProperties;
|
||||
}
|
||||
// Use normal property
|
||||
if (aSelect) {
|
||||
return content->SetAttr(nameSpaceID, nsAccessibilityAtoms::selected, NS_LITERAL_STRING("true"), PR_TRUE);
|
||||
return content->SetAttr(nameSpaceID, nsAccessibilityAtoms::selected,
|
||||
NS_LITERAL_STRING("true"), PR_TRUE);
|
||||
}
|
||||
return content->UnsetAttr(nameSpaceID, nsAccessibilityAtoms::selected, PR_TRUE);
|
||||
}
|
||||
@ -1633,8 +1646,9 @@ nsresult nsAccessible::AppendFlatStringFromSubtreeRecurse(nsIContent *aContent,
|
||||
nsIContent *nsAccessible::GetLabelContent(nsIContent *aForNode)
|
||||
{
|
||||
if (aForNode->IsNodeOfType(nsINode::eXUL))
|
||||
return FindNeighbourPointingToNode(aForNode, nsAccessibilityAtoms::label,
|
||||
nsAccessibilityAtoms::control);
|
||||
return nsAccUtils::FindNeighbourPointingToNode(aForNode, eAria_none,
|
||||
nsAccessibilityAtoms::label,
|
||||
nsAccessibilityAtoms::control);
|
||||
|
||||
return GetHTMLLabelContent(aForNode);
|
||||
}
|
||||
@ -1662,15 +1676,15 @@ nsIContent* nsAccessible::GetHTMLLabelContent(nsIContent *aForNode)
|
||||
break;
|
||||
}
|
||||
// Actually we'll be walking down the content this time, with a depth first search
|
||||
return FindDescendantPointingToID(&forId, walkUpContent,
|
||||
nsAccessibilityAtoms::_for);
|
||||
return nsAccUtils::FindDescendantPointingToID(&forId, walkUpContent, eAria_none,
|
||||
nsAccessibilityAtoms::_for);
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult nsAccessible::GetTextFromRelationID(nsIAtom *aIDAttrib, nsString &aName)
|
||||
nsresult nsAccessible::GetTextFromRelationID(EAriaProperty aIDProperty, nsString &aName)
|
||||
{
|
||||
// Get DHTML name from content subtree pointed to by ID attribute
|
||||
aName.Truncate();
|
||||
@ -1678,7 +1692,7 @@ nsresult nsAccessible::GetTextFromRelationID(nsIAtom *aIDAttrib, nsString &aName
|
||||
NS_ASSERTION(content, "Called from shutdown accessible");
|
||||
|
||||
nsAutoString ids;
|
||||
if (!content->GetAttr(kNameSpaceID_WAIProperties, aIDAttrib, ids)) {
|
||||
if (!nsAccUtils::GetAriaProperty(content, mWeakShell, aIDProperty, ids)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
ids.CompressWhitespace(PR_TRUE, PR_TRUE);
|
||||
@ -1721,129 +1735,6 @@ nsresult nsAccessible::GetTextFromRelationID(nsIAtom *aIDAttrib, nsString &aName
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsAccessible::FindNeighbourPointingToNode(nsIContent *aForNode,
|
||||
nsIAtom *aTagName, nsIAtom *aRelationAttr,
|
||||
PRUint32 aRelationNameSpaceID,
|
||||
PRUint32 aAncestorLevelsToSearch)
|
||||
{
|
||||
nsCOMPtr<nsIContent> binding;
|
||||
nsAutoString controlID;
|
||||
if (!nsAccUtils::GetID(aForNode, controlID)) {
|
||||
binding = aForNode->GetBindingParent();
|
||||
if (binding == aForNode)
|
||||
return nsnull;
|
||||
|
||||
aForNode->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::anonid, controlID);
|
||||
if (controlID.IsEmpty())
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Look for label in subtrees of nearby ancestors
|
||||
PRUint32 count = 0;
|
||||
nsIContent *labelContent = nsnull;
|
||||
nsIContent *prevSearched = nsnull;
|
||||
|
||||
while (!labelContent && ++count <= aAncestorLevelsToSearch &&
|
||||
(aForNode = aForNode->GetParent()) != nsnull) {
|
||||
|
||||
if (aForNode == binding) {
|
||||
// When we reach the binding parent, make sure to check
|
||||
// all of its anonymous child subtrees
|
||||
nsCOMPtr<nsIDocument> doc = aForNode->GetCurrentDoc();
|
||||
nsCOMPtr<nsIDOMDocumentXBL> xblDoc(do_QueryInterface(doc));
|
||||
if (!xblDoc)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> nodes;
|
||||
nsCOMPtr<nsIDOMElement> forElm(do_QueryInterface(aForNode));
|
||||
xblDoc->GetAnonymousNodes(forElm, getter_AddRefs(nodes));
|
||||
if (!nodes)
|
||||
return nsnull;
|
||||
|
||||
PRUint32 length;
|
||||
nsresult rv = nodes->GetLength(&length);
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
for (PRUint32 index = 0; index < length && !labelContent; index++) {
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
rv = nodes->Item(index, getter_AddRefs(node));
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
|
||||
if (!content)
|
||||
return nsnull;
|
||||
|
||||
if (content != prevSearched) {
|
||||
labelContent = FindDescendantPointingToID(&controlID, content, aRelationAttr,
|
||||
aRelationNameSpaceID, nsnull,
|
||||
aTagName);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
labelContent = FindDescendantPointingToID(&controlID, aForNode,
|
||||
aRelationAttr, aRelationNameSpaceID,
|
||||
prevSearched, aTagName);
|
||||
prevSearched = aForNode;
|
||||
}
|
||||
|
||||
return labelContent;
|
||||
}
|
||||
|
||||
// Pass in aRelationAttr == nsnull if any <label> will do
|
||||
nsIContent*
|
||||
nsAccessible::FindDescendantPointingToID(const nsAString *aId,
|
||||
nsIContent *aLookContent,
|
||||
nsIAtom *aRelationAttr,
|
||||
PRUint32 aRelationNameSpaceID,
|
||||
nsIContent *aExcludeContent,
|
||||
nsIAtom *aTagType)
|
||||
{
|
||||
if (!aTagType || aLookContent->Tag() == aTagType) {
|
||||
if (aRelationAttr) {
|
||||
// Check for ID in the attribute aRelationAttr, which can be a list
|
||||
nsAutoString idList;
|
||||
if (aLookContent->GetAttr(aRelationNameSpaceID, aRelationAttr, idList)) {
|
||||
idList.Insert(' ', 0); // Surround idlist with spaces for search
|
||||
idList.Append(' ');
|
||||
nsAutoString id(*aId);
|
||||
id.Insert(' ', 0); // Surround id with spaces for search
|
||||
id.Append(' ');
|
||||
// idList is now a set of id's with spaces around each,
|
||||
// and id also has spaces around it.
|
||||
// If id is a substring of idList then we have a match
|
||||
if (idList.Find(id) != -1) {
|
||||
return aLookContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aTagType) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively search descendants for labels
|
||||
PRUint32 count = 0;
|
||||
nsIContent *child;
|
||||
nsIContent *labelContent = nsnull;
|
||||
|
||||
while ((child = aLookContent->GetChildAt(count++)) != nsnull) {
|
||||
if (child != aExcludeContent) {
|
||||
labelContent = FindDescendantPointingToID(aId, child, aRelationAttr,
|
||||
aRelationNameSpaceID, aExcludeContent,
|
||||
aTagType);
|
||||
if (labelContent) {
|
||||
return labelContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only called if the element is not a nsIDOMXULControlElement. Initially walks up
|
||||
* the DOM tree to the form, concatonating label elements as it goes. Then checks for
|
||||
@ -1858,7 +1749,7 @@ nsresult nsAccessible::GetHTMLName(nsAString& aLabel, PRBool aCanAggregateSubtre
|
||||
|
||||
// Check for DHTML accessibility labelledby relationship property
|
||||
nsAutoString label;
|
||||
nsresult rv = GetTextFromRelationID(nsAccessibilityAtoms::labelledby, label);
|
||||
nsresult rv = GetTextFromRelationID(eAria_labelledby, label);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aLabel = label;
|
||||
return rv;
|
||||
@ -1909,7 +1800,7 @@ nsresult nsAccessible::GetXULName(nsAString& aLabel, PRBool aCanAggregateSubtree
|
||||
|
||||
// First check for label override via accessibility labelledby relationship
|
||||
nsAutoString label;
|
||||
nsresult rv = GetTextFromRelationID(nsAccessibilityAtoms::labelledby, label);
|
||||
nsresult rv = GetTextFromRelationID(eAria_labelledby, label);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aLabel = label;
|
||||
return rv;
|
||||
@ -1942,8 +1833,9 @@ nsresult nsAccessible::GetXULName(nsAString& aLabel, PRBool aCanAggregateSubtree
|
||||
if (NS_FAILED(rv) || label.IsEmpty()) {
|
||||
label.Truncate();
|
||||
nsIContent *labelContent =
|
||||
FindNeighbourPointingToNode(content, nsAccessibilityAtoms::label,
|
||||
nsAccessibilityAtoms::control);
|
||||
nsAccUtils::FindNeighbourPointingToNode(content, eAria_none,
|
||||
nsAccessibilityAtoms::label,
|
||||
nsAccessibilityAtoms::control);
|
||||
|
||||
nsCOMPtr<nsIDOMXULLabelElement> xulLabel(do_QueryInterface(labelContent));
|
||||
// Check if label's value attribute is used
|
||||
@ -2040,9 +1932,9 @@ NS_IMETHODIMP nsAccessible::GetFinalRole(PRUint32 *aRole)
|
||||
// This is where the nsIAccessible role depends on both the role and ARIA state
|
||||
if (*aRole == nsIAccessibleRole::ROLE_ENTRY) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
|
||||
if (content &&
|
||||
content->AttrValueIs(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::secret,
|
||||
nsAccessibilityAtoms::_true, eCaseMatters)) {
|
||||
nsAutoString secret;
|
||||
if (content && nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_secret, secret) &&
|
||||
secret.EqualsLiteral("true")) {
|
||||
// For entry field with aaa:secret="true"
|
||||
*aRole = nsIAccessibleRole::ROLE_PASSWORD_TEXT;
|
||||
}
|
||||
@ -2050,15 +1942,18 @@ NS_IMETHODIMP nsAccessible::GetFinalRole(PRUint32 *aRole)
|
||||
else if (*aRole == nsIAccessibleRole::ROLE_PUSHBUTTON) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
|
||||
if (content) {
|
||||
if (content->HasAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::pressed)) {
|
||||
if (nsAccUtils::HasAriaProperty(content, mWeakShell, eAria_pressed)) {
|
||||
// For aaa:pressed="false" or aaa:pressed="true"
|
||||
// For simplicity, any pressed attribute indicates it's a toggle button
|
||||
*aRole = nsIAccessibleRole::ROLE_TOGGLE_BUTTON;
|
||||
}
|
||||
else if (content->AttrValueIs(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::haspopup,
|
||||
nsAccessibilityAtoms::_true, eCaseMatters)) {
|
||||
// For button with aaa:haspopup="true"
|
||||
*aRole = nsIAccessibleRole::ROLE_BUTTONMENU;
|
||||
else {
|
||||
nsAutoString haspopup;
|
||||
if (nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_haspopup, haspopup) &&
|
||||
haspopup.EqualsLiteral("true")) {
|
||||
// For button with aaa:haspopup="true"
|
||||
*aRole = nsIAccessibleRole::ROLE_BUTTONMENU;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2099,16 +1994,20 @@ nsAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("xml-roles"), xmlRole, oldValueUnused);
|
||||
}
|
||||
|
||||
char *ariaProperties[] = { "live", "channel", "atomic", "relevant", "datatype", "level",
|
||||
// Make sure to keep these two arrays in sync
|
||||
PRUint32 ariaPropTypes = nsAccUtils::GetAriaPropTypes(content, mWeakShell);
|
||||
char *ariaPropertyString[] = { "live", "channel", "atomic", "relevant", "datatype", "level",
|
||||
"posinset", "setsize", "sort", "grab", "dropeffect"};
|
||||
|
||||
for (PRUint32 index = 0; index < NS_ARRAY_LENGTH(ariaProperties); index ++) {
|
||||
EAriaProperty ariaPropertyEnum[] = { eAria_live, eAria_channel, eAria_atomic, eAria_relevant,
|
||||
eAria_datatype, eAria_level, eAria_posinset, eAria_setsize,
|
||||
eAria_sort, eAria_grab, eAria_dropeffect};
|
||||
NS_ASSERTION(NS_ARRAY_LENGTH(ariaPropertyString) == NS_ARRAY_LENGTH(ariaPropertyEnum),
|
||||
"ARIA attributes and object property name arrays out of sync");
|
||||
for (PRUint32 index = 0; index < NS_ARRAY_LENGTH(ariaPropertyString); index ++) {
|
||||
nsAutoString value;
|
||||
nsCOMPtr<nsIAtom> attr = do_GetAtom(ariaProperties[index]);
|
||||
NS_ENSURE_TRUE(attr, NS_ERROR_OUT_OF_MEMORY);
|
||||
if (content->GetAttr(kNameSpaceID_WAIProperties, attr, value)) {
|
||||
if (nsAccUtils::GetAriaProperty(content, mWeakShell, ariaPropertyEnum[index], value, ariaPropTypes)) {
|
||||
ToLowerCase(value);
|
||||
attributes->SetStringProperty(nsDependentCString(ariaProperties[index]), value, oldValueUnused);
|
||||
attributes->SetStringProperty(nsDependentCString(ariaPropertyString[index]), value, oldValueUnused);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2116,20 +2015,20 @@ nsAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
|
||||
// the live region attribute
|
||||
nsAutoString atomic, live, relevant, channel, busy;
|
||||
while (content) {
|
||||
if (relevant.IsEmpty() &&
|
||||
content->GetAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::relevant, relevant))
|
||||
if (relevant.IsEmpty() &&
|
||||
nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_relevant, relevant, ariaPropTypes))
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("container-relevant"), relevant, oldValueUnused);
|
||||
if (live.IsEmpty() &&
|
||||
content->GetAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::live, live))
|
||||
nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_live, live, ariaPropTypes))
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("container-live"), live, oldValueUnused);
|
||||
if (channel.IsEmpty() &&
|
||||
content->GetAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::channel, channel))
|
||||
nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_channel, channel, ariaPropTypes))
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("container-channel"), channel, oldValueUnused);
|
||||
if (atomic.IsEmpty() &&
|
||||
content->GetAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::atomic, atomic))
|
||||
nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_atomic, atomic, ariaPropTypes))
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("container-atomic"), atomic, oldValueUnused);
|
||||
if (busy.IsEmpty() &&
|
||||
content->GetAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::busy, busy))
|
||||
nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_busy, busy, ariaPropTypes))
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("container-busy"), busy, oldValueUnused);
|
||||
content = content->GetParent();
|
||||
}
|
||||
@ -2264,14 +2163,12 @@ PRBool nsAccessible::MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut
|
||||
nsStateMapEntry *aStateMapEntry)
|
||||
{
|
||||
// Return true if we should continue
|
||||
if (!aStateMapEntry->attributeName) {
|
||||
if (aStateMapEntry->attributeName == eAria_none) {
|
||||
return PR_FALSE; // Stop looking -- no more states
|
||||
}
|
||||
|
||||
nsAutoString attribValue;
|
||||
nsCOMPtr<nsIAtom> attribAtom = do_GetAtom(aStateMapEntry->attributeName); // XXX put atoms directly in entry
|
||||
NS_ENSURE_TRUE(attribAtom, NS_ERROR_OUT_OF_MEMORY);
|
||||
if (aContent->GetAttr(kNameSpaceID_WAIProperties, attribAtom, attribValue)) {
|
||||
if (nsAccUtils::GetAriaProperty(aContent, mWeakShell, aStateMapEntry->attributeName, attribValue)) {
|
||||
if (aStateMapEntry->attributeValue == kBoolState) {
|
||||
// No attribute value map specified in state map entry indicates state cleared
|
||||
if (attribValue.EqualsLiteral("false")) {
|
||||
@ -2335,8 +2232,7 @@ nsAccessible::GetFinalState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
NS_ENSURE_STATE(content);
|
||||
|
||||
nsAutoString autocomplete;
|
||||
if (content->GetAttr(kNameSpaceID_WAIProperties,
|
||||
nsAccessibilityAtoms::autocomplete, autocomplete) &&
|
||||
if (nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_autocomplete, autocomplete) &&
|
||||
(autocomplete.EqualsIgnoreCase("inline") ||
|
||||
autocomplete.EqualsIgnoreCase("list") ||
|
||||
autocomplete.EqualsIgnoreCase("both"))) {
|
||||
@ -2345,9 +2241,9 @@ nsAccessible::GetFinalState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
|
||||
// XXX We can remove this hack once we support RDF-based role & state maps
|
||||
if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_ENTRY) {
|
||||
if (content->AttrValueIs(kNameSpaceID_WAIProperties,
|
||||
nsAccessibilityAtoms::multiline,
|
||||
nsAccessibilityAtoms::_true, eCaseMatters)) {
|
||||
nsAutoString multiline;
|
||||
if (nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_multiline, multiline) &&
|
||||
multiline.EqualsLiteral("true")) {
|
||||
*aExtraState |= nsIAccessibleStates::EXT_STATE_MULTI_LINE;
|
||||
}
|
||||
else {
|
||||
@ -2393,8 +2289,7 @@ nsAccessible::GetARIAState()
|
||||
|
||||
PRUint32 ariaState = 0;
|
||||
PRUint32 index = 0;
|
||||
while (nsARIAMap::gWAIUnivStateMap[index].attributeName != nsnull) {
|
||||
MappedAttrState(content, &ariaState, &nsARIAMap::gWAIUnivStateMap[index]);
|
||||
while (MappedAttrState(content, &ariaState, &nsARIAMap::gWAIUnivStateMap[index])) {
|
||||
++ index;
|
||||
}
|
||||
|
||||
@ -2438,8 +2333,7 @@ NS_IMETHODIMP nsAccessible::GetValue(nsAString& aValue)
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
if (content && content->GetAttr(kNameSpaceID_WAIProperties,
|
||||
nsAccessibilityAtoms::valuenow, aValue)) {
|
||||
if (content && nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_valuenow, aValue)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
@ -2450,15 +2344,13 @@ NS_IMETHODIMP nsAccessible::GetValue(nsAString& aValue)
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetMaximumValue(double *aMaximumValue)
|
||||
{
|
||||
return GetAttrValue(kNameSpaceID_WAIProperties,
|
||||
nsAccessibilityAtoms::valuemax, aMaximumValue);
|
||||
return GetAttrValue(eAria_valuemax, aMaximumValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetMinimumValue(double *aMinimumValue)
|
||||
{
|
||||
return GetAttrValue(kNameSpaceID_WAIProperties,
|
||||
nsAccessibilityAtoms::valuemin, aMinimumValue);
|
||||
return GetAttrValue(eAria_valuemin, aMinimumValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -2474,8 +2366,7 @@ nsAccessible::GetMinimumIncrement(double *aMinIncrement)
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetCurrentValue(double *aValue)
|
||||
{
|
||||
return GetAttrValue(kNameSpaceID_WAIProperties,
|
||||
nsAccessibilityAtoms::valuenow, aValue);
|
||||
return GetAttrValue(eAria_valuenow, aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -2506,6 +2397,12 @@ nsAccessible::SetCurrentValue(double aValue)
|
||||
|
||||
nsAutoString newValue;
|
||||
newValue.AppendFloat(aValue);
|
||||
if (0 == (nsAccUtils::GetAriaPropTypes(content, mWeakShell) &
|
||||
nsIAccessibleDocument::eCheckNamespaced)) {
|
||||
// No WAI namespaced properties used in this doc
|
||||
return content->SetAttr(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::aria_valuenow, newValue, PR_TRUE);
|
||||
}
|
||||
return content->SetAttr(kNameSpaceID_WAIProperties,
|
||||
nsAccessibilityAtoms::valuenow, newValue, PR_TRUE);
|
||||
}
|
||||
@ -2612,39 +2509,16 @@ NS_IMETHODIMP nsAccessible::GetAccessibleBelow(nsIAccessible **_retval)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMNode>
|
||||
nsAccessible::FindNeighbourPointingToThis(nsIAtom *aRelationAttr,
|
||||
PRUint32 aRelationNameSpaceID,
|
||||
PRUint32 aAncestorLevelsToSearch)
|
||||
{
|
||||
nsIContent *content = GetRoleContent(mDOMNode);
|
||||
if (!content)
|
||||
return nsnull; // Node shut down
|
||||
|
||||
nsIContent* description = FindNeighbourPointingToNode(content, nsnull,
|
||||
aRelationAttr,
|
||||
aRelationNameSpaceID,
|
||||
aAncestorLevelsToSearch);
|
||||
|
||||
if (!description)
|
||||
return nsnull;
|
||||
|
||||
nsIDOMNode *relatedNode;
|
||||
CallQueryInterface(description, &relatedNode);
|
||||
return relatedNode;
|
||||
}
|
||||
|
||||
nsIDOMNode* nsAccessible::GetAtomicRegion()
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
|
||||
nsIContent *loopContent = content;
|
||||
nsAutoString atomic;
|
||||
PRUint32 ariaPropTypes = nsAccUtils::GetAriaPropTypes(content, mWeakShell);
|
||||
|
||||
while (loopContent) {
|
||||
loopContent->GetAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::atomic, atomic);
|
||||
if (!atomic.IsEmpty()) {
|
||||
break;
|
||||
}
|
||||
while (loopContent && !nsAccUtils::GetAriaProperty(loopContent, mWeakShell,
|
||||
eAria_atomic, atomic,
|
||||
ariaPropTypes)) {
|
||||
loopContent = loopContent->GetParent();
|
||||
}
|
||||
|
||||
@ -2683,43 +2557,33 @@ NS_IMETHODIMP nsAccessible::GetAccessibleRelated(PRUint32 aRelationType, nsIAcce
|
||||
content->GetAttr(kNameSpaceID_None, relatedIDAttr, relatedID);
|
||||
}
|
||||
if (relatedID.IsEmpty()) {
|
||||
const PRUint32 kAncestorLevelsToSearch = 3;
|
||||
relatedNode = FindNeighbourPointingToThis(nsAccessibilityAtoms::labelledby,
|
||||
kNameSpaceID_WAIProperties,
|
||||
kAncestorLevelsToSearch);
|
||||
relatedNode =
|
||||
do_QueryInterface(nsAccUtils::FindNeighbourPointingToNode(content, eAria_labelledby));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsIAccessibleRelation::RELATION_LABELLED_BY:
|
||||
{
|
||||
content->GetAttr(kNameSpaceID_WAIProperties,
|
||||
nsAccessibilityAtoms::labelledby, relatedID);
|
||||
if (relatedID.IsEmpty()) {
|
||||
if (!nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_labelledby, relatedID)) {
|
||||
relatedNode = do_QueryInterface(GetLabelContent(content));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsIAccessibleRelation::RELATION_DESCRIBED_BY:
|
||||
{
|
||||
content->GetAttr(kNameSpaceID_WAIProperties,
|
||||
nsAccessibilityAtoms::describedby, relatedID);
|
||||
if (relatedID.IsEmpty()) {
|
||||
nsIContent *description =
|
||||
FindNeighbourPointingToNode(content,
|
||||
nsAccessibilityAtoms::description,
|
||||
nsAccessibilityAtoms::control);
|
||||
if (!nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_describedby, relatedID)) {
|
||||
relatedNode = do_QueryInterface(
|
||||
nsAccUtils::FindNeighbourPointingToNode(content, eAria_none,
|
||||
nsAccessibilityAtoms::description,
|
||||
nsAccessibilityAtoms::control));
|
||||
|
||||
relatedNode = do_QueryInterface(description);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR:
|
||||
{
|
||||
const PRUint32 kAncestorLevelsToSearch = 3;
|
||||
relatedNode =
|
||||
FindNeighbourPointingToThis(nsAccessibilityAtoms::describedby,
|
||||
kNameSpaceID_WAIProperties,
|
||||
kAncestorLevelsToSearch);
|
||||
do_QueryInterface(nsAccUtils::FindNeighbourPointingToNode(content, eAria_describedby));
|
||||
|
||||
if (!relatedNode && content->Tag() == nsAccessibilityAtoms::description &&
|
||||
content->IsNodeOfType(nsINode::eXUL)) {
|
||||
@ -2733,35 +2597,32 @@ NS_IMETHODIMP nsAccessible::GetAccessibleRelated(PRUint32 aRelationType, nsIAcce
|
||||
}
|
||||
case nsIAccessibleRelation::RELATION_NODE_CHILD_OF:
|
||||
{
|
||||
relatedNode = FindNeighbourPointingToThis(nsAccessibilityAtoms::owns,
|
||||
kNameSpaceID_WAIProperties);
|
||||
relatedNode =
|
||||
do_QueryInterface(nsAccUtils::FindNeighbourPointingToNode(content, eAria_owns));
|
||||
break;
|
||||
}
|
||||
case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
|
||||
{
|
||||
relatedNode = FindNeighbourPointingToThis(nsAccessibilityAtoms::controls,
|
||||
kNameSpaceID_WAIProperties);
|
||||
relatedNode =
|
||||
do_QueryInterface(nsAccUtils::FindNeighbourPointingToNode(content, eAria_controls));
|
||||
break;
|
||||
}
|
||||
case nsIAccessibleRelation::RELATION_CONTROLLER_FOR:
|
||||
{
|
||||
content->GetAttr(kNameSpaceID_WAIProperties,
|
||||
nsAccessibilityAtoms::controls, relatedID);
|
||||
nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_controls, relatedID);
|
||||
break;
|
||||
}
|
||||
case nsIAccessibleRelation::RELATION_FLOWS_TO:
|
||||
{
|
||||
content->GetAttr(kNameSpaceID_WAIProperties,
|
||||
nsAccessibilityAtoms::flowto, relatedID);
|
||||
nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_flowto, relatedID);
|
||||
break;
|
||||
}
|
||||
case nsIAccessibleRelation::RELATION_FLOWS_FROM:
|
||||
{
|
||||
relatedNode = FindNeighbourPointingToThis(nsAccessibilityAtoms::flowto,
|
||||
kNameSpaceID_WAIProperties);
|
||||
relatedNode =
|
||||
do_QueryInterface(nsAccUtils::FindNeighbourPointingToNode(content, eAria_flowto));
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIAccessibleRelation::RELATION_DEFAULT_BUTTON:
|
||||
{
|
||||
if (content->IsNodeOfType(nsINode::eHTML)) {
|
||||
@ -3346,8 +3207,7 @@ PRBool nsAccessible::CheckVisibilityInParentChain(nsIDocument* aDocument, nsIVie
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccessible::GetAttrValue(PRUint32 aNameSpaceID, nsIAtom *aName,
|
||||
double *aValue)
|
||||
nsAccessible::GetAttrValue(EAriaProperty aProperty, double *aValue)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aValue);
|
||||
*aValue = 0;
|
||||
@ -3363,7 +3223,7 @@ nsAccessible::GetAttrValue(PRUint32 aNameSpaceID, nsIAtom *aName,
|
||||
|
||||
PRInt32 result = NS_OK;
|
||||
nsAutoString value;
|
||||
if (content->GetAttr(aNameSpaceID, aName, value) && !value.IsEmpty())
|
||||
if (nsAccUtils::GetAriaProperty(content, mWeakShell, aProperty, value))
|
||||
*aValue = value.ToFloat(&result);
|
||||
|
||||
return result;
|
||||
|
@ -168,63 +168,16 @@ protected:
|
||||
PRBool IsVisible(PRBool *aIsOffscreen);
|
||||
|
||||
// Relation helpers
|
||||
nsresult GetTextFromRelationID(nsIAtom *aIDAttrib, nsString &aName);
|
||||
|
||||
/**
|
||||
* Search element in neighborhood of the given element by tag name and
|
||||
* attribute value that equals to ID attribute of the current element.
|
||||
* ID attribute can be either 'id' attribute or 'anonid' if the element is
|
||||
* anonymous.
|
||||
* For a given ARIA relation, such as labelledby or describedby, get the collated text
|
||||
* for the subtree that's pointed to.
|
||||
*
|
||||
* @param aRelationAttr - attribute name of searched element
|
||||
* @param aRelationNamespaceID - namespace id of searched attribute, by default
|
||||
* empty namespace
|
||||
* @param aAncestorLevelsToSearch - points how is the neighborhood of the
|
||||
* given element big.
|
||||
* @param aIDProperty The ARIA relationship property to get the text for
|
||||
* @param aName Where to put the text
|
||||
* @return error or success code
|
||||
*/
|
||||
already_AddRefed<nsIDOMNode> FindNeighbourPointingToThis(nsIAtom *aRelationAttr,
|
||||
PRUint32 aRelationNameSpaceID = kNameSpaceID_None,
|
||||
PRUint32 aAncestorLevelsToSearch = 0);
|
||||
|
||||
/**
|
||||
* Search element in neighborhood of the given element by tag name and
|
||||
* attribute value that equals to ID attribute of the given element.
|
||||
* ID attribute can be either 'id' attribute or 'anonid' if the element is
|
||||
* anonymous.
|
||||
*
|
||||
* @param aForNode - the given element the search is performed for
|
||||
* @param aTagName - tag name of searched element
|
||||
* @param aRelationAttr - attribute name of searched element
|
||||
* @param aRelationNamespaceID - namespace id of searched attribute, by default
|
||||
* empty namespace
|
||||
* @param aAncestorLevelsToSearch - points how is the neighborhood of the
|
||||
* given element big.
|
||||
*/
|
||||
static nsIContent *FindNeighbourPointingToNode(nsIContent *aForNode,
|
||||
nsIAtom *aTagName,
|
||||
nsIAtom *aRelationAttr,
|
||||
PRUint32 aRelationNameSpaceID = kNameSpaceID_None,
|
||||
PRUint32 aAncestorLevelsToSearch = 5);
|
||||
|
||||
/**
|
||||
* Search for element that satisfies the requirements in subtree of the given
|
||||
* element. The requirements are tag name, attribute name and value of
|
||||
* attribute.
|
||||
*
|
||||
* @param aId - value of searched attribute
|
||||
* @param aLookContent - element that search is performed inside
|
||||
* @param aRelationAttr - searched attribute
|
||||
* @param aRelationNamespaceID - namespace id of searched attribute, by default
|
||||
* empty namespace
|
||||
* @param aExcludeContent - element that is skiped for search
|
||||
* @param aTagType - tag name of searched element, by default it is 'label'
|
||||
*/
|
||||
static nsIContent *FindDescendantPointingToID(const nsAString *aId,
|
||||
nsIContent *aLookContent,
|
||||
nsIAtom *aRelationAttr,
|
||||
PRUint32 aRelationNamespaceID = kNameSpaceID_None,
|
||||
nsIContent *aExcludeContent = nsnull,
|
||||
nsIAtom *aTagType = nsAccessibilityAtoms::label);
|
||||
nsresult GetTextFromRelationID(EAriaProperty aIDProperty, nsString &aName);
|
||||
|
||||
static nsIContent *GetHTMLLabelContent(nsIContent *aForNode);
|
||||
static nsIContent *GetLabelContent(nsIContent *aForNode);
|
||||
@ -284,15 +237,14 @@ protected:
|
||||
nsIDOMNode* GetAtomicRegion();
|
||||
|
||||
/**
|
||||
* Get numeric value of the given attribute.
|
||||
* Get numeric value of the given ARIA attribute.
|
||||
*
|
||||
* @param aNameSpaceID - namespace ID of the attribute
|
||||
* @param aName - name of the attribute
|
||||
* @param aAriaProperty - the ARIA property we're using
|
||||
* @param aValue - value of the attribute
|
||||
*
|
||||
* @return - NS_OK_NO_ARIA_VALUE if there is no setted ARIA attribute
|
||||
*/
|
||||
nsresult GetAttrValue(PRUint32 aNameSpaceID, nsIAtom *aName, double *aValue);
|
||||
nsresult GetAttrValue(EAriaProperty aAriaProperty, double *aValue);
|
||||
|
||||
// Data Members
|
||||
nsCOMPtr<nsIAccessible> mParent;
|
||||
|
@ -84,7 +84,8 @@ PRUint32 nsDocAccessible::gLastFocusedAccessiblesState = 0;
|
||||
//-----------------------------------------------------
|
||||
nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell):
|
||||
nsHyperTextAccessibleWrap(aDOMNode, aShell), mWnd(nsnull),
|
||||
mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE)
|
||||
mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE),
|
||||
mAriaPropTypes(eCheckNamespaced)
|
||||
{
|
||||
// For GTK+ native window, we do nothing here.
|
||||
if (!mDOMNode)
|
||||
@ -97,7 +98,24 @@ nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell)
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell(do_QueryReferent(mWeakShell));
|
||||
if (shell) {
|
||||
// Find mDocument
|
||||
mDocument = shell->GetDocument();
|
||||
// Find mAriaPropTypes: the initial type of ARIA properties that should be checked for
|
||||
if (!mDocument) {
|
||||
NS_WARNING("No document!");
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNSHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
|
||||
if (htmlDoc) {
|
||||
nsAutoString mimeType;
|
||||
GetMimeType(mimeType);
|
||||
mAriaPropTypes = eCheckHyphenated;
|
||||
if (! mimeType.EqualsLiteral("text/html")) {
|
||||
mAriaPropTypes |= eCheckNamespaced;
|
||||
}
|
||||
}
|
||||
// Find mWnd
|
||||
nsIViewManager* vm = shell->GetViewManager();
|
||||
if (vm) {
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
@ -904,7 +922,14 @@ NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
NS_IMETHODIMP
|
||||
nsDocAccessible::GetAriaPropTypes(PRUint32 *aAriaPropTypes)
|
||||
{
|
||||
*aAriaPropTypes = mAriaPropTypes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// nsIDocumentObserver
|
||||
|
||||
NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(nsDocAccessible)
|
||||
@ -948,6 +973,14 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID
|
||||
if (!docShell) {
|
||||
return;
|
||||
}
|
||||
if (aNameSpaceID == kNameSpaceID_WAIProperties) {
|
||||
// Using setAttributeNS() in HTML to set namespaced ARIA properties.
|
||||
// From this point forward, check namespaced properties, which
|
||||
// take precedence over hyphenated properties, since in text/html
|
||||
// that can only be set dynamically.
|
||||
mAriaPropTypes |= eCheckNamespaced;
|
||||
}
|
||||
|
||||
PRUint32 busyFlags;
|
||||
docShell->GetBusyFlags(&busyFlags);
|
||||
if (busyFlags) {
|
||||
@ -971,7 +1004,8 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID
|
||||
nsAccEvent::PrepareForEvent(targetNode);
|
||||
|
||||
// Universal boolean properties that don't require a role.
|
||||
if (aAttribute == nsAccessibilityAtoms::disabled) {
|
||||
if (aAttribute == nsAccessibilityAtoms::disabled ||
|
||||
(aAttribute == nsAccessibilityAtoms::aria_disabled && (mAriaPropTypes & eCheckHyphenated))) {
|
||||
// Fire the state change whether disabled attribute is
|
||||
// set for XUL, HTML or ARIA namespace.
|
||||
// Checking the namespace would not seem to gain us anything, because
|
||||
@ -991,8 +1025,22 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for namespaced ARIA attribute
|
||||
nsCOMPtr<nsIAtom> ariaAttribute;
|
||||
if (aNameSpaceID == kNameSpaceID_WAIProperties) {
|
||||
ARIAAttributeChanged(aContent, aAttribute);
|
||||
ariaAttribute = aAttribute;
|
||||
}
|
||||
else if (mAriaPropTypes & eCheckHyphenated && aNameSpaceID == kNameSpaceID_None) {
|
||||
// Check for hyphenated aria-foo property?
|
||||
const char* attributeName;
|
||||
aAttribute->GetUTF8String(&attributeName);
|
||||
if (!PL_strncmp("aria-", attributeName, 5)) {
|
||||
// Convert to WAI property atom attribute
|
||||
ariaAttribute = do_GetAtom(attributeName + 5);
|
||||
}
|
||||
}
|
||||
if (ariaAttribute) { // We have an ARIA attribute
|
||||
ARIAAttributeChanged(aContent, ariaAttribute);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -204,6 +204,7 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
|
||||
protected:
|
||||
PRBool mIsAnchor;
|
||||
PRBool mIsAnchorJumped;
|
||||
PRUint32 mAriaPropTypes;
|
||||
static PRUint32 gLastFocusedAccessiblesState;
|
||||
|
||||
private:
|
||||
|
@ -388,6 +388,12 @@ void nsRootAccessible::TryFireEarlyLoadEvent(nsIDOMNode *aDocNode)
|
||||
if (itemType != nsIDocShellTreeItem::typeContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// At minimum, create doc accessible so that events are listened to,
|
||||
// allowing us to see any mutations from a page load handler
|
||||
nsCOMPtr<nsIAccessible> docAccessible;
|
||||
GetAccService()->GetAccessibleFor(aDocNode, getter_AddRefs(docAccessible));
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeNode> treeNode(do_QueryInterface(treeItem));
|
||||
if (treeNode) {
|
||||
PRInt32 subDocuments;
|
||||
@ -460,7 +466,7 @@ PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
|
||||
nsCOMPtr<nsIContent> finalFocusContent = do_QueryInterface(aNode);
|
||||
if (finalFocusContent) {
|
||||
nsAutoString id;
|
||||
if (finalFocusContent->GetAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::activedescendant, id)) {
|
||||
if (nsAccUtils::GetAriaProperty(finalFocusContent, nsnull, eAria_activedescendant, id)) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
aNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
if (!domDoc) {
|
||||
|
@ -216,7 +216,7 @@ NS_IMETHODIMP
|
||||
nsXFormsAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
nsAutoString name;
|
||||
nsresult rv = GetTextFromRelationID(nsAccessibilityAtoms::labelledby, name);
|
||||
nsresult rv = GetTextFromRelationID(eAria_labelledby, name);
|
||||
if (NS_SUCCEEDED(rv) && !name.IsEmpty()) {
|
||||
aName = name;
|
||||
return NS_OK;
|
||||
@ -230,8 +230,7 @@ NS_IMETHODIMP
|
||||
nsXFormsAccessible::GetDescription(nsAString& aDescription)
|
||||
{
|
||||
nsAutoString description;
|
||||
nsresult rv = GetTextFromRelationID(nsAccessibilityAtoms::describedby,
|
||||
description);
|
||||
nsresult rv = GetTextFromRelationID(eAria_describedby, description);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !description.IsEmpty()) {
|
||||
aDescription = description;
|
||||
|
@ -59,7 +59,7 @@ NS_IMETHODIMP
|
||||
nsXFormsLabelAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
nsAutoString name;
|
||||
nsresult rv = GetTextFromRelationID(nsAccessibilityAtoms::labelledby, name);
|
||||
nsresult rv = GetTextFromRelationID(eAria_labelledby, name);
|
||||
aName = name;
|
||||
return rv;
|
||||
}
|
||||
@ -68,8 +68,7 @@ NS_IMETHODIMP
|
||||
nsXFormsLabelAccessible::GetDescription(nsAString& aDescription)
|
||||
{
|
||||
nsAutoString description;
|
||||
nsresult rv = GetTextFromRelationID(nsAccessibilityAtoms::describedby,
|
||||
description);
|
||||
nsresult rv = GetTextFromRelationID(eAria_describedby, description);
|
||||
aDescription = description;
|
||||
return rv;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user