Bug 494807 - Do not expose a11y info specific to hyperlinks when role is overridden using ARIA. r=surkov
authorDavid Bolter <dbolter@mozilla.com>
Mon, 19 Oct 2009 12:14:05 -0400
changeset 34248 d490e107ea2ac3f53af4380d34421ea0ddd4504e
parent 34247 872a2ad2af5d10869365085b60a0a98473504c5f
child 34249 914f639bc64535449a705f5b3ddb494ec53dbdee
push id115
push userbmcbride@mozilla.com
push dateMon, 19 Oct 2009 23:27:00 +0000
reviewerssurkov
bugs494807
milestone1.9.3a1pre
Bug 494807 - Do not expose a11y info specific to hyperlinks when role is overridden using ARIA. r=surkov
accessible/src/base/nsAccessibilityService.cpp
accessible/tests/mochitest/Makefile.in
accessible/tests/mochitest/test_states.html
accessible/tests/mochitest/test_value.html
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -543,16 +543,25 @@ nsAccessibilityService::CreateHTMLAccess
   }
   else if (tag == nsAccessibilityAtoms::optgroup) {
     *aAccessible = new nsHTMLSelectOptGroupAccessible(aNode, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::ul || tag == nsAccessibilityAtoms::ol) {
     *aAccessible = new nsHTMLListAccessible(aNode, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::a) {
+
+    // Only some roles truly enjoy life as nsHTMLLinkAccessibles, for details
+    // see closed bug 494807.
+    nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aNode);
+    if (roleMapEntry && roleMapEntry->role != nsIAccessibleRole::ROLE_NOTHING
+        && roleMapEntry->role != nsIAccessibleRole::ROLE_LINK) {
+      return CreateHyperTextAccessible(aFrame, aAccessible);
+    }
+
     *aAccessible = new nsHTMLLinkAccessible(aNode, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::li && aFrame->GetType() != nsAccessibilityAtoms::blockFrame) {
     // Normally this is created by the list item frame which knows about the bullet frame
     // However, in this case the list item must have been styled using display: foo
     *aAccessible = new nsHTMLLIAccessible(aNode, aWeakShell, EmptyString());
   }
   else if (tag == nsAccessibilityAtoms::abbr ||
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -155,16 +155,17 @@ include $(topsrcdir)/config/rules.mk
 		test_table_struct.html \
 		test_table_struct_ariagrid.html \
 		test_table_struct_ariatreegrid.html \
 		test_table_struct_listbox.xul \
 		test_table_struct_tree.xul \
 		test_textattrs.html \
 		test_textboxes.html \
 		test_textboxes.xul \
+		test_value.html \
 		test_value.xul \
 		testTextboxes.js \
 		treeview.css \
 		treeview.js \
 		z_states_frame.html \
 		z_states_framearticle.html \
 		z_states_framecheckbox.html \
 		z_states_frametextbox.html \
--- a/accessible/tests/mochitest/test_states.html
+++ b/accessible/tests/mochitest/test_states.html
@@ -64,16 +64,40 @@
 
       // test disabled group and all its descendants to see if they are
       // disabled, too. See bug 429285.
       testStatesInSubtree("group", STATE_UNAVAILABLE);
 
       // offscreen test
       testStates("aria_offscreen_textbox", STATE_OFFSCREEN);
 
+      //
+      // This section tests aria roles on links/anchors for underlying
+      // nsHTMLLinkAccessible creation. (see closed bug 494807)
+      //
+
+      // strong roles
+      testStates("aria_menuitem_link", 0, 0, STATE_LINKED);
+      testStates("aria_button_link", 0, 0, STATE_LINKED);
+      testStates("aria_checkbox_link", 0, 0, STATE_LINKED);
+
+      // strong landmark
+      testStates("aria_application_link", 0, 0, STATE_LINKED);
+      testStates("aria_application_anchor", 0, 0, STATE_SELECTABLE);
+
+      // strange cases
+      testStates("aria_link_link", STATE_LINKED);
+      testStates("aria_link_anchor", STATE_SELECTABLE);
+
+      // some weak landmarks
+      testStates("aria_main_link", STATE_LINKED);
+      testStates("aria_navigation_link", STATE_LINKED);
+      testStates("aria_main_anchor", STATE_SELECTABLE);
+      testStates("aria_navigation_anchor", STATE_SELECTABLE);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 
 </head>
@@ -135,10 +159,29 @@
       <div role="option" id="item4">Item 4</div>
     </div>
     <div role="slider" tabindex="0">A slider</div>
   </div>
   
   <div id="offscreen_log" role="log" class="offscreen">
     <div id="aria_offscreen_textbox" role="textbox" aria-readonly="true">This text should be offscreen</div>
   </div>
+
+  <a id="aria_menuitem_link" role="menuitem" href="foo">menuitem</a>
+  <a id="aria_button_link" role="button" href="foo">button</a>
+  <a id="aria_checkbox_link" role="checkbox" href="foo">checkbox</a>
+
+  <!-- strange edge case: please don't do this in the wild -->
+  <a id="aria_link_link" role="link" href="foo">link</a>
+  <a id="aria_link_anchor" role="link" name="link_anchor">link</a>
+
+  <!-- landmarks: links -->
+  <a id="aria_application_link" role="application" href="foo">app</a>
+  <a id="aria_main_link" role="main" href="foo">main</a>
+  <a id="aria_navigation_link" role="navigation" href="foo">nav</a>
+  
+  <!-- landmarks: anchors -->
+  <a id="aria_application_anchor" role="application" name="app_anchor">app</a>
+  <a id="aria_main_anchor" role="main" name="main_anchor">main</a>
+  <a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a>
+
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/test_value.html
@@ -0,0 +1,81 @@
+<html>
+
+<head>
+  <title>nsIAccessible value testing</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <style type="text/css">
+    .offscreen {
+      position: absolute;
+      left: -5000px;
+      top: -5000px;
+      height: 100px;
+      width: 100px;
+    }
+  </style>
+
+  <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">
+    function doTest()
+    {
+      function testValue(aID, aValue)
+      {
+        var acc = getAccessible(aID);
+        if (!acc)
+          return;
+        is(acc.value, aValue, "Wrong value for " + aID + "!");
+      }
+
+      var href = "chrome://mochikit/content/a11y/accessible/foo";
+
+      // roles that can't live as nsHTMLLinkAccessibles
+      testValue("aria_menuitem_link", "");
+      testValue("aria_button_link", "");
+      testValue("aria_checkbox_link", "");
+      testValue("aria_application_link", "");
+
+      // roles that can live as nsHTMLLinkAccessibles
+      testValue("aria_link_link", href);
+      testValue("aria_main_link", href);
+      testValue("aria_navigation_link", href);
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=494807"
+     title="Do not expose a11y info specific to hyperlinks when role is overridden using ARIA">
+    Mozilla Bug 494807
+  </a><br />
+
+  <a id="aria_menuitem_link" role="menuitem" href="foo">menuitem</a>
+  <a id="aria_button_link" role="button" href="foo">button</a>
+  <a id="aria_checkbox_link" role="checkbox" href="foo">checkbox</a>
+
+  <!-- landmark links -->
+  <a id="aria_application_link" role="application" href="foo">app</a>
+  <a id="aria_main_link" role="main" href="foo">main</a>
+  <a id="aria_navigation_link" role="navigation" href="foo">nav</a>
+  
+  <!-- strange edge case: please don't do this in the wild -->
+  <a id="aria_link_link" role="link" href="foo">link</a>
+
+</body>
+</html>