Bug 457219 - collapsed and expanded states are exposed both, r=marcoz, aaronlev
authorAlexander Surkov <surkov.alexander@gmail.com>
Wed, 08 Oct 2008 13:27:24 +0800
changeset 20128 f9bbc6e85b6e2e7ebb6cb3f5953c82cf2d849341
parent 20127 4a461b03f6ae91f4dd6af9492de0b90c86934f77
child 20129 b0376f90fb73310bde03c276bd068b828bfa024a
push idunknown
push userunknown
push dateunknown
reviewersmarcoz, aaronlev
bugs457219
milestone1.9.1b2pre
Bug 457219 - collapsed and expanded states are exposed both, r=marcoz, aaronlev
accessible/src/base/nsAccessible.cpp
accessible/tests/mochitest/Makefile.in
accessible/tests/mochitest/common.js
accessible/tests/mochitest/nsIAccessible_states.js
accessible/tests/mochitest/test_nsIAccessible_states.html
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -2459,38 +2459,39 @@ nsAccessible::GetFinalState(PRUint32 *aS
         NS_ENSURE_STATE(tabPanelNode);
 
         if (nsAccUtils::IsAncestorOf(tabPanelNode, gLastFocusedNode))
           *aState |= nsIAccessibleStates::STATE_SELECTED;
       }
     }
   }
 
+  const PRUint32 kExpandCollapseStates =
+    nsIAccessibleStates::STATE_COLLAPSED | nsIAccessibleStates::STATE_EXPANDED;
+  if ((*aState & kExpandCollapseStates) == kExpandCollapseStates) {
+    // Cannot be both expanded and collapsed -- this happens in ARIA expanded
+    // combobox because of limitation of nsARIAMap.
+    // XXX: Perhaps we will be able to make this less hacky if we support
+    // extended states in nsARIAMap, e.g. derive COLLAPSED from
+    // EXPANDABLE && !EXPANDED.
+    *aState &= ~nsIAccessibleStates::STATE_COLLAPSED;
+  }
+
   // Set additional states which presence depends on another states.
   if (!aExtraState)
     return NS_OK;
 
   if (!(*aState & nsIAccessibleStates::STATE_UNAVAILABLE)) {
     *aExtraState |= nsIAccessibleStates::EXT_STATE_ENABLED |
                     nsIAccessibleStates::EXT_STATE_SENSITIVE;
   }
 
-  const PRUint32 kExpandCollapseStates =
-    nsIAccessibleStates::STATE_COLLAPSED | nsIAccessibleStates::STATE_EXPANDED;
-  if (*aState & kExpandCollapseStates) {
+  if ((*aState & nsIAccessibleStates::STATE_COLLAPSED) ||
+      (*aState & nsIAccessibleStates::STATE_EXPANDED))
     *aExtraState |= nsIAccessibleStates::EXT_STATE_EXPANDABLE;
-    if ((*aState & kExpandCollapseStates) == kExpandCollapseStates) {
-      // Cannot be both expanded and collapsed -- this happens 
-      // in ARIA expanded combobox because of limitation of nsARIAMap
-      // XXX Perhaps we will be able to make this less hacky if 
-      // we support extended states in nsARIAMap, e.g. derive
-      // COLLAPSED from EXPANDABLE && !EXPANDED
-      *aExtraState &= ~nsIAccessibleStates::STATE_COLLAPSED;
-    }
-  }
 
   if (mRoleMapEntry) {
     // If an object has an ancestor with the activedescendant property
     // pointing at it, we mark it as ACTIVE even if it's not currently focused.
     // This allows screen reader virtual buffer modes to know which descendant
     // is the current one that would get focus if the user navigates to the container widget.
     nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
     nsAutoString id;
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -49,30 +49,32 @@ include $(topsrcdir)/config/rules.mk
 		moz.png \
 		longdesc_src.html \
 		common.js \
 		nsIAccessible_actions.js \
 		nsIAccessible_name.css \
 		nsIAccessible_name.js \
 		nsIAccessible_name.xbl \
  		nsIAccessible_selects.js \
+		nsIAccessible_states.js \
 		nsIAccessibleEditableText.js \
 		test_aria_activedescendant.html \
 		test_aria_role_article.html \
 		test_bug368835.xul \
 		test_bug420863.html \
 		test_cssattrs.html \
 		test_events_caretmove.html \
 		test_groupattrs.xul \
 	$(warning test_table_indexes.html temporarily disabled) \
 		test_nsIAccessible_actions.html \
 		test_nsIAccessible_actions.xul \
 		test_nsIAccessible_name.html \
 		test_nsIAccessible_name.xul \
  		test_nsIAccessible_selects.html \
+		test_nsIAccessible_states.html \
 		test_nsIAccessible_focus.html \
 		test_nsIAccessibleDocument.html \
 		test_nsIAccessibleEditableText.html \
 		test_nsIAccessibleHyperLink.html \
 		test_nsIAccessibleHyperLink.xul \
 		test_nsIAccessibleHyperText.html \
 		test_nsIAccessibleImage.html \
 		test_nsIAccessibleTable_1.html \
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -27,36 +27,42 @@ const nsIAccessibleTable = Components.in
 const nsIAccessibleValue = Components.interfaces.nsIAccessibleValue;
 
 const nsIObserverService = Components.interfaces.nsIObserverService;
 
 const nsIDOMNode = Components.interfaces.nsIDOMNode;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Roles
+
 const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
 const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
 const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION;
 const ROLE_LABEL = nsIAccessibleRole.ROLE_LABEL;
 const ROLE_LIST = nsIAccessibleRole.ROLE_LIST;
 const ROLE_OPTION = nsIAccessibleRole.ROLE_OPTION;
 const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
 
 ////////////////////////////////////////////////////////////////////////////////
 // States
+
 const STATE_COLLAPSED = nsIAccessibleStates.STATE_COLLAPSED;
 const STATE_EXPANDED = nsIAccessibleStates.STATE_EXPANDED;
 const STATE_EXTSELECTABLE = nsIAccessibleStates.STATE_EXTSELECTABLE;
 const STATE_FOCUSABLE = nsIAccessibleStates.STATE_FOCUSABLE;
 const STATE_FOCUSED = nsIAccessibleStates.STATE_FOCUSED;
 const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP;
 const STATE_MULTISELECTABLE = nsIAccessibleStates.STATE_MULTISELECTABLE;
+const STATE_READONLY = nsIAccessibleStates.STATE_READONLY;
 const STATE_SELECTABLE = nsIAccessibleStates.STATE_SELECTABLE;
 const STATE_SELECTED = nsIAccessibleStates.STATE_SELECTED;
 
+const EXT_STATE_EDITABLE = nsIAccessibleStates.EXT_STATE_EDITABLE;
+const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE;
+
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible general
 
 /**
  * nsIAccessibleRetrieval, initialized when test is loaded.
  */
 var gAccRetrieval = null;
 
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/nsIAccessible_states.js
@@ -0,0 +1,59 @@
+function testStates(aAccOrElmOrID, aState, aExtraState, aAbsentState)
+{
+  var [state, extraState] = getStates(aAccOrElmOrID);
+
+  is(state & aState, aState,
+     "wrong state bits for " + aAccOrElmOrID + "!");
+
+  if (aExtraState)
+    is(extraState & aExtraState, aExtraState,
+       "wrong extra state bits for " + aAccOrElmOrID + "!");
+
+  if (aAbsentState)
+    is(state & aAbsentState, 0,
+       "state bits should not be present in ID " + aAccOrElmOrID + "!");
+
+  if (state & STATE_READONLY)
+    is(extraState & EXT_STATE_EDITABLE, 0,
+       "Read-only " + aAccOrElmOrID + " cannot be editable!");
+
+  if (extraState & EXT_STATE_EDITABLE)
+    is(state & STATE_READONLY, 0,
+       "Editable " + aAccOrElmOrID + " cannot be readonly!");
+
+  if (state & STATE_COLLAPSED || state & STATE_EXPANDED)
+    is(extraState & EXT_STATE_EXPANDABLE, EXT_STATE_EXPANDABLE,
+       "Collapsed or expanded " + aAccOrElmOrID + " should be expandable!");
+
+  if (state & STATE_COLLAPSED)
+    is(state & STATE_EXPANDED, 0,
+       "Collapsed " + aAccOrElmOrID + " cannot be expanded!");
+
+  if (state & STATE_EXPANDED)
+    is(state & STATE_COLLAPSED, 0,
+       "Expanded " + aAccOrElmOrID + " cannot be collapsed!");
+}
+
+function getStringStates(aAccOrElmOrID)
+{
+  var [state, extraState] = getStates(aAccOrElmOrID);
+  var list = gAccRetrieval.getStringStates(state, extraState);
+
+  var str = "";
+  for (var index = 0; index < list.length; index++)
+    str += list.item(index) + ", ";
+
+  return str;
+}
+
+function getStates(aAccOrElmOrID)
+{
+  var acc = getAccessible(aAccOrElmOrID);
+  if (!acc)
+    return [0, 0];
+  
+  var state = {}, extraState = {};
+  acc.getFinalState(state, extraState);
+
+  return [state.value, extraState.value];
+}
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/test_nsIAccessible_states.html
@@ -0,0 +1,51 @@
+<html>
+
+<head>
+  <title>nsIAccessible states testing</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/common.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/nsIAccessible_states.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      testStates("combobox", STATE_COLLAPSED);
+      testStates("combobox_expanded", STATE_EXPANDED);
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addLoadEvent(doTest);
+  </script>
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=457219"
+     title="nsIAccessible states testing">
+    Mozilla Bug 457219
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <div id="combobox" role="combobox">combobox</div>
+
+  <div id="combobox_expanded" role="combobox"
+       aria-expanded="true">combobox</div>
+
+</body>
+</html>