Bug 725432 - HTML buttons with aria-pressed not exposing IA2 TOGGLE_BUTTON role, r=tbsaunde, f=surkov
authorMax Li <maxli@maxli.ca>
Thu, 29 Mar 2012 20:04:06 -0400
changeset 93994 38d50ee4b9bac84f0ccc7a2f09e297fe864e16b9
parent 93993 cf941140cded6887c3ca5b6fabb9723a0dba78cb
child 93995 461760e5dbd591abf0b943e89ca9cabad2485ecf
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde
bugs725432
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 725432 - HTML buttons with aria-pressed not exposing IA2 TOGGLE_BUTTON role, r=tbsaunde, f=surkov
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsAccessible.h
accessible/tests/mochitest/test_aria_roles.html
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1799,57 +1799,54 @@ nsAccessible::GetKeyBindings(PRUint8 aAc
   if (!defaultKey.IsEmpty())
     keyBindings->Add(defaultKey);
 
   NS_ADDREF(*aKeyBindings = keyBindings);
   return NS_OK;
 }
 
 role
-nsAccessible::ARIARoleInternal()
+nsAccessible::ARIATransformRole(role aRole)
 {
-  NS_PRECONDITION(mRoleMapEntry && mRoleMapEntry->roleRule == kUseMapRole,
-                  "ARIARoleInternal should only be called when ARIA role overrides!");
-
   // XXX: these unfortunate exceptions don't fit into the ARIA table. This is
   // where the accessible role depends on both the role and ARIA state.
-  if (mRoleMapEntry->role == roles::PUSHBUTTON) {
+  if (aRole == roles::PUSHBUTTON) {
     if (nsAccUtils::HasDefinedARIAToken(mContent, nsGkAtoms::aria_pressed)) {
       // For simplicity, any existing pressed attribute except "" or "undefined"
       // indicates a toggle.
       return roles::TOGGLE_BUTTON;
     }
 
     if (mContent->AttrValueIs(kNameSpaceID_None,
                               nsGkAtoms::aria_haspopup,
                               nsGkAtoms::_true,
                               eCaseMatters)) {
       // For button with aria-haspopup="true".
       return roles::BUTTONMENU;
     }
 
-  } else if (mRoleMapEntry->role == roles::LISTBOX) {
+  } else if (aRole == roles::LISTBOX) {
     // A listbox inside of a combobox needs a special role because of ATK
     // mapping to menu.
     if (mParent && mParent->Role() == roles::COMBOBOX) {
       return roles::COMBOBOX_LIST;
 
       Relation rel = RelationByType(nsIAccessibleRelation::RELATION_NODE_CHILD_OF);
       nsAccessible* targetAcc = nsnull;
       while ((targetAcc = rel.Next()))
         if (targetAcc->Role() == roles::COMBOBOX)
           return roles::COMBOBOX_LIST;
     }
 
-  } else if (mRoleMapEntry->role == roles::OPTION) {
+  } else if (aRole == roles::OPTION) {
     if (mParent && mParent->Role() == roles::COMBOBOX_LIST)
       return roles::COMBOBOX_OPTION;
   }
 
-  return mRoleMapEntry->role;
+  return aRole;
 }
 
 role
 nsAccessible::NativeRole()
 {
   return nsCoreUtils::IsXLink(mContent) ? roles::LINK : roles::NOTHING;
 }
 
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -173,19 +173,19 @@ public:
   virtual nsresult GetNameInternal(nsAString& aName);
 
   /**
    * Return enumerated accessible role (see constants in Role.h).
    */
   inline mozilla::a11y::role Role()
   {
     if (!mRoleMapEntry || mRoleMapEntry->roleRule != kUseMapRole)
-      return NativeRole();
+      return ARIATransformRole(NativeRole());
 
-    return ARIARoleInternal();
+    return ARIATransformRole(mRoleMapEntry->role);
   }
 
   /**
    * Return true if ARIA role is specified on the element.
    */
   inline bool HasARIARole() const
   {
     return mRoleMapEntry;
@@ -195,17 +195,17 @@ public:
    * Return accessible role specified by ARIA (see constants in
    * roles).
    */
   inline mozilla::a11y::role ARIARole()
   {
     if (!mRoleMapEntry || mRoleMapEntry->roleRule != kUseMapRole)
       return mozilla::a11y::roles::NOTHING;
 
-    return ARIARoleInternal();
+    return ARIATransformRole(mRoleMapEntry->role);
   }
 
   /**
    * Returns enumerated accessible role from native markup (see constants in
    * Role.h). Doesn't take into account ARIA roles.
    */
   virtual mozilla::a11y::role NativeRole();
 
@@ -722,17 +722,17 @@ protected:
   };
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous helpers
 
   /**
    * Return ARIA role (helper method).
    */
-  mozilla::a11y::role ARIARoleInternal();
+  mozilla::a11y::role ARIATransformRole(mozilla::a11y::role aRole);
 
   virtual nsIFrame* GetBoundsFrame();
   virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
 
   //////////////////////////////////////////////////////////////////////////////
   // Name helpers
 
   /**
--- a/accessible/tests/mochitest/test_aria_roles.html
+++ b/accessible/tests/mochitest/test_aria_roles.html
@@ -63,16 +63,20 @@ https://bugzilla.mozilla.org/show_bug.cg
       // abstract roles
       var abstract_roles = ["composite", "landmark", "structure", "widget",
                             "window", "input", "range", "select", "section",
                             "sectionhead"];
       for (a in abstract_roles)
         testRole(abstract_roles[a], ROLE_SECTION);
 
       //////////////////////////////////////////////////////////////////////////
+      // roles transformed by ARIA state attributes
+      testRole("togglebutton", ROLE_TOGGLE_BUTTON);
+
+      //////////////////////////////////////////////////////////////////////////
       // misc roles
       testRole("note", ROLE_NOTE);
       testRole("scrollbar", ROLE_SCROLLBAR);
       testRole("dir", ROLE_LIST);
 
       //////////////////////////////////////////////////////////////////////////
       // test document role map update
       var testDoc = getAccessible(document, [nsIAccessibleDocument]);
@@ -90,16 +94,21 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=481114">Mozilla Bug 481114</a>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469688">Mozilla Bug 469688</a>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469688">Mozilla Bug 520188</a>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=529289">Mozilla Bug 529289</a>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=529289">Mozilla Bug 607219</a>
   <a target="_blank"
+     title="HTML buttons with aria-pressed not exposing IA2 TOGGLE_BUTTON role"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=725432">
+    Bug 725432
+  </a>
+  <a target="_blank"
      title="Map ARIA role FORM"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=735645">
     Bug 735645
   </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
@@ -157,16 +166,19 @@ https://bugzilla.mozilla.org/show_bug.cg
   <!-- test abstract input roles -->
   <div role="input" id="input">input</div>
   <div role="range" id="range">range</div>
   <div role="select" id="select">select</div>
   <!-- test abstract structure roles -->
   <div role="section" id="section">section</div>
   <div role="sectionhead" id="sectionhead">sectionhead</div>
 
+  <!-- roles transformed by ARIA state attributes -->
+  <button aria-pressed="true" id="togglebutton">
+
   <!-- misc roles -->
   <div role="note" id="note">note</div>
   <div role="scrollbar" id="scrollbar">scrollbar</div>
 
   <div id="dir" role="directory">
     <div role="listitem">A</div>
     <div role="listitem">B</div>
     <div role="listitem">C</div>