Bug 1694865 part 25: Remove inheritance of Msaa*Accessible/ia2*Accessible into *AccessibleWrap! r=morgan
authorJames Teh <jteh@mozilla.com>
Mon, 03 May 2021 11:31:04 +0000
changeset 578306 4173ffb5fcb940b11ab6c024ea1f5d70cb2e4b8e
parent 578305 981f344314a0955aa481cf225da92b27beef7892
child 578307 b86b1afad5257a6c9a22d69be9a52b341be01555
push id38429
push userncsoregi@mozilla.com
push dateMon, 03 May 2021 15:32:34 +0000
treeherdermozilla-central@cdcfe2f59d26 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmorgan
bugs1694865
milestone90.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 1694865 part 25: Remove inheritance of Msaa*Accessible/ia2*Accessible into *AccessibleWrap! r=morgan 1. ia2AccessibleApplication is instantiated for ApplicationAccessible, so it now inherits from MsaaAccessible. 2. ia2AccessibleHypertext is instantiated for HyperTextAccessible, so it now inherits from MsaaAccessible. 3. ia2AccessibleImage is instantiated for ImageAccessible, so it inherits from MsaaAccessible. 4. ia2AccessibleTable is instantiated for TableAccessible, so it inherits from ia2AccessibleHypertext (since most TableAccessible implementations implement HyperTextAccessible). 5. ia2AccessibleTableCell is instantiated for TableCellAccessible, so it inherits from ia2AccessibleHypertext (since most TableCellAccessible implementations implement HyperTextAccessible). 6. All of the above override QueryInterface as appropriate, replacing the QueryInterface implementations from all *AccessibleWrap classes. 7. The ARIAGridAccessibleWrap, HTMLTableAccessibleWrap, ImageAccessibleWrap, XULListboxAccessibleWrap and XULTreeGridAccessibleWrap classes previously served only to host ia2AccessibleImage, ia2AccessibleTable, etc. Since these ia2 classes are now instantiated via MsaaAccessible, these Wrap classes have been removed and replaced with aliases. 8. The QueryInterface handling for ISimpleDOMText has been moved into MsaaAccessible. Since this was the only purpose of TextLeafAccessibleWrap, this too has been removed and replaced with an alias. 9. AccessibleWrap now holds a strong reference to MsaaAccessible and MsaaAccessible holds a weak reference to AccessibleWrap. 10. An MsaaAccessible (or derived class) is instantiated by MsaaAccessible::Create. 11. MsaaAccessible now implements its own COM reference counting using DECL_IUNKNOWN, since it does not need nsISupports (XPCOM). Differential Revision: https://phabricator.services.mozilla.com/D112956
accessible/windows/ProxyWrappers.h
accessible/windows/ia2/ia2AccessibleApplication.cpp
accessible/windows/ia2/ia2AccessibleApplication.h
accessible/windows/ia2/ia2AccessibleEditableText.cpp
accessible/windows/ia2/ia2AccessibleHypertext.cpp
accessible/windows/ia2/ia2AccessibleHypertext.h
accessible/windows/ia2/ia2AccessibleImage.cpp
accessible/windows/ia2/ia2AccessibleImage.h
accessible/windows/ia2/ia2AccessibleTable.cpp
accessible/windows/ia2/ia2AccessibleTable.h
accessible/windows/ia2/ia2AccessibleTableCell.cpp
accessible/windows/ia2/ia2AccessibleTableCell.h
accessible/windows/ia2/ia2AccessibleText.cpp
accessible/windows/ia2/ia2AccessibleText.h
accessible/windows/msaa/ARIAGridAccessibleWrap.cpp
accessible/windows/msaa/ARIAGridAccessibleWrap.h
accessible/windows/msaa/AccessibleWrap.cpp
accessible/windows/msaa/AccessibleWrap.h
accessible/windows/msaa/ApplicationAccessibleWrap.cpp
accessible/windows/msaa/ApplicationAccessibleWrap.h
accessible/windows/msaa/DocAccessibleWrap.cpp
accessible/windows/msaa/DocAccessibleWrap.h
accessible/windows/msaa/HTMLTableAccessibleWrap.cpp
accessible/windows/msaa/HTMLTableAccessibleWrap.h
accessible/windows/msaa/HyperTextAccessibleWrap.cpp
accessible/windows/msaa/HyperTextAccessibleWrap.h
accessible/windows/msaa/ImageAccessibleWrap.cpp
accessible/windows/msaa/ImageAccessibleWrap.h
accessible/windows/msaa/MsaaAccessible.cpp
accessible/windows/msaa/MsaaAccessible.h
accessible/windows/msaa/MsaaDocAccessible.cpp
accessible/windows/msaa/MsaaDocAccessible.h
accessible/windows/msaa/MsaaRootAccessible.cpp
accessible/windows/msaa/MsaaRootAccessible.h
accessible/windows/msaa/MsaaXULMenuAccessible.h
accessible/windows/msaa/RootAccessibleWrap.cpp
accessible/windows/msaa/RootAccessibleWrap.h
accessible/windows/msaa/ServiceProvider.cpp
accessible/windows/msaa/TextLeafAccessibleWrap.cpp
accessible/windows/msaa/TextLeafAccessibleWrap.h
accessible/windows/msaa/XULListboxAccessibleWrap.cpp
accessible/windows/msaa/XULListboxAccessibleWrap.h
accessible/windows/msaa/XULMenuAccessibleWrap.cpp
accessible/windows/msaa/XULMenuAccessibleWrap.h
accessible/windows/msaa/XULTreeGridAccessibleWrap.cpp
accessible/windows/msaa/XULTreeGridAccessibleWrap.h
accessible/windows/msaa/moz.build
--- a/accessible/windows/ProxyWrappers.h
+++ b/accessible/windows/ProxyWrappers.h
@@ -17,16 +17,19 @@ class RemoteAccessibleWrap : public Acce
  public:
   explicit RemoteAccessibleWrap(RemoteAccessible* aProxy)
       : AccessibleWrap(nullptr, nullptr) {
     mType = eProxyType;
     mBits.proxy = aProxy;
   }
 
   virtual void Shutdown() override {
+    if (mMsaa) {
+      mMsaa->MsaaShutdown();
+    }
     mBits.proxy = nullptr;
     mStateFlags |= eIsDefunct;
   }
 
   virtual void GetNativeInterface(void** aOutAccessible) override {
     mBits.proxy->GetCOMInterface(aOutAccessible);
   }
 };
@@ -35,16 +38,19 @@ class HyperTextRemoteAccessibleWrap : pu
  public:
   explicit HyperTextRemoteAccessibleWrap(RemoteAccessible* aProxy)
       : HyperTextAccessibleWrap(nullptr, nullptr) {
     mType = eProxyType;
     mBits.proxy = aProxy;
   }
 
   virtual void Shutdown() override {
+    if (mMsaa) {
+      mMsaa->MsaaShutdown();
+    }
     mBits.proxy = nullptr;
     mStateFlags |= eIsDefunct;
   }
 
   virtual void GetNativeInterface(void** aOutAccessible) override {
     mBits.proxy->GetCOMInterface(aOutAccessible);
   }
 };
@@ -99,16 +105,17 @@ class RemoteIframeDocRemoteAccessibleWra
  public:
   explicit RemoteIframeDocRemoteAccessibleWrap(IDispatch* aCOMProxy)
       : HyperTextAccessibleWrap(nullptr, nullptr), mCOMProxy(aCOMProxy) {
     mType = eProxyType;
     mBits.proxy = nullptr;
   }
 
   virtual void Shutdown() override {
+    MOZ_ASSERT(!mMsaa);
     mStateFlags |= eIsDefunct;
     mCOMProxy = nullptr;
   }
 
   virtual void GetNativeInterface(void** aOutAccessible) override {
     RefPtr<IDispatch> addRefed = mCOMProxy;
     addRefed.forget(aOutAccessible);
   }
--- a/accessible/windows/ia2/ia2AccessibleApplication.cpp
+++ b/accessible/windows/ia2/ia2AccessibleApplication.cpp
@@ -9,40 +9,25 @@
 
 #include "AccessibleApplication_i.c"
 #include "ApplicationAccessibleWrap.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ApplicationAccessible* ia2AccessibleApplication::AppAcc() {
-  // XXX This first static_cast is a necessary hack until we get rid of the
-  // inheritance of ApplicationAccessibleWrap.
-  auto wrap = static_cast<ApplicationAccessibleWrap*>(this);
-  AccessibleWrap* acc = static_cast<MsaaAccessible*>(wrap)->LocalAcc();
-  return static_cast<ApplicationAccessible*>(acc);
+  return static_cast<ApplicationAccessible*>(LocalAcc());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // IUnknown
 
-STDMETHODIMP
-ia2AccessibleApplication::QueryInterface(REFIID iid, void** ppv) {
-  if (!ppv) return E_INVALIDARG;
-
-  *ppv = nullptr;
-
-  if (IID_IAccessibleApplication == iid) {
-    *ppv = static_cast<IAccessibleApplication*>(this);
-    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
-    return S_OK;
-  }
-
-  return E_NOINTERFACE;
-}
+IMPL_IUNKNOWN_QUERY_HEAD(ia2AccessibleApplication)
+IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleApplication)
+IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(MsaaAccessible)
 
 ////////////////////////////////////////////////////////////////////////////////
 // IAccessibleApplication
 
 STDMETHODIMP
 ia2AccessibleApplication::get_appName(BSTR* aName) {
   if (!aName) return E_INVALIDARG;
 
--- a/accessible/windows/ia2/ia2AccessibleApplication.h
+++ b/accessible/windows/ia2/ia2AccessibleApplication.h
@@ -4,39 +4,46 @@
 /* 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/. */
 
 #ifndef IA2_ACCESSIBLE_APPLICATION_H_
 #define IA2_ACCESSIBLE_APPLICATION_H_
 
 #include "AccessibleApplication.h"
+#include "IUnknownImpl.h"
+#include "MsaaAccessible.h"
 
 namespace mozilla {
 namespace a11y {
 class ApplicationAccessible;
 
-class ia2AccessibleApplication : public IAccessibleApplication {
+class ia2AccessibleApplication : public IAccessibleApplication,
+                                 public MsaaAccessible {
  public:
   // IUnknown
-  STDMETHODIMP QueryInterface(REFIID, void**);
+  DECL_IUNKNOWN_INHERITED
+  IMPL_IUNKNOWN_REFCOUNTING_INHERITED(MsaaAccessible)
 
   // IAccessibleApplication
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_appName(
       /* [retval][out] */ BSTR* name);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_appVersion(
       /* [retval][out] */ BSTR* version);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_toolkitName(
       /* [retval][out] */ BSTR* name);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_toolkitVersion(
       /* [retval][out] */ BSTR* version);
 
+ protected:
+  using MsaaAccessible::MsaaAccessible;
+
  private:
   ApplicationAccessible* AppAcc();
 };
 
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/ia2/ia2AccessibleEditableText.cpp
+++ b/accessible/windows/ia2/ia2AccessibleEditableText.cpp
@@ -1,32 +1,31 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:expandtab:shiftwidth=2:tabstop=2:
  */
 /* 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/. */
 
 #include "ia2AccessibleEditableText.h"
+#include "ia2AccessibleHypertext.h"
 
 #include "AccessibleEditableText_i.c"
 #include "HyperTextAccessible-inl.h"
 #include "HyperTextAccessibleWrap.h"
 #include "ProxyWrappers.h"
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
 
 using namespace mozilla::a11y;
 
 HyperTextAccessibleWrap* ia2AccessibleEditableText::TextAcc() {
-  // XXX This first static_cast is a necessary hack until we get rid of the
-  // inheritance of HyperTextAccessibleWrap.
-  auto wrap = static_cast<HyperTextAccessibleWrap*>(this);
-  AccessibleWrap* acc = static_cast<MsaaAccessible*>(wrap)->LocalAcc();
+  auto hyp = static_cast<ia2AccessibleHypertext*>(this);
+  AccessibleWrap* acc = static_cast<MsaaAccessible*>(hyp)->LocalAcc();
   return static_cast<HyperTextAccessibleWrap*>(acc);
 }
 
 // IAccessibleEditableText
 
 STDMETHODIMP
 ia2AccessibleEditableText::copyText(long aStartOffset, long aEndOffset) {
   HyperTextAccessible* textAcc = TextAcc();
--- a/accessible/windows/ia2/ia2AccessibleHypertext.cpp
+++ b/accessible/windows/ia2/ia2AccessibleHypertext.cpp
@@ -10,23 +10,48 @@
 #include "AccessibleHypertext_i.c"
 
 #include "HyperTextAccessibleWrap.h"
 #include "IUnknownImpl.h"
 
 using namespace mozilla::a11y;
 
 HyperTextAccessibleWrap* ia2AccessibleHypertext::TextAcc() {
-  // XXX This first static_cast is a necessary hack until we get rid of the
-  // inheritance of HyperTextAccessibleWrap.
-  auto wrap = static_cast<HyperTextAccessibleWrap*>(this);
-  AccessibleWrap* acc = static_cast<MsaaAccessible*>(wrap)->LocalAcc();
+  AccessibleWrap* acc = LocalAcc();
   return static_cast<HyperTextAccessibleWrap*>(acc);
 }
 
+// IUnknown
+STDMETHODIMP
+ia2AccessibleHypertext::QueryInterface(REFIID aIID, void** aInstancePtr) {
+  if (!aInstancePtr) return E_FAIL;
+
+  *aInstancePtr = nullptr;
+
+  HyperTextAccessibleWrap* hyp = TextAcc();
+  if (hyp && hyp->IsTextRole()) {
+    if (aIID == IID_IAccessibleText)
+      *aInstancePtr =
+          static_cast<IAccessibleText*>(static_cast<ia2AccessibleText*>(this));
+    else if (aIID == IID_IAccessibleHypertext)
+      *aInstancePtr = static_cast<IAccessibleHypertext*>(this);
+    else if (aIID == IID_IAccessibleHypertext2)
+      *aInstancePtr = static_cast<IAccessibleHypertext2*>(this);
+    else if (aIID == IID_IAccessibleEditableText)
+      *aInstancePtr = static_cast<IAccessibleEditableText*>(this);
+
+    if (*aInstancePtr) {
+      AddRef();
+      return S_OK;
+    }
+  }
+
+  return MsaaAccessible::QueryInterface(aIID, aInstancePtr);
+}
+
 // IAccessibleHypertext
 
 STDMETHODIMP
 ia2AccessibleHypertext::get_nHyperlinks(long* aHyperlinkCount) {
   if (!aHyperlinkCount) return E_INVALIDARG;
 
   *aHyperlinkCount = 0;
 
--- a/accessible/windows/ia2/ia2AccessibleHypertext.h
+++ b/accessible/windows/ia2/ia2AccessibleHypertext.h
@@ -5,26 +5,41 @@
  * 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/. */
 
 #ifndef _ACCESSIBLE_HYPERTEXT_H
 #define _ACCESSIBLE_HYPERTEXT_H
 
 #include "nsISupports.h"
 
+#include "ia2AccessibleEditableText.h"
 #include "ia2AccessibleText.h"
 #include "AccessibleHypertext2.h"
+#include "IUnknownImpl.h"
+#include "MsaaAccessible.h"
 
 namespace mozilla {
 namespace a11y {
 class HyperTextAccessibleWrap;
 
 class ia2AccessibleHypertext : public ia2AccessibleText,
-                               public IAccessibleHypertext2 {
+                               public IAccessibleHypertext2,
+                               public ia2AccessibleEditableText,
+                               public MsaaAccessible {
  public:
+  // IUnknown
+  DECL_IUNKNOWN_INHERITED
+  IMPL_IUNKNOWN_REFCOUNTING_INHERITED(MsaaAccessible)
+
+  // IAccessible2
+  // We indirectly inherit IAccessible2, which has a get_attributes method,
+  // but IAccessibleText also has a get_attributes method with a different
+  // signature. We want both.
+  using MsaaAccessible::get_attributes;
+
   // IAccessibleText
   FORWARD_IACCESSIBLETEXT(ia2AccessibleText)
 
   // IAccessibleHypertext
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_nHyperlinks(
       /* [retval][out] */ long* hyperlinkCount);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_hyperlink(
@@ -35,16 +50,19 @@ class ia2AccessibleHypertext : public ia
       /* [in] */ long charIndex,
       /* [retval][out] */ long* hyperlinkIndex);
 
   // IAccessibleHypertext2
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_hyperlinks(
       /* [out, size_is(,*nHyperlinks)] */ IAccessibleHyperlink*** hyperlinks,
       /* [out, retval] */ long* nHyperlinks);
 
+ protected:
+  using MsaaAccessible::MsaaAccessible;
+
  private:
   HyperTextAccessibleWrap* TextAcc();
 };
 
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/ia2/ia2AccessibleImage.cpp
+++ b/accessible/windows/ia2/ia2AccessibleImage.cpp
@@ -14,39 +14,24 @@
 #include "nsIAccessibleTypes.h"
 
 #include "nsString.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ImageAccessible* ia2AccessibleImage::ImageAcc() {
-  // XXX This first static_cast is a necessary hack until we get rid of the
-  // inheritance of ImageAccessibleWrap.
-  auto wrap = static_cast<ImageAccessibleWrap*>(this);
-  AccessibleWrap* acc = static_cast<MsaaAccessible*>(wrap)->LocalAcc();
+  AccessibleWrap* acc = static_cast<MsaaAccessible*>(this)->LocalAcc();
   return static_cast<ImageAccessible*>(acc);
 }
 
 // IUnknown
-
-STDMETHODIMP
-ia2AccessibleImage::QueryInterface(REFIID iid, void** ppv) {
-  if (!ppv) return E_INVALIDARG;
-
-  *ppv = nullptr;
-
-  if (IID_IAccessibleImage == iid) {
-    *ppv = static_cast<IAccessibleImage*>(this);
-    (static_cast<IUnknown*>(*ppv))->AddRef();
-    return S_OK;
-  }
-
-  return E_NOINTERFACE;
-}
+IMPL_IUNKNOWN_QUERY_HEAD(ia2AccessibleImage)
+IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleImage)
+IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(MsaaAccessible)
 
 // IAccessibleImage
 
 STDMETHODIMP
 ia2AccessibleImage::get_description(BSTR* aDescription) {
   if (!aDescription) return E_INVALIDARG;
 
   *aDescription = nullptr;
--- a/accessible/windows/ia2/ia2AccessibleImage.h
+++ b/accessible/windows/ia2/ia2AccessibleImage.h
@@ -4,39 +4,45 @@
 /* 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/. */
 
 #ifndef _ACCESSIBLE_IMAGE_H
 #define _ACCESSIBLE_IMAGE_H
 
 #include "AccessibleImage.h"
+#include "IUnknownImpl.h"
+#include "MsaaAccessible.h"
 
 namespace mozilla {
 namespace a11y {
 class ImageAccessible;
 
-class ia2AccessibleImage : public IAccessibleImage {
+class ia2AccessibleImage : public IAccessibleImage, public MsaaAccessible {
  public:
   // IUnknown
-  STDMETHODIMP QueryInterface(REFIID, void**);
+  DECL_IUNKNOWN_INHERITED
+  IMPL_IUNKNOWN_REFCOUNTING_INHERITED(MsaaAccessible)
 
   // IAccessibleImage
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_description(
       /* [retval][out] */ BSTR* description);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_imagePosition(
       /* [in] */ enum IA2CoordinateType coordinateType,
       /* [out] */ long* x,
       /* [retval][out] */ long* y);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_imageSize(
       /* [out] */ long* height,
       /* [retval][out] */ long* width);
 
+ protected:
+  using MsaaAccessible::MsaaAccessible;
+
  private:
   ImageAccessible* ImageAcc();
 };
 
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/ia2/ia2AccessibleTable.cpp
+++ b/accessible/windows/ia2/ia2AccessibleTable.cpp
@@ -16,16 +16,21 @@
 #include "Statistics.h"
 #include "TableAccessible.h"
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
 
 using namespace mozilla::a11y;
 
+TableAccessible* ia2AccessibleTable::TableAcc() {
+  AccessibleWrap* acc = LocalAcc();
+  return acc ? acc->AsTable() : nullptr;
+}
+
 // IUnknown
 
 STDMETHODIMP
 ia2AccessibleTable::QueryInterface(REFIID iid, void** ppv) {
   if (!ppv) return E_INVALIDARG;
 
   *ppv = nullptr;
 
@@ -37,17 +42,17 @@ ia2AccessibleTable::QueryInterface(REFII
   }
 
   if (IID_IAccessibleTable2 == iid) {
     *ppv = static_cast<IAccessibleTable2*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
-  return E_NOINTERFACE;
+  return ia2AccessibleHypertext::QueryInterface(iid, ppv);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // IAccessibleTable
 
 STDMETHODIMP
 ia2AccessibleTable::get_accessibleAt(long aRowIdx, long aColIdx,
                                      IUnknown** aAccessible) {
--- a/accessible/windows/ia2/ia2AccessibleTable.h
+++ b/accessible/windows/ia2/ia2AccessibleTable.h
@@ -5,26 +5,31 @@
  * 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/. */
 
 #ifndef _ACCESSIBLE_TABLE_H
 #define _ACCESSIBLE_TABLE_H
 
 #include "AccessibleTable.h"
 #include "AccessibleTable2.h"
+#include "ia2AccessibleHypertext.h"
+#include "IUnknownImpl.h"
 
 namespace mozilla {
 namespace a11y {
 
 class TableAccessible;
 
-class ia2AccessibleTable : public IAccessibleTable, public IAccessibleTable2 {
+class ia2AccessibleTable : public IAccessibleTable,
+                           public IAccessibleTable2,
+                           public ia2AccessibleHypertext {
  public:
   // IUnknown
-  STDMETHODIMP QueryInterface(REFIID, void**);
+  DECL_IUNKNOWN_INHERITED
+  IMPL_IUNKNOWN_REFCOUNTING_INHERITED(ia2AccessibleHypertext)
 
   // IAccessibleTable
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_accessibleAt(
       /* [in] */ long row,
       /* [in] */ long column,
       /* [retval][out] */ IUnknown** accessible);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_caption(
@@ -156,20 +161,18 @@ class ia2AccessibleTable : public IAcces
       /* [out, size_is(,*nColumns)] */ long** selectedColumns,
       /* [out, retval] */ long* nColumns);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_selectedRows(
       /* [out, size_is(,*nRows)] */ long** selectedRows,
       /* [out, retval] */ long* nRows);
 
  protected:
-  ia2AccessibleTable(TableAccessible* aTable) : mTable(aTable) {}
-
-  TableAccessible* mTable;
+  using ia2AccessibleHypertext::ia2AccessibleHypertext;
 
  private:
-  TableAccessible* TableAcc() { return mTable; }
+  TableAccessible* TableAcc();
 };
 
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/ia2/ia2AccessibleTableCell.cpp
+++ b/accessible/windows/ia2/ia2AccessibleTableCell.cpp
@@ -15,32 +15,25 @@
 #include "TableCellAccessible.h"
 #include "IUnknownImpl.h"
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
 
 using namespace mozilla::a11y;
 
-// IUnknown
-
-STDMETHODIMP
-ia2AccessibleTableCell::QueryInterface(REFIID iid, void** ppv) {
-  if (!ppv) return E_INVALIDARG;
-
-  *ppv = nullptr;
+TableCellAccessible* ia2AccessibleTableCell::CellAcc() {
+  AccessibleWrap* acc = LocalAcc();
+  return acc ? acc->AsTableCell() : nullptr;
+}
 
-  if (IID_IAccessibleTableCell == iid) {
-    *ppv = static_cast<IAccessibleTableCell*>(this);
-    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
-    return S_OK;
-  }
-
-  return E_NOINTERFACE;
-}
+// IUnknown
+IMPL_IUNKNOWN_QUERY_HEAD(ia2AccessibleTableCell)
+IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleTableCell)
+IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(MsaaAccessible)
 
 ////////////////////////////////////////////////////////////////////////////////
 // IAccessibleTableCell
 
 STDMETHODIMP
 ia2AccessibleTableCell::get_table(IUnknown** aTable) {
   if (!aTable) return E_INVALIDARG;
 
--- a/accessible/windows/ia2/ia2AccessibleTableCell.h
+++ b/accessible/windows/ia2/ia2AccessibleTableCell.h
@@ -4,25 +4,28 @@
 /* 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/. */
 
 #ifndef _ACCESSIBLE_TABLECELL_H
 #define _ACCESSIBLE_TABLECELL_H
 
 #include "AccessibleTableCell.h"
+#include "MsaaAccessible.h"
 
 namespace mozilla {
 namespace a11y {
 class TableCellAccessible;
 
-class ia2AccessibleTableCell : public IAccessibleTableCell {
+class ia2AccessibleTableCell : public IAccessibleTableCell,
+                               public MsaaAccessible {
  public:
   // IUnknown
-  STDMETHODIMP QueryInterface(REFIID, void**);
+  DECL_IUNKNOWN_INHERITED
+  IMPL_IUNKNOWN_REFCOUNTING_INHERITED(MsaaAccessible)
 
   // IAccessibleTableCell
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_table(
       /* [out, retval] */ IUnknown** table);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_columnExtent(
       /* [out, retval] */ long* nColumnsSpanned);
@@ -50,21 +53,18 @@ class ia2AccessibleTableCell : public IA
       /* [out] */ long* rowExtents,
       /* [out] */ long* columnExtents,
       /* [out, retval] */ boolean* isSelected);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_isSelected(
       /* [out, retval] */ boolean* isSelected);
 
  protected:
-  ia2AccessibleTableCell(TableCellAccessible* aTableCell)
-      : mTableCell(aTableCell) {}
-
-  TableCellAccessible* mTableCell;
+  using MsaaAccessible::MsaaAccessible;
 
  private:
-  TableCellAccessible* CellAcc() { return mTableCell; }
+  TableCellAccessible* CellAcc();
 };
 
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/ia2/ia2AccessibleText.cpp
+++ b/accessible/windows/ia2/ia2AccessibleText.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:expandtab:shiftwidth=2:tabstop=2:
  */
 /* 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/. */
 
 #include "ia2Accessible.h"
+#include "ia2AccessibleHypertext.h"
 #include "ia2AccessibleText.h"
 
 #include "AccessibleText_i.c"
 
 #include "HyperTextAccessibleWrap.h"
 #include "HyperTextAccessible-inl.h"
 #include "ProxyWrappers.h"
 #include "mozilla/ClearOnShutdown.h"
@@ -19,20 +20,18 @@ using namespace mozilla::a11y;
 
 StaticRefPtr<HyperTextAccessibleWrap> ia2AccessibleText::sLastTextChangeAcc;
 StaticAutoPtr<nsString> ia2AccessibleText::sLastTextChangeString;
 uint32_t ia2AccessibleText::sLastTextChangeStart = 0;
 uint32_t ia2AccessibleText::sLastTextChangeEnd = 0;
 bool ia2AccessibleText::sLastTextChangeWasInsert = false;
 
 HyperTextAccessibleWrap* ia2AccessibleText::TextAcc() {
-  // XXX This first static_cast is a necessary hack until we get rid of the
-  // inheritance of HyperTextAccessibleWrap.
-  auto wrap = static_cast<HyperTextAccessibleWrap*>(this);
-  AccessibleWrap* acc = static_cast<MsaaAccessible*>(wrap)->LocalAcc();
+  auto hyp = static_cast<ia2AccessibleHypertext*>(this);
+  AccessibleWrap* acc = static_cast<MsaaAccessible*>(hyp)->LocalAcc();
   return static_cast<HyperTextAccessibleWrap*>(acc);
 }
 
 // IAccessibleText
 
 STDMETHODIMP
 ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset) {
   HyperTextAccessible* textAcc = TextAcc();
--- a/accessible/windows/ia2/ia2AccessibleText.h
+++ b/accessible/windows/ia2/ia2AccessibleText.h
@@ -4,18 +4,24 @@
 /* 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/. */
 
 #ifndef _ACCESSIBLE_TEXT_H
 #define _ACCESSIBLE_TEXT_H
 
 #include "AccessibleText.h"
+#include "nsIAccessibleText.h"
 
 namespace mozilla {
+template <class T>
+class StaticAutoPtr;
+template <class T>
+class StaticRefPtr;
+
 namespace a11y {
 class HyperTextAccessibleWrap;
 
 class ia2AccessibleText : public IAccessibleText {
  public:
   // IAccessibleText
   virtual HRESULT STDMETHODCALLTYPE addSelection(
       /* [in] */ long startOffset,
deleted file mode 100644
--- a/accessible/windows/msaa/ARIAGridAccessibleWrap.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:expandtab:shiftwidth=2:tabstop=2:
- */
-/* 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/. */
-
-#include "ARIAGridAccessibleWrap.h"
-
-using namespace mozilla;
-using namespace mozilla::a11y;
-
-////////////////////////////////////////////////////////////////////////////////
-// ARIAGridAccessibleWrap
-////////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_ISUPPORTS_INHERITED0(ARIAGridAccessibleWrap, ARIAGridAccessible)
-
-IMPL_IUNKNOWN_INHERITED2(ARIAGridAccessibleWrap, MsaaAccessible,
-                         HyperTextAccessibleWrap, ia2AccessibleTable)
-
-void ARIAGridAccessibleWrap::Shutdown() {
-  ia2AccessibleTable::mTable = nullptr;
-  ARIAGridAccessible::Shutdown();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ARIAGridCellAccessibleWrap
-////////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_ISUPPORTS_INHERITED0(ARIAGridCellAccessibleWrap, ARIAGridCellAccessible)
-
-IMPL_IUNKNOWN_INHERITED1(ARIAGridCellAccessibleWrap, HyperTextAccessibleWrap,
-                         ia2AccessibleTableCell)
-
-void ARIAGridCellAccessibleWrap::Shutdown() {
-  ia2AccessibleTableCell::mTableCell = nullptr;
-  ARIAGridCellAccessible::Shutdown();
-}
--- a/accessible/windows/msaa/ARIAGridAccessibleWrap.h
+++ b/accessible/windows/msaa/ARIAGridAccessibleWrap.h
@@ -4,64 +4,17 @@
 /* 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/. */
 
 #ifndef MOZILLA_A11Y_ARIAGRIDACCESSIBLEWRAP_H
 #define MOZILLA_A11Y_ARIAGRIDACCESSIBLEWRAP_H
 
 #include "ARIAGridAccessible.h"
-#include "ia2AccessibleTable.h"
-#include "ia2AccessibleTableCell.h"
 
 namespace mozilla {
 namespace a11y {
-
-/**
- * IA2 wrapper class for ARIAGridAccessible implementing IAccessibleTable and
- * IAccessibleTable2 interfaces.
- */
-class ARIAGridAccessibleWrap : public ARIAGridAccessible,
-                               public ia2AccessibleTable {
-  ~ARIAGridAccessibleWrap() {}
-
- public:
-  ARIAGridAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
-      : ARIAGridAccessible(aContent, aDoc), ia2AccessibleTable(this) {}
-
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
-
-  // nsISupports
-  // Need to declare addref/release here unconditionally, because
-  // ia2AccessibleTable has pure-virtual refcounting.
-  NS_DECL_ISUPPORTS_INHERITED
-
-  virtual void Shutdown() override;
-};
-
-/**
- * IA2 wrapper class for ARIAGridCellAccessible implementing
- * IAccessibleTableCell interface.
- */
-class ARIAGridCellAccessibleWrap : public ARIAGridCellAccessible,
-                                   public ia2AccessibleTableCell {
-  ~ARIAGridCellAccessibleWrap() {}
-
- public:
-  ARIAGridCellAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
-      : ARIAGridCellAccessible(aContent, aDoc), ia2AccessibleTableCell(this) {}
-
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
-
-  // nsISupports
-  // Need to declare addref/release here unconditionally, because
-  // ia2AccessibleTable has pure-virtual refcounting.
-  NS_DECL_ISUPPORTS_INHERITED
-
-  virtual void Shutdown() override;
-};
-
+using ARIAGridAccessibleWrap = ARIAGridAccessible;
+using ARIAGridCellAccessibleWrap = ARIAGridCellAccessible;
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/windows/msaa/AccessibleWrap.cpp
@@ -34,27 +34,39 @@ StaticAutoPtr<nsTArray<AccessibleWrap::H
 // AccessibleWrap
 ////////////////////////////////////////////////////////////////////////////////
 AccessibleWrap::AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
     : LocalAccessible(aContent, aDoc) {}
 
 NS_IMPL_ISUPPORTS_INHERITED0(AccessibleWrap, LocalAccessible)
 
 void AccessibleWrap::Shutdown() {
-  MsaaShutdown();
+  if (mMsaa) {
+    mMsaa->MsaaShutdown();
+    // Don't release mMsaa here because this will cause its id to be released
+    // immediately, which will result in immediate reuse, causing problems
+    // for clients. Instead, we release it in the destructor.
+  }
   LocalAccessible::Shutdown();
 }
 
 //-----------------------------------------------------
 // IUnknown interface methods - see iunknown.h for documentation
 //-----------------------------------------------------
 
+MsaaAccessible* AccessibleWrap::GetMsaa() {
+  if (!mMsaa) {
+    mMsaa = MsaaAccessible::Create(this);
+  }
+  return mMsaa;
+}
+
 void AccessibleWrap::GetNativeInterface(void** aOutAccessible) {
-  *aOutAccessible = static_cast<IAccessible*>(this);
-  NS_ADDREF_THIS();
+  RefPtr<IAccessible> result = GetMsaa();
+  return result.forget(aOutAccessible);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // LocalAccessible
 
 nsresult AccessibleWrap::HandleAccEvent(AccEvent* aEvent) {
   nsresult rv = LocalAccessible::HandleAccEvent(aEvent);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/accessible/windows/msaa/AccessibleWrap.h
+++ b/accessible/windows/msaa/AccessibleWrap.h
@@ -24,17 +24,17 @@
 // design, so silence the warning.
 #  pragma GCC diagnostic ignored "-Woverloaded-virtual"
 #endif
 
 namespace mozilla {
 namespace a11y {
 class DocRemoteAccessibleWrap;
 
-class AccessibleWrap : public LocalAccessible, public MsaaAccessible {
+class AccessibleWrap : public LocalAccessible {
  public:  // construction, destruction
   AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
  public:
   // LocalAccessible
@@ -58,29 +58,31 @@ class AccessibleWrap : public LocalAcces
                                    const LayoutDeviceIntRect& aCaretRect);
 
  public:
   /**
    * Determine whether this is the root accessible for its HWND.
    */
   bool IsRootForHWND();
 
-  MsaaAccessible* GetMsaa() { return this; }
+  MsaaAccessible* GetMsaa();
   virtual void GetNativeInterface(void** aOutAccessible) override;
 
   static void SetHandlerControl(DWORD aPid, RefPtr<IHandlerControl> aCtrl);
 
   static void InvalidateHandlers();
 
   bool DispatchTextChangeToHandler(bool aIsInsert, const nsString& aText,
                                    int32_t aStart, uint32_t aLen);
 
  protected:
   virtual ~AccessibleWrap() = default;
 
+  RefPtr<MsaaAccessible> mMsaa;
+
   struct HandlerControllerData final {
     HandlerControllerData(DWORD aPid, RefPtr<IHandlerControl>&& aCtrl)
         : mPid(aPid), mCtrl(std::move(aCtrl)) {
       mIsProxy = mozilla::mscom::IsProxy(mCtrl);
     }
 
     HandlerControllerData(HandlerControllerData&& aOther)
         : mPid(aOther.mPid),
--- a/accessible/windows/msaa/ApplicationAccessibleWrap.cpp
+++ b/accessible/windows/msaa/ApplicationAccessibleWrap.cpp
@@ -2,33 +2,28 @@
 /* vim:expandtab:shiftwidth=4:tabstop=4:
  */
 /* 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/. */
 
 #include "ApplicationAccessibleWrap.h"
 
-#include "IUnknownImpl.h"
-
 #include "nsIGfxInfo.h"
 #include "nsPersistentProperties.h"
 #include "nsServiceManagerUtils.h"
 #include "mozilla/Components.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 NS_IMPL_ISUPPORTS_INHERITED0(ApplicationAccessibleWrap, ApplicationAccessible)
 
-IMPL_IUNKNOWN_INHERITED1(ApplicationAccessibleWrap, MsaaAccessible,
-                         ia2AccessibleApplication)
-
 already_AddRefed<nsIPersistentProperties>
 ApplicationAccessibleWrap::NativeAttributes() {
   RefPtr<nsPersistentProperties> attributes = new nsPersistentProperties();
 
   nsCOMPtr<nsIGfxInfo> gfxInfo = components::GfxInfo::Service();
   if (gfxInfo) {
     bool isD2DEnabled = false;
     gfxInfo->GetD2DEnabled(&isD2DEnabled);
--- a/accessible/windows/msaa/ApplicationAccessibleWrap.h
+++ b/accessible/windows/msaa/ApplicationAccessibleWrap.h
@@ -5,33 +5,26 @@
  * 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/. */
 
 #ifndef mozilla_a11y_ApplicationAccessibleWrap_h__
 #define mozilla_a11y_ApplicationAccessibleWrap_h__
 
 #include "ApplicationAccessible.h"
 
-#include "AccessibleApplication.h"
-#include "ia2AccessibleApplication.h"
-
 namespace mozilla {
 namespace a11y {
 
-class ApplicationAccessibleWrap : public ia2AccessibleApplication,
-                                  public ApplicationAccessible {
+class ApplicationAccessibleWrap : public ApplicationAccessible {
   ~ApplicationAccessibleWrap() {}
 
  public:
   // nsISupporst
   NS_DECL_ISUPPORTS_INHERITED
 
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
-
   // nsAccessible
   virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() override;
 };
 
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/msaa/DocAccessibleWrap.cpp
+++ b/accessible/windows/msaa/DocAccessibleWrap.cpp
@@ -19,29 +19,20 @@ using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // DocAccessibleWrap
 ////////////////////////////////////////////////////////////////////////////////
 
 DocAccessibleWrap::DocAccessibleWrap(dom::Document* aDocument,
                                      PresShell* aPresShell)
-    : MsaaDocAccessible(aDocument, aPresShell), mHWND(nullptr) {}
+    : DocAccessible(aDocument, aPresShell), mHWND(nullptr) {}
 
 DocAccessibleWrap::~DocAccessibleWrap() {}
 
-IMPL_IUNKNOWN_QUERY_HEAD(DocAccessibleWrap)
-if (aIID == IID_ISimpleDOMDocument) {
-  statistics::ISimpleDOMUsed();
-  *aInstancePtr = static_cast<ISimpleDOMDocument*>(new sdnDocAccessible(this));
-  static_cast<IUnknown*>(*aInstancePtr)->AddRef();
-  return S_OK;
-}
-IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(HyperTextAccessibleWrap)
-
 ////////////////////////////////////////////////////////////////////////////////
 // LocalAccessible
 
 void DocAccessibleWrap::Shutdown() {
   // Do window emulation specific shutdown if emulation was started.
   if (nsWinUtils::IsWindowEmulationStarted()) {
     // Destroy window created for root document.
     if (mDocFlags & eTopLevelContentDocInProcess) {
--- a/accessible/windows/msaa/DocAccessibleWrap.h
+++ b/accessible/windows/msaa/DocAccessibleWrap.h
@@ -2,31 +2,29 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #ifndef mozilla_a11y_DocAccessibleWrap_h__
 #define mozilla_a11y_DocAccessibleWrap_h__
 
-#include "MsaaDocAccessible.h"
+#include "DocAccessible.h"
 
 namespace mozilla {
 
 class PresShell;
 
 namespace a11y {
 
-class DocAccessibleWrap : public MsaaDocAccessible {
+class DocAccessibleWrap : public DocAccessible {
  public:
   DocAccessibleWrap(dom::Document* aDocument, PresShell* aPresShell);
   virtual ~DocAccessibleWrap();
 
-  DECL_IUNKNOWN_INHERITED
-
   // LocalAccessible
   virtual void Shutdown();
 
   // DocAccessible
   virtual void* GetNativeWindow() const;
 
  protected:
   void* mHWND;
deleted file mode 100644
--- a/accessible/windows/msaa/HTMLTableAccessibleWrap.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:expandtab:shiftwidth=2:tabstop=2:
- */
-/* 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/. */
-
-#include "HTMLTableAccessibleWrap.h"
-
-using namespace mozilla::a11y;
-
-////////////////////////////////////////////////////////////////////////////////
-// HTMLTableAccessibleWrap
-////////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableAccessibleWrap, HTMLTableAccessible)
-
-IMPL_IUNKNOWN_INHERITED2(HTMLTableAccessibleWrap, MsaaAccessible,
-                         HyperTextAccessibleWrap, ia2AccessibleTable)
-
-void HTMLTableAccessibleWrap::Shutdown() {
-  ia2AccessibleTable::mTable = nullptr;
-  HTMLTableAccessible::Shutdown();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// HTMLTableCellAccessibleWrap
-////////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableCellAccessibleWrap,
-                             HTMLTableCellAccessible)
-
-IMPL_IUNKNOWN_INHERITED1(HTMLTableCellAccessibleWrap, HyperTextAccessibleWrap,
-                         ia2AccessibleTableCell)
-
-void HTMLTableCellAccessibleWrap::Shutdown() {
-  ia2AccessibleTableCell::mTableCell = nullptr;
-  HTMLTableCellAccessible::Shutdown();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// HTMLTableCellAccessibleWrap
-////////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableHeaderCellAccessibleWrap,
-                             HTMLTableHeaderCellAccessible)
-
-IMPL_IUNKNOWN_INHERITED1(HTMLTableHeaderCellAccessibleWrap,
-                         HyperTextAccessibleWrap, ia2AccessibleTableCell)
-
-void HTMLTableHeaderCellAccessibleWrap::Shutdown() {
-  ia2AccessibleTableCell::mTableCell = nullptr;
-  HTMLTableHeaderCellAccessible::Shutdown();
-}
--- a/accessible/windows/msaa/HTMLTableAccessibleWrap.h
+++ b/accessible/windows/msaa/HTMLTableAccessibleWrap.h
@@ -5,82 +5,17 @@
  * 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/. */
 
 #ifndef mozilla_a11y_HTMLTableAccessibleWrap_h__
 #define mozilla_a11y_HTMLTableAccessibleWrap_h__
 
 #include "HTMLTableAccessible.h"
 
-#include "ia2AccessibleTable.h"
-#include "ia2AccessibleTableCell.h"
-
 namespace mozilla {
 namespace a11y {
-
-/**
- * IA2 wrapper class for HTMLTableAccessible implementing IAccessibleTable
- * and IAccessibleTable2 interfaces.
- */
-class HTMLTableAccessibleWrap : public HTMLTableAccessible,
-                                public ia2AccessibleTable {
-  ~HTMLTableAccessibleWrap() {}
-
- public:
-  HTMLTableAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
-      : HTMLTableAccessible(aContent, aDoc), ia2AccessibleTable(this) {}
-
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  virtual void Shutdown() override;
-};
-
-/**
- * IA2 wrapper class for HTMLTableCellAccessible implementing
- * IAccessibleTableCell interface.
- */
-class HTMLTableCellAccessibleWrap : public HTMLTableCellAccessible,
-                                    public ia2AccessibleTableCell {
-  ~HTMLTableCellAccessibleWrap() {}
-
- public:
-  HTMLTableCellAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
-      : HTMLTableCellAccessible(aContent, aDoc), ia2AccessibleTableCell(this) {}
-
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  virtual void Shutdown() override;
-};
-
-/**
- * IA2 wrapper class for HTMLTableHeaderCellAccessible implementing
- * IAccessibleTableCell interface.
- */
-class HTMLTableHeaderCellAccessibleWrap : public HTMLTableHeaderCellAccessible,
-                                          public ia2AccessibleTableCell {
-  ~HTMLTableHeaderCellAccessibleWrap() {}
-
- public:
-  HTMLTableHeaderCellAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
-      : HTMLTableHeaderCellAccessible(aContent, aDoc),
-        ia2AccessibleTableCell(this) {}
-
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  virtual void Shutdown() override;
-};
-
+using HTMLTableAccessibleWrap = HTMLTableAccessible;
+using HTMLTableCellAccessibleWrap = HTMLTableCellAccessible;
+using HTMLTableHeaderCellAccessibleWrap = HTMLTableHeaderCellAccessible;
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/msaa/HyperTextAccessibleWrap.cpp
+++ b/accessible/windows/msaa/HyperTextAccessibleWrap.cpp
@@ -12,42 +12,16 @@
 
 #include "mozilla/StaticPtr.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 NS_IMPL_ISUPPORTS_INHERITED0(HyperTextAccessibleWrap, HyperTextAccessible)
 
-STDMETHODIMP
-HyperTextAccessibleWrap::QueryInterface(REFIID aIID, void** aInstancePtr) {
-  if (!aInstancePtr) return E_FAIL;
-
-  *aInstancePtr = nullptr;
-
-  if (IsTextRole()) {
-    if (aIID == IID_IAccessibleText)
-      *aInstancePtr =
-          static_cast<IAccessibleText*>(static_cast<ia2AccessibleText*>(this));
-    else if (aIID == IID_IAccessibleHypertext)
-      *aInstancePtr = static_cast<IAccessibleHypertext*>(this);
-    else if (aIID == IID_IAccessibleHypertext2)
-      *aInstancePtr = static_cast<IAccessibleHypertext2*>(this);
-    else if (aIID == IID_IAccessibleEditableText)
-      *aInstancePtr = static_cast<IAccessibleEditableText*>(this);
-
-    if (*aInstancePtr) {
-      AddRef();
-      return S_OK;
-    }
-  }
-
-  return MsaaAccessible::QueryInterface(aIID, aInstancePtr);
-}
-
 nsresult HyperTextAccessibleWrap::HandleAccEvent(AccEvent* aEvent) {
   uint32_t eventType = aEvent->GetEventType();
 
   if (eventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED ||
       eventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED) {
     LocalAccessible* accessible = aEvent->GetAccessible();
     if (accessible && accessible->IsHyperText()) {
       AccTextChangeEvent* event = downcast_accEvent(aEvent);
--- a/accessible/windows/msaa/HyperTextAccessibleWrap.h
+++ b/accessible/windows/msaa/HyperTextAccessibleWrap.h
@@ -4,37 +4,24 @@
 /* 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/. */
 
 #ifndef mozilla_a11y_HyperTextAccessibleWrap_h__
 #define mozilla_a11y_HyperTextAccessibleWrap_h__
 
 #include "HyperTextAccessible.h"
-#include "ia2AccessibleEditableText.h"
-#include "ia2AccessibleHypertext.h"
-#include "IUnknownImpl.h"
 
 namespace mozilla {
-template <class T>
-class StaticAutoPtr;
-template <class T>
-class StaticRefPtr;
 
 namespace a11y {
 
-class HyperTextAccessibleWrap : public HyperTextAccessible,
-                                public ia2AccessibleHypertext,
-                                public ia2AccessibleEditableText {
+class HyperTextAccessibleWrap : public HyperTextAccessible {
  public:
-  HyperTextAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
-      : HyperTextAccessible(aContent, aDoc) {}
-
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
+  using HyperTextAccessible::HyperTextAccessible;
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // LocalAccessible
   virtual nsresult HandleAccEvent(AccEvent* aEvent);
 
  protected:
deleted file mode 100644
--- a/accessible/windows/msaa/ImageAccessibleWrap.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:expandtab:shiftwidth=2:tabstop=2:
- */
-/* 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/. */
-
-#include "ImageAccessibleWrap.h"
-
-using namespace mozilla;
-using namespace mozilla::a11y;
-
-NS_IMPL_ISUPPORTS_INHERITED0(ImageAccessibleWrap, ImageAccessible)
-
-IMPL_IUNKNOWN_INHERITED1(ImageAccessibleWrap, MsaaAccessible,
-                         ia2AccessibleImage)
--- a/accessible/windows/msaa/ImageAccessibleWrap.h
+++ b/accessible/windows/msaa/ImageAccessibleWrap.h
@@ -4,32 +4,16 @@
 /* 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/. */
 
 #ifndef mozilla_a11y_ImageAccessibleWrap_h__
 #define mozilla_a11y_ImageAccessibleWrap_h__
 
 #include "ImageAccessible.h"
-#include "ia2AccessibleImage.h"
 
 namespace mozilla {
 namespace a11y {
-
-class ImageAccessibleWrap : public ImageAccessible, public ia2AccessibleImage {
- public:
-  ImageAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
-      : ImageAccessible(aContent, aDoc) {}
-
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
- protected:
-  ~ImageAccessibleWrap() {}
-};
-
+using ImageAccessibleWrap = ImageAccessible;
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/msaa/MsaaAccessible.cpp
+++ b/accessible/windows/msaa/MsaaAccessible.cpp
@@ -1,58 +1,114 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "EnumVariant.h"
-#include "MsaaAccessible.h"
+#include "ia2AccessibleApplication.h"
+#include "ia2AccessibleHypertext.h"
+#include "ia2AccessibleImage.h"
+#include "ia2AccessibleTable.h"
+#include "ia2AccessibleTableCell.h"
 #include "mozilla/a11y/AccessibleWrap.h"
 #include "mozilla/a11y/DocAccessibleParent.h"
 #include "mozilla/dom/BrowserBridgeParent.h"
 #include "mozilla/dom/BrowserParent.h"
 #include "mozilla/mscom/Interceptor.h"
+#include "MsaaAccessible.h"
+#include "MsaaDocAccessible.h"
+#include "MsaaRootAccessible.h"
+#include "MsaaXULMenuAccessible.h"
 #include "nsEventMap.h"
 #include "nsViewManager.h"
 #include "nsWinUtils.h"
 #include "Relation.h"
 #include "sdnAccessible.h"
+#include "sdnTextAccessible.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 const uint32_t USE_ROLE_STRING = 0;
 static const VARIANT kVarChildIdSelf = {{{VT_I4}}};
 
 MsaaIdGenerator MsaaAccessible::sIDGen;
 ITypeInfo* MsaaAccessible::gTypeInfo = nullptr;
 
-MsaaAccessible::MsaaAccessible() : mID(kNoID) {}
+/* static */
+MsaaAccessible* MsaaAccessible::Create(Accessible* aAcc) {
+  // We don't support RemoteAccessible yet.
+  MOZ_ASSERT(aAcc->IsLocal());
+  // The order of some of these is important! For example, when isRoot is true,
+  // IsDoc will also be true, so we must check IsRoot first. IsTable/Cell and
+  // IsHyperText are a similar case.
+  if (aAcc->IsRoot()) {
+    return new MsaaRootAccessible(aAcc);
+  }
+  if (aAcc->IsDoc()) {
+    return new MsaaDocAccessible(aAcc);
+  }
+  if (aAcc->IsTable()) {
+    return new ia2AccessibleTable(aAcc);
+  }
+  if (aAcc->IsTableCell()) {
+    return new ia2AccessibleTableCell(aAcc);
+  }
+  if (aAcc->IsApplication()) {
+    return new ia2AccessibleApplication(aAcc);
+  }
+  if (aAcc->IsHyperText()) {
+    return new ia2AccessibleHypertext(aAcc);
+  }
+  if (aAcc->IsImage()) {
+    return new ia2AccessibleImage(aAcc);
+  }
+  if (aAcc->AsLocal()->GetContent() &&
+      aAcc->AsLocal()->GetContent()->IsXULElement(nsGkAtoms::menuitem)) {
+    return new MsaaXULMenuitemAccessible(aAcc);
+  }
+  return new MsaaAccessible(aAcc);
+}
+
+MsaaAccessible::MsaaAccessible(Accessible* aAcc) : mAcc(aAcc), mID(kNoID) {}
 
 MsaaAccessible::~MsaaAccessible() {
+  MOZ_ASSERT(!mAcc, "MsaaShutdown wasn't called!");
   if (mID != kNoID) {
     sIDGen.ReleaseID(WrapNotNull(this));
   }
 }
 
 void MsaaAccessible::MsaaShutdown() {
+  // Accessibles can be shut down twice in some cases. If that happens,
+  // MsaaShutdown will also be called twice because AccessibleWrap holds
+  // the reference until its destructor is called; see the comments in
+  // AccessibleWrap::Shutdown.
+  if (!mAcc) {
+    return;
+  }
+
+  // We don't support RemoteAccessible yet.
+  MOZ_ASSERT(mAcc->IsLocal());
+  if (mAcc->AsLocal()->IsProxy()) {
+    // For RemoteAccessibleWrap, we just need to clear mAcc.
+    mAcc = nullptr;
+    return;
+  }
+
   if (mID != kNoID) {
     // Don't use LocalAcc() here because it requires that the Accessible is
     // not defunct. When shutting down, the Accessible might already be
     // marked defunct. It's safe for us to call LocalAccessible::Document() here
     // regardless.
-    auto localAcc = static_cast<AccessibleWrap*>(this);
-    DocAccessible* docAcc = localAcc->Document();
-    auto doc = docAcc ? MsaaDocAccessible::GetFrom(docAcc) : nullptr;
-    // Accessibles can be shut down twice in some cases. When this happens,
-    // doc will be null.
-    if (doc) {
-      doc->RemoveID(mID);
-    }
+    auto doc = MsaaDocAccessible::GetFrom(mAcc->AsLocal()->Document());
+    MOZ_ASSERT(doc);
+    doc->RemoveID(mID);
   }
 
   if (XRE_IsContentProcess()) {
     // Bug 1434822: To improve performance for cross-process COM, we disable COM
     // garbage collection. However, this means we never receive Release calls
     // from clients, so defunct accessibles can never be deleted. Since we
     // know when an accessible is shutting down, we can work around this by
     // forcing COM to disconnect this object from all of its remote clients,
@@ -66,21 +122,23 @@ void MsaaAccessible::MsaaShutdown() {
     // bug 1440267 is fixed.
     unk = static_cast<IAccessibleHyperlink*>(this);
     mscom::Interceptor::DisconnectRemotesForTarget(unk);
     for (auto& assocUnk : mAssociatedCOMObjectsForDisconnection) {
       mscom::Interceptor::DisconnectRemotesForTarget(assocUnk);
     }
     mAssociatedCOMObjectsForDisconnection.Clear();
   }
+
+  mAcc = nullptr;
 }
 
 void MsaaAccessible::SetID(uint32_t aID) {
-  MOZ_ASSERT(XRE_IsParentProcess() &&
-             static_cast<AccessibleWrap*>(this)->IsProxy());
+  MOZ_ASSERT(XRE_IsParentProcess() && mAcc && mAcc->IsLocal() &&
+             mAcc->AsLocal()->IsProxy());
   mID = aID;
 }
 
 int32_t MsaaAccessible::GetChildIDFor(LocalAccessible* aAccessible) {
   // A child ID of the window is required, when we use NotifyWinEvent,
   // so that the 3rd party application can call back and get the IAccessible
   // the event occurred on.
 
@@ -247,18 +305,20 @@ void MsaaAccessible::FireWinEvent(LocalA
     AccessibleWrap::InvalidateHandlers();
   }
 
   // Fire MSAA event for client area window.
   ::NotifyWinEvent(winEvent, hwnd, OBJID_CLIENT, childID);
 }
 
 AccessibleWrap* MsaaAccessible::LocalAcc() {
-  auto acc = static_cast<AccessibleWrap*>(this);
-  return acc->IsDefunct() ? nullptr : acc;
+  auto acc = static_cast<AccessibleWrap*>(mAcc);
+  MOZ_ASSERT(!acc || !acc->IsDefunct(),
+             "mAcc defunct but MsaaShutdown wasn't called");
+  return acc;
 }
 
 /**
  * This function is a helper for implementing IAccessible methods that accept
  * a Child ID as a parameter. If the child ID is CHILDID_SELF, the function
  * returns S_OK but a null *aOutInterface. Otherwise, *aOutInterface points
  * to the resolved IAccessible.
  *
@@ -661,16 +721,22 @@ MsaaAccessible::QueryInterface(REFIID ii
   } else if (IID_IServiceProvider == iid)
     *ppv = new ServiceProvider(this);
   else if (IID_ISimpleDOMNode == iid && !acc->IsProxy()) {
     if (!acc->HasOwnContent() && !acc->IsDoc()) {
       return E_NOINTERFACE;
     }
 
     *ppv = static_cast<ISimpleDOMNode*>(new sdnAccessible(WrapNotNull(this)));
+  } else if (iid == IID_ISimpleDOMText && acc->IsTextLeaf() &&
+             !acc->IsProxy()) {
+    statistics::ISimpleDOMUsed();
+    *ppv = static_cast<ISimpleDOMText*>(new sdnTextAccessible(this));
+    static_cast<IUnknown*>(*ppv)->AddRef();
+    return S_OK;
   }
 
   if (nullptr == *ppv) {
     HRESULT hr = ia2Accessible::QueryInterface(iid, ppv);
     if (SUCCEEDED(hr)) return hr;
   }
 
   if (nullptr == *ppv && !acc->IsProxy()) {
@@ -695,25 +761,16 @@ MsaaAccessible::QueryInterface(REFIID ii
   }
 
   if (nullptr == *ppv) return E_NOINTERFACE;
 
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
   return S_OK;
 }
 
-// XXX This delegation to AccessibleWrap is a necessary hack until we can move
-// the IUnknown implementation out of AccessibleWrap.
-ULONG STDMETHODCALLTYPE MsaaAccessible::AddRef() {
-  return static_cast<AccessibleWrap*>(this)->AddRef();
-}
-ULONG STDMETHODCALLTYPE MsaaAccessible::Release() {
-  return static_cast<AccessibleWrap*>(this)->Release();
-}
-
 // IAccessible methods
 
 STDMETHODIMP
 MsaaAccessible::get_accParent(IDispatch __RPC_FAR* __RPC_FAR* ppdispParent) {
   if (!ppdispParent) return E_INVALIDARG;
 
   *ppdispParent = nullptr;
 
--- a/accessible/windows/msaa/MsaaAccessible.h
+++ b/accessible/windows/msaa/MsaaAccessible.h
@@ -6,33 +6,34 @@
 
 #ifndef mozilla_a11y_MsaaAccessible_h_
 #define mozilla_a11y_MsaaAccessible_h_
 
 #include "ia2Accessible.h"
 #include "ia2AccessibleComponent.h"
 #include "ia2AccessibleHyperlink.h"
 #include "ia2AccessibleValue.h"
+#include "IUnknownImpl.h"
 #include "mozilla/a11y/MsaaIdGenerator.h"
 #include "mozilla/dom/ipc/IdType.h"
 #include "nsXULAppAPI.h"
 
 namespace mozilla {
 namespace a11y {
 class Accessible;
 class AccessibleWrap;
 class LocalAccessible;
 class sdnAccessible;
 
 class MsaaAccessible : public ia2Accessible,
                        public ia2AccessibleComponent,
                        public ia2AccessibleHyperlink,
                        public ia2AccessibleValue {
  public:
-  MsaaAccessible();
+  static MsaaAccessible* Create(Accessible* aAcc);
 
   AccessibleWrap* LocalAcc();
 
   uint32_t GetExistingID() const { return mID; }
   static const uint32_t kNoID = 0;
   void SetID(uint32_t aID);
 
   static int32_t GetChildIDFor(LocalAccessible* aAccessible);
@@ -64,20 +65,17 @@ class MsaaAccessible : public ia2Accessi
   }
 
   void MsaaShutdown();
 
   static IDispatch* NativeAccessible(LocalAccessible* aAccessible);
 
   static MsaaAccessible* GetFrom(Accessible* aAcc);
 
-  // IUnknown
-  STDMETHODIMP QueryInterface(REFIID, void**) override;
-  ULONG STDMETHODCALLTYPE AddRef() override;
-  ULONG STDMETHODCALLTYPE Release() override;
+  DECL_IUNKNOWN
 
   // IAccessible
   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent(
       /* [retval][out] */ IDispatch __RPC_FAR* __RPC_FAR* ppdispParent)
       override;
   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accChildCount(
       /* [retval][out] */ long __RPC_FAR* pcountChildren) override;
   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accChild(
@@ -152,18 +150,21 @@ class MsaaAccessible : public ia2Accessi
   virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid,
                                            LCID lcid, WORD wFlags,
                                            DISPPARAMS* pDispParams,
                                            VARIANT* pVarResult,
                                            EXCEPINFO* pExcepInfo,
                                            UINT* puArgErr) override;
 
  protected:
+  explicit MsaaAccessible(Accessible* aAcc);
   virtual ~MsaaAccessible();
 
+  Accessible* mAcc;
+
   uint32_t mID;
   static MsaaIdGenerator sIDGen;
 
   HRESULT
   ResolveChild(const VARIANT& aVarChild, IAccessible** aOutInterface);
 
   enum navRelations {
     NAVRELATION_CONTROLLED_BY = 0x1000,
--- a/accessible/windows/msaa/MsaaDocAccessible.cpp
+++ b/accessible/windows/msaa/MsaaDocAccessible.cpp
@@ -9,28 +9,34 @@
 #include "DocAccessibleChild.h"
 #include "nsWinUtils.h"
 #include "Role.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 DocAccessible* MsaaDocAccessible::DocAcc() {
-  // XXX This first static_cast is a necessary hack until we get rid of the
-  // inheritance of DocAccessibleWrap.
-  auto wrap = static_cast<DocAccessible*>(this);
-  AccessibleWrap* acc = static_cast<MsaaAccessible*>(wrap)->LocalAcc();
-  return static_cast<DocAccessible*>(acc);
+  return static_cast<DocAccessible*>(LocalAcc());
 }
 
 /* static */
 MsaaDocAccessible* MsaaDocAccessible::GetFrom(DocAccessible* aDoc) {
   return static_cast<MsaaDocAccessible*>(MsaaAccessible::GetFrom(aDoc));
 }
 
+// IUnknown
+IMPL_IUNKNOWN_QUERY_HEAD(MsaaDocAccessible)
+if (aIID == IID_ISimpleDOMDocument) {
+  statistics::ISimpleDOMUsed();
+  *aInstancePtr = static_cast<ISimpleDOMDocument*>(new sdnDocAccessible(this));
+  static_cast<IUnknown*>(*aInstancePtr)->AddRef();
+  return S_OK;
+}
+IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(ia2AccessibleHypertext)
+
 STDMETHODIMP
 MsaaDocAccessible::get_accParent(
     /* [retval][out] */ IDispatch __RPC_FAR* __RPC_FAR* ppdispParent) {
   DocAccessible* docAcc = DocAcc();
   if (!docAcc) {
     return CO_E_OBJNOTCONNECTED;
   }
 
--- a/accessible/windows/msaa/MsaaDocAccessible.h
+++ b/accessible/windows/msaa/MsaaDocAccessible.h
@@ -2,41 +2,31 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #ifndef mozilla_a11y_MsaaDocAccessible_h__
 #define mozilla_a11y_MsaaDocAccessible_h__
 
-#include "DocAccessible.h"
-#include "MsaaAccessible.h"
+#include "ia2AccessibleHypertext.h"
 
 namespace mozilla {
 
-class PresShell;
-
 namespace a11y {
+class Accessible;
 class DocAccessible;
 
-// XXX This should inherit from MsaaAccessible. Inheriting from DocAccessible
-// is a necessary hack until we remove the inheritance of DocAccessibleWrap.
-class MsaaDocAccessible : public DocAccessible {
+class MsaaDocAccessible : public ia2AccessibleHypertext {
  public:
-  MsaaDocAccessible(dom::Document* aDocument, PresShell* aPresShell)
-      : DocAccessible(aDocument, aPresShell) {}
-
   DocAccessible* DocAcc();
 
   // IUnknown
-  // XXX This override of QueryInterface is a necessary hack until we get rid
-  // of the inheritance of DocAccessible.
-  STDMETHODIMP QueryInterface(REFIID iid, void** ppv) override {
-    return MsaaAccessible::QueryInterface(iid, ppv);
-  }
+  DECL_IUNKNOWN_INHERITED
+  IMPL_IUNKNOWN_REFCOUNTING_INHERITED(ia2AccessibleHypertext)
 
   // IAccessible
 
   // Override get_accParent for e10s
   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent(
       /* [retval][out] */ IDispatch __RPC_FAR* __RPC_FAR* ppdispParent)
       override;
 
@@ -54,16 +44,18 @@ class MsaaDocAccessible : public DocAcce
   void RemoveID(uint32_t aID) { mIDToAccessibleMap.Remove(aID); }
   AccessibleWrap* GetAccessibleByID(uint32_t aID) const {
     return mIDToAccessibleMap.Get(aID);
   }
 
   static MsaaDocAccessible* GetFrom(DocAccessible* aDoc);
 
  protected:
+  using ia2AccessibleHypertext::ia2AccessibleHypertext;
+
   /*
    * This provides a mapping from 32 bit id to accessible objects.
    */
   nsTHashMap<nsUint32HashKey, AccessibleWrap*> mIDToAccessibleMap;
 };
 
 }  // namespace a11y
 }  // namespace mozilla
--- a/accessible/windows/msaa/MsaaRootAccessible.cpp
+++ b/accessible/windows/msaa/MsaaRootAccessible.cpp
@@ -7,21 +7,17 @@
 #include "MsaaRootAccessible.h"
 #include "Relation.h"
 #include "RootAccessible.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 RootAccessible* MsaaRootAccessible::RootAcc() {
-  // XXX This first static_cast is a necessary hack until we get rid of the
-  // inheritance of RootAccessibleWrap.
-  auto wrap = static_cast<RootAccessible*>(this);
-  AccessibleWrap* acc = static_cast<MsaaAccessible*>(wrap)->LocalAcc();
-  return static_cast<RootAccessible*>(acc);
+  return static_cast<RootAccessible*>(LocalAcc());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Aggregated IUnknown
 HRESULT
 MsaaRootAccessible::InternalQueryInterface(REFIID aIid, void** aOutInterface) {
   if (!aOutInterface) {
     return E_INVALIDARG;
@@ -31,25 +27,25 @@ MsaaRootAccessible::InternalQueryInterfa
   // when queried for IID_IUnknown...
   if (aIid == IID_IUnknown) {
     RefPtr<IUnknown> punk(&mInternalUnknown);
     punk.forget(aOutInterface);
     return S_OK;
   }
 
   // ...Otherwise we pass through to the base COM implementation of
-  // QueryInterface which is provided by DocAccessibleWrap.
-  return DocAccessibleWrap::QueryInterface(aIid, aOutInterface);
+  // QueryInterface which is provided by MsaaDocAccessible.
+  return MsaaDocAccessible::QueryInterface(aIid, aOutInterface);
 }
 
 ULONG
-MsaaRootAccessible::InternalAddRef() { return DocAccessible::AddRef(); }
+MsaaRootAccessible::InternalAddRef() { return MsaaDocAccessible::AddRef(); }
 
 ULONG
-MsaaRootAccessible::InternalRelease() { return DocAccessible::Release(); }
+MsaaRootAccessible::InternalRelease() { return MsaaDocAccessible::Release(); }
 
 already_AddRefed<IUnknown> MsaaRootAccessible::Aggregate(IUnknown* aOuter) {
   MOZ_ASSERT(mOuter &&
              (mOuter == &mInternalUnknown || mOuter == aOuter || !aOuter));
   if (!aOuter) {
     // If there is no aOuter then we should always set mOuter to
     // mInternalUnknown. This is standard COM aggregation stuff.
     mOuter = &mInternalUnknown;
--- a/accessible/windows/msaa/MsaaRootAccessible.h
+++ b/accessible/windows/msaa/MsaaRootAccessible.h
@@ -2,31 +2,26 @@
 /* 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/. */
 
 #ifndef mozilla_a11y_MsaaRootAccessible_h__
 #define mozilla_a11y_MsaaRootAccessible_h__
 
 #include "mozilla/mscom/Aggregation.h"
-#include "RootAccessible.h"
+#include "MsaaDocAccessible.h"
 
 namespace mozilla {
 
-class PresShell;
-
 namespace a11y {
 
-// XXX This should inherit from MsaaDocAccessible. Inheriting from
-// RootAccessible is a necessary hack until we remove the inheritance of
-// RootAccessibleWrap.
-class MsaaRootAccessible : public RootAccessible {
+class MsaaRootAccessible : public MsaaDocAccessible {
  public:
-  MsaaRootAccessible(dom::Document* aDocument, PresShell* aPresShell)
-      : RootAccessible(aDocument, aPresShell), mOuter(&mInternalUnknown) {}
+  explicit MsaaRootAccessible(Accessible* aAcc)
+      : MsaaDocAccessible(aAcc), mOuter(&mInternalUnknown) {}
 
   /**
    * This method enables a RootAccessibleWrap to be wrapped by a
    * LazyInstantiator.
    *
    * @param aOuter The IUnknown of the object that is wrapping this
    *               RootAccessibleWrap, or nullptr to unwrap the aOuter from
    *               a previous call.
--- a/accessible/windows/msaa/MsaaXULMenuAccessible.h
+++ b/accessible/windows/msaa/MsaaXULMenuAccessible.h
@@ -1,29 +1,27 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #ifndef mozilla_a11y_MsaaXULMenuAccessible_h__
 #define mozilla_a11y_MsaaXULMenuAccessible_h__
 
-#include "XULMenuAccessible.h"
+#include "MsaaAccessible.h"
 
 namespace mozilla {
 namespace a11y {
 
-// XXX This should inherit from MsaaAccessible. Inheriting from
-// XULMenuitemAccessible is a necessary hack until we remove the inheritance of
-// XULMenuitemAccessibleWrap.
-class MsaaXULMenuitemAccessible : public XULMenuitemAccessible {
+class MsaaXULMenuitemAccessible : public MsaaAccessible {
  public:
-  using XULMenuitemAccessible::XULMenuitemAccessible;
-
   virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR* pszKeyboardShortcut) override;
+
+ protected:
+  using MsaaAccessible::MsaaAccessible;
 };
 
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/msaa/RootAccessibleWrap.cpp
+++ b/accessible/windows/msaa/RootAccessibleWrap.cpp
@@ -13,17 +13,17 @@
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Constructor/destructor
 
 RootAccessibleWrap::RootAccessibleWrap(dom::Document* aDocument,
                                        PresShell* aPresShell)
-    : MsaaRootAccessible(aDocument, aPresShell) {}
+    : RootAccessible(aDocument, aPresShell) {}
 
 RootAccessibleWrap::~RootAccessibleWrap() {}
 
 ////////////////////////////////////////////////////////////////////////////////
 // RootAccessible
 
 void RootAccessibleWrap::DocumentActivated(DocAccessible* aDocument) {
   // This check will never work with e10s enabled, in other words, as of
--- a/accessible/windows/msaa/RootAccessibleWrap.h
+++ b/accessible/windows/msaa/RootAccessibleWrap.h
@@ -1,25 +1,25 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #ifndef mozilla_a11y_RootAccessibleWrap_h__
 #define mozilla_a11y_RootAccessibleWrap_h__
 
-#include "MsaaRootAccessible.h"
+#include "RootAccessible.h"
 
 namespace mozilla {
 
 class PresShell;
 
 namespace a11y {
 
-class RootAccessibleWrap : public MsaaRootAccessible {
+class RootAccessibleWrap : public RootAccessible {
  public:
   RootAccessibleWrap(dom::Document* aDocument, PresShell* aPresShell);
   virtual ~RootAccessibleWrap();
 
   // RootAccessible
   virtual void DocumentActivated(DocAccessible* aDocument);
 };
 
--- a/accessible/windows/msaa/ServiceProvider.cpp
+++ b/accessible/windows/msaa/ServiceProvider.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "ServiceProvider.h"
 
+#include "AccessibleApplication_i.c"
 #include "ApplicationAccessibleWrap.h"
 #include "DocAccessible.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 #include "Relation.h"
 #include "RootAccessible.h"
 #include "uiaRawElmProvider.h"
 
deleted file mode 100644
--- a/accessible/windows/msaa/TextLeafAccessibleWrap.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* 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/. */
-
-#include "TextLeafAccessibleWrap.h"
-
-#include "sdnTextAccessible.h"
-#include "Statistics.h"
-
-using namespace mozilla::a11y;
-
-IMPL_IUNKNOWN_QUERY_HEAD(TextLeafAccessibleWrap)
-if (aIID == IID_ISimpleDOMText) {
-  statistics::ISimpleDOMUsed();
-  *aInstancePtr = static_cast<ISimpleDOMText*>(new sdnTextAccessible(this));
-  static_cast<IUnknown*>(*aInstancePtr)->AddRef();
-  return S_OK;
-}
-IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(MsaaAccessible)
--- a/accessible/windows/msaa/TextLeafAccessibleWrap.h
+++ b/accessible/windows/msaa/TextLeafAccessibleWrap.h
@@ -6,27 +6,13 @@
 
 #ifndef mozilla_a11y_TextLeafAccessibleWrap_h__
 #define mozilla_a11y_TextLeafAccessibleWrap_h__
 
 #include "TextLeafAccessible.h"
 
 namespace mozilla {
 namespace a11y {
-
-/**
- * Wrap TextLeafAccessible to expose ISimpleDOMText as a native interface with
- * a tear off.
- */
-class TextLeafAccessibleWrap : public TextLeafAccessible {
- public:
-  TextLeafAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
-      : TextLeafAccessible(aContent, aDoc) {}
-  virtual ~TextLeafAccessibleWrap() {}
-
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
-};
-
+using TextLeafAccessibleWrap = TextLeafAccessible;
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
deleted file mode 100644
--- a/accessible/windows/msaa/XULListboxAccessibleWrap.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#include "XULListboxAccessibleWrap.h"
-
-#include "LocalAccessible-inl.h"
-
-using namespace mozilla::a11y;
-
-////////////////////////////////////////////////////////////////////////////////
-// XULListboxAccessibleWrap
-////////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_ISUPPORTS_INHERITED0(XULListboxAccessibleWrap, XULListboxAccessible)
-
-IMPL_IUNKNOWN_QUERY_HEAD(XULListboxAccessibleWrap)
-IMPL_IUNKNOWN_QUERY_CLASS_COND(ia2AccessibleTable,
-                               !IsDefunct() && IsMulticolumn());
-IMPL_IUNKNOWN_QUERY_CLASS(MsaaAccessible)
-IMPL_IUNKNOWN_QUERY_TAIL
-
-void XULListboxAccessibleWrap::Shutdown() {
-  ia2AccessibleTable::mTable = nullptr;
-  XULListboxAccessible::Shutdown();
-}
--- a/accessible/windows/msaa/XULListboxAccessibleWrap.h
+++ b/accessible/windows/msaa/XULListboxAccessibleWrap.h
@@ -7,34 +7,13 @@
 #define mozilla_a11y_XULListboxAccessibleWrap_h__
 
 #include "XULListboxAccessible.h"
 
 #include "ia2AccessibleTable.h"
 
 namespace mozilla {
 namespace a11y {
-
-/**
- * IA2 wrapper class for XULListboxAccessible class implementing
- * IAccessibleTable and IAccessibleTable2 interfaces.
- */
-class XULListboxAccessibleWrap : public XULListboxAccessible,
-                                 public ia2AccessibleTable {
-  ~XULListboxAccessibleWrap() {}
-
- public:
-  XULListboxAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc)
-      : XULListboxAccessible(aContent, aDoc), ia2AccessibleTable(this) {}
-
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  virtual void Shutdown() override;
-};
-
+using XULListboxAccessibleWrap = XULListboxAccessible;
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/msaa/XULMenuAccessibleWrap.cpp
+++ b/accessible/windows/msaa/XULMenuAccessibleWrap.cpp
@@ -1,25 +1,26 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #include "XULMenuAccessibleWrap.h"
+#include "mozilla/dom/Element.h"
 #include "nsNameSpaceManager.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULMenuAccessibleWrap
 ////////////////////////////////////////////////////////////////////////////////
 
 XULMenuitemAccessibleWrap::XULMenuitemAccessibleWrap(nsIContent* aContent,
                                                      DocAccessible* aDoc)
-    : MsaaXULMenuitemAccessible(aContent, aDoc) {}
+    : XULMenuitemAccessible(aContent, aDoc) {}
 
 ENameValueFlag XULMenuitemAccessibleWrap::Name(nsString& aName) const {
   // XXX This should be done in MSAA's get_accName() so that
   // LocalAccessible::Name()] provides the same results on all platforms
   XULMenuitemAccessible::Name(aName);
   if (aName.IsEmpty()) return eNameOK;
 
   nsAutoString accel;
--- a/accessible/windows/msaa/XULMenuAccessibleWrap.h
+++ b/accessible/windows/msaa/XULMenuAccessibleWrap.h
@@ -1,22 +1,22 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #ifndef mozilla_a11y_XULMenuAccessibleWrap_h__
 #define mozilla_a11y_XULMenuAccessibleWrap_h__
 
-#include "MsaaXULMenuAccessible.h"
+#include "XULMenuAccessible.h"
 
 namespace mozilla {
 namespace a11y {
 
-class XULMenuitemAccessibleWrap : public MsaaXULMenuitemAccessible {
+class XULMenuitemAccessibleWrap : public XULMenuitemAccessible {
  public:
   XULMenuitemAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc);
   virtual ~XULMenuitemAccessibleWrap() {}
 
   // nsIAccessible
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName) const override;
 };
 
deleted file mode 100644
--- a/accessible/windows/msaa/XULTreeGridAccessibleWrap.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#include "XULTreeGridAccessibleWrap.h"
-
-using namespace mozilla::a11y;
-
-////////////////////////////////////////////////////////////////////////////////
-// XULTreeGridAccessibleWrap
-////////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_ISUPPORTS_INHERITED0(XULTreeGridAccessibleWrap, XULTreeGridAccessible)
-
-IMPL_IUNKNOWN_INHERITED1(XULTreeGridAccessibleWrap, MsaaAccessible,
-                         ia2AccessibleTable)
-
-void XULTreeGridAccessibleWrap::Shutdown() {
-  ia2AccessibleTable::mTable = nullptr;
-  XULTreeGridAccessible::Shutdown();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// XULTreeGridCellAccessibleWrap
-////////////////////////////////////////////////////////////////////////////////
-
-NS_IMPL_ISUPPORTS_INHERITED0(XULTreeGridCellAccessibleWrap,
-                             XULTreeGridCellAccessible)
-
-IMPL_IUNKNOWN_INHERITED1(XULTreeGridCellAccessibleWrap, MsaaAccessible,
-                         ia2AccessibleTableCell)
-
-void XULTreeGridCellAccessibleWrap::Shutdown() {
-  ia2AccessibleTableCell::mTableCell = nullptr;
-  XULTreeGridCellAccessible::Shutdown();
-}
--- a/accessible/windows/msaa/XULTreeGridAccessibleWrap.h
+++ b/accessible/windows/msaa/XULTreeGridAccessibleWrap.h
@@ -3,68 +3,16 @@
  * 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/. */
 
 #ifndef mozilla_a11y_XULTreeGridAccessibleWrap_h__
 #define mozilla_a11y_XULTreeGridAccessibleWrap_h__
 
 #include "XULTreeGridAccessible.h"
 
-#include "ia2AccessibleTable.h"
-#include "ia2AccessibleTableCell.h"
-
 namespace mozilla {
 namespace a11y {
-
-/**
- * IA2 wrapper class for XULTreeGridAccessible class implementing
- * IAccessibleTable and IAccessibleTable2 interfaces.
- */
-class XULTreeGridAccessibleWrap : public XULTreeGridAccessible,
-                                  public ia2AccessibleTable {
-  ~XULTreeGridAccessibleWrap() {}
-
- public:
-  XULTreeGridAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc,
-                            nsTreeBodyFrame* aTree)
-      : XULTreeGridAccessible(aContent, aDoc, aTree),
-        ia2AccessibleTable(this) {}
-
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  virtual void Shutdown() override;
-};
-
-/**
- * IA2 wrapper class for XULTreeGridCellAccessible class, implements
- * IAccessibleTableCell interface.
- */
-class XULTreeGridCellAccessibleWrap : public XULTreeGridCellAccessible,
-                                      public ia2AccessibleTableCell {
-  ~XULTreeGridCellAccessibleWrap() {}
-
- public:
-  XULTreeGridCellAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc,
-                                XULTreeGridRowAccessible* aRowAcc,
-                                dom::XULTreeElement* aTree,
-                                nsITreeView* aTreeView, int32_t aRow,
-                                nsTreeColumn* aColumn)
-      : XULTreeGridCellAccessible(aContent, aDoc, aRowAcc, aTree, aTreeView,
-                                  aRow, aColumn),
-        ia2AccessibleTableCell(this) {}
-
-  // IUnknown
-  DECL_IUNKNOWN_INHERITED
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  virtual void Shutdown() override;
-};
-
+using XULTreeGridAccessibleWrap = XULTreeGridAccessible;
+using XULTreeGridCellAccessibleWrap = XULTreeGridCellAccessible;
 }  // namespace a11y
 }  // namespace mozilla
 
 #endif
--- a/accessible/windows/msaa/moz.build
+++ b/accessible/windows/msaa/moz.build
@@ -16,53 +16,47 @@ EXPORTS.mozilla.a11y += [
     "MsaaAccessible.h",
     "MsaaIdGenerator.h",
     "nsWinUtils.h",
 ]
 
 UNIFIED_SOURCES += [
     "AccessibleWrap.cpp",
     "ApplicationAccessibleWrap.cpp",
-    "ARIAGridAccessibleWrap.cpp",
     "Compatibility.cpp",
     "CompatibilityUIA.cpp",
     "DocAccessibleWrap.cpp",
     "EnumVariant.cpp",
     "GeckoCustom.cpp",
-    "HTMLTableAccessibleWrap.cpp",
     "HyperTextAccessibleWrap.cpp",
-    "ImageAccessibleWrap.cpp",
     "IUnknownImpl.cpp",
     "MsaaAccessible.cpp",
     "MsaaDocAccessible.cpp",
     "MsaaIdGenerator.cpp",
     "MsaaRootAccessible.cpp",
     "MsaaXULMenuAccessible.cpp",
     "nsWinUtils.cpp",
     "Platform.cpp",
     "RootAccessibleWrap.cpp",
-    "TextLeafAccessibleWrap.cpp",
 ]
 
 SOURCES += [
     # This file cannot be built in unified mode because it redefines _WIN32_WINNT
     "LazyInstantiator.cpp",
     # This file cannot be built in unified mode because it includes ISimpleDOMNode_i.c.
     "ServiceProvider.cpp",
 ]
 
 OS_LIBS += [
     "ntdll",
 ]
 
 if CONFIG["MOZ_XUL"]:
     UNIFIED_SOURCES += [
-        "XULListboxAccessibleWrap.cpp",
         "XULMenuAccessibleWrap.cpp",
-        "XULTreeGridAccessibleWrap.cpp",
     ]
 
 LOCAL_INCLUDES += [
     "/accessible/base",
     "/accessible/generic",
     "/accessible/html",
     "/accessible/ipc",
     "/accessible/ipc/win",