Bug 690199 - ARIA select widget should expose focusable state regardless the way they manage its children. r=surkov
authorMax Li <maxli@maxli.ca>
Fri, 26 Jul 2013 06:26:44 -0400
changeset 140142 35f1055fd2179c264946c5007496a89fe4045eb2
parent 140141 77df61af1a84b8e5d554920e1f48781de6d63600
child 140143 0621ef3a01da803d6f7465d0f5fdc447ff020610
push idunknown
push userunknown
push dateunknown
reviewerssurkov
bugs690199
milestone25.0a1
Bug 690199 - ARIA select widget should expose focusable state regardless the way they manage its children. r=surkov
accessible/src/base/ARIAMap.cpp
accessible/src/base/ARIAStateMap.cpp
accessible/src/base/ARIAStateMap.h
accessible/tests/mochitest/states/test_aria.html
--- a/accessible/src/base/ARIAMap.cpp
+++ b/accessible/src/base/ARIAMap.cpp
@@ -171,19 +171,20 @@ static nsRoleMapEntry sWAIRoleMaps[] =
   { // grid
     &nsGkAtoms::grid,
     roles::TABLE,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eSelect | eTable,
-    states::FOCUSABLE,
+    kNoReqStates,
     eARIAMultiSelectable,
-    eARIAReadonlyOrEditable
+    eARIAReadonlyOrEditable,
+    eFocusableUntilDisabled
   },
   { // gridcell
     &nsGkAtoms::gridcell,
     roles::GRID_CELL,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
@@ -258,17 +259,18 @@ static nsRoleMapEntry sWAIRoleMaps[] =
     roles::LISTBOX,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eListControl | eSelect,
     kNoReqStates,
     eARIAMultiSelectable,
-    eARIAReadonly
+    eARIAReadonly,
+    eFocusableUntilDisabled
   },
   { // listitem
     &nsGkAtoms::listitem,
     roles::LISTITEM,
     kUseMapRole,
     eNoValue,
     eNoAction, // XXX: should depend on state, parent accessible
     eNoLiveAttr,
@@ -600,29 +602,31 @@ static nsRoleMapEntry sWAIRoleMaps[] =
     roles::OUTLINE,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eSelect,
     kNoReqStates,
     eARIAReadonly,
-    eARIAMultiSelectable
+    eARIAMultiSelectable,
+    eFocusableUntilDisabled
   },
   { // treegrid
     &nsGkAtoms::treegrid,
     roles::TREE_TABLE,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eSelect | eTable,
     kNoReqStates,
     eARIAReadonly,
-    eARIAMultiSelectable
+    eARIAMultiSelectable,
+    eFocusableUntilDisabled
   },
   { // treeitem
     &nsGkAtoms::treeitem,
     roles::OUTLINEITEM,
     kUseMapRole,
     eNoValue,
     eActivateAction, // XXX: should expose second 'expand/collapse' action based
                      // on states
--- a/accessible/src/base/ARIAStateMap.cpp
+++ b/accessible/src/base/ARIAStateMap.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ARIAMap.h"
+#include "nsAccUtils.h"
 #include "States.h"
 
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 using namespace mozilla::a11y::aria;
 
@@ -322,16 +323,26 @@ aria::MapToState(EStateRule aRule, dom::
     {
       if (!aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_valuenow) &&
           !aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_valuetext))
         *aState |= states::MIXED;
 
       return true;
     }
 
+    case eFocusableUntilDisabled:
+    {
+      if (!nsAccUtils::HasDefinedARIAToken(aElement, nsGkAtoms::aria_disabled) ||
+          aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_disabled,
+                                nsGkAtoms::_false, eCaseMatters))
+        *aState |= states::FOCUSABLE;
+
+      return true;
+    }
+
     default:
       return false;
   }
 }
 
 static void
 MapEnumType(dom::Element* aElement, uint64_t* aState, const EnumTypeData& aData)
 {
--- a/accessible/src/base/ARIAStateMap.h
+++ b/accessible/src/base/ARIAStateMap.h
@@ -39,17 +39,18 @@ enum EStateRule
   eARIAPressed,
   eARIAReadonly,
   eARIAReadonlyOrEditable,
   eARIAReadonlyOrEditableIfDefined,
   eARIARequired,
   eARIASelectable,
   eARIASelectableIfDefined,
   eReadonlyUntilEditable,
-  eIndeterminateIfNoValue
+  eIndeterminateIfNoValue,
+  eFocusableUntilDisabled
 };
 
 /**
  * Expose the accessible states for the given element accordingly to state
  * mapping rule.
  *
  * @param  aRule     [in] state mapping rule ID
  * @param  aElement  [in] node of the accessible
--- a/accessible/tests/mochitest/states/test_aria.html
+++ b/accessible/tests/mochitest/states/test_aria.html
@@ -193,16 +193,24 @@
       testStates("aria_vslider", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
 
       // indeterminate ARIA progressbars (no aria-valuenow or aria-valuetext attribute)
       // should expose mixed state
       testStates("aria_progressbar", STATE_MIXED);
       testStates("aria_progressbar_valuenow", 0, 0, STATE_MIXED);
       testStates("aria_progressbar_valuetext", 0, 0, STATE_MIXED);
 
+      testStates("aria_listbox", STATE_FOCUSABLE);
+      testStates("aria_grid", STATE_FOCUSABLE);
+      testStates("aria_tree", STATE_FOCUSABLE);
+      testStates("aria_treegrid", STATE_FOCUSABLE);
+      testStates("aria_listbox_disabled", 0, 0, STATE_FOCUSABLE);
+      testStates("aria_grid_disabled", 0, 0, STATE_FOCUSABLE);
+      testStates("aria_tree_disabled", 0, 0, STATE_FOCUSABLE);
+      testStates("aria_treegrid_disabled", 0, 0, STATE_FOCUSABLE);
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 
 </head>
@@ -215,60 +223,66 @@
     Mozilla Bug 457219
   </a><br />
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=429285"
      title="Propagate aria-disabled to descendants">
     Mozilla Bug 429285
   </a>
   <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=457226"
+     title="Mochitests for ARIA states">
+    Mozilla Bug 457226
+  </a>
+  <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=499653"
      title="Unify ARIA state attributes mapping rules">
     Mozilla Bug 499653
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=681674"
      title="aria-autocomplete not supported on standard form text input controls">
     Mozilla Bug 681674
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=681674"
      title="aria-orientation should be applied to separator and slider roles">
     Mozilla Bug 681674
   </a>
   <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=689847"
+     title="Expose active state on current item of selectable widgets">
+    Mozilla Bug 689847
+  </a>
+  <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=699017"
      title="File input control should be propogate states to descendants">
     Mozilla Bug 699017
   </a>
   <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=689847"
-     title="Expose active state on current item of selectable widgets">
-    Mozilla Bug 689847
-  </a>
-  <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=457226"
-     title="Mochitests for ARIA states">
-    Mozilla Bug 457226
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=690199"
+     title="ARIA select widget should expose focusable state regardless the way they manage its children">
+    Mozilla Bug 690199
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=740851"
      title="ARIA undetermined progressmeters should expose mixed state">
     Mozilla Bug 740851
   </a>
   <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=762876
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=762876"
      title="fix default horizontal / vertical state of role=scrollbar and ensure only one of horizontal / vertical states is exposed">
     Mozilla Bug 762876
   </a>
   <a target="_blank"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=835121
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=835121"
      title="ARIA grid should be editable by default">
     Mozilla Bug 835121
   </a>
+
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <div id="textbox_autocomplete_inline" role="textbox" aria-autocomplete="inline"></div>
   <div id="textbox_autocomplete_list" role="textbox" aria-autocomplete="list"></div>
   <div id="textbox_autocomplete_both" role="textbox" aria-autocomplete="both"></div>
@@ -408,10 +422,44 @@
   <div id="aria_slider" role="slider">slider</div>
   <div id="aria_hslider" role="slider" aria-orientation="horizontal">horizontal slider</div>
   <div id="aria_vslider" role="slider" aria-orientation="vertical">vertical slider</div>
   
   <!-- indeterminate ARIA progressbars should expose mixed state -->
   <div id="aria_progressbar" role="progressbar"></div>
   <div id="aria_progressbar_valuenow" role="progressbar" aria-valuenow="1"></div>
   <div id="aria_progressbar_valuetext" role="progressbar" aria-valuetext="value"></div>
+
+  <!-- ARIA select widget should expose focusable state regardless the way they manage its children -->
+  <div id="aria_listbox" role="listbox">
+    <div role="option" tabindex="0">A</div>
+    <div role="option" tabindex="0">a</div>
+  </div>
+  <div id="aria_grid" role="grid">
+    <div role="row"><div role="gridcell" tabindex="0">B</div></div></div>
+    <div role="row"><div role="gridcell" tabindex="0">b</div></div></div>
+  <div id="aria_tree" role="tree">
+    <div role="treeitem" tabindex="0">C</div>
+    <div role="treeitem" tabindex="0">c</div>
+  </div>
+  <div id="aria_treegrid" role="treegrid">
+    <div role="row"><div role="gridcell" tabindex="0">D</div></div>
+    <div role="row"><div role="gridcell" tabindex="0">d</div></div>
+  </div>
+  <div id="aria_listbox_disabled" role="listbox" aria-disabled="true">
+    <div role="option">E</div>
+    <div role="option">e</div>
+  </div>
+  <div id="aria_grid_disabled" role="grid" aria-disabled="true">
+    <div role="row"><div role="gridcell">F</div></div>
+    <div role="row"><div role="gridcell">f</div></div>
+  </div>
+  <div id="aria_tree_disabled" role="tree" aria-disabled="true">
+    <div role="treeitem">G</div>
+    <div role="treeitem">g</div>
+  </div>
+  <div id="aria_treegrid_disabled" role="treegrid" aria-disabled="true">
+    <div role="row"><div role="gridcell">H</div></div>
+    <div role="row"><div role="gridcell">h</div></div>
+  </div>
+
 </body>
 </html>