Bug 1403231 - Create accessibles for the XUL "image" element using the tag name instead of the XBL role. r=surkov
authorYura Zenevich <yura.zenevich@gmail.com>
Fri, 03 Nov 2017 11:15:44 +0000
changeset 443304 58101c3badd54b512456a23342930c45c3127439
parent 443303 469018312d09835aa48f3ba532077180e15e5191
child 443305 baeb2e4f4c1c46b8eced876a4d60de306f20c0a4
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssurkov
bugs1403231
milestone58.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 1403231 - Create accessibles for the XUL "image" element using the tag name instead of the XBL role. r=surkov This also adds the lookup infrastructure required for converting other XUL elements to this method of creating accessibles. MozReview-Commit-ID: GAO63iUNMAn
accessible/base/XULMap.h
accessible/base/nsAccessibilityService.cpp
accessible/base/nsAccessibilityService.h
new file mode 100644
--- /dev/null
+++ b/accessible/base/XULMap.h
@@ -0,0 +1,5 @@
+/* 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/. */
+
+XULMAP(image, New_MaybeImageOrToolbarButtonAccessible)
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -245,16 +245,34 @@ static Accessible*
 New_HTMLTableHeaderCellIfScope(nsIContent* aContent, Accessible* aContext)
 {
   if (aContext->IsTableRow() && aContext->GetContent() == aContent->GetParent() &&
       aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::scope))
     return new HTMLTableHeaderCellAccessibleWrap(aContent, aContext->Document());
   return nullptr;
 }
 
+#ifdef MOZ_XUL
+static Accessible*
+New_MaybeImageOrToolbarButtonAccessible(nsIContent* aContent,
+                                        Accessible* aContext)
+{
+  if (aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::onclick)) {
+    return new XULToolbarButtonAccessible(aContent, aContext->Document());
+  }
+
+  // Don't include nameless images in accessible tree.
+  if (!aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext)) {
+    return nullptr;
+  }
+
+  return new ImageAccessibleWrap(aContent, aContext->Document());
+}
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////
 // Markup maps array.
 
 #define Attr(name, value) \
   { &nsGkAtoms::name, &nsGkAtoms::value }
 
 #define AttrFromDOM(name, DOMAttrName) \
   { &nsGkAtoms::name, nullptr, &nsGkAtoms::DOMAttrName }
@@ -264,32 +282,47 @@ New_HTMLTableHeaderCellIfScope(nsIConten
 
 #define MARKUPMAP(atom, new_func, r, ... ) \
   { &nsGkAtoms::atom, new_func, static_cast<a11y::role>(r), { __VA_ARGS__ } },
 
 static const MarkupMapInfo sMarkupMapList[] = {
   #include "MarkupMap.h"
 };
 
+#ifdef MOZ_XUL
+#define XULMAP(atom, new_func) \
+  { &nsGkAtoms::atom, new_func },
+
+static const XULMarkupMapInfo sXULMapList[] = {
+  #include "XULMap.h"
+};
+#endif
+
 #undef Attr
 #undef AttrFromDOM
 #undef AttrFromDOMIf
 #undef MARKUPMAP
+#ifdef MOZ_XUL
+#undef XULMAP
+#endif
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService
 ////////////////////////////////////////////////////////////////////////////////
 
 nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nullptr;
 ApplicationAccessible* nsAccessibilityService::gApplicationAccessible = nullptr;
 xpcAccessibleApplication* nsAccessibilityService::gXPCApplicationAccessible = nullptr;
 uint32_t nsAccessibilityService::gConsumers = 0;
 
 nsAccessibilityService::nsAccessibilityService() :
   DocManager(), FocusManager(), mMarkupMaps(ArrayLength(sMarkupMapList))
+#ifdef MOZ_XUL
+  , mXULMarkupMaps(ArrayLength(sXULMapList))
+#endif
 {
 }
 
 nsAccessibilityService::~nsAccessibilityService()
 {
   NS_ASSERTION(IsShutdown(), "Accessibility wasn't shutdown!");
   gAccessibilityService = nullptr;
 }
@@ -1157,19 +1190,30 @@ nsAccessibilityService::CreateAccessible
       if (deckFrame && deckFrame->GetSelectedBox() != frame) {
         if (aIsSubtreeHidden)
           *aIsSubtreeHidden = true;
 
         return nullptr;
       }
     }
 
+#ifdef MOZ_XUL
+    // Prefer to use XUL to decide if and what kind of accessible to create.
+    const XULMarkupMapInfo* xulMap =
+      mXULMarkupMaps.Get(content->NodeInfo()->NameAtom());
+    if (xulMap && xulMap->new_func) {
+      newAcc = xulMap->new_func(content, aContext);
+    }
+#endif
+
     // XBL bindings may use @role attribute to point the accessible type
     // they belong to.
-    newAcc = CreateAccessibleByType(content, document);
+    if (!newAcc) {
+      newAcc = CreateAccessibleByType(content, document);
+    }
 
     // Any XUL box can be used as tabpanel, make sure we create a proper
     // accessible for it.
     if (!newAcc && aContext->IsXULTabpanels() &&
         content->GetParent() == aContext->GetContent()) {
       LayoutFrameType frameType = frame->Type();
       if (frameType == LayoutFrameType::Box ||
           frameType == LayoutFrameType::Scroll) {
@@ -1271,16 +1315,21 @@ nsAccessibilityService::Init()
   if (!eventListenerService)
     return false;
 
   eventListenerService->AddListenerChangeListener(this);
 
   for (uint32_t i = 0; i < ArrayLength(sMarkupMapList); i++)
     mMarkupMaps.Put(*sMarkupMapList[i].tag, &sMarkupMapList[i]);
 
+#ifdef MOZ_XUL
+  for (uint32_t i = 0; i < ArrayLength(sXULMapList); i++)
+    mXULMarkupMaps.Put(*sXULMapList[i].tag, &sXULMapList[i]);
+#endif
+
 #ifdef A11Y_LOG
   logging::CheckEnv();
 #endif
 
   gAccessibilityService = this;
   NS_ADDREF(gAccessibilityService); // will release in Shutdown()
 
   if (XRE_IsParentProcess()) {
@@ -1416,29 +1465,16 @@ nsAccessibilityService::CreateAccessible
       accessible = new XULTabpanelsAccessible(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:dropmarker")) {
       accessible = new XULDropmarkerAccessible(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:groupbox")) {
       accessible = new XULGroupboxAccessible(aContent, aDoc);
 
-  } else if (role.EqualsLiteral("xul:image")) {
-    if (aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::onclick)) {
-      accessible = new XULToolbarButtonAccessible(aContent, aDoc);
-
-    } else {
-      // Don't include nameless images in accessible tree.
-      if (!aContent->HasAttr(kNameSpaceID_None,
-                             nsGkAtoms::tooltiptext))
-        return nullptr;
-
-      accessible = new ImageAccessibleWrap(aContent, aDoc);
-    }
-
   } else if (role.EqualsLiteral("xul:link")) {
     accessible = new XULLinkAccessible(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:listbox")) {
       accessible = new XULListboxAccessibleWrap(aContent, aDoc);
 
   } else if (role.EqualsLiteral("xul:listcell")) {
     // Only create cells if there's more than one per row.
--- a/accessible/base/nsAccessibilityService.h
+++ b/accessible/base/nsAccessibilityService.h
@@ -62,16 +62,23 @@ struct MarkupAttrInfo {
 
 struct MarkupMapInfo {
   nsStaticAtom** tag;
   New_Accessible* new_func;
   a11y::role role;
   MarkupAttrInfo attrs[4];
 };
 
+#ifdef MOZ_XUL
+struct XULMarkupMapInfo {
+  nsStaticAtom** tag;
+  New_Accessible* new_func;
+};
+#endif
+
 } // namespace a11y
 } // namespace mozilla
 
 class nsAccessibilityService final : public mozilla::a11y::DocManager,
                                      public mozilla::a11y::FocusManager,
                                      public mozilla::a11y::SelectionManager,
                                      public nsIListenerChangeListener,
                                      public nsIObserver
@@ -306,16 +313,19 @@ private:
   static mozilla::a11y::xpcAccessibleApplication* gXPCApplicationAccessible;
 
   /**
    * Contains a set of accessibility service consumers.
    */
   static uint32_t gConsumers;
 
   nsDataHashtable<nsPtrHashKey<const nsAtom>, const mozilla::a11y::MarkupMapInfo*> mMarkupMaps;
+#ifdef MOZ_XUL
+  nsDataHashtable<nsPtrHashKey<const nsAtom>, const mozilla::a11y::XULMarkupMapInfo*> mXULMarkupMaps;
+#endif
 
   friend nsAccessibilityService* GetAccService();
   friend nsAccessibilityService* GetOrCreateAccService(uint32_t);
   friend void MaybeShutdownAccService(uint32_t);
   friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr();
   friend mozilla::a11y::SelectionManager* mozilla::a11y::SelectionMgr();
   friend mozilla::a11y::ApplicationAccessible* mozilla::a11y::ApplicationAcc();
   friend mozilla::a11y::xpcAccessibleApplication* mozilla::a11y::XPCApplicationAcc();