Bug 421565. ARIA tweaks. r=surkov, a=dsicore
authoraaronleventhal@moonset.net
Thu, 13 Mar 2008 10:39:18 -0700
changeset 13012 90bf98eb63086a0556f78ec85b8ae7c93c263385
parent 13011 8a8b1f94e0787dcde8d988cf3ef897bad84a1cf5
child 13013 3fb667068af27be5ce40acfa8e44c596594805d8
push idunknown
push userunknown
push dateunknown
reviewerssurkov, dsicore
bugs421565
milestone1.9b5pre
Bug 421565. ARIA tweaks. r=surkov, a=dsicore
accessible/src/atk/nsAccessibleWrap.cpp
accessible/src/base/nsARIAMap.cpp
accessible/src/base/nsAccessibilityAtomList.h
accessible/src/base/nsAccessibilityUtils.cpp
accessible/src/base/nsAccessibilityUtils.h
accessible/src/base/nsAccessible.cpp
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -797,22 +797,16 @@ GetAttributeSet(nsIAccessible* aAccessib
         PRUint32 state;
         aAccessible->GetFinalState(&state, nsnull);
         if (state & nsIAccessibleStates::STATE_HASPOPUP) {
           // There is no ATK state for haspopup, must use object attribute to expose the same info
           nsAutoString oldValueUnused;
           attributes->SetStringProperty(NS_LITERAL_CSTRING("haspopup"), NS_LITERAL_STRING("true"),
                                         oldValueUnused);
         }
-        if (state & nsIAccessibleStates::STATE_CHECKABLE) {
-          // There is no ATK state for haspopup, must use object attribute to expose the same info
-          nsAutoString oldValueUnused;
-          attributes->SetStringProperty(NS_LITERAL_CSTRING("checkable"), NS_LITERAL_STRING("true"),
-                                        oldValueUnused);
-        }
 
         nsCOMPtr<nsISimpleEnumerator> propEnum;
         nsresult rv = attributes->Enumerate(getter_AddRefs(propEnum));
         NS_ENSURE_SUCCESS(rv, nsnull);
 
         PRBool hasMore;
         while (NS_SUCCEEDED(propEnum->HasMoreElements(&hasMore)) && hasMore) {
             nsCOMPtr<nsISupports> sup;
--- a/accessible/src/base/nsARIAMap.cpp
+++ b/accessible/src/base/nsARIAMap.cpp
@@ -91,23 +91,22 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] 
             {&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
             {&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
             {&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
   {"group", nsIAccessibleRole::ROLE_GROUPING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"heading", nsIAccessibleRole::ROLE_HEADING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"img", nsIAccessibleRole::ROLE_GRAPHIC, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"label", nsIAccessibleRole::ROLE_LABEL, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
   {"link", nsIAccessibleRole::ROLE_LINK, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_LINKED, kEndEntry},
-  {"list", nsIAccessibleRole::ROLE_LIST, eNameLabelOrTitle, eNoValue, kNoReqStates,
-            {&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
+  {"list", nsIAccessibleRole::ROLE_LIST, eNameLabelOrTitle, eNoValue, nsIAccessibleStates::STATE_READONLY,
             {&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
   {"listbox", nsIAccessibleRole::ROLE_LISTBOX, eNameLabelOrTitle, eNoValue, kNoReqStates,
             {&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
             {&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
-  {"listitem", nsIAccessibleRole::ROLE_LISTITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
+  {"listitem", nsIAccessibleRole::ROLE_LISTITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_READONLY,
             {&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
             {&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
             {&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
             {&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
             {&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
   {"menu", nsIAccessibleRole::ROLE_MENUPOPUP, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"menubar", nsIAccessibleRole::ROLE_MENUBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
   {"menuitem", nsIAccessibleRole::ROLE_MENUITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
--- a/accessible/src/base/nsAccessibilityAtomList.h
+++ b/accessible/src/base/nsAccessibilityAtomList.h
@@ -152,16 +152,17 @@ ACCESSIBILITY_ATOM(ul, "ul")
   // 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(contenteditable, "contenteditable")
 ACCESSIBILITY_ATOM(control, "control")
 ACCESSIBILITY_ATOM(disabled, "disabled")
+ACCESSIBILITY_ATOM(_class, "class")
 ACCESSIBILITY_ATOM(cycles, "cycles") // used for XUL cycler attribute
 ACCESSIBILITY_ATOM(curpos, "curpos") // XUL
 ACCESSIBILITY_ATOM(data, "data")
 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")
--- a/accessible/src/base/nsAccessibilityUtils.cpp
+++ b/accessible/src/base/nsAccessibilityUtils.cpp
@@ -902,8 +902,34 @@ nsAccUtils::GetRoleMapEntry(nsIDOMNode *
     }
   }
 
   // Always use some entry if there is a role string
   // To ensure an accessible object is created
   return &nsARIAMap::gLandmarkRoleMap;
 }
 
+PRBool
+nsAccUtils::IsARIAPropForObjectAttr(nsIAtom *aAtom)
+{
+  return aAtom != nsAccessibilityAtoms::aria_activedescendant &&
+         aAtom != nsAccessibilityAtoms::aria_checked &&
+         aAtom != nsAccessibilityAtoms::aria_controls &&
+         aAtom != nsAccessibilityAtoms::aria_describedby &&
+         aAtom != nsAccessibilityAtoms::aria_disabled &&
+         aAtom != nsAccessibilityAtoms::aria_expanded &&
+         aAtom != nsAccessibilityAtoms::aria_flowto &&
+         aAtom != nsAccessibilityAtoms::aria_invalid &&
+         aAtom != nsAccessibilityAtoms::aria_haspopup &&
+         aAtom != nsAccessibilityAtoms::aria_labelledby &&
+         aAtom != nsAccessibilityAtoms::aria_multiline &&
+         aAtom != nsAccessibilityAtoms::aria_multiselectable &&
+         aAtom != nsAccessibilityAtoms::aria_owns &&
+         aAtom != nsAccessibilityAtoms::aria_pressed &&
+         aAtom != nsAccessibilityAtoms::aria_readonly &&
+         aAtom != nsAccessibilityAtoms::aria_relevant &&
+         aAtom != nsAccessibilityAtoms::aria_required &&
+         aAtom != nsAccessibilityAtoms::aria_selected &&
+         aAtom != nsAccessibilityAtoms::aria_valuemax &&
+         aAtom != nsAccessibilityAtoms::aria_valuemin &&
+         aAtom != nsAccessibilityAtoms::aria_valuenow &&
+         aAtom != nsAccessibilityAtoms::aria_valuetext;
+}
--- a/accessible/src/base/nsAccessibilityUtils.h
+++ b/accessible/src/base/nsAccessibilityUtils.h
@@ -358,12 +358,15 @@ public:
 
   // Helper for FindDescendantPointingToID(), same args
   static nsIContent *FindDescendantPointingToIDImpl(nsCString& aIdWithSpaces,
                                                     nsIContent *aLookContent,
                                                     nsIAtom **aRelationAttrs,
                                                     PRUint32 aAttrNum = 1,
                                                     nsIContent *aExcludeContent = nsnull,
                                                     nsIAtom *aTagType = nsAccessibilityAtoms::label);
+  
+  // Return PR_TRUE if the ARIA property should always be exposed as an object attribute
+  static PRBool IsARIAPropForObjectAttr(nsIAtom *aAtom);
 };
 
 #endif
 
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -82,16 +82,17 @@
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIURI.h"
 #include "nsITimer.h"
 #include "nsIMutableArray.h"
 #include "nsIObserverService.h"
 #include "nsIServiceManager.h"
 #include "nsWhitespaceTokenizer.h"
+#include "nsAttrName.h"
 
 #ifdef NS_DEBUG
 #include "nsIFrameDebug.h"
 #include "nsIDOMCharacterData.h"
 #endif
 
 /**
  * nsAccessibleDOMStringList implementation
@@ -1961,21 +1962,27 @@ NS_IMETHODIMP nsAccessible::GetFinalRole
                                       nsAccessibilityAtoms::_true, eCaseMatters)) {
           // For button with aria-haspopup="true"
           *aRole = nsIAccessibleRole::ROLE_BUTTONMENU;
         }
       }
     }
     else if (*aRole == nsIAccessibleRole::ROLE_LISTBOX) {
       // A listbox inside of a combo box needs a special role because of ATK mapping to menu
-      nsCOMPtr<nsIAccessible> parent;
-      GetParent(getter_AddRefs(parent));
-      if (parent && Role(parent) == nsIAccessibleRole::ROLE_COMBOBOX) {
+      nsCOMPtr<nsIAccessible> possibleCombo;
+      GetParent(getter_AddRefs(possibleCombo));
+      if (possibleCombo && Role(possibleCombo) == nsIAccessibleRole::ROLE_COMBOBOX) {
         *aRole = nsIAccessibleRole::ROLE_COMBOBOX_LIST;
       }
+      else {   // Check to see if combo owns the listbox instead
+        GetAccessibleRelated(nsIAccessibleRelation::RELATION_NODE_CHILD_OF, getter_AddRefs(possibleCombo));
+        if (possibleCombo && Role(possibleCombo) == nsIAccessibleRole::ROLE_COMBOBOX) {
+          *aRole = nsIAccessibleRole::ROLE_COMBOBOX_LIST;
+        }
+      }
     }
     else if (*aRole == nsIAccessibleRole::ROLE_OPTION) {
       nsCOMPtr<nsIAccessible> parent;
       GetParent(getter_AddRefs(parent));
       if (parent && Role(parent) == nsIAccessibleRole::ROLE_COMBOBOX_LIST) {
         *aRole = nsIAccessibleRole::ROLE_COMBOBOX_OPTION;
       }
     }
@@ -2013,79 +2020,85 @@ nsAccessible::GetAttributes(nsIPersisten
   nsresult rv = GetAttributesInternal(attributes);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString id;
   nsAutoString oldValueUnused;
   if (nsAccUtils::GetID(content, id)) {
     attributes->SetStringProperty(NS_LITERAL_CSTRING("id"), id, oldValueUnused);
   }
+  
+  nsAutoString _class;
+  if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::_class, _class))
+    nsAccUtils::SetAccAttr(attributes, nsAccessibilityAtoms::_class, _class);
 
   nsAutoString xmlRoles;
   if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::role, xmlRoles)) {
     attributes->SetStringProperty(NS_LITERAL_CSTRING("xml-roles"),  xmlRoles, oldValueUnused);          
   }
 
-  // Make sure to keep these two arrays in sync
-  char *ariaPropertyString[] = { "live", "channel", "atomic", "relevant", "datatype", "level",
-                             "posinset", "setsize", "sort", "grab", "dropeffect"};
-  nsIAtom *ariaPropertyEnum[] = { nsAccessibilityAtoms::aria_live, nsAccessibilityAtoms::aria_channel, nsAccessibilityAtoms::aria_atomic, nsAccessibilityAtoms::aria_relevant,
-                                     nsAccessibilityAtoms::aria_datatype, nsAccessibilityAtoms::aria_level, nsAccessibilityAtoms::aria_posinset, nsAccessibilityAtoms::aria_setsize,
-                                     nsAccessibilityAtoms::aria_sort, nsAccessibilityAtoms::aria_grab, nsAccessibilityAtoms::aria_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;
-    if (content->GetAttr(kNameSpaceID_None, ariaPropertyEnum[index], value)) {
-      ToLowerCase(value);
-      attributes->SetStringProperty(nsDependentCString(ariaPropertyString[index]), value, oldValueUnused);    
-    }
-  }
-
   nsCOMPtr<nsIAccessibleValue> supportsValue = do_QueryInterface(static_cast<nsIAccessible*>(this));
   if (supportsValue) {
     // We support values, so expose the string value as well, via the valuetext object attribute
     // We test for the value interface because we don't want to expose traditional get_accValue()
     // information such as URL's on links and documents, or text in an input
     nsAutoString valuetext;
     GetValue(valuetext);
     attributes->SetStringProperty(NS_LITERAL_CSTRING("valuetext"), valuetext, 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) {
+  nsIContent *ancestor = content;
+  while (ancestor) {
     if (relevant.IsEmpty() &&
-        content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_relevant, relevant))
+        ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_relevant, relevant))
       attributes->SetStringProperty(NS_LITERAL_CSTRING("container-relevant"), relevant, oldValueUnused);
     if (live.IsEmpty() &&
-        content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_live, live))
+        ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_live, live))
       attributes->SetStringProperty(NS_LITERAL_CSTRING("container-live"), live, oldValueUnused);
     if (channel.IsEmpty() &&
-        content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_channel, channel))
+        ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_channel, channel))
       attributes->SetStringProperty(NS_LITERAL_CSTRING("container-channel"), channel, oldValueUnused);
     if (atomic.IsEmpty() &&
-        content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_atomic, atomic))
+        ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_atomic, atomic))
       attributes->SetStringProperty(NS_LITERAL_CSTRING("container-atomic"), atomic, oldValueUnused);
     if (busy.IsEmpty() &&
-        content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_busy, busy))
+        ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_busy, busy))
       attributes->SetStringProperty(NS_LITERAL_CSTRING("container-busy"), busy, oldValueUnused);
-    content = content->GetParent();
+    ancestor = ancestor->GetParent();
   }
 
+  PRUint32 role = Role(this);
+  if (role == nsIAccessibleRole::ROLE_CHECKBUTTON ||
+      role == nsIAccessibleRole::ROLE_PUSHBUTTON ||
+      role == nsIAccessibleRole::ROLE_MENUITEM ||
+      role == nsIAccessibleRole::ROLE_LISTITEM ||
+      role == nsIAccessibleRole::ROLE_OUTLINEITEM ||
+      content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_checked)) {
+    // Might be checkable -- checking role & ARIA attribute first is faster than getting state
+    PRUint32 state = 0;
+    GetFinalState(&state, nsnull);
+    if (state & nsIAccessibleStates::STATE_CHECKABLE) {
+      // No official state for checkable, so use object attribute to expose that
+      attributes->SetStringProperty(NS_LITERAL_CSTRING("checkable"), NS_LITERAL_STRING("true"),
+                                    oldValueUnused);
+    }
+  }
+
+  // Level/setsize/posinset
   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
     // these properties to map them into description.
 
     // If accessible is invisible we don't want to calculate group ARIA
     // attributes for it.
-    PRUint32 role = Role(this);
     if ((role == nsIAccessibleRole::ROLE_LISTITEM ||
         role == nsIAccessibleRole::ROLE_MENUITEM ||
         role == nsIAccessibleRole::ROLE_RADIOBUTTON ||
         role == nsIAccessibleRole::ROLE_PAGETAB ||
         role == nsIAccessibleRole::ROLE_OUTLINEITEM) &&
         0 == (State(this) & nsIAccessibleStates::STATE_INVISIBLE)) {
       nsCOMPtr<nsIAccessible> parent = GetParent();
       NS_ENSURE_TRUE(parent, NS_ERROR_FAILURE);
@@ -2131,16 +2144,35 @@ nsAccessible::GetAttributes(nsIPersisten
         }
       }
 
       nsAccUtils::SetAccGroupAttrs(attributes, groupLevel, positionInGroup,
                                    setSize);
     }
   }
 
+  // Expose all ARIA attributes
+  PRUint32 numAttrs = content->GetAttrCount();
+  for (PRUint32 count = 0; count < numAttrs; count ++) {
+    const nsAttrName *attr = content->GetAttrNameAt(count);
+    if (attr && attr->NamespaceEquals(kNameSpaceID_None)) {
+      nsIAtom *attrAtom = attr->Atom();
+      const char *attrStr;
+      attrAtom->GetUTF8String(&attrStr);
+      if (PL_strncmp(attrStr, "aria-", 5)) 
+        continue; // Not ARIA
+      if (!nsAccUtils::IsARIAPropForObjectAttr(attrAtom))
+        continue; // No need to expose obj attribute -- will be exposed some other way
+      nsAutoString value;
+      if (content->GetAttr(kNameSpaceID_None, attrAtom, value)) {
+        attributes->SetStringProperty(nsDependentCString(attrStr + 5), value, oldValueUnused);
+      }
+    }
+  }
+
   attributes.swap(*aAttributes);
 
   return NS_OK;
 }
 
 nsresult
 nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
 {
@@ -2303,17 +2335,16 @@ nsAccessible::GetFinalState(PRUint32 *aS
     }
   }
 
   PRUint32 role;
   rv = GetFinalRole(&role);
   NS_ENSURE_SUCCESS(rv, rv);
 
   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_None, nsAccessibilityAtoms::aria_autocomplete, autocomplete) &&
         (autocomplete.EqualsIgnoreCase("inline") ||
@@ -2322,16 +2353,20 @@ nsAccessible::GetFinalState(PRUint32 *aS
       *aExtraState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
     }
 
     // XXX We can remove this hack once we support RDF-based role & state maps
     if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_ENTRY) {
       PRBool isMultiLine = content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::aria_multiline,
                                                 nsAccessibilityAtoms::_true, eCaseMatters);
       *aExtraState |= isMultiLine ? nsIAccessibleStates::EXT_STATE_MULTI_LINE : nsIAccessibleStates::EXT_STATE_SINGLE_LINE;
+      if (0 == (*aState & nsIAccessibleStates::STATE_READONLY))
+        *aExtraState |= nsIAccessibleStates::EXT_STATE_EDITABLE; // Not readonly
+      else  // We're readonly: make sure editable state wasn't set by impl class
+        *aExtraState &= ~nsIAccessibleStates::EXT_STATE_EDITABLE;
     }
   }
 
   // For some reasons DOM node may have not a frame. We tract such accessibles
   // as invisible.
   nsIFrame *frame = GetFrame();
   if (!frame)
     return NS_OK;
@@ -2383,23 +2418,16 @@ nsAccessible::GetARIAState()
       MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap3) &&
       MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap4) &&
       MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap5) &&
       MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap6) &&
       MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap7)) {
     MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap8);
   }
 
-  if (ariaState & nsIAccessibleStates::STATE_UNAVAILABLE) {
-    // Disabled elements are not selectable or focusable, even if disabled
-    // via DHTML accessibility disabled property
-    ariaState &= ~(nsIAccessibleStates::STATE_SELECTABLE |
-                   nsIAccessibleStates::STATE_FOCUSABLE);
-  }
-
   return ariaState;
 }
 
 // Not implemented by this class
 
 /* DOMString getValue (); */
 NS_IMETHODIMP nsAccessible::GetValue(nsAString& aValue)
 {