Bug 1501182 - Expose WAI-ARIA landmarks as landmark roles through accessibility APIs, r=Jamie
authorMarco Zehe <mzehe@mozilla.com>
Thu, 15 Aug 2019 01:25:56 +0000
changeset 488174 3769178b9a30790002c9c9555a11a045d460d5a3
parent 488173 5d6185ef02c746f5846f24b516c3ba1f9d7361c3
child 488175 9406ccf380bbc14f54eeecd3eec671750b22f53f
push id36437
push userncsoregi@mozilla.com
push dateThu, 15 Aug 2019 19:33:18 +0000
treeherdermozilla-central@44aac6fc3352 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersJamie
bugs1501182
milestone70.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 1501182 - Expose WAI-ARIA landmarks as landmark roles through accessibility APIs, r=Jamie This change will bring us on par with what Chrome does. However, if the author makes an error in applying a landmark role to an interactive element, or other element where the landmark role is illegal, as defined in the [WAI-ARIA in HTML specification section 2](https://www.w3.org/TR/html-aria/#document-conformance-requirements-for-use-of-aria-attributes-in-html), the accessible properties will now be that of the landmark role, no longer that of the native host language element. This might make some elements less accessible due to author error than before, but we currently do not know of examples in the wild that actually expose this problem. This could only be solved by applying the rules from said table also in the user agents, but that is not specified anywhere. Differential Revision: https://phabricator.services.mozilla.com/D41923
accessible/base/ARIAMap.cpp
accessible/tests/mochitest/role/test_aria.html
accessible/tests/mochitest/states/test_aria.html
accessible/tests/mochitest/states/test_doc.html
accessible/tests/mochitest/value/test_general.html
--- a/accessible/base/ARIAMap.cpp
+++ b/accessible/base/ARIAMap.cpp
@@ -75,18 +75,18 @@ static const nsRoleMapEntry sWAIRoleMaps
     eNoAction,
     eNoLiveAttr,
     kGenericAccType,
     kNoReqStates,
     eReadonlyUntilEditable
   },
   { // banner
     nsGkAtoms::banner,
-    roles::NOTHING,
-    kUseNativeRole,
+    roles::LANDMARK,
+    kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eLandmark,
     kNoReqStates
   },
   { // blockquote
     nsGkAtoms::blockquote,
@@ -161,28 +161,28 @@ static const nsRoleMapEntry sWAIRoleMaps
     eCombobox,
     states::COLLAPSED | states::HASPOPUP,
     eARIAAutoComplete,
     eARIAReadonly,
     eARIAOrientation
   },
   { // complementary
     nsGkAtoms::complementary,
-    roles::NOTHING,
-    kUseNativeRole,
+    roles::LANDMARK,
+    kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eLandmark,
     kNoReqStates
   },
   { // contentinfo
     nsGkAtoms::contentinfo,
-    roles::NOTHING,
-    kUseNativeRole,
+    roles::LANDMARK,
+    kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eLandmark,
     kNoReqStates
   },
   { // dialog
     nsGkAtoms::dialog,
@@ -783,18 +783,18 @@ static const nsRoleMapEntry sWAIRoleMaps
     eNoValue,
     eNoAction,
     ePoliteLiveAttr,
     kGenericAccType,
     kNoReqStates
   },
   { // main
     nsGkAtoms::main,
-    roles::NOTHING,
-    kUseNativeRole,
+    roles::LANDMARK,
+    kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eLandmark,
     kNoReqStates
   },
   { // marquee
     nsGkAtoms::marquee,
@@ -870,18 +870,18 @@ static const nsRoleMapEntry sWAIRoleMaps
     eNoLiveAttr,
     kGenericAccType,
     kNoReqStates,
     eARIACheckableBool,
     eARIAReadonly
   },
   { // navigation
     nsGkAtoms::navigation,
-    roles::NOTHING,
-    kUseNativeRole,
+    roles::LANDMARK,
+    kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eLandmark,
     kNoReqStates
   },
   { // none
     nsGkAtoms::none,
@@ -1020,18 +1020,18 @@ static const nsRoleMapEntry sWAIRoleMaps
     eNoLiveAttr,
     kGenericAccType,
     states::VERTICAL,
     eARIAOrientation,
     eARIAReadonly
   },
   { // search
     nsGkAtoms::search,
-    roles::NOTHING,
-    kUseNativeRole,
+    roles::LANDMARK,
+    kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     eLandmark,
     kNoReqStates
   },
   { // searchbox
     nsGkAtoms::searchbox,
--- a/accessible/tests/mochitest/role/test_aria.html
+++ b/accessible/tests/mochitest/role/test_aria.html
@@ -82,17 +82,17 @@
       testRole("aria_treegrid", ROLE_TREE_TABLE);
       testRole("aria_treeitem", ROLE_OUTLINEITEM);
 
       // Note:
       // The phrase "weak foo" here means that there is no good foo-to-platform
       // role mapping. Similarly "strong foo" means there is a good foo-to-
       // platform role mapping.
 
-      testRole("articlemain", ROLE_ARTICLE);
+      testRole("articlemain", ROLE_LANDMARK);
       testRole("articleform", ROLE_FORM);
 
       // Test article exposed as article
       testRole("testArticle", ROLE_ARTICLE);
 
       // weak roles that are forms of "live regions"
       testRole("log_table", ROLE_TABLE);
       testRole("timer_div", ROLE_SECTION);
@@ -100,27 +100,28 @@
       // other roles that are forms of "live regions"
       testRole("marquee_h1", ROLE_ANIMATION);
 
       // strong landmark
       testRole("application", ROLE_APPLICATION);
       testRole("form", ROLE_FORM);
       testRole("application_table", ROLE_APPLICATION);
 
-      // weak landmarks
-      var weak_landmarks = ["banner", "complementary", "contentinfo",
+      // landmarks
+      let landmarks = ["banner", "complementary", "contentinfo",
           "main", "navigation", "search"];
-      for (l in weak_landmarks)
-        testRole(weak_landmarks[l], ROLE_SECTION);
+      for (l in landmarks) {
+        testRole(landmarks[l], ROLE_LANDMARK);
+      }
 
-      for (l in weak_landmarks) {
-        var id = weak_landmarks[l] + "_table";
-        testRole(id, ROLE_TABLE);
+      for (l in landmarks) {
+        let id = landmarks[l] + "_table";
+        testRole(id, ROLE_LANDMARK);
     
-        var accessibleTable = getAccessible(id, [nsIAccessibleTable], null,
+        let accessibleTable = getAccessible(id, [nsIAccessibleTable], null,
                                             DONOTFAIL_IF_NO_INTERFACE);
         ok(!!accessibleTable, "landmarked table should have nsIAccessibleTable");
     
         if (accessibleTable)
           is(accessibleTable.getCellAt(0, 0).firstChild.name, "hi", "no cell");
       }
 
       // ////////////////////////////////////////////////////////////////////////
--- a/accessible/tests/mochitest/states/test_aria.html
+++ b/accessible/tests/mochitest/states/test_aria.html
@@ -211,21 +211,22 @@
       // 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);
+      // some landmarks that break accessibility for these native elements
+      // Note that these are illegal uses by web authors as per WAI-ARIA in HTML
+      testStates("aria_main_link", 0, 0, STATE_LINKED);
+      testStates("aria_navigation_link", 0, 0, STATE_LINKED);
+      testStates("aria_main_anchor", 0, 0, STATE_SELECTABLE);
+      testStates("aria_navigation_anchor", 0, 0, STATE_SELECTABLE);
 
       // aria-orientation
       testStates("aria_combobox", 0, 0, 0, EXT_STATE_HORIZONTAL | EXT_STATE_VERTICAL);
       testStates("aria_hcombobox", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
       testStates("aria_vcombobox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
       testStates("aria_listbox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
       testStates("aria_hlistbox", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
       testStates("aria_vlistbox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
--- a/accessible/tests/mochitest/states/test_doc.html
+++ b/accessible/tests/mochitest/states/test_doc.html
@@ -18,17 +18,17 @@
     function doTest() {
       // Bug 566542: root accesible should expose active state when focused.
       testStates(getRootAccessible(), 0, EXT_STATE_ACTIVE);
 
       // Bug 509696, 607219.
       testStates(document, STATE_READONLY, 0); // role=""
 
       document.body.setAttribute("role", "banner"); // no platform mapping
-      testStates(document, STATE_READONLY);
+      testStates(document, 0, 0, STATE_READONLY);
       document.body.setAttribute("role", "foo"); // bogus role
       testStates(document, STATE_READONLY);
       document.body.removeAttribute("role");
       testStates(document, STATE_READONLY);
 
       // Bugs 454997 and 467387
       testStates(document, STATE_READONLY);
       testStates("document", STATE_READONLY);
--- a/accessible/tests/mochitest/value/test_general.html
+++ b/accessible/tests/mochitest/value/test_general.html
@@ -34,21 +34,21 @@
 
       var href = getRootDirectory(window.location.href) + "foo";
 
       // roles that can't live as HTMLLinkAccessibles
       testValue("aria_menuitem_link", "");
       testValue("aria_button_link", "");
       testValue("aria_checkbox_link", "");
       testValue("aria_application_link", "");
+      testValue("aria_main_link", "");
+      testValue("aria_navigation_link", "");
 
       // roles that can live as HTMLLinkAccessibles
       testValue("aria_link_link", href);
-      testValue("aria_main_link", href);
-      testValue("aria_navigation_link", href);
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA textboxes
 
       testValue("aria_textbox1", "helo");
 
       // ////////////////////////////////////////////////////////////////////////
       // ARIA comboboxes