Bug 396632. Don't require namespaces when using ARIA properties in text/html
authoraaronleventhal@moonset.net
Mon, 24 Sep 2007 18:19:03 -0700
changeset 6279 fa57a420065e5a0c0106e2b0b980e2bb64cc3fcd
parent 6278 56d2b5c022495ad90e6c5ec7327971f14668580c
child 6280 c74835ddb2ccaf74c23283914a0fc64fdc110817
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs396632
milestone1.9a9pre
Bug 396632. Don't require namespaces when using ARIA properties in text/html
accessible/public/nsIAccessibleDocument.idl
accessible/src/base/nsARIAMap.cpp
accessible/src/base/nsARIAMap.h
accessible/src/base/nsARIAPropertyList.h
accessible/src/base/nsAccessibilityAtomList.h
accessible/src/base/nsAccessibilityService.cpp
accessible/src/base/nsAccessibilityService.h
accessible/src/base/nsAccessibilityUtils.cpp
accessible/src/base/nsAccessibilityUtils.h
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsAccessible.h
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsDocAccessible.h
accessible/src/base/nsRootAccessible.cpp
accessible/src/xforms/nsXFormsAccessible.cpp
accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
--- a/accessible/public/nsIAccessibleDocument.idl
+++ b/accessible/public/nsIAccessibleDocument.idl
@@ -53,17 +53,17 @@ interface nsIDOMWindow;
  * You can QueryInterface to nsIAccessibleDocument from
  * the nsIAccessible or nsIAccessNode for the root node
  * of a document. You can also get one from 
  * nsIAccessNode::GetAccessibleDocument() or 
  * nsIAccessibleEvent::GetAccessibleDocument()
  *
  * @status UNDER_REVIEW
  */
-[scriptable, uuid(6cc11286-e02d-4a8d-960a-e7a61161b230)]
+[scriptable, uuid(d118c0e9-b5e7-4671-854a-65b4713d9552)]
 interface nsIAccessibleDocument : nsISupports
 {
   /**
    * The URL of the document
    */
   readonly attribute AString URL;
 
   /**
@@ -116,9 +116,32 @@ interface nsIAccessibleDocument : nsISup
    * Guaranteed not to return nsnull if the DOM node is in a document.
    * @param aDOMNode The DOM node we need an accessible for.
    * @param aCanCreate Can accessibles be created or must it be the first 
    *                   cached accessible in the parent chain?
    * @return An first nsIAccessible found by crawling up the DOM node
    *         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;
 };
--- a/accessible/src/base/nsARIAMap.cpp
+++ b/accessible/src/base/nsARIAMap.cpp
@@ -36,184 +36,195 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsARIAMap.h"
 #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.
  *
  *  There are no nsIAccessibleRole enums for the following landmark roles:
  *    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[] = 
 {
   {"alert", nsIAccessibleRole::ROLE_ALERT, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"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
 };
 
 /**
  * Universal states:
  * The following state rules are applied to any accessible element,
  * 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
 };
 
--- a/accessible/src/base/nsARIAMap.h
+++ b/accessible/src/base/nsARIAMap.h
@@ -36,16 +36,23 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsARIAMap_H_
 #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
 {
   // eNameLabelOrTitle:
   // Collect name from:
   //   1) The content subtrees pointed to by labelledby
   //      which contains the IDs for the label content, or if unspecified
@@ -74,17 +81,17 @@ enum EValueRule
 
 // Used in nsRoleMapEntry.state if no nsIAccessibleStates are automatic for a given role
 #define kNoReqStates 0
 
 // For this name and value pair, what is the nsIAccessibleStates mapping.
 // nsStateMapEntry.state
 struct nsStateMapEntry
 {
-  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
 };
 
 // For each ARIA role, this maps the nsIAccessible information
 struct nsRoleMapEntry
 {
   // ARIA role: string representation such as "button"
@@ -119,13 +126,15 @@ struct nsRoleMapEntry
 
 /**
  *  These are currently initialized (hardcoded) in nsARIAMap.cpp, 
  *  and provide the mappings for WAI-ARIA roles and properties using the 
  *  structs defined in this file.
  */
 struct nsARIAMap
 {
+  static nsIAtom** gAriaAtomPtrsNS[eAria_none];
+  static nsIAtom** gAriaAtomPtrsHyphenated[eAria_none];
   static nsRoleMapEntry gWAIRoleMap[];
   static nsStateMapEntry gWAIUnivStateMap[];
 };
 
 #endif
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/nsARIAPropertyList.h
@@ -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)
--- a/accessible/src/base/nsAccessibilityAtomList.h
+++ b/accessible/src/base/nsAccessibilityAtomList.h
@@ -135,79 +135,55 @@ ACCESSIBILITY_ATOM(textbox, "textbox")  
 ACCESSIBILITY_ATOM(toolbaritem, "toolbaritem")   // XUL
 ACCESSIBILITY_ATOM(toolbarseparator, "toolbarseparator")   // XUL
 ACCESSIBILITY_ATOM(toolbarspring, "toolbarspring")   // XUL
 ACCESSIBILITY_ATOM(toolbarspacer, "toolbarspacer")   // XUL
 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")
 ACCESSIBILITY_ATOM(hidden, "hidden")   // XUL tree columns
 ACCESSIBILITY_ATOM(href, "href")
 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")
 ACCESSIBILITY_ATOM(title, "title")
 ACCESSIBILITY_ATOM(tooltiptext, "tooltiptext")
 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
 // of an HTML button from the button frame
 ACCESSIBILITY_ATOM(defaultLabel, "defaultLabel")
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -1426,48 +1426,66 @@ NS_IMETHODIMP nsAccessibilityService::Ge
 
   // If no accessible, see if we need to create a generic accessible because
   // of some property that makes this object interesting
   // We don't do this for <body>, <html>, <window>, <dialog> etc. which 
   // correspond to the doc accessible and will be created in any case
   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.
     if (isHTML) {
       // Interesting HTML container which may have selectable text and/or embedded objects
       CreateHyperTextAccessible(frame, getter_AddRefs(newAcc));
     }
     else {  // XUL, SVG, MathML etc.
       // Interesting generic non-HTML container
       newAcc = new nsAccessibleWrap(aNode, aWeakShell);
     }
   }
 
   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)
 {
   // The method returns node that is relevant for attached accessible check.
   // Sometimes element that is XBL widget hasn't accessible children in
   // anonymous content. This method check whether given node can be accessible
   // by looking through all nested bindings that given node is anonymous for. If
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -114,16 +114,26 @@ private:
    * Return accessible object if parent is a deck frame.
    *
    * @param aNode - DOMNode that accessible is returned for.
    */
   nsresult GetAccessibleForDeckChildren(nsIDOMNode *aNode,
                                         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);
 };
 
 /**
  * Map nsIAccessibleRole constants to strings. Used by
  * nsIAccessibleRetrieval::getStringRole() method.
  */
 static const char kRoleNames[][20] = {
   "nothing",             //ROLE_NOTHING
--- a/accessible/src/base/nsAccessibilityUtils.cpp
+++ b/accessible/src/base/nsAccessibilityUtils.cpp
@@ -37,20 +37,24 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsAccessibilityUtils.h"
 
 #include "nsIAccessibleTypes.h"
 #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"
 #include "nsIDOMWindowInternal.h"
 #include "nsIEventListenerManager.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIEventStateManager.h"
@@ -405,8 +409,230 @@ nsAccUtils::GetDocShellTreeItemFor(nsIDO
 }
 
 PRBool
 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;
+}
+
--- a/accessible/src/base/nsAccessibilityUtils.h
+++ b/accessible/src/base/nsAccessibilityUtils.h
@@ -36,23 +36,25 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsAccessibilityUtils_h_
 #define nsAccessibilityUtils_h_
 
 #include "nsAccessibilityAtoms.h"
 #include "nsIAccessible.h"
+#include "nsARIAMap.h"
 
 #include "nsIDOMNode.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIContent.h"
 #include "nsIFrame.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsPoint.h"
+#include "nsIAccessibleDocument.h"
 
 class nsAccUtils
 {
 public:
   /**
    * Returns value of attribute from the given attributes container.
    *
    * @param aAttributes - attributes container
@@ -183,12 +185,98 @@ public:
 
   /**
    * Get the ID for an element, in some types of XML this may not be the ID attribute
    * @param aContent  Node to get the ID for
    * @param aID       Where to put ID string
    * @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
 
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -70,16 +70,17 @@
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIFrame.h"
 #include "nsIViewManager.h"
 #include "nsIDocShellTreeItem.h"
 
 #include "nsXPIDLString.h"
 #include "nsUnicharUtils.h"
+#include "nsReadableUtils.h"
 #include "prdtoa.h"
 #include "nsIAtom.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIURI.h"
 #include "nsITimer.h"
 #include "nsIMutableArray.h"
 #include "nsIObserverService.h"
@@ -192,26 +193,23 @@ nsresult nsAccessible::QueryInterface(RE
 
   if (aIID.Equals(NS_GET_IID(nsIAccessibleSelectable))) {
     nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
     if (!content) {
       return NS_ERROR_FAILURE; // This accessible has been shut down
     }
     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;
       }
     }
   }
 
   if (aIID.Equals(NS_GET_IID(nsIAccessibleValue))) {
@@ -298,24 +296,25 @@ NS_IMETHODIMP nsAccessible::GetDescripti
   // 3. it doesn't have an accName; or
   // 4. its title attribute already equals to its accName nsAutoString name; 
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   if (!content) {
     return NS_ERROR_FAILURE;  // Node shut down
   }
   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
           AppendFlatStringFromSubtree(descriptionContent, &description);
         }
       }
       if (description.IsEmpty()) {
         nsIAtom *descAtom = isXUL ? nsAccessibilityAtoms::tooltiptext :
@@ -1372,20 +1371,34 @@ NS_IMETHODIMP nsAccessible::SetSelected(
   if (state & nsIAccessibleStates::STATE_SELECTABLE) {
     nsCOMPtr<nsIAccessible> multiSelect = GetMultiSelectFor(mDOMNode);
     if (!multiSelect) {
       return aSelect ? TakeFocus() : NS_ERROR_FAILURE;
     }
     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);
   }
 
   return NS_ERROR_FAILURE;
 }
 
 /* void takeSelection (); */
@@ -1628,18 +1641,19 @@ nsresult nsAccessible::AppendFlatStringF
     AppendFlatStringFromSubtreeRecurse(aContent->GetChildAt(index), aFlatString);
   }
   return NS_OK;
 }
 
 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);
 }
 
 nsIContent* nsAccessible::GetHTMLLabelContent(nsIContent *aForNode)
 {
   // Get either <label for="[id]"> element which explictly points to aForNode, or 
   // <label> ancestor which implicitly point to it
@@ -1657,33 +1671,33 @@ nsIContent* nsAccessible::GetHTMLLabelCo
       // There can be a label targeted at this control using the 
       // for="control_id" attribute. To save computing time, only 
       // look for those inside of a form element
       nsAutoString forId;
       if (!nsAccUtils::GetID(aForNode, forId)) {
         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();
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   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);
 
   nsCOMPtr<nsIDOMDocument> domDoc;
   mDOMNode->GetOwnerDocument(getter_AddRefs(domDoc));
   NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
   
@@ -1716,154 +1730,31 @@ nsresult nsAccessible::GetTextFromRelati
     if (NS_SUCCEEDED(rv)) {
       aName.CompressWhitespace();
     }
   }
   
   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
   *   labels with the for="controlID" property.
   */
 nsresult nsAccessible::GetHTMLName(nsAString& aLabel, PRBool aCanAggregateSubtree)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   if (!content) {
     return NS_ERROR_FAILURE;   // Node shut down
   }
 
   // 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;
   }
 
   nsIContent *labelContent = GetHTMLLabelContent(content);
   if (labelContent) {
     AppendFlatStringFromSubtree(labelContent, &label);
@@ -1904,17 +1795,17 @@ nsresult nsAccessible::GetHTMLName(nsASt
   */
 nsresult nsAccessible::GetXULName(nsAString& aLabel, PRBool aCanAggregateSubtree)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   NS_ASSERTION(content, "No nsIContent for DOM node");
 
   // 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;
   }
 
   // CASE #1 (via label attribute) -- great majority of the cases
   nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl(do_QueryInterface(mDOMNode));
   if (labeledEl) {
@@ -1937,18 +1828,19 @@ nsresult nsAccessible::GetXULName(nsAStr
       }
     }
   }
 
   // CASES #2 and #3 ------ label as a child or <label control="id" ... > </label>
   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
     if (xulLabel && NS_SUCCEEDED(xulLabel->GetValue(label)) && label.IsEmpty()) {
       // If no value attribute, a non-empty label must contain
       // children that define it's text -- possibly using HTML
       AppendFlatStringFromSubtree(labelContent, &label);
     }
@@ -2035,35 +1927,38 @@ NS_IMETHODIMP nsAccessible::GetFinalRole
 
   if (mRoleMapEntry) {
     *aRole = mRoleMapEntry->role;
 
     // These unfortunate exceptions don't fit into the ARIA table
     // 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;
       }
     }
     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;
+          }
         }
       }
     }
   
     if (*aRole != nsIAccessibleRole::ROLE_NOTHING) {
       return NS_OK;
     }
   }
@@ -2094,47 +1989,51 @@ nsAccessible::GetAttributes(nsIPersisten
     attributes->SetStringProperty(NS_LITERAL_CSTRING("id"), id, oldValueUnused);
     // XXX In the future we may need to expose the dynamic content role inheritance chain
     // through this attribute
     nsAutoString xmlRole;
     if (GetARIARole(content, xmlRole)) {
       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);    
       }
     }
 
     // Get container-foo computed live region properties based on the closest container with
     // 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();
     }
   }
 
   if (!nsAccUtils::HasAccGroupAttrs(attributes)) {
     // The role of an accessible can be pointed by ARIA attribute but ARIA
     // posinset, level, setsize may be skipped. Therefore we calculate here
@@ -2259,24 +2158,22 @@ nsAccessible::GroupPosition(PRInt32 *aGr
 
   return NS_OK;
 }
 
 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")) {
         *aStateInOut &= ~aStateMapEntry->state;
       }
       else {
         *aStateInOut |= aStateMapEntry->state;
       }
@@ -2330,29 +2227,28 @@ nsAccessible::GetFinalState(PRUint32 *aS
   if (role == nsIAccessibleRole::ROLE_ENTRY ||
       role == nsIAccessibleRole::ROLE_PASSWORD_TEXT ||
       role == nsIAccessibleRole::ROLE_COMBOBOX) {
 
     nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
     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"))) {
       *aExtraState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
     }
 
     // XXX We can remove this hack once we support RDF-based role & state maps
     if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_ENTRY) {
-      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 {
         *aExtraState |= nsIAccessibleStates::EXT_STATE_SINGLE_LINE;
       }
     }
   }
 
@@ -2388,18 +2284,17 @@ nsAccessible::GetARIAState()
   // Test for universal states first
   nsIContent *content = GetRoleContent(mDOMNode);
   if (!content) {
     return 0;
   }
 
   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;
   }
 
   if (!mRoleMapEntry)
     return ariaState;
 
   // Once DHTML role is used, we're only readonly if DHTML readonly used
   ariaState &= ~nsIAccessibleStates::STATE_READONLY;
@@ -2433,54 +2328,50 @@ NS_IMETHODIMP nsAccessible::GetValue(nsA
   if (!mDOMNode) {
     return NS_ERROR_FAILURE;  // Node already shut down
   }
   if (mRoleMapEntry) {
     if (mRoleMapEntry->valueRule == eNoValue) {
       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;
     }
   }
   return NS_OK;
 }
 
 // nsIAccessibleValue
 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
 nsAccessible::GetMinimumIncrement(double *aMinIncrement)
 {
   NS_ENSURE_ARG_POINTER(aMinIncrement);
   *aMinIncrement = 0;
 
   // No mimimum increment in dynamic content spec right now
   return NS_OK_NO_ARIA_VALUE;
 }
 
 NS_IMETHODIMP
 nsAccessible::GetCurrentValue(double *aValue)
 {
-  return GetAttrValue(kNameSpaceID_WAIProperties,
-                      nsAccessibilityAtoms::valuenow, aValue);
+  return GetAttrValue(eAria_valuenow, aValue);
 }
 
 NS_IMETHODIMP
 nsAccessible::SetCurrentValue(double aValue)
 {
   if (!mDOMNode)
     return NS_ERROR_FAILURE;  // Node already shut down
 
@@ -2501,16 +2392,22 @@ nsAccessible::SetCurrentValue(double aVa
   if (NS_SUCCEEDED(GetMaximumValue(&maxValue)) && aValue > maxValue)
     return NS_ERROR_INVALID_ARG;
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   NS_ENSURE_STATE(content);
 
   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);
 }
 
 /* void setName (in DOMString name); */
 NS_IMETHODIMP nsAccessible::SetName(const nsAString& name)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
@@ -2607,49 +2504,26 @@ NS_IMETHODIMP nsAccessible::GetAccessibl
 }
 
 /* nsIAccessible getAccessibleBelow(); */
 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;
-
-  while (loopContent) {
-    loopContent->GetAttr(kNameSpaceID_WAIProperties, nsAccessibilityAtoms::atomic, atomic);
-    if (!atomic.IsEmpty()) {
-      break;
-    }
+  PRUint32 ariaPropTypes = nsAccUtils::GetAriaPropTypes(content, mWeakShell);
+
+  while (loopContent && !nsAccUtils::GetAriaProperty(loopContent, mWeakShell,
+                                                     eAria_atomic, atomic,
+                                                     ariaPropTypes)) {
     loopContent = loopContent->GetParent();
   }
 
   nsCOMPtr<nsIDOMNode> atomicRegion;
   if (atomic.EqualsLiteral("true")) {
     atomicRegion = do_QueryInterface(loopContent);
   }
   return atomicRegion;
@@ -2678,95 +2552,82 @@ NS_IMETHODIMP nsAccessible::GetAccessibl
   case nsIAccessibleRelation::RELATION_LABEL_FOR:
     {
       if (content->Tag() == nsAccessibilityAtoms::label) {
         nsIAtom *relatedIDAttr = content->IsNodeOfType(nsINode::eHTML) ?
           nsAccessibilityAtoms::_for : nsAccessibilityAtoms::control;
         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);
-
-        relatedNode = do_QueryInterface(description);
+      if (!nsAccUtils::GetAriaProperty(content, mWeakShell, eAria_describedby, relatedID)) {
+        relatedNode = do_QueryInterface(
+          nsAccUtils::FindNeighbourPointingToNode(content, eAria_none,
+                                                  nsAccessibilityAtoms::description,
+                                                  nsAccessibilityAtoms::control));
+
       }
       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)) {
         // This affectively adds an optional control attribute to xul:description,
         // which only affects accessibility, by allowing the description to be
         // tied to a control.
         content->GetAttr(kNameSpaceID_None,
                          nsAccessibilityAtoms::control, relatedID);
       }
       break;
     }
   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)) {
         // HTML form controls implements nsIFormControl interface.
         nsCOMPtr<nsIFormControl> control(do_QueryInterface(content));
         if (control) {
           nsCOMPtr<nsIDOMHTMLFormElement> htmlform;
           control->GetForm(getter_AddRefs(htmlform));
@@ -3341,34 +3202,33 @@ PRBool nsAccessible::CheckVisibilityInPa
 
     document = parentDoc;
   }
 
   return PR_TRUE;
 }
 
 nsresult
-nsAccessible::GetAttrValue(PRUint32 aNameSpaceID, nsIAtom *aName,
-                           double *aValue)
+nsAccessible::GetAttrValue(EAriaProperty aProperty, double *aValue)
 {
   NS_ENSURE_ARG_POINTER(aValue);
   *aValue = 0;
 
   if (!mDOMNode)
     return NS_ERROR_FAILURE;  // Node already shut down
 
  if (!mRoleMapEntry || mRoleMapEntry->valueRule == eNoValue)
     return NS_OK_NO_ARIA_VALUE;
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   NS_ENSURE_STATE(content);
 
   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;
 }
 
 PRBool nsAccessible::MustPrune(nsIAccessible *aAccessible)
 { 
   PRUint32 role = Role(aAccessible);
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -163,73 +163,26 @@ public:
   
 protected:
   PRBool MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut, nsStateMapEntry *aStateMapEntry);
   virtual nsIFrame* GetBoundsFrame();
   virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
   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.
-   *
-   * @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.
-   */
-  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.
+   * For a given ARIA relation, such as labelledby or describedby, get the collated text
+   * for the subtree that's pointed to.
    *
-   * @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.
+   * @param aIDProperty  The ARIA relationship property to get the text for
+   * @param aName        Where to put the text
+   * @return error or success code
    */
-  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);
   static nsIContent *GetRoleContent(nsIDOMNode *aDOMNode);
 
   // Name helpers
   nsresult GetHTMLName(nsAString& _retval, PRBool aCanAggregateSubtree = PR_TRUE);
   nsresult GetXULName(nsAString& aName, PRBool aCanAggregateSubtree = PR_TRUE);
@@ -279,25 +232,24 @@ protected:
 
   /**
    *  Get the container node for an atomic region, defined by aria:atomic="true"
    *  @return the container node
    */
   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;
   nsIAccessible *mFirstChild, *mNextSibling;
   nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well
   PRInt32 mAccChildCount;
 };
 
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -79,30 +79,48 @@
 
 PRUint32 nsDocAccessible::gLastFocusedAccessiblesState = 0;
 
 //-----------------------------------------------------
 // construction
 //-----------------------------------------------------
 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)
     return;
 
   // Because of the way document loading happens, the new nsIWidget is created before
   // the old one is removed. Since it creates the nsDocAccessible, for a brief moment
   // there can be 2 nsDocAccessible's for the content area, although for 2 different
   // pres shells.
 
   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;
       vm->GetWidget(getter_AddRefs(widget));
       if (widget) {
         mWnd = widget->GetNativeData(NS_NATIVE_WINDOW);
       }
     }
@@ -899,17 +917,24 @@ NS_IMETHODIMP nsDocAccessible::Observe(n
       new nsAccStateChangeEvent(this, nsIAccessibleStates::EXT_STATE_EDITABLE,
                                 PR_TRUE, PR_TRUE);
     FireAccessibleEvent(event);
   }
 
   return NS_OK;
 }
 
-///////////////////////////////////////////////////////////////////////
+NS_IMETHODIMP
+nsDocAccessible::GetAriaPropTypes(PRUint32 *aAriaPropTypes) 
+{
+  *aAriaPropTypes = mAriaPropTypes;
+  return NS_OK;
+}
+
+  ///////////////////////////////////////////////////////////////////////
 // nsIDocumentObserver
 
 NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(nsDocAccessible)
 NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(nsDocAccessible)
 NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(nsDocAccessible)
 
 void
 nsDocAccessible::AttributeChanged(nsIDocument *aDocument, nsIContent* aContent,
@@ -943,16 +968,24 @@ nsDocAccessible::AttributeChangedImpl(ns
   // Otherwise it may just be a state change, for example an object changing
   // its visibility
 
   nsCOMPtr<nsISupports> container = mDocument->GetContainer();
   nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
   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) {
     return; // Still loading, ignore setting of initial attributes
   }
 
   nsCOMPtr<nsIPresShell> shell = GetPresShell();
   if (!shell) {
@@ -966,17 +999,18 @@ nsDocAccessible::AttributeChangedImpl(ns
   }
 
   // Since we're in synchronous code, we can store whether the current attribute
   // change is from user input or not. If the attribute change causes an asynchronous
   // layout change, that event can use the last known user input state
   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
     // disabled really is going to mean the same thing in any namespace.
     // We use the attribute instead of the disabled state bit because
     // ARIA's aaa:disabled does not affect the disabled state bit
     nsCOMPtr<nsIAccessibleStateChangeEvent> enabledChangeEvent =
       new nsAccStateChangeEvent(targetNode,
@@ -986,18 +1020,32 @@ nsDocAccessible::AttributeChangedImpl(ns
     nsCOMPtr<nsIAccessibleStateChangeEvent> sensitiveChangeEvent =
       new nsAccStateChangeEvent(targetNode,
                                 nsIAccessibleStates::EXT_STATE_SENSITIVE,
                                 PR_TRUE);
     FireDelayedAccessibleEvent(sensitiveChangeEvent);
     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;
   }
 
   if (aNameSpaceID == kNameSpaceID_XHTML2_Unofficial ||
       aNameSpaceID == kNameSpaceID_XHTML) {
     if (aAttribute == nsAccessibilityAtoms::role)
       InvalidateCacheSubtree(aContent, nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE);
     return;
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -199,16 +199,17 @@ class nsDocAccessible : public nsHyperTe
     nsCOMPtr<nsITimer> mFireEventTimer;
     PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
     PRPackedBool mIsContentLoaded;
     nsCOMArray<nsIAccessibleEvent> mEventsToFire;
 
 protected:
     PRBool mIsAnchor;
     PRBool mIsAnchorJumped;
+    PRUint32 mAriaPropTypes;
     static PRUint32 gLastFocusedAccessiblesState;
 
 private:
     static void DocLoadCallback(nsITimer *aTimer, void *aClosure);
     nsCOMPtr<nsITimer> mDocLoadTimer;
 };
 
 #endif  
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -383,16 +383,22 @@ void nsRootAccessible::TryFireEarlyLoadE
   if (!treeItem) {
     return;
   }
   PRInt32 itemType;
   treeItem->GetItemType(&itemType);
   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;
     treeNode->GetChildCount(&subDocuments);
     if (subDocuments) {
       return;
     }
   }
@@ -455,17 +461,17 @@ PRBool nsRootAccessible::FireAccessibleF
   }
 
   // Check for aaa:activedescendant, which changes which element has focus
   nsCOMPtr<nsIDOMNode> finalFocusNode = aNode;
   nsCOMPtr<nsIAccessible> finalFocusAccessible = 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) {
         return PR_FALSE;
       }
       nsCOMPtr<nsIDOMElement> relatedEl;
       domDoc->GetElementById(id, getter_AddRefs(relatedEl));
       finalFocusNode = do_QueryInterface(relatedEl);
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsAccessible.cpp
@@ -211,32 +211,31 @@ nsXFormsAccessible::GetState(PRUint32 *a
 
   return NS_OK;
 }
 
 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;
   }
 
   // search the xforms:label element
   return GetBoundChildElementValue(NS_LITERAL_STRING("label"), aName);
 }
 
 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;
     return NS_OK;
   }
 
   // search the xforms:hint element
   return GetBoundChildElementValue(NS_LITERAL_STRING("hint"), aDescription);
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
@@ -54,27 +54,26 @@ nsXFormsLabelAccessible::GetRole(PRUint3
   *aRole = nsIAccessibleRole::ROLE_STATICTEXT;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXFormsLabelAccessible::GetName(nsAString& aName)
 {
   nsAutoString name;
-  nsresult rv = GetTextFromRelationID(nsAccessibilityAtoms::labelledby, name);
+  nsresult rv = GetTextFromRelationID(eAria_labelledby, name);
   aName = name;
   return rv;
 }
 
 NS_IMETHODIMP
 nsXFormsLabelAccessible::GetDescription(nsAString& aDescription)
 {
   nsAutoString description;
-  nsresult rv = GetTextFromRelationID(nsAccessibilityAtoms::describedby,
-                                      description);
+  nsresult rv = GetTextFromRelationID(eAria_describedby, description);
   aDescription = description;
   return rv;
 }
 
 // nsXFormsOutputAccessible
 
 nsXFormsOutputAccessible::
   nsXFormsOutputAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell):