Bug 1310794 - implement aria-details and aria-errormessage, r=davidb
authorAlexander Surkov <surkov.alexander@gmail.com>
Tue, 25 Oct 2016 13:51:27 -0400
changeset 319435 22dd21caab66dd9c0504c6b984a096639f916e5a
parent 319434 eb02e92724f5a2ab1f4169408f797ec29a6ba4d4
child 319436 95e09163347acc8fee5d6151aef2f8522272b86f
push id30871
push usercbook@mozilla.com
push dateWed, 26 Oct 2016 14:54:32 +0000
treeherdermozilla-central@d26ac63f1b81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdavidb
bugs1310794
milestone52.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 1310794 - implement aria-details and aria-errormessage, r=davidb
accessible/base/ARIAMap.cpp
accessible/base/RelationType.h
accessible/base/RelationTypeMap.h
accessible/generic/Accessible.cpp
accessible/generic/DocAccessible.cpp
accessible/interfaces/nsIAccessibleRelation.idl
accessible/tests/mochitest/relations.js
accessible/tests/mochitest/relations/test_general.html
accessible/windows/msaa/AccessibleWrap.h
dom/base/nsGkAtomList.h
other-licenses/ia2/AccessibleRelation.idl
--- a/accessible/base/ARIAMap.cpp
+++ b/accessible/base/ARIAMap.cpp
@@ -822,18 +822,20 @@ struct AttrCharacteristics
 
 static const AttrCharacteristics gWAIUnivAttrMap[] = {
   {&nsGkAtoms::aria_activedescendant,  ATTR_BYPASSOBJ                               },
   {&nsGkAtoms::aria_atomic,   ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
   {&nsGkAtoms::aria_busy,                               ATTR_VALTOKEN | ATTR_GLOBAL },
   {&nsGkAtoms::aria_checked,           ATTR_BYPASSOBJ | ATTR_VALTOKEN               }, /* exposes checkable obj attr */
   {&nsGkAtoms::aria_controls,          ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   {&nsGkAtoms::aria_describedby,       ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
+  {&nsGkAtoms::aria_details,           ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   {&nsGkAtoms::aria_disabled,          ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
   {&nsGkAtoms::aria_dropeffect,                         ATTR_VALTOKEN | ATTR_GLOBAL },
+  {&nsGkAtoms::aria_errormessage,      ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   {&nsGkAtoms::aria_expanded,          ATTR_BYPASSOBJ | ATTR_VALTOKEN               },
   {&nsGkAtoms::aria_flowto,            ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   {&nsGkAtoms::aria_grabbed,                            ATTR_VALTOKEN | ATTR_GLOBAL },
   {&nsGkAtoms::aria_haspopup,          ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
   {&nsGkAtoms::aria_hidden,            ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL }, /* handled special way */
   {&nsGkAtoms::aria_invalid,           ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
   {&nsGkAtoms::aria_label,             ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
   {&nsGkAtoms::aria_labelledby,        ATTR_BYPASSOBJ                 | ATTR_GLOBAL },
--- a/accessible/base/RelationType.h
+++ b/accessible/base/RelationType.h
@@ -122,16 +122,42 @@ enum class RelationType {
    */
   CONTAINING_WINDOW = 0x13,
 
   /**
    * The target object is the containing application object.
    */
   CONTAINING_APPLICATION = 0x14,
 
-  LAST = CONTAINING_APPLICATION
+
+  /**
+   * The target object provides the detailed, extended description for this
+   * object. It provides more detailed information than would normally be
+   * provided using the DESCRIBED_BY relation. A common use for this relation is
+   * in digital publishing where an extended description needs to be conveyed in
+   * a book that requires structural markup or the embedding of other technology
+   * to provide illustrative content.
+   */
+  DETAILS = 0x15,
 
+  /**
+   * This object provides the detailed, extended description for the target
+   * object. See DETAILS relation.
+   */
+  DETAILS_FOR = 0x16,
+
+  /**
+   * The target object is the error message for this object.
+   */
+  ERRORMSG = 0x17,
+
+  /**
+   * This object is the error message for the target object.
+   */
+  ERRORMSG_FOR = 0x18,
+
+  LAST = ERRORMSG_FOR
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/base/RelationTypeMap.h
+++ b/accessible/base/RelationTypeMap.h
@@ -123,8 +123,32 @@ RELATIONTYPE(CONTAINING_TAB_PANE,
              NAVRELATION_CONTAINING_TAB_PANE,
              IA2_RELATION_CONTAINING_TAB_PANE)
 
 RELATIONTYPE(CONTAINING_APPLICATION,
              "containing application",
              ATK_RELATION_NULL,
              NAVRELATION_CONTAINING_APPLICATION,
              IA2_RELATION_CONTAINING_APPLICATION)
+
+RELATIONTYPE(DETAILS,
+             "details",
+             ATK_RELATION_NULL,
+             NAVRELATION_DETAILS,
+             IA2_RELATION_DETAILS)
+
+RELATIONTYPE(DETAILS_FOR,
+             "details for",
+             ATK_RELATION_NULL,
+             NAVRELATION_DETAILS_FOR,
+             IA2_RELATION_DETAILS_FOR)
+
+RELATIONTYPE(ERRORMSG,
+             "error",
+             ATK_RELATION_NULL,
+             NAVRELATION_ERROR,
+             IA2_RELATION_ERROR)
+
+RELATIONTYPE(ERRORMSG_FOR,
+             "error for",
+             ATK_RELATION_NULL,
+             NAVRELATION_ERROR_FOR,
+             IA2_RELATION_ERROR_FOR)
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -1742,22 +1742,34 @@ Accessible::RelationByType(RelationType 
           // If the item type is typeContent, we assume we are in browser tab
           // content. Note, this includes content such as about:addons,
           // for consistency.
           if (root->ItemType() == nsIDocShellTreeItem::typeContent) {
             return Relation(nsAccUtils::GetDocAccessibleFor(root));
           }
         }
       }
-      return  Relation();
+      return Relation();
     }
 
     case RelationType::CONTAINING_APPLICATION:
       return Relation(ApplicationAcc());
 
+    case RelationType::DETAILS:
+      return Relation(new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_details));
+
+    case RelationType::DETAILS_FOR:
+      return Relation(new RelatedAccIterator(mDoc, mContent, nsGkAtoms::aria_details));
+
+    case RelationType::ERRORMSG:
+      return Relation(new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_errormessage));
+
+    case RelationType::ERRORMSG_FOR:
+      return Relation(new RelatedAccIterator(mDoc, mContent, nsGkAtoms::aria_errormessage));
+
     default:
       return Relation();
   }
 }
 
 void
 Accessible::GetNativeInterface(void** aNativeAccessible)
 {
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -58,19 +58,21 @@ using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Static member initialization
 
 static nsIAtom** kRelationAttrs[] =
 {
   &nsGkAtoms::aria_labelledby,
   &nsGkAtoms::aria_describedby,
+  &nsGkAtoms::aria_details,
   &nsGkAtoms::aria_owns,
   &nsGkAtoms::aria_controls,
   &nsGkAtoms::aria_flowto,
+  &nsGkAtoms::aria_errormessage,
   &nsGkAtoms::_for,
   &nsGkAtoms::control
 };
 
 static const uint32_t kRelationAttrsLen = ArrayLength(kRelationAttrs);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Constructor/desctructor
--- a/accessible/interfaces/nsIAccessibleRelation.idl
+++ b/accessible/interfaces/nsIAccessibleRelation.idl
@@ -120,16 +120,42 @@ interface nsIAccessibleRelation : nsISup
   const unsigned long RELATION_CONTAINING_TAB_PANE = 0x12;
 
   /**
    * The target object is the containing application object.
    */
   const unsigned long RELATION_CONTAINING_APPLICATION = 0x14;
 
   /**
+   * The target object provides the detailed, extended description for this
+   * object. It provides more detailed information than would normally be
+   * provided using the DESCRIBED_BY relation. A common use for this relation is
+   * in digital publishing where an extended description needs to be conveyed in
+   * a book that requires structural markup or the embedding of other technology
+   * to provide illustrative content.
+   */
+  const unsigned long RELATION_DETAILS = 0x15;
+
+  /**
+   * This object provides the detailed, extended description for the target
+   * object. See DETAILS relation.
+   */
+  const unsigned long RELATION_DETAILS_FOR = 0x16;
+
+  /**
+   * The target object is the error message for this object.
+   */
+  const unsigned long RELATION_ERRORMSG = 0x17;
+
+  /**
+   * This object is the error message for the target object.
+   */
+  const unsigned long RELATION_ERRORMSG_FOR = 0x18;
+
+  /**
    * Returns the type of the relation.
    */
   readonly attribute unsigned long relationType;
 
   /**
    * Returns the number of targets for this relation.
    */
   readonly attribute unsigned long targetsCount;
--- a/accessible/tests/mochitest/relations.js
+++ b/accessible/tests/mochitest/relations.js
@@ -16,16 +16,20 @@ var RELATION_MEMBER_OF = nsIAccessibleRe
 var RELATION_NODE_CHILD_OF = nsIAccessibleRelation.RELATION_NODE_CHILD_OF;
 var RELATION_NODE_PARENT_OF = nsIAccessibleRelation.RELATION_NODE_PARENT_OF;
 var RELATION_PARENT_WINDOW_OF = nsIAccessibleRelation.RELATION_PARENT_WINDOW_OF;
 var RELATION_POPUP_FOR = nsIAccessibleRelation.RELATION_POPUP_FOR;
 var RELATION_SUBWINDOW_OF = nsIAccessibleRelation.RELATION_SUBWINDOW_OF;
 var RELATION_CONTAINING_DOCUMENT = nsIAccessibleRelation.RELATION_CONTAINING_DOCUMENT;
 var RELATION_CONTAINING_TAB_PANE = nsIAccessibleRelation.RELATION_CONTAINING_TAB_PANE;
 var RELATION_CONTAINING_APPLICATION = nsIAccessibleRelation.RELATION_CONTAINING_APPLICATION;
+const RELATION_DETAILS = nsIAccessibleRelation.RELATION_DETAILS;
+const RELATION_DETAILS_FOR = nsIAccessibleRelation.RELATION_DETAILS_FOR;
+const RELATION_ERRORMSG = nsIAccessibleRelation.RELATION_ERRORMSG;
+const RELATION_ERRORMSG_FOR = nsIAccessibleRelation.RELATION_ERRORMSG_FOR;
 
 ////////////////////////////////////////////////////////////////////////////////
 // General
 
 /**
  * Test the accessible relation.
  *
  * @param aIdentifier          [in] identifier to get an accessible, may be ID
--- a/accessible/tests/mochitest/relations/test_general.html
+++ b/accessible/tests/mochitest/relations/test_general.html
@@ -183,16 +183,24 @@
       testRelation("legend", RELATION_LABEL_FOR, "fieldset");
       testRelation("fieldset", RELATION_LABELLED_BY, "legend");
 
       // containing relations
       testRelation("control1_1", RELATION_CONTAINING_DOCUMENT, document);
       testRelation("control1_1", RELATION_CONTAINING_TAB_PANE, getTabDocAccessible("control1_1"));
       testRelation("control1_1", RELATION_CONTAINING_APPLICATION, getApplicationAccessible());
 
+      // details
+      testRelation("has_details", RELATION_DETAILS, "details");
+      testRelation("details", RELATION_DETAILS_FOR, "has_details");
+
+      // error
+      testRelation("has_error", RELATION_ERRORMSG, "error");
+      testRelation("error", RELATION_ERRORMSG_FOR, "has_error");
+
       // finish test
       SimpleTest.finish();
     }
 
     disableLogging(); // from test_embeds.xul
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
@@ -386,10 +394,13 @@
       <td>cell1</td><td>cell2</td>
     </tr>
   </table>
 
   <fieldset id="fieldset">
     <legend id="legend">legend</legend>
     <input />
   </fieldset>
+
+  <input id="has_details" aria-details="details"><section id="details"></section>
+  <input id="has_error" aria-errormessage="error"><section id="error"></section>
 </body>
 </html>
--- a/accessible/windows/msaa/AccessibleWrap.h
+++ b/accessible/windows/msaa/AccessibleWrap.h
@@ -231,17 +231,21 @@ protected:
     NAVRELATION_POPUP_FOR = 0x100b,
     NAVRELATION_PARENT_WINDOW_OF = 0x100c,
     NAVRELATION_DEFAULT_BUTTON = 0x100d,
     NAVRELATION_DESCRIBED_BY = 0x100e,
     NAVRELATION_DESCRIPTION_FOR = 0x100f,
     NAVRELATION_NODE_PARENT_OF = 0x1010,
     NAVRELATION_CONTAINING_DOCUMENT = 0x1011,
     NAVRELATION_CONTAINING_TAB_PANE = 0x1012,
-    NAVRELATION_CONTAINING_APPLICATION = 0x1014
+    NAVRELATION_CONTAINING_APPLICATION = 0x1014,
+    NAVRELATION_DETAILS = 0x1015,
+    NAVRELATION_DETAILS_FOR = 0x1016,
+    NAVRELATION_ERROR = 0x1017,
+    NAVRELATION_ERROR_FOR = 0x1018
   };
 };
 
 static inline AccessibleWrap*
 WrapperFor(const ProxyAccessible* aProxy)
 {
   return reinterpret_cast<AccessibleWrap*>(aProxy->GetWrapper());
 }
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -2320,18 +2320,20 @@ GK_ATOM(aria_activedescendant, "aria-act
 GK_ATOM(aria_atomic, "aria-atomic")
 GK_ATOM(aria_autocomplete, "aria-autocomplete")
 GK_ATOM(aria_busy, "aria-busy")
 GK_ATOM(aria_checked, "aria-checked")
 GK_ATOM(aria_colcount, "aria-colcount")
 GK_ATOM(aria_colindex, "aria-colindex")
 GK_ATOM(aria_controls, "aria-controls")
 GK_ATOM(aria_describedby, "aria-describedby")
+GK_ATOM(aria_details, "aria-details")
 GK_ATOM(aria_disabled, "aria-disabled")
 GK_ATOM(aria_dropeffect, "aria-dropeffect")
+GK_ATOM(aria_errormessage, "aria-errormessage")
 GK_ATOM(aria_expanded, "aria-expanded")
 GK_ATOM(aria_flowto, "aria-flowto")
 GK_ATOM(aria_grabbed, "aria-grabbed")
 GK_ATOM(aria_haspopup, "aria-haspopup")
 GK_ATOM(aria_hidden, "aria-hidden")
 GK_ATOM(aria_invalid, "aria-invalid")
 GK_ATOM(aria_label, "aria-label")
 GK_ATOM(aria_labelledby, "aria-labelledby")
--- a/other-licenses/ia2/AccessibleRelation.idl
+++ b/other-licenses/ia2/AccessibleRelation.idl
@@ -149,16 +149,34 @@ const WCHAR *const IA2_RELATION_PARENT_W
 const WCHAR *const IA2_RELATION_POPUP_FOR = L"popupFor";
 
 /** The target object is the previous object in the tab order. */
 const WCHAR *const IA2_RELATION_PREVIOUS_TABBABLE = L"previousTabbable";
 
 /** This object is a sub window of a target object. */
 const WCHAR *const IA2_RELATION_SUBWINDOW_OF = L"subwindowOf";
 
+/** The target object provides the detailed, extended description for this
+ object. It provides more detailed information than would normally be provided
+ using the IA2_RELATION_DESCRIBED_BY relation. A common use for this relation is
+ in digital publishing where an extended description needs to be conveyed in
+ a book that requires structural markup or the embedding of other technology to
+ provide illustrative content. */
+const WCHAR *const IA2_RELATION_DETAILS = L"details";
+
+/** This object provides the detailed, extended description for the target
+ object. See IA2_RELATION_DETAILS. */
+const WCHAR *const IA2_RELATION_DETAILS_FOR = L"detailsFor";
+
+/** The target object is the error message for this object. */
+const WCHAR *const IA2_RELATION_ERROR = L"error";
+
+/** This object is the error message for the target object. */
+const WCHAR *const IA2_RELATION_ERROR_FOR = L"errorFor";
+
 ///@}
 
 /** This interface gives access to an object's set of relations.
 */
 [object, uuid(7CDF86EE-C3DA-496a-BDA4-281B336E1FDC)]
 interface IAccessibleRelation : IUnknown
 {
   /** @brief Returns the type of the relation.