Bug 1268544: Refactor ProxyAccessible and dependencies; r?tbsaunde draft
authorAaron Klotz <aklotz@mozilla.com>
Thu, 04 Aug 2016 18:28:08 -0600
changeset 397129 af269c12584896abd07290232ea98938ad6e33d5
parent 397128 2228cf6d302e0eaf59db4f13ce3027ba5c3f0892
child 397130 0c4f83c948f9422de5cd85d7387279167f5d3802
push id25211
push useraklotz@mozilla.com
push dateFri, 05 Aug 2016 07:53:24 +0000
reviewerstbsaunde
bugs1268544
milestone50.0a1
Bug 1268544: Refactor ProxyAccessible and dependencies; r?tbsaunde MozReview-Commit-ID: EHV0JR6NmKf
accessible/ipc/ProxyAccessible.cpp
accessible/ipc/ProxyAccessible.h
accessible/ipc/ProxyAccessibleBase.cpp
accessible/ipc/ProxyAccessibleBase.h
accessible/ipc/moz.build
accessible/ipc/other/ProxyAccessible.cpp
accessible/ipc/other/ProxyAccessible.h
accessible/ipc/other/moz.build
accessible/ipc/win/ProxyAccessible.cpp
accessible/ipc/win/ProxyAccessible.h
accessible/ipc/win/moz.build
accessible/windows/ProxyWrappers.h
accessible/xpcom/xpcAccessibleDocument.h
rename from accessible/ipc/ProxyAccessible.cpp
rename to accessible/ipc/ProxyAccessibleBase.cpp
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/ProxyAccessibleBase.cpp
@@ -1,74 +1,80 @@
 /* -*- 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 "ProxyAccessible.h"
-#include "DocAccessibleParent.h"
 #include "DocAccessible.h"
+#include "mozilla/a11y/DocAccessibleParent.h"
 #include "mozilla/a11y/DocManager.h"
+#include "mozilla/a11y/Platform.h"
+#include "mozilla/a11y/ProxyAccessibleBase.h"
+#include "mozilla/a11y/ProxyAccessible.h"
+#include "mozilla/a11y/Role.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/unused.h"
-#include "mozilla/a11y/Platform.h"
 #include "RelationType.h"
-#include "mozilla/a11y/Role.h"
 #include "xpcAccessibleDocument.h"
 
 namespace mozilla {
 namespace a11y {
 
+template class ProxyAccessibleBase<ProxyAccessible>;
+
+template <class Derived>
 void
-ProxyAccessible::Shutdown()
+ProxyAccessibleBase<Derived>::Shutdown()
 {
   MOZ_DIAGNOSTIC_ASSERT(!IsDoc());
   NS_ASSERTION(!mOuterDoc, "Why do we still have a child doc?");
   xpcAccessibleDocument* xpcDoc =
     GetAccService()->GetCachedXPCDocument(Document());
   if (xpcDoc) {
-    xpcDoc->NotifyOfShutdown(this);
+    xpcDoc->NotifyOfShutdown(static_cast<Derived*>(this));
   }
 
   // XXX Ideally  this wouldn't be necessary, but it seems OuterDoc accessibles
   // can be destroyed before the doc they own.
   if (!mOuterDoc) {
     uint32_t childCount = mChildren.Length();
     for (uint32_t idx = 0; idx < childCount; idx++)
       mChildren[idx]->Shutdown();
   } else {
     if (mChildren.Length() != 1)
       MOZ_CRASH("outer doc doesn't own adoc!");
 
     mChildren[0]->AsDoc()->Unbind();
   }
 
   mChildren.Clear();
-  ProxyDestroyed(this);
-  mDoc->RemoveAccessible(this);
+  ProxyDestroyed(static_cast<Derived*>(this));
+  mDoc->RemoveAccessible(static_cast<Derived*>(this));
 }
 
+template <class Derived>
 void
-ProxyAccessible::SetChildDoc(DocAccessibleParent* aParent)
+ProxyAccessibleBase<Derived>::SetChildDoc(DocAccessibleParent* aParent)
 {
   if (aParent) {
     MOZ_ASSERT(mChildren.IsEmpty());
     mChildren.AppendElement(aParent);
     mOuterDoc = true;
   } else {
     MOZ_ASSERT(mChildren.Length() == 1);
     mChildren.Clear();
     mOuterDoc = false;
   }
 }
 
+template <class Derived>
 bool
-ProxyAccessible::MustPruneChildren() const
+ProxyAccessibleBase<Derived>::MustPruneChildren() const
 {
   // this is the equivalent to nsAccUtils::MustPrune for proxies and should be
   // kept in sync with that.
   if (mRole != roles::MENUITEM && mRole != roles::COMBOBOX_OPTION
       && mRole != roles::OPTION && mRole != roles::ENTRY
       && mRole != roles::FLAT_EQUATION && mRole != roles::PASSWORD_TEXT
       && mRole != roles::PUSHBUTTON && mRole != roles::TOGGLE_BUTTON
       && mRole != roles::GRAPHIC && mRole != roles::SLIDER
@@ -77,998 +83,51 @@ ProxyAccessible::MustPruneChildren() con
 
   if (mChildren.Length() != 1)
     return false;
 
   return mChildren[0]->Role() == roles::TEXT_LEAF
     || mChildren[0]->Role() == roles::STATICTEXT;
 }
 
-uint64_t
-ProxyAccessible::State() const
-{
-  uint64_t state = 0;
-  Unused << mDoc->SendState(mID, &state);
-  return state;
-}
-
-uint64_t
-ProxyAccessible::NativeState() const
-{
-  uint64_t state = 0;
-  Unused << mDoc->SendNativeState(mID, &state);
-  return state;
-}
-
-void
-ProxyAccessible::Name(nsString& aName) const
-{
-  Unused << mDoc->SendName(mID, &aName);
-}
-
-void
-ProxyAccessible::Value(nsString& aValue) const
-{
-  Unused << mDoc->SendValue(mID, &aValue);
-}
-
-void
-ProxyAccessible::Help(nsString& aHelp) const
-{
-  Unused << mDoc->SendHelp(mID, &aHelp);
-}
-
-void
-ProxyAccessible::Description(nsString& aDesc) const
-{
-  Unused << mDoc->SendDescription(mID, &aDesc);
-}
-
-void
-ProxyAccessible::Attributes(nsTArray<Attribute> *aAttrs) const
-{
-  Unused << mDoc->SendAttributes(mID, aAttrs);
-}
-
-nsTArray<ProxyAccessible*>
-ProxyAccessible::RelationByType(RelationType aType) const
-{
-  nsTArray<uint64_t> targetIDs;
-  Unused << mDoc->SendRelationByType(mID, static_cast<uint32_t>(aType),
-                                     &targetIDs);
-
-  size_t targetCount = targetIDs.Length();
-  nsTArray<ProxyAccessible*> targets(targetCount);
-  for (size_t i = 0; i < targetCount; i++)
-    if (ProxyAccessible* proxy = mDoc->GetAccessible(targetIDs[i]))
-      targets.AppendElement(proxy);
-
-  return Move(targets);
-}
-
-void
-ProxyAccessible::Relations(nsTArray<RelationType>* aTypes,
-                           nsTArray<nsTArray<ProxyAccessible*>>* aTargetSets)
-  const
-{
-  nsTArray<RelationTargets> ipcRelations;
-  Unused << mDoc->SendRelations(mID, &ipcRelations);
-
-  size_t relationCount = ipcRelations.Length();
-  aTypes->SetCapacity(relationCount);
-  aTargetSets->SetCapacity(relationCount);
-  for (size_t i = 0; i < relationCount; i++) {
-    uint32_t type = ipcRelations[i].Type();
-    if (type > static_cast<uint32_t>(RelationType::LAST))
-      continue;
-
-    size_t targetCount = ipcRelations[i].Targets().Length();
-    nsTArray<ProxyAccessible*> targets(targetCount);
-    for (size_t j = 0; j < targetCount; j++)
-      if (ProxyAccessible* proxy = mDoc->GetAccessible(ipcRelations[i].Targets()[j]))
-        targets.AppendElement(proxy);
-
-    if (targets.IsEmpty())
-      continue;
-
-    aTargetSets->AppendElement(Move(targets));
-    aTypes->AppendElement(static_cast<RelationType>(type));
-  }
-}
-
-bool
-ProxyAccessible::IsSearchbox() const
-{
-  bool retVal = false;
-  Unused << mDoc->SendIsSearchbox(mID, &retVal);
-  return retVal;
-}
-
-nsIAtom*
-ProxyAccessible::LandmarkRole() const
-{
-  nsString landmark;
-  Unused << mDoc->SendLandmarkRole(mID, &landmark);
-  return NS_GetStaticAtom(landmark);
-}
-
-nsIAtom*
-ProxyAccessible::ARIARoleAtom() const
-{
-  nsString role;
-  Unused << mDoc->SendARIARoleAtom(mID, &role);
-  return NS_GetStaticAtom(role);
-}
-
-int32_t
-ProxyAccessible::GetLevelInternal()
-{
-  int32_t level = 0;
-  Unused << mDoc->SendGetLevelInternal(mID, &level);
-  return level;
-}
-
-void
-ProxyAccessible::ScrollTo(uint32_t aScrollType)
-{
-  Unused << mDoc->SendScrollTo(mID, aScrollType);
-}
-
-void
-ProxyAccessible::ScrollToPoint(uint32_t aScrollType, int32_t aX, int32_t aY)
-{
-  Unused << mDoc->SendScrollToPoint(mID, aScrollType, aX, aY);
-}
-
-int32_t
-ProxyAccessible::CaretLineNumber()
-{
-  int32_t line = -1;
-  Unused << mDoc->SendCaretOffset(mID, &line);
-  return line;
-}
-
-int32_t
-ProxyAccessible::CaretOffset()
-{
-  int32_t offset = 0;
-  Unused << mDoc->SendCaretOffset(mID, &offset);
-  return offset;
-}
-
-void
-ProxyAccessible::SetCaretOffset(int32_t aOffset)
-{
-  Unused << mDoc->SendSetCaretOffset(mID, aOffset);
-}
-
-int32_t
-ProxyAccessible::CharacterCount()
-{
-  int32_t count = 0;
-  Unused << mDoc->SendCharacterCount(mID, &count);
-  return count;
-}
-
-int32_t
-ProxyAccessible::SelectionCount()
-{
-  int32_t count = 0;
-  Unused << mDoc->SendSelectionCount(mID, &count);
-  return count;
-}
-
-bool
-ProxyAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOfset,
-                               nsString& aText) const
-{
-  bool valid;
-  Unused << mDoc->SendTextSubstring(mID, aStartOffset, aEndOfset, &aText, &valid);
-  return valid;
-}
-
-void
-ProxyAccessible::GetTextAfterOffset(int32_t aOffset,
-                                    AccessibleTextBoundary aBoundaryType,
-                                    nsString& aText, int32_t* aStartOffset,
-                                    int32_t* aEndOffset)
-{
-  Unused << mDoc->SendGetTextAfterOffset(mID, aOffset, aBoundaryType,
-                                         &aText, aStartOffset, aEndOffset);
-}
-
-void
-ProxyAccessible::GetTextAtOffset(int32_t aOffset,
-                                 AccessibleTextBoundary aBoundaryType,
-                                 nsString& aText, int32_t* aStartOffset,
-                                 int32_t* aEndOffset)
-{
-  Unused << mDoc->SendGetTextAtOffset(mID, aOffset, aBoundaryType,
-                                      &aText, aStartOffset, aEndOffset);
-}
-
-void
-ProxyAccessible::GetTextBeforeOffset(int32_t aOffset,
-                                     AccessibleTextBoundary aBoundaryType,
-                                     nsString& aText, int32_t* aStartOffset,
-                                     int32_t* aEndOffset)
-{
-  Unused << mDoc->SendGetTextBeforeOffset(mID, aOffset, aBoundaryType,
-                                          &aText, aStartOffset, aEndOffset);
-}
-
-char16_t
-ProxyAccessible::CharAt(int32_t aOffset)
-{
-  uint16_t retval = 0;
-  Unused << mDoc->SendCharAt(mID, aOffset, &retval);
-  return static_cast<char16_t>(retval);
-}
-
-void
-ProxyAccessible::TextAttributes(bool aIncludeDefAttrs,
-                                int32_t aOffset,
-                                nsTArray<Attribute>* aAttributes,
-                                int32_t* aStartOffset,
-                                int32_t* aEndOffset)
-{
-  Unused << mDoc->SendTextAttributes(mID, aIncludeDefAttrs, aOffset,
-                                     aAttributes, aStartOffset, aEndOffset);
-}
-
-void
-ProxyAccessible::DefaultTextAttributes(nsTArray<Attribute>* aAttrs)
-{
-  Unused << mDoc->SendDefaultTextAttributes(mID, aAttrs);
-}
-
-nsIntRect
-ProxyAccessible::TextBounds(int32_t aStartOffset, int32_t aEndOffset,
-                            uint32_t aCoordType)
-{
-  nsIntRect rect;
-  Unused <<
-    mDoc->SendTextBounds(mID, aStartOffset, aEndOffset, aCoordType, &rect);
-  return rect;
-}
-
-nsIntRect
-ProxyAccessible::CharBounds(int32_t aOffset, uint32_t aCoordType)
-{
-  nsIntRect rect;
-  Unused <<
-    mDoc->SendCharBounds(mID, aOffset, aCoordType, &rect);
-  return rect;
-}
-
-int32_t
-ProxyAccessible::OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType)
-{
-  int32_t retVal = -1;
-  Unused << mDoc->SendOffsetAtPoint(mID, aX, aY, aCoordType, &retVal);
-  return retVal;
-}
-
-bool
-ProxyAccessible::SelectionBoundsAt(int32_t aSelectionNum,
-                                   nsString& aData,
-                                   int32_t* aStartOffset,
-                                   int32_t* aEndOffset)
-{
-  bool retVal = false;
-  Unused << mDoc->SendSelectionBoundsAt(mID, aSelectionNum, &retVal, &aData,
-                                        aStartOffset, aEndOffset);
-  return retVal;
-}
-
-bool
-ProxyAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
-                                      int32_t aStartOffset,
-                                      int32_t aEndOffset)
-{
-  bool retVal = false;
-  Unused << mDoc->SendSetSelectionBoundsAt(mID, aSelectionNum, aStartOffset,
-                                           aEndOffset, &retVal);
-  return retVal;
-}
-
-bool
-ProxyAccessible::AddToSelection(int32_t aStartOffset,
-                                int32_t aEndOffset)
-{
-  bool retVal = false;
-  Unused << mDoc->SendAddToSelection(mID, aStartOffset, aEndOffset, &retVal);
-  return retVal;
-}
-
-bool
-ProxyAccessible::RemoveFromSelection(int32_t aSelectionNum)
-{
-  bool retVal = false;
-  Unused << mDoc->SendRemoveFromSelection(mID, aSelectionNum, &retVal);
-  return retVal;
-}
-
-void
-ProxyAccessible::ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
-                                   uint32_t aScrollType)
-{
-  Unused << mDoc->SendScrollSubstringTo(mID, aStartOffset, aEndOffset, aScrollType);
-}
-
-void
-ProxyAccessible::ScrollSubstringToPoint(int32_t aStartOffset,
-                                        int32_t aEndOffset,
-                                        uint32_t aCoordinateType,
-                                        int32_t aX, int32_t aY)
-{
-  Unused << mDoc->SendScrollSubstringToPoint(mID, aStartOffset, aEndOffset,
-                                             aCoordinateType, aX, aY);
-}
-
-void
-ProxyAccessible::Text(nsString* aText)
-{
-  Unused << mDoc->SendText(mID, aText);
-}
-
-void
-ProxyAccessible::ReplaceText(const nsString& aText)
-{
-  Unused << mDoc->SendReplaceText(mID, aText);
-}
-
-bool
-ProxyAccessible::InsertText(const nsString& aText, int32_t aPosition)
-{
-  bool valid;
-  Unused << mDoc->SendInsertText(mID, aText, aPosition, &valid);
-  return valid;
-}
-
-bool
-ProxyAccessible::CopyText(int32_t aStartPos, int32_t aEndPos)
-{
-  bool valid;
-  Unused << mDoc->SendCopyText(mID, aStartPos, aEndPos, &valid);
-  return valid;
-}
-
-bool
-ProxyAccessible::CutText(int32_t aStartPos, int32_t aEndPos)
-{
-  bool valid;
-  Unused << mDoc->SendCutText(mID, aStartPos, aEndPos, &valid);
-  return valid;
-}
-
-bool
-ProxyAccessible::DeleteText(int32_t aStartPos, int32_t aEndPos)
-{
-  bool valid;
-  Unused << mDoc->SendDeleteText(mID, aStartPos, aEndPos, &valid);
-  return valid;
-}
-
-bool
-ProxyAccessible::PasteText(int32_t aPosition)
-{
-  bool valid;
-  Unused << mDoc->SendPasteText(mID, aPosition, &valid);
-  return valid;
-}
-
-nsIntPoint
-ProxyAccessible::ImagePosition(uint32_t aCoordType)
-{
-  nsIntPoint retVal;
-  Unused << mDoc->SendImagePosition(mID, aCoordType, &retVal);
-  return retVal;
-}
-
-nsIntSize
-ProxyAccessible::ImageSize()
-{
-  nsIntSize retVal;
-  Unused << mDoc->SendImageSize(mID, &retVal);
-  return retVal;
-}
-
-uint32_t
-ProxyAccessible::StartOffset(bool* aOk)
-{
-  uint32_t retVal = 0;
-  Unused << mDoc->SendStartOffset(mID, &retVal, aOk);
-  return retVal;
-}
-
-uint32_t
-ProxyAccessible::EndOffset(bool* aOk)
-{
-  uint32_t retVal = 0;
-  Unused << mDoc->SendEndOffset(mID, &retVal, aOk);
-  return retVal;
-}
-
-bool
-ProxyAccessible::IsLinkValid()
-{
-  bool retVal = false;
-  Unused << mDoc->SendIsLinkValid(mID, &retVal);
-  return retVal;
-}
-
-uint32_t
-ProxyAccessible::AnchorCount(bool* aOk)
-{
-  uint32_t retVal = 0;
-  Unused << mDoc->SendAnchorCount(mID, &retVal, aOk);
-  return retVal;
-}
-
-void
-ProxyAccessible::AnchorURIAt(uint32_t aIndex, nsCString& aURI, bool* aOk)
-{
-  Unused << mDoc->SendAnchorURIAt(mID, aIndex, &aURI, aOk);
-}
-
-ProxyAccessible*
-ProxyAccessible::AnchorAt(uint32_t aIndex)
-{
-  uint64_t id = 0;
-  bool ok = false;
-  Unused << mDoc->SendAnchorAt(mID, aIndex, &id, &ok);
-  return ok ? mDoc->GetAccessible(id) : nullptr;
-}
-
+template <class Derived>
 uint32_t
-ProxyAccessible::LinkCount()
-{
-  uint32_t retVal = 0;
-  Unused << mDoc->SendLinkCount(mID, &retVal);
-  return retVal;
-}
-
-ProxyAccessible*
-ProxyAccessible::LinkAt(const uint32_t& aIndex)
-{
-  uint64_t linkID = 0;
-  bool ok = false;
-  Unused << mDoc->SendLinkAt(mID, aIndex, &linkID, &ok);
-  return ok ? mDoc->GetAccessible(linkID) : nullptr;
-}
-
-int32_t
-ProxyAccessible::LinkIndexOf(ProxyAccessible* aLink)
-{
-  int32_t retVal = -1;
-  if (aLink) {
-    Unused << mDoc->SendLinkIndexOf(mID, aLink->ID(), &retVal);
-  }
-
-  return retVal;
-}
-
-int32_t
-ProxyAccessible::LinkIndexAtOffset(uint32_t aOffset)
-{
-  int32_t retVal = -1;
-  Unused << mDoc->SendLinkIndexAtOffset(mID, aOffset, &retVal);
-  return retVal;
-}
-
-ProxyAccessible*
-ProxyAccessible::TableOfACell()
-{
-  uint64_t tableID = 0;
-  bool ok = false;
-  Unused << mDoc->SendTableOfACell(mID, &tableID, &ok);
-  return ok ? mDoc->GetAccessible(tableID) : nullptr;
-}
-
-uint32_t
-ProxyAccessible::ColIdx()
-{
-  uint32_t index = 0;
-  Unused << mDoc->SendColIdx(mID, &index);
-  return index;
-}
-
-uint32_t
-ProxyAccessible::RowIdx()
-{
-  uint32_t index = 0;
-  Unused << mDoc->SendRowIdx(mID, &index);
-  return index;
-}
-
-uint32_t
-ProxyAccessible::ColExtent()
-{
-  uint32_t extent = 0;
-  Unused << mDoc->SendColExtent(mID, &extent);
-  return extent;
-}
-
-uint32_t
-ProxyAccessible::RowExtent()
-{
-  uint32_t extent = 0;
-  Unused << mDoc->SendRowExtent(mID, &extent);
-  return extent;
-}
-
-void
-ProxyAccessible::ColHeaderCells(nsTArray<ProxyAccessible*>* aCells)
-{
-  nsTArray<uint64_t> targetIDs;
-  Unused << mDoc->SendColHeaderCells(mID, &targetIDs);
-
-  size_t targetCount = targetIDs.Length();
-  for (size_t i = 0; i < targetCount; i++) {
-    aCells->AppendElement(mDoc->GetAccessible(targetIDs[i]));
-  }
-}
-
-void
-ProxyAccessible::RowHeaderCells(nsTArray<ProxyAccessible*>* aCells)
-{
-  nsTArray<uint64_t> targetIDs;
-  Unused << mDoc->SendRowHeaderCells(mID, &targetIDs);
-
-  size_t targetCount = targetIDs.Length();
-  for (size_t i = 0; i < targetCount; i++) {
-    aCells->AppendElement(mDoc->GetAccessible(targetIDs[i]));
-  }
-}
-
-bool
-ProxyAccessible::IsCellSelected()
-{
-  bool selected = false;
-  Unused << mDoc->SendIsCellSelected(mID, &selected);
-  return selected;
-}
-
-ProxyAccessible*
-ProxyAccessible::TableCaption()
-{
-  uint64_t captionID = 0;
-  bool ok = false;
-  Unused << mDoc->SendTableCaption(mID, &captionID, &ok);
-  return ok ? mDoc->GetAccessible(captionID) : nullptr;
-}
-
-void
-ProxyAccessible::TableSummary(nsString& aSummary)
-{
-  Unused << mDoc->SendTableSummary(mID, &aSummary);
-}
-
-uint32_t
-ProxyAccessible::TableColumnCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendTableColumnCount(mID, &count);
-  return count;
-}
-
-uint32_t
-ProxyAccessible::TableRowCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendTableRowCount(mID, &count);
-  return count;
-}
-
-ProxyAccessible*
-ProxyAccessible::TableCellAt(uint32_t aRow, uint32_t aCol)
-{
-  uint64_t cellID = 0;
-  bool ok = false;
-  Unused << mDoc->SendTableCellAt(mID, aRow, aCol, &cellID, &ok);
-  return ok ? mDoc->GetAccessible(cellID) : nullptr;
-}
-
-int32_t
-ProxyAccessible::TableCellIndexAt(uint32_t aRow, uint32_t aCol)
-{
-  int32_t index = 0;
-  Unused << mDoc->SendTableCellIndexAt(mID, aRow, aCol, &index);
-  return index;
-}
-
-int32_t
-ProxyAccessible::TableColumnIndexAt(uint32_t aCellIndex)
-{
-  int32_t index = 0;
-  Unused << mDoc->SendTableColumnIndexAt(mID, aCellIndex, &index);
-  return index;
-}
-
-int32_t
-ProxyAccessible::TableRowIndexAt(uint32_t aCellIndex)
-{
-  int32_t index = 0;
-  Unused << mDoc->SendTableRowIndexAt(mID, aCellIndex, &index);
-  return index;
-}
-
-void
-ProxyAccessible::TableRowAndColumnIndicesAt(uint32_t aCellIndex,
-                                            int32_t* aRow, int32_t* aCol)
-{
-  Unused << mDoc->SendTableRowAndColumnIndicesAt(mID, aCellIndex, aRow, aCol);
-}
-
-uint32_t
-ProxyAccessible::TableColumnExtentAt(uint32_t aRow, uint32_t aCol)
-{
-  uint32_t extent = 0;
-  Unused << mDoc->SendTableColumnExtentAt(mID, aRow, aCol, &extent);
-  return extent;
-}
-
-uint32_t
-ProxyAccessible::TableRowExtentAt(uint32_t aRow, uint32_t aCol)
-{
-  uint32_t extent = 0;
-  Unused << mDoc->SendTableRowExtentAt(mID, aRow, aCol, &extent);
-  return extent;
-}
-
-void
-ProxyAccessible::TableColumnDescription(uint32_t aCol, nsString& aDescription)
-{
-  Unused << mDoc->SendTableColumnDescription(mID, aCol, &aDescription);
-}
-
-void
-ProxyAccessible::TableRowDescription(uint32_t aRow, nsString& aDescription)
-{
-  Unused << mDoc->SendTableRowDescription(mID, aRow, &aDescription);
-}
-
-bool
-ProxyAccessible::TableColumnSelected(uint32_t aCol)
-{
-  bool selected = false;
-  Unused << mDoc->SendTableColumnSelected(mID, aCol, &selected);
-  return selected;
-}
-
-bool
-ProxyAccessible::TableRowSelected(uint32_t aRow)
-{
-  bool selected = false;
-  Unused << mDoc->SendTableRowSelected(mID, aRow, &selected);
-  return selected;
-}
-
-bool
-ProxyAccessible::TableCellSelected(uint32_t aRow, uint32_t aCol)
-{
-  bool selected = false;
-  Unused << mDoc->SendTableCellSelected(mID, aRow, aCol, &selected);
-  return selected;
-}
-
-uint32_t
-ProxyAccessible::TableSelectedCellCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendTableSelectedCellCount(mID, &count);
-  return count;
-}
-
-uint32_t
-ProxyAccessible::TableSelectedColumnCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendTableSelectedColumnCount(mID, &count);
-  return count;
-}
-
-uint32_t
-ProxyAccessible::TableSelectedRowCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendTableSelectedRowCount(mID, &count);
-  return count;
-}
-
-void
-ProxyAccessible::TableSelectedCells(nsTArray<ProxyAccessible*>* aCellIDs)
-{
-  AutoTArray<uint64_t, 30> cellIDs;
-  Unused << mDoc->SendTableSelectedCells(mID, &cellIDs);
-  aCellIDs->SetCapacity(cellIDs.Length());
-  for (uint32_t i = 0; i < cellIDs.Length(); ++i) {
-    aCellIDs->AppendElement(mDoc->GetAccessible(cellIDs[i]));
-  }
-}
-
-void
-ProxyAccessible::TableSelectedCellIndices(nsTArray<uint32_t>* aCellIndices)
-{
-  Unused << mDoc->SendTableSelectedCellIndices(mID, aCellIndices);
-}
-
-void
-ProxyAccessible::TableSelectedColumnIndices(nsTArray<uint32_t>* aColumnIndices)
-{
-  Unused << mDoc->SendTableSelectedColumnIndices(mID, aColumnIndices);
-}
-
-void
-ProxyAccessible::TableSelectedRowIndices(nsTArray<uint32_t>* aRowIndices)
-{
-  Unused << mDoc->SendTableSelectedRowIndices(mID, aRowIndices);
-}
-
-void
-ProxyAccessible::TableSelectColumn(uint32_t aCol)
-{
-  Unused << mDoc->SendTableSelectColumn(mID, aCol);
-}
-
-void
-ProxyAccessible::TableSelectRow(uint32_t aRow)
-{
-  Unused << mDoc->SendTableSelectRow(mID, aRow);
-}
-
-void
-ProxyAccessible::TableUnselectColumn(uint32_t aCol)
-{
-  Unused << mDoc->SendTableUnselectColumn(mID, aCol);
-}
-
-void
-ProxyAccessible::TableUnselectRow(uint32_t aRow)
-{
-  Unused << mDoc->SendTableUnselectRow(mID, aRow);
-}
-
-bool
-ProxyAccessible::TableIsProbablyForLayout()
-{
-  bool forLayout = false;
-  Unused << mDoc->SendTableIsProbablyForLayout(mID, &forLayout);
-  return forLayout;
-}
-
-ProxyAccessible*
-ProxyAccessible::AtkTableColumnHeader(int32_t aCol)
-{
-  uint64_t headerID = 0;
-  bool ok = false;
-  Unused << mDoc->SendAtkTableColumnHeader(mID, aCol, &headerID, &ok);
-  return ok ? mDoc->GetAccessible(headerID) : nullptr;
-}
-
-ProxyAccessible*
-ProxyAccessible::AtkTableRowHeader(int32_t aRow)
-{
-  uint64_t headerID = 0;
-  bool ok = false;
-  Unused << mDoc->SendAtkTableRowHeader(mID, aRow, &headerID, &ok);
-  return ok ? mDoc->GetAccessible(headerID) : nullptr;
-}
-
-void
-ProxyAccessible::SelectedItems(nsTArray<ProxyAccessible*>* aSelectedItems)
-{
-  AutoTArray<uint64_t, 10> itemIDs;
-  Unused << mDoc->SendSelectedItems(mID, &itemIDs);
-  aSelectedItems->SetCapacity(itemIDs.Length());
-  for (size_t i = 0; i < itemIDs.Length(); ++i) {
-    aSelectedItems->AppendElement(mDoc->GetAccessible(itemIDs[i]));
-  }
-}
-
-uint32_t
-ProxyAccessible::SelectedItemCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendSelectedItemCount(mID, &count);
-  return count;
-}
-
-ProxyAccessible*
-ProxyAccessible::GetSelectedItem(uint32_t aIndex)
-{
-  uint64_t selectedItemID = 0;
-  bool ok = false;
-  Unused << mDoc->SendGetSelectedItem(mID, aIndex, &selectedItemID, &ok);
-  return ok ? mDoc->GetAccessible(selectedItemID) : nullptr;
-}
-
-bool
-ProxyAccessible::IsItemSelected(uint32_t aIndex)
-{
-  bool selected = false;
-  Unused << mDoc->SendIsItemSelected(mID, aIndex, &selected);
-  return selected;
-}
- 
-bool
-ProxyAccessible::AddItemToSelection(uint32_t aIndex)
-{
-  bool success = false;
-  Unused << mDoc->SendAddItemToSelection(mID, aIndex, &success);
-  return success;
-}
-
-bool
-ProxyAccessible::RemoveItemFromSelection(uint32_t aIndex)
-{
-  bool success = false;
-  Unused << mDoc->SendRemoveItemFromSelection(mID, aIndex, &success);
-  return success;
-}
-
-bool
-ProxyAccessible::SelectAll()
-{
-  bool success = false;
-  Unused << mDoc->SendSelectAll(mID, &success);
-  return success;
-}
-
-bool
-ProxyAccessible::UnselectAll()
-{
-  bool success = false;
-  Unused << mDoc->SendUnselectAll(mID, &success);
-  return success;
-}
-
-void
-ProxyAccessible::TakeSelection()
-{
-  Unused << mDoc->SendTakeSelection(mID);
-}
-
-void
-ProxyAccessible::SetSelected(bool aSelect)
-{
-  Unused << mDoc->SendSetSelected(mID, aSelect);
-}
-
-bool
-ProxyAccessible::DoAction(uint8_t aIndex)
-{
-  bool success = false;
-  Unused << mDoc->SendDoAction(mID, aIndex, &success);
-  return success;
-}
-
-uint8_t
-ProxyAccessible::ActionCount()
-{
-  uint8_t count = 0;
-  Unused << mDoc->SendActionCount(mID, &count);
-  return count;
-}
-
-void
-ProxyAccessible::ActionDescriptionAt(uint8_t aIndex, nsString& aDescription)
-{
-  Unused << mDoc->SendActionDescriptionAt(mID, aIndex, &aDescription);
-}
-
-void
-ProxyAccessible::ActionNameAt(uint8_t aIndex, nsString& aName)
-{
-  Unused << mDoc->SendActionNameAt(mID, aIndex, &aName);
-}
-
-KeyBinding
-ProxyAccessible::AccessKey()
-{
-  uint32_t key = 0;
-  uint32_t modifierMask = 0;
-  Unused << mDoc->SendAccessKey(mID, &key, &modifierMask);
-  return KeyBinding(key, modifierMask);
-}
-
-KeyBinding
-ProxyAccessible::KeyboardShortcut()
-{
-  uint32_t key = 0;
-  uint32_t modifierMask = 0;
-  Unused << mDoc->SendKeyboardShortcut(mID, &key, &modifierMask);
-  return KeyBinding(key, modifierMask);
-}
-
-void
-ProxyAccessible::AtkKeyBinding(nsString& aBinding)
-{
-  Unused << mDoc->SendAtkKeyBinding(mID, &aBinding);
-}
-
-double
-ProxyAccessible::CurValue()
-{
-  double val = UnspecifiedNaN<double>();
-  Unused << mDoc->SendCurValue(mID, &val);
-  return val;
-}
-
-bool
-ProxyAccessible::SetCurValue(double aValue)
-{
-  bool success = false;
-  Unused << mDoc->SendSetCurValue(mID, aValue, &success);
-  return success;
-}
-
-double
-ProxyAccessible::MinValue()
-{
-  double val = UnspecifiedNaN<double>();
-  Unused << mDoc->SendMinValue(mID, &val);
-  return val;
-}
-
-double
-ProxyAccessible::MaxValue()
-{
-  double val = UnspecifiedNaN<double>();
-  Unused << mDoc->SendMaxValue(mID, &val);
-  return val;
-}
-
-double
-ProxyAccessible::Step()
-{
-  double step = UnspecifiedNaN<double>();
-  Unused << mDoc->SendStep(mID, &step);
-  return step;
-}
-
-void
-ProxyAccessible::TakeFocus()
-{
-  Unused << mDoc->SendTakeFocus(mID);
-}
-
-uint32_t
-ProxyAccessible::EmbeddedChildCount() const
+ProxyAccessibleBase<Derived>::EmbeddedChildCount() const
 {
   size_t count = 0, kids = mChildren.Length();
   for (size_t i = 0; i < kids; i++) {
     if (mChildren[i]->IsEmbeddedObject()) {
       count++;
     }
   }
 
   return count;
 }
 
+template <class Derived>
 int32_t
-ProxyAccessible::IndexOfEmbeddedChild(const ProxyAccessible* aChild)
+ProxyAccessibleBase<Derived>::IndexOfEmbeddedChild(const Derived* aChild)
 {
   size_t index = 0, kids = mChildren.Length();
   for (size_t i = 0; i < kids; i++) {
     if (mChildren[i]->IsEmbeddedObject()) {
       if (mChildren[i] == aChild) {
         return index;
       }
 
       index++;
     }
   }
 
   return -1;
 }
 
-ProxyAccessible*
-ProxyAccessible::EmbeddedChildAt(size_t aChildIdx)
+template <class Derived>
+Derived*
+ProxyAccessibleBase<Derived>::EmbeddedChildAt(size_t aChildIdx)
 {
   size_t index = 0, kids = mChildren.Length();
   for (size_t i = 0; i < kids; i++) {
     if (!mChildren[i]->IsEmbeddedObject()) {
       continue;
     }
 
     if (index == aChildIdx) {
@@ -1076,117 +135,25 @@ ProxyAccessible::EmbeddedChildAt(size_t 
     }
 
     index++;
   }
 
   return nullptr;
 }
 
-ProxyAccessible*
-ProxyAccessible::FocusedChild()
-{
-  uint64_t childID = 0;
-  bool ok = false;
-  Unused << mDoc->SendFocusedChild(mID, &childID, &ok);
-  return ok ? mDoc->GetAccessible(childID) : nullptr;
-}
-
-ProxyAccessible*
-ProxyAccessible::ChildAtPoint(int32_t aX, int32_t aY,
-                              Accessible::EWhichChildAtPoint aWhichChild)
-{
-  uint64_t childID = 0;
-  bool ok = false;
-  Unused << mDoc->SendAccessibleAtPoint(mID, aX, aY, false,
-                                        static_cast<uint32_t>(aWhichChild),
-                                        &childID, &ok);
-  return ok ? mDoc->GetAccessible(childID) : nullptr;
-}
-
-nsIntRect
-ProxyAccessible::Bounds()
-{
-  nsIntRect rect;
-  Unused << mDoc->SendExtents(mID, false,
-                              &(rect.x), &(rect.y),
-                              &(rect.width), &(rect.height));
-  return rect;
-}
-
-void
-ProxyAccessible::Language(nsString& aLocale)
-{
-  Unused << mDoc->SendLanguage(mID, &aLocale);
-}
-
-void
-ProxyAccessible::DocType(nsString& aType)
-{
-  Unused << mDoc->SendDocType(mID, &aType);
-}
-
-void
-ProxyAccessible::Title(nsString& aTitle)
-{
-  Unused << mDoc->SendTitle(mID, &aTitle);
-}
-
-void
-ProxyAccessible::URL(nsString& aURL)
-{
-  Unused << mDoc->SendURL(mID, &aURL);
-}
-
-void
-ProxyAccessible::MimeType(nsString aMime)
-{
-  Unused << mDoc->SendMimeType(mID, &aMime);
-}
-
-void
-ProxyAccessible::URLDocTypeMimeType(nsString& aURL, nsString& aDocType,
-                                    nsString& aMimeType)
-{
-  Unused << mDoc->SendURLDocTypeMimeType(mID, &aURL, &aDocType, &aMimeType);
-}
-
-ProxyAccessible*
-ProxyAccessible::AccessibleAtPoint(int32_t aX, int32_t aY,
-                                   bool aNeedsScreenCoords)
-{
-  uint64_t childID = 0;
-  bool ok = false;
-  Unused <<
-    mDoc->SendAccessibleAtPoint(mID, aX, aY, aNeedsScreenCoords,
-                                static_cast<uint32_t>(Accessible::eDirectChild),
-                                &childID, &ok);
-  return ok ? mDoc->GetAccessible(childID) : nullptr;
-}
-
-void
-ProxyAccessible::Extents(bool aNeedsScreenCoords, int32_t* aX, int32_t* aY,
-                        int32_t* aWidth, int32_t* aHeight)
-{
-  Unused << mDoc->SendExtents(mID, aNeedsScreenCoords, aX, aY, aWidth, aHeight);
-}
-
-void
-ProxyAccessible::DOMNodeID(nsString& aID)
-{
-  Unused << mDoc->SendDOMNodeID(mID, &aID);
-}
-
+template <class Derived>
 Accessible*
-ProxyAccessible::OuterDocOfRemoteBrowser() const
+ProxyAccessibleBase<Derived>::OuterDocOfRemoteBrowser() const
 {
   auto tab = static_cast<dom::TabParent*>(mDoc->Manager());
   dom::Element* frame = tab->GetOwnerElement();
   NS_ASSERTION(frame, "why isn't the tab in a frame!");
   if (!frame)
     return nullptr;
 
   DocAccessible* chromeDoc = GetExistingDocAccessible(frame->OwnerDoc());
 
   return chromeDoc ? chromeDoc->GetAccessible(frame) : nullptr;
 }
-}
-}
+
+} // namespace a11y
+} // namespace mozilla
rename from accessible/ipc/ProxyAccessible.h
rename to accessible/ipc/ProxyAccessibleBase.h
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/ProxyAccessibleBase.h
@@ -1,109 +1,118 @@
 /* -*- 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/. */
 
-#ifndef mozilla_a11y_ProxyAccessible_h
-#define mozilla_a11y_ProxyAccessible_h
+#ifndef mozilla_a11y_ProxyAccessibleBase_h
+#define mozilla_a11y_ProxyAccessibleBase_h
 
 #include "mozilla/a11y/Role.h"
 #include "nsIAccessibleText.h"
 #include "nsIAccessibleTypes.h"
 #include "Accessible.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsRect.h"
 #include "Accessible.h"
 
 namespace mozilla {
 namespace a11y {
 
 class Accessible;
 class Attribute;
 class DocAccessibleParent;
+class ProxyAccessible;
 enum class RelationType;
 
 enum Interfaces
 {
   HYPERTEXT = 1,
   HYPERLINK = 1 << 1,
   IMAGE = 1 << 2,
   VALUE = 1 << 3,
   TABLE = 1 << 4,
   TABLECELL = 1 << 5,
   DOCUMENT = 1 << 6,
   SELECTION = 1 << 7,
   ACTION = 1 << 8,
 };
 
-class ProxyAccessible
+template <class Derived>
+class ProxyAccessibleBase
 {
 public:
+  ProxyAccessibleBase(uint64_t aID, Derived* aParent,
+                      DocAccessibleParent* aDoc, role aRole,
+                      uint32_t aInterfaces)
+    : mParent(aParent)
+    , mDoc(aDoc)
+    , mWrapper(0)
+    , mID(aID)
+    , mRole(aRole)
+    , mOuterDoc(false)
+    , mIsDoc(false)
+    , mHasValue(aInterfaces & Interfaces::VALUE)
+    , mIsHyperLink(aInterfaces & Interfaces::HYPERLINK)
+    , mIsHyperText(aInterfaces & Interfaces::HYPERTEXT)
+  {
+    MOZ_COUNT_CTOR(ProxyAccessibleBase);
+  }
 
-  ProxyAccessible(uint64_t aID, ProxyAccessible* aParent,
-                  DocAccessibleParent* aDoc, role aRole, uint32_t aInterfaces) :
-     mParent(aParent), mDoc(aDoc), mWrapper(0), mID(aID), mRole(aRole),
-     mOuterDoc(false), mIsDoc(false),
-     mHasValue(aInterfaces & Interfaces::VALUE),
-     mIsHyperLink(aInterfaces & Interfaces::HYPERLINK),
-     mIsHyperText(aInterfaces & Interfaces::HYPERTEXT)
+  ~ProxyAccessibleBase()
   {
-    MOZ_COUNT_CTOR(ProxyAccessible);
-  }
-  ~ProxyAccessible()
-  {
-    MOZ_COUNT_DTOR(ProxyAccessible);
+    MOZ_COUNT_DTOR(ProxyAccessibleBase);
     MOZ_ASSERT(!mWrapper);
   }
 
-  void AddChildAt(uint32_t aIdx, ProxyAccessible* aChild)
+  void AddChildAt(uint32_t aIdx, Derived* aChild)
   { mChildren.InsertElementAt(aIdx, aChild); }
 
   uint32_t ChildrenCount() const { return mChildren.Length(); }
-  ProxyAccessible* ChildAt(uint32_t aIdx) const { return mChildren[aIdx]; }
-  ProxyAccessible* FirstChild() const
+  Derived* ChildAt(uint32_t aIdx) const { return mChildren[aIdx]; }
+  Derived* FirstChild() const
     { return mChildren.Length() ? mChildren[0] : nullptr; }
-  ProxyAccessible* LastChild() const
+  Derived* LastChild() const
     { return mChildren.Length() ? mChildren[mChildren.Length() - 1] : nullptr; }
-  ProxyAccessible* PrevSibling() const
+  Derived* PrevSibling() const
   {
     size_t idx = IndexInParent();
     return idx > 0 ? Parent()->mChildren[idx - 1] : nullptr;
   }
-  ProxyAccessible* NextSibling() const
+  Derived* NextSibling() const
   {
     size_t idx = IndexInParent();
     return idx + 1 < Parent()->mChildren.Length() ? Parent()->mChildren[idx + 1]
     : nullptr;
   }
 
   // XXX evaluate if this is fast enough.
-  size_t IndexInParent() const { return Parent()->mChildren.IndexOf(this); }
+  size_t IndexInParent() const { return
+    Parent()->mChildren.IndexOf(static_cast<const Derived*>(this)); }
   uint32_t EmbeddedChildCount() const;
-  int32_t IndexOfEmbeddedChild(const ProxyAccessible*);
-  ProxyAccessible* EmbeddedChildAt(size_t aChildIdx);
+  int32_t IndexOfEmbeddedChild(const Derived* aChild);
+  Derived* EmbeddedChildAt(size_t aChildIdx);
   bool MustPruneChildren() const;
 
   void Shutdown();
 
   void SetChildDoc(DocAccessibleParent*);
 
   /**
    * Remove The given child.
    */
-  void RemoveChild(ProxyAccessible* aChild)
+  void RemoveChild(Derived* aChild)
     { mChildren.RemoveElement(aChild); }
 
   /**
    * Return the proxy for the parent of the wrapped accessible.
    */
-  ProxyAccessible* Parent() const { return mParent; }
+  Derived* Parent() const { return mParent; }
 
   Accessible* OuterDocOfRemoteBrowser() const;
 
   /**
    * Get the role of the accessible we're proxying.
    */
   role Role() const { return mRole; }
 
@@ -113,294 +122,16 @@ public:
   bool IsEmbeddedObject() const
   {
     role role = Role();
     return role != roles::TEXT_LEAF &&
            role != roles::WHITESPACE &&
            role != roles::STATICTEXT;
   }
 
-  /*
-   * Return the states for the proxied accessible.
-   */
-  uint64_t State() const;
-
-  /*
-   * Return the native states for the proxied accessible.
-   */
-  uint64_t NativeState() const;
-
-  /*
-   * Set aName to the name of the proxied accessible.
-   */
-  void Name(nsString& aName) const;
-
-  /*
-   * Set aValue to the value of the proxied accessible.
-   */
-  void Value(nsString& aValue) const;
-
-  /*
-   * Set aHelp to the help string of the proxied accessible.
-   */
-  void Help(nsString& aHelp) const;
-
-  /**
-   * Set aDesc to the description of the proxied accessible.
-   */
-  void Description(nsString& aDesc) const;
-
-  /**
-   * Get the set of attributes on the proxied accessible.
-   */
-  void Attributes(nsTArray<Attribute> *aAttrs) const;
-
-  /**
-   * Return set of targets of given relation type.
-   */
-  nsTArray<ProxyAccessible*> RelationByType(RelationType aType) const;
-
-  /**
-   * Get all relations for this accessible.
-   */
-  void Relations(nsTArray<RelationType>* aTypes,
-                 nsTArray<nsTArray<ProxyAccessible*>>* aTargetSets) const;
-
-  bool IsSearchbox() const;
-
-  nsIAtom* LandmarkRole() const;
-
-  nsIAtom* ARIARoleAtom() const;
-
-  int32_t GetLevelInternal();
-  void ScrollTo(uint32_t aScrollType);
-  void ScrollToPoint(uint32_t aScrollType, int32_t aX, int32_t aY);
-
-  int32_t CaretLineNumber();
-  int32_t CaretOffset();
-  void SetCaretOffset(int32_t aOffset);
-
-  int32_t CharacterCount();
-  int32_t SelectionCount();
-
-  /**
-   * Get the text between the given offsets.
-   */
-  bool TextSubstring(int32_t aStartOffset, int32_t aEndOfset,
-                     nsString& aText) const;
-
-  void GetTextAfterOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
-                          nsString& aText, int32_t* aStartOffset,
-                          int32_t* aEndOffset);
-
-  void GetTextAtOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
-                       nsString& aText, int32_t* aStartOffset,
-                       int32_t* aEndOffset);
-
-  void GetTextBeforeOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
-                           nsString& aText, int32_t* aStartOffset,
-                           int32_t* aEndOffset);
-
-  char16_t CharAt(int32_t aOffset);
-
-  void TextAttributes(bool aIncludeDefAttrs,
-                      const int32_t aOffset,
-                      nsTArray<Attribute>* aAttributes,
-                      int32_t* aStartOffset,
-                      int32_t* aEndOffset);
-  void DefaultTextAttributes(nsTArray<Attribute>* aAttrs);
-
-  nsIntRect TextBounds(int32_t aStartOffset, int32_t aEndOffset,
-                       uint32_t aCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE);
-
-  nsIntRect CharBounds(int32_t aOffset, uint32_t aCoordType);
-
-  int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType);
-
-  bool SelectionBoundsAt(int32_t aSelectionNum,
-                         nsString& aData,
-                         int32_t* aStartOffset,
-                         int32_t* aEndOffset);
-
-  bool SetSelectionBoundsAt(int32_t aSelectionNum,
-                            int32_t aStartOffset,
-                            int32_t aEndOffset);
-
-  bool AddToSelection(int32_t aStartOffset,
-                      int32_t aEndOffset);
-
-  bool RemoveFromSelection(int32_t aSelectionNum);
-
-  void ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
-                         uint32_t aScrollType);
-
-  void ScrollSubstringToPoint(int32_t aStartOffset,
-                              int32_t aEndOffset,
-                              uint32_t aCoordinateType,
-                              int32_t aX, int32_t aY);
-
-  void Text(nsString* aText);
-
-  void ReplaceText(const nsString& aText);
-
-  bool InsertText(const nsString& aText, int32_t aPosition);
-
-  bool CopyText(int32_t aStartPos, int32_t aEndPos);
-
-  bool CutText(int32_t aStartPos, int32_t aEndPos);
-
-  bool DeleteText(int32_t aStartPos, int32_t aEndPos);
-
-  bool PasteText(int32_t aPosition);
-
-  nsIntPoint ImagePosition(uint32_t aCoordType);
-
-  nsIntSize ImageSize();
-
-  uint32_t StartOffset(bool* aOk);
-
-  uint32_t EndOffset(bool* aOk);
-
-  bool IsLinkValid();
-
-  // XXX checking mRole alone may not result in same behavior as Accessibles
-  // due to ARIA roles. See bug 1210477.
-  inline bool IsTable() const
-  {
-    return mRole == roles::TABLE || mRole == roles::MATHML_TABLE;
-  }
-  inline bool IsTableRow() const
-  {
-    return (mRole == roles::ROW ||
-            mRole == roles::MATHML_TABLE_ROW ||
-            mRole == roles::MATHML_LABELED_ROW);
-  }
-  inline bool IsTableCell() const
-  {
-    return (mRole == roles::CELL ||
-            mRole == roles::COLUMNHEADER ||
-            mRole == roles::ROWHEADER ||
-            mRole == roles::GRID_CELL ||
-            mRole == roles::MATHML_CELL);
-  }
-
-  uint32_t AnchorCount(bool* aOk);
-
-  void AnchorURIAt(uint32_t aIndex, nsCString& aURI, bool* aOk);
-
-  ProxyAccessible* AnchorAt(uint32_t aIndex);
-
-  uint32_t LinkCount();
-
-  ProxyAccessible* LinkAt(const uint32_t& aIndex);
-
-  int32_t LinkIndexOf(ProxyAccessible* aLink);
-
-  int32_t LinkIndexAtOffset(uint32_t aOffset);
-
-  ProxyAccessible* TableOfACell();
-
-  uint32_t ColIdx();
-
-  uint32_t RowIdx();
-
-  uint32_t ColExtent();
-
-  uint32_t RowExtent();
-
-  void ColHeaderCells(nsTArray<ProxyAccessible*>* aCells);
-
-  void RowHeaderCells(nsTArray<ProxyAccessible*>* aCells);
-
-  bool IsCellSelected();
-
-  ProxyAccessible* TableCaption();
-  void TableSummary(nsString& aSummary);
-  uint32_t TableColumnCount();
-  uint32_t TableRowCount();
-  ProxyAccessible* TableCellAt(uint32_t aRow, uint32_t aCol);
-  int32_t TableCellIndexAt(uint32_t aRow, uint32_t aCol);
-  int32_t TableColumnIndexAt(uint32_t aCellIndex);
-  int32_t TableRowIndexAt(uint32_t aCellIndex);
-  void TableRowAndColumnIndicesAt(uint32_t aCellIndex,
-                                  int32_t* aRow, int32_t* aCol);
-  uint32_t TableColumnExtentAt(uint32_t aRow, uint32_t aCol);
-  uint32_t TableRowExtentAt(uint32_t aRow, uint32_t aCol);
-  void TableColumnDescription(uint32_t aCol, nsString& aDescription);
-  void TableRowDescription(uint32_t aRow, nsString& aDescription);
-  bool TableColumnSelected(uint32_t aCol);
-  bool TableRowSelected(uint32_t aRow);
-  bool TableCellSelected(uint32_t aRow, uint32_t aCol);
-  uint32_t TableSelectedCellCount();
-  uint32_t TableSelectedColumnCount();
-  uint32_t TableSelectedRowCount();
-  void TableSelectedCells(nsTArray<ProxyAccessible*>* aCellIDs);
-  void TableSelectedCellIndices(nsTArray<uint32_t>* aCellIndices);
-  void TableSelectedColumnIndices(nsTArray<uint32_t>* aColumnIndices);
-  void TableSelectedRowIndices(nsTArray<uint32_t>* aRowIndices);
-  void TableSelectColumn(uint32_t aCol);
-  void TableSelectRow(uint32_t aRow);
-  void TableUnselectColumn(uint32_t aCol);
-  void TableUnselectRow(uint32_t aRow);
-  bool TableIsProbablyForLayout();
-  ProxyAccessible* AtkTableColumnHeader(int32_t aCol);
-  ProxyAccessible* AtkTableRowHeader(int32_t aRow);
-
-  void SelectedItems(nsTArray<ProxyAccessible*>* aSelectedItems);
-  uint32_t SelectedItemCount();
-  ProxyAccessible* GetSelectedItem(uint32_t aIndex);
-  bool IsItemSelected(uint32_t aIndex);
-  bool AddItemToSelection(uint32_t aIndex);
-  bool RemoveItemFromSelection(uint32_t aIndex);
-  bool SelectAll();
-  bool UnselectAll();
-
-  void TakeSelection();
-  void SetSelected(bool aSelect);
-
-  bool DoAction(uint8_t aIndex);
-  uint8_t ActionCount();
-  void ActionDescriptionAt(uint8_t aIndex, nsString& aDescription);
-  void ActionNameAt(uint8_t aIndex, nsString& aName);
-  KeyBinding AccessKey();
-  KeyBinding KeyboardShortcut();
-  void AtkKeyBinding(nsString& aBinding);
-
-  double CurValue();
-  bool SetCurValue(double aValue);
-  double MinValue();
-  double MaxValue();
-  double Step();
-
-  void TakeFocus();
-  ProxyAccessible* FocusedChild();
-  ProxyAccessible* ChildAtPoint(int32_t aX, int32_t aY,
-                                Accessible::EWhichChildAtPoint aWhichChild);
-  nsIntRect Bounds();
-
-  void Language(nsString& aLocale);
-  void DocType(nsString& aType);
-  void Title(nsString& aTitle);
-  void URL(nsString& aURL);
-  void MimeType(nsString aMime);
-  void URLDocTypeMimeType(nsString& aURL, nsString& aDocType,
-                          nsString& aMimeType);
-
-  ProxyAccessible* AccessibleAtPoint(int32_t aX, int32_t aY,
-                                     bool aNeedsScreenCoords);
-
-  void Extents(bool aNeedsScreenCoords, int32_t* aX, int32_t* aY,
-               int32_t* aWidth, int32_t* aHeight);
-
-  /**
-   * Return the id of the dom node this accessible represents.  Note this
-   * should probably only be used for testing.
-   */
-  void DOMNodeID(nsString& aID);
-
   /**
    * Allow the platform to store a pointers worth of data on us.
    */
   uintptr_t GetWrapper() const { return mWrapper; }
   void SetWrapper(uintptr_t aWrapper) { mWrapper = aWrapper; }
 
   /*
    * Return the ID of the accessible being proxied.
@@ -414,35 +145,40 @@ public:
   DocAccessibleParent* Document() const { return mDoc; }
 
   /**
    * Return true if this proxy is a DocAccessibleParent.
    */
   bool IsDoc() const { return mIsDoc; }
   DocAccessibleParent* AsDoc() const { return IsDoc() ? mDoc : nullptr; }
 
+
 protected:
-  explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc) :
+  explicit ProxyAccessibleBase(DocAccessibleParent* aThisAsDoc) :
     mParent(nullptr), mDoc(aThisAsDoc), mWrapper(0), mID(0),
     mRole(roles::DOCUMENT), mOuterDoc(false), mIsDoc(true), mHasValue(false),
     mIsHyperLink(false), mIsHyperText(false)
-  { MOZ_COUNT_CTOR(ProxyAccessible); }
+  { MOZ_COUNT_CTOR(ProxyAccessibleBase); }
 
 protected:
-  ProxyAccessible* mParent;
+  Derived* mParent;
 
 private:
-  nsTArray<ProxyAccessible*> mChildren;
+  friend Derived;
+
+  nsTArray<Derived*> mChildren;
   DocAccessibleParent* mDoc;
   uintptr_t mWrapper;
   uint64_t mID;
+
 protected:
   // XXX DocAccessibleParent gets to change this to change the role of
   // documents.
   role mRole : 27;
+
 private:
   bool mOuterDoc : 1;
 
 public:
   const bool mIsDoc: 1;
   const bool mHasValue: 1;
   const bool mIsHyperLink: 1;
   const bool mIsHyperText: 1;
--- a/accessible/ipc/moz.build
+++ b/accessible/ipc/moz.build
@@ -17,23 +17,23 @@ if CONFIG['GNU_CXX']:
     CXXFLAGS += ['-Wno-error=shadow']
 
 # with --disable-accessibility we need to compile PDocAccessible.ipdl, but not
 # the C++.
 if CONFIG['ACCESSIBILITY']:
     EXPORTS.mozilla.a11y += [
         'DocAccessibleChildBase.h',
         'DocAccessibleParent.h',
-        'ProxyAccessible.h'
+        'ProxyAccessibleBase.h',
     ]
 
     UNIFIED_SOURCES += [
         'DocAccessibleChildBase.cpp',
         'DocAccessibleParent.cpp',
-        'ProxyAccessible.cpp'
+        'ProxyAccessibleBase.cpp',
     ]
 
     LOCAL_INCLUDES += [
         '/accessible/base',
         '/accessible/generic',
         '/accessible/xpcom',
     ]
 
copy from accessible/ipc/ProxyAccessible.cpp
copy to accessible/ipc/other/ProxyAccessible.cpp
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/other/ProxyAccessible.cpp
@@ -1,92 +1,29 @@
 /* -*- 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 "ProxyAccessible.h"
-#include "DocAccessibleParent.h"
+#include "mozilla/a11y/DocAccessibleParent.h"
 #include "DocAccessible.h"
 #include "mozilla/a11y/DocManager.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/unused.h"
 #include "mozilla/a11y/Platform.h"
 #include "RelationType.h"
 #include "mozilla/a11y/Role.h"
 #include "xpcAccessibleDocument.h"
 
 namespace mozilla {
 namespace a11y {
 
-void
-ProxyAccessible::Shutdown()
-{
-  MOZ_DIAGNOSTIC_ASSERT(!IsDoc());
-  NS_ASSERTION(!mOuterDoc, "Why do we still have a child doc?");
-  xpcAccessibleDocument* xpcDoc =
-    GetAccService()->GetCachedXPCDocument(Document());
-  if (xpcDoc) {
-    xpcDoc->NotifyOfShutdown(this);
-  }
-
-  // XXX Ideally  this wouldn't be necessary, but it seems OuterDoc accessibles
-  // can be destroyed before the doc they own.
-  if (!mOuterDoc) {
-    uint32_t childCount = mChildren.Length();
-    for (uint32_t idx = 0; idx < childCount; idx++)
-      mChildren[idx]->Shutdown();
-  } else {
-    if (mChildren.Length() != 1)
-      MOZ_CRASH("outer doc doesn't own adoc!");
-
-    mChildren[0]->AsDoc()->Unbind();
-  }
-
-  mChildren.Clear();
-  ProxyDestroyed(this);
-  mDoc->RemoveAccessible(this);
-}
-
-void
-ProxyAccessible::SetChildDoc(DocAccessibleParent* aParent)
-{
-  if (aParent) {
-    MOZ_ASSERT(mChildren.IsEmpty());
-    mChildren.AppendElement(aParent);
-    mOuterDoc = true;
-  } else {
-    MOZ_ASSERT(mChildren.Length() == 1);
-    mChildren.Clear();
-    mOuterDoc = false;
-  }
-}
-
-bool
-ProxyAccessible::MustPruneChildren() const
-{
-  // this is the equivalent to nsAccUtils::MustPrune for proxies and should be
-  // kept in sync with that.
-  if (mRole != roles::MENUITEM && mRole != roles::COMBOBOX_OPTION
-      && mRole != roles::OPTION && mRole != roles::ENTRY
-      && mRole != roles::FLAT_EQUATION && mRole != roles::PASSWORD_TEXT
-      && mRole != roles::PUSHBUTTON && mRole != roles::TOGGLE_BUTTON
-      && mRole != roles::GRAPHIC && mRole != roles::SLIDER
-      && mRole != roles::PROGRESSBAR && mRole != roles::SEPARATOR)
-    return false;
-
-  if (mChildren.Length() != 1)
-    return false;
-
-  return mChildren[0]->Role() == roles::TEXT_LEAF
-    || mChildren[0]->Role() == roles::STATICTEXT;
-}
-
 uint64_t
 ProxyAccessible::State() const
 {
   uint64_t state = 0;
   Unused << mDoc->SendState(mID, &state);
   return state;
 }
 
@@ -1027,65 +964,16 @@ ProxyAccessible::Step()
 }
 
 void
 ProxyAccessible::TakeFocus()
 {
   Unused << mDoc->SendTakeFocus(mID);
 }
 
-uint32_t
-ProxyAccessible::EmbeddedChildCount() const
-{
-  size_t count = 0, kids = mChildren.Length();
-  for (size_t i = 0; i < kids; i++) {
-    if (mChildren[i]->IsEmbeddedObject()) {
-      count++;
-    }
-  }
-
-  return count;
-}
-
-int32_t
-ProxyAccessible::IndexOfEmbeddedChild(const ProxyAccessible* aChild)
-{
-  size_t index = 0, kids = mChildren.Length();
-  for (size_t i = 0; i < kids; i++) {
-    if (mChildren[i]->IsEmbeddedObject()) {
-      if (mChildren[i] == aChild) {
-        return index;
-      }
-
-      index++;
-    }
-  }
-
-  return -1;
-}
-
-ProxyAccessible*
-ProxyAccessible::EmbeddedChildAt(size_t aChildIdx)
-{
-  size_t index = 0, kids = mChildren.Length();
-  for (size_t i = 0; i < kids; i++) {
-    if (!mChildren[i]->IsEmbeddedObject()) {
-      continue;
-    }
-
-    if (index == aChildIdx) {
-      return mChildren[i];
-    }
-
-    index++;
-  }
-
-  return nullptr;
-}
-
 ProxyAccessible*
 ProxyAccessible::FocusedChild()
 {
   uint64_t childID = 0;
   bool ok = false;
   Unused << mDoc->SendFocusedChild(mID, &childID, &ok);
   return ok ? mDoc->GetAccessible(childID) : nullptr;
 }
@@ -1170,23 +1058,10 @@ ProxyAccessible::Extents(bool aNeedsScre
 }
 
 void
 ProxyAccessible::DOMNodeID(nsString& aID)
 {
   Unused << mDoc->SendDOMNodeID(mID, &aID);
 }
 
-Accessible*
-ProxyAccessible::OuterDocOfRemoteBrowser() const
-{
-  auto tab = static_cast<dom::TabParent*>(mDoc->Manager());
-  dom::Element* frame = tab->GetOwnerElement();
-  NS_ASSERTION(frame, "why isn't the tab in a frame!");
-  if (!frame)
-    return nullptr;
-
-  DocAccessible* chromeDoc = GetExistingDocAccessible(frame->OwnerDoc());
-
-  return chromeDoc ? chromeDoc->GetAccessible(frame) : nullptr;
 }
 }
-}
copy from accessible/ipc/ProxyAccessible.h
copy to accessible/ipc/other/ProxyAccessible.h
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/other/ProxyAccessible.h
@@ -2,125 +2,43 @@
 /* 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_ProxyAccessible_h
 #define mozilla_a11y_ProxyAccessible_h
 
+#include "Accessible.h"
+#include "mozilla/a11y/ProxyAccessibleBase.h"
 #include "mozilla/a11y/Role.h"
 #include "nsIAccessibleText.h"
 #include "nsIAccessibleTypes.h"
-#include "Accessible.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsRect.h"
-#include "Accessible.h"
 
 namespace mozilla {
 namespace a11y {
 
-class Accessible;
-class Attribute;
-class DocAccessibleParent;
-enum class RelationType;
-
-enum Interfaces
-{
-  HYPERTEXT = 1,
-  HYPERLINK = 1 << 1,
-  IMAGE = 1 << 2,
-  VALUE = 1 << 3,
-  TABLE = 1 << 4,
-  TABLECELL = 1 << 5,
-  DOCUMENT = 1 << 6,
-  SELECTION = 1 << 7,
-  ACTION = 1 << 8,
-};
-
-class ProxyAccessible
+class ProxyAccessible : public ProxyAccessibleBase<ProxyAccessible>
 {
 public:
 
   ProxyAccessible(uint64_t aID, ProxyAccessible* aParent,
-                  DocAccessibleParent* aDoc, role aRole, uint32_t aInterfaces) :
-     mParent(aParent), mDoc(aDoc), mWrapper(0), mID(aID), mRole(aRole),
-     mOuterDoc(false), mIsDoc(false),
-     mHasValue(aInterfaces & Interfaces::VALUE),
-     mIsHyperLink(aInterfaces & Interfaces::HYPERLINK),
-     mIsHyperText(aInterfaces & Interfaces::HYPERTEXT)
-  {
-    MOZ_COUNT_CTOR(ProxyAccessible);
-  }
-  ~ProxyAccessible()
-  {
-    MOZ_COUNT_DTOR(ProxyAccessible);
-    MOZ_ASSERT(!mWrapper);
-  }
+                  DocAccessibleParent* aDoc, role aRole, uint32_t aInterfaces)
+    : ProxyAccessibleBase(aID, aParent, aDoc, aRole, aInterfaces)
 
-  void AddChildAt(uint32_t aIdx, ProxyAccessible* aChild)
-  { mChildren.InsertElementAt(aIdx, aChild); }
-
-  uint32_t ChildrenCount() const { return mChildren.Length(); }
-  ProxyAccessible* ChildAt(uint32_t aIdx) const { return mChildren[aIdx]; }
-  ProxyAccessible* FirstChild() const
-    { return mChildren.Length() ? mChildren[0] : nullptr; }
-  ProxyAccessible* LastChild() const
-    { return mChildren.Length() ? mChildren[mChildren.Length() - 1] : nullptr; }
-  ProxyAccessible* PrevSibling() const
   {
-    size_t idx = IndexInParent();
-    return idx > 0 ? Parent()->mChildren[idx - 1] : nullptr;
-  }
-  ProxyAccessible* NextSibling() const
-  {
-    size_t idx = IndexInParent();
-    return idx + 1 < Parent()->mChildren.Length() ? Parent()->mChildren[idx + 1]
-    : nullptr;
+    MOZ_COUNT_CTOR_INHERITED(ProxyAccessible, ProxyAccessibleBase);
   }
 
-  // XXX evaluate if this is fast enough.
-  size_t IndexInParent() const { return Parent()->mChildren.IndexOf(this); }
-  uint32_t EmbeddedChildCount() const;
-  int32_t IndexOfEmbeddedChild(const ProxyAccessible*);
-  ProxyAccessible* EmbeddedChildAt(size_t aChildIdx);
-  bool MustPruneChildren() const;
-
-  void Shutdown();
-
-  void SetChildDoc(DocAccessibleParent*);
-
-  /**
-   * Remove The given child.
-   */
-  void RemoveChild(ProxyAccessible* aChild)
-    { mChildren.RemoveElement(aChild); }
-
-  /**
-   * Return the proxy for the parent of the wrapped accessible.
-   */
-  ProxyAccessible* Parent() const { return mParent; }
-
-  Accessible* OuterDocOfRemoteBrowser() const;
-
-  /**
-   * Get the role of the accessible we're proxying.
-   */
-  role Role() const { return mRole; }
-
-  /**
-   * Return true if this is an embedded object.
-   */
-  bool IsEmbeddedObject() const
+  ~ProxyAccessible()
   {
-    role role = Role();
-    return role != roles::TEXT_LEAF &&
-           role != roles::WHITESPACE &&
-           role != roles::STATICTEXT;
+    MOZ_COUNT_DTOR_INHERITED(ProxyAccessible, ProxyAccessibleBase);
   }
 
   /*
    * Return the states for the proxied accessible.
    */
   uint64_t State() const;
 
   /*
@@ -391,64 +309,18 @@ public:
                int32_t* aWidth, int32_t* aHeight);
 
   /**
    * Return the id of the dom node this accessible represents.  Note this
    * should probably only be used for testing.
    */
   void DOMNodeID(nsString& aID);
 
-  /**
-   * Allow the platform to store a pointers worth of data on us.
-   */
-  uintptr_t GetWrapper() const { return mWrapper; }
-  void SetWrapper(uintptr_t aWrapper) { mWrapper = aWrapper; }
-
-  /*
-   * Return the ID of the accessible being proxied.
-   */
-  uint64_t ID() const { return mID; }
-
-  /**
-   * Return the document containing this proxy, or the proxy itself if it is a
-   * document.
-   */
-  DocAccessibleParent* Document() const { return mDoc; }
-
-  /**
-   * Return true if this proxy is a DocAccessibleParent.
-   */
-  bool IsDoc() const { return mIsDoc; }
-  DocAccessibleParent* AsDoc() const { return IsDoc() ? mDoc : nullptr; }
-
 protected:
-  explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc) :
-    mParent(nullptr), mDoc(aThisAsDoc), mWrapper(0), mID(0),
-    mRole(roles::DOCUMENT), mOuterDoc(false), mIsDoc(true), mHasValue(false),
-    mIsHyperLink(false), mIsHyperText(false)
+  explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc)
+    : ProxyAccessibleBase(aThisAsDoc)
   { MOZ_COUNT_CTOR(ProxyAccessible); }
-
-protected:
-  ProxyAccessible* mParent;
-
-private:
-  nsTArray<ProxyAccessible*> mChildren;
-  DocAccessibleParent* mDoc;
-  uintptr_t mWrapper;
-  uint64_t mID;
-protected:
-  // XXX DocAccessibleParent gets to change this to change the role of
-  // documents.
-  role mRole : 27;
-private:
-  bool mOuterDoc : 1;
-
-public:
-  const bool mIsDoc: 1;
-  const bool mHasValue: 1;
-  const bool mIsHyperLink: 1;
-  const bool mIsHyperText: 1;
 };
 
 }
 }
 
 #endif
--- a/accessible/ipc/other/moz.build
+++ b/accessible/ipc/other/moz.build
@@ -6,22 +6,22 @@
 
 IPDL_SOURCES += ['PDocAccessible.ipdl']
 
 # with --disable-accessibility we need to compile PDocAccessible.ipdl, but not
 # the C++.
 if CONFIG['ACCESSIBILITY']:
     EXPORTS.mozilla.a11y += [
         'DocAccessibleChild.h',
-        'ProxyAccessible.h'
+        'ProxyAccessible.h',
     ]
 
     SOURCES += [
         'DocAccessibleChild.cpp',
-        'ProxyAccessible.cpp'
+        'ProxyAccessible.cpp',
     ]
 
     LOCAL_INCLUDES += [
         '../../base',
         '../../generic',
         '../../xpcom',
     ]
 
copy from accessible/ipc/ProxyAccessible.cpp
copy to accessible/ipc/win/ProxyAccessible.cpp
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/win/ProxyAccessible.cpp
@@ -1,1192 +1,280 @@
 /* -*- 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 "Accessible2.h"
 #include "ProxyAccessible.h"
-#include "DocAccessibleParent.h"
+#include "mozilla/a11y/DocAccessibleParent.h"
 #include "DocAccessible.h"
 #include "mozilla/a11y/DocManager.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/unused.h"
 #include "mozilla/a11y/Platform.h"
 #include "RelationType.h"
 #include "mozilla/a11y/Role.h"
 #include "xpcAccessibleDocument.h"
 
+#include <comutil.h>
+
 namespace mozilla {
 namespace a11y {
 
-void
-ProxyAccessible::Shutdown()
+bool
+ProxyAccessible::GetCOMInterface(void** aOutAccessible) const
 {
-  MOZ_DIAGNOSTIC_ASSERT(!IsDoc());
-  NS_ASSERTION(!mOuterDoc, "Why do we still have a child doc?");
-  xpcAccessibleDocument* xpcDoc =
-    GetAccService()->GetCachedXPCDocument(Document());
-  if (xpcDoc) {
-    xpcDoc->NotifyOfShutdown(this);
+  if (!aOutAccessible) {
+    return false;
+  }
+  RefPtr<IAccessible> addRefed = mCOMProxy;
+  addRefed.forget(aOutAccessible);
+  return !!mCOMProxy;
+}
+
+void
+ProxyAccessible::Name(nsString& aName) const
+{
+  aName.Truncate();
+  RefPtr<IAccessible> acc;
+  if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+    return;
   }
 
-  // XXX Ideally  this wouldn't be necessary, but it seems OuterDoc accessibles
-  // can be destroyed before the doc they own.
-  if (!mOuterDoc) {
-    uint32_t childCount = mChildren.Length();
-    for (uint32_t idx = 0; idx < childCount; idx++)
-      mChildren[idx]->Shutdown();
-  } else {
-    if (mChildren.Length() != 1)
-      MOZ_CRASH("outer doc doesn't own adoc!");
-
-    mChildren[0]->AsDoc()->Unbind();
+  VARIANT id;
+  id.vt = VT_I4;
+  id.lVal = CHILDID_SELF;
+  BSTR result;
+  HRESULT hr = acc->get_accName(id, &result);
+  _bstr_t resultWrap(result, false);
+  if (FAILED(hr)) {
+    return;
   }
-
-  mChildren.Clear();
-  ProxyDestroyed(this);
-  mDoc->RemoveAccessible(this);
+  aName = (wchar_t*)resultWrap;
 }
 
 void
-ProxyAccessible::SetChildDoc(DocAccessibleParent* aParent)
+ProxyAccessible::Value(nsString& aValue) const
 {
-  if (aParent) {
-    MOZ_ASSERT(mChildren.IsEmpty());
-    mChildren.AppendElement(aParent);
-    mOuterDoc = true;
-  } else {
-    MOZ_ASSERT(mChildren.Length() == 1);
-    mChildren.Clear();
-    mOuterDoc = false;
+  aValue.Truncate();
+  RefPtr<IAccessible> acc;
+  if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+    return;
   }
+
+  VARIANT id;
+  id.vt = VT_I4;
+  id.lVal = CHILDID_SELF;
+  BSTR result;
+  HRESULT hr = acc->get_accValue(id, &result);
+  _bstr_t resultWrap(result, false);
+  if (FAILED(hr)) {
+    return;
+  }
+  aValue = (wchar_t*)resultWrap;
 }
 
-bool
-ProxyAccessible::MustPruneChildren() const
+void
+ProxyAccessible::Description(nsString& aDesc) const
 {
-  // this is the equivalent to nsAccUtils::MustPrune for proxies and should be
-  // kept in sync with that.
-  if (mRole != roles::MENUITEM && mRole != roles::COMBOBOX_OPTION
-      && mRole != roles::OPTION && mRole != roles::ENTRY
-      && mRole != roles::FLAT_EQUATION && mRole != roles::PASSWORD_TEXT
-      && mRole != roles::PUSHBUTTON && mRole != roles::TOGGLE_BUTTON
-      && mRole != roles::GRAPHIC && mRole != roles::SLIDER
-      && mRole != roles::PROGRESSBAR && mRole != roles::SEPARATOR)
-    return false;
+  aDesc.Truncate();
+  RefPtr<IAccessible> acc;
+  if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+    return;
+  }
 
-  if (mChildren.Length() != 1)
-    return false;
-
-  return mChildren[0]->Role() == roles::TEXT_LEAF
-    || mChildren[0]->Role() == roles::STATICTEXT;
+  VARIANT id;
+  id.vt = VT_I4;
+  id.lVal = CHILDID_SELF;
+  BSTR result;
+  HRESULT hr = acc->get_accDescription(id, &result);
+  _bstr_t resultWrap(result, false);
+  if (FAILED(hr)) {
+    return;
+  }
+  aDesc = (wchar_t*)resultWrap;
 }
 
 uint64_t
 ProxyAccessible::State() const
 {
   uint64_t state = 0;
-  Unused << mDoc->SendState(mID, &state);
-  return state;
-}
-
-uint64_t
-ProxyAccessible::NativeState() const
-{
-  uint64_t state = 0;
-  Unused << mDoc->SendNativeState(mID, &state);
-  return state;
-}
-
-void
-ProxyAccessible::Name(nsString& aName) const
-{
-  Unused << mDoc->SendName(mID, &aName);
-}
-
-void
-ProxyAccessible::Value(nsString& aValue) const
-{
-  Unused << mDoc->SendValue(mID, &aValue);
-}
-
-void
-ProxyAccessible::Help(nsString& aHelp) const
-{
-  Unused << mDoc->SendHelp(mID, &aHelp);
-}
-
-void
-ProxyAccessible::Description(nsString& aDesc) const
-{
-  Unused << mDoc->SendDescription(mID, &aDesc);
-}
-
-void
-ProxyAccessible::Attributes(nsTArray<Attribute> *aAttrs) const
-{
-  Unused << mDoc->SendAttributes(mID, aAttrs);
-}
-
-nsTArray<ProxyAccessible*>
-ProxyAccessible::RelationByType(RelationType aType) const
-{
-  nsTArray<uint64_t> targetIDs;
-  Unused << mDoc->SendRelationByType(mID, static_cast<uint32_t>(aType),
-                                     &targetIDs);
-
-  size_t targetCount = targetIDs.Length();
-  nsTArray<ProxyAccessible*> targets(targetCount);
-  for (size_t i = 0; i < targetCount; i++)
-    if (ProxyAccessible* proxy = mDoc->GetAccessible(targetIDs[i]))
-      targets.AppendElement(proxy);
-
-  return Move(targets);
-}
-
-void
-ProxyAccessible::Relations(nsTArray<RelationType>* aTypes,
-                           nsTArray<nsTArray<ProxyAccessible*>>* aTargetSets)
-  const
-{
-  nsTArray<RelationTargets> ipcRelations;
-  Unused << mDoc->SendRelations(mID, &ipcRelations);
-
-  size_t relationCount = ipcRelations.Length();
-  aTypes->SetCapacity(relationCount);
-  aTargetSets->SetCapacity(relationCount);
-  for (size_t i = 0; i < relationCount; i++) {
-    uint32_t type = ipcRelations[i].Type();
-    if (type > static_cast<uint32_t>(RelationType::LAST))
-      continue;
-
-    size_t targetCount = ipcRelations[i].Targets().Length();
-    nsTArray<ProxyAccessible*> targets(targetCount);
-    for (size_t j = 0; j < targetCount; j++)
-      if (ProxyAccessible* proxy = mDoc->GetAccessible(ipcRelations[i].Targets()[j]))
-        targets.AppendElement(proxy);
-
-    if (targets.IsEmpty())
-      continue;
-
-    aTargetSets->AppendElement(Move(targets));
-    aTypes->AppendElement(static_cast<RelationType>(type));
-  }
-}
-
-bool
-ProxyAccessible::IsSearchbox() const
-{
-  bool retVal = false;
-  Unused << mDoc->SendIsSearchbox(mID, &retVal);
-  return retVal;
-}
-
-nsIAtom*
-ProxyAccessible::LandmarkRole() const
-{
-  nsString landmark;
-  Unused << mDoc->SendLandmarkRole(mID, &landmark);
-  return NS_GetStaticAtom(landmark);
-}
-
-nsIAtom*
-ProxyAccessible::ARIARoleAtom() const
-{
-  nsString role;
-  Unused << mDoc->SendARIARoleAtom(mID, &role);
-  return NS_GetStaticAtom(role);
-}
-
-int32_t
-ProxyAccessible::GetLevelInternal()
-{
-  int32_t level = 0;
-  Unused << mDoc->SendGetLevelInternal(mID, &level);
-  return level;
-}
-
-void
-ProxyAccessible::ScrollTo(uint32_t aScrollType)
-{
-  Unused << mDoc->SendScrollTo(mID, aScrollType);
-}
-
-void
-ProxyAccessible::ScrollToPoint(uint32_t aScrollType, int32_t aX, int32_t aY)
-{
-  Unused << mDoc->SendScrollToPoint(mID, aScrollType, aX, aY);
-}
-
-int32_t
-ProxyAccessible::CaretLineNumber()
-{
-  int32_t line = -1;
-  Unused << mDoc->SendCaretOffset(mID, &line);
-  return line;
-}
-
-int32_t
-ProxyAccessible::CaretOffset()
-{
-  int32_t offset = 0;
-  Unused << mDoc->SendCaretOffset(mID, &offset);
-  return offset;
-}
-
-void
-ProxyAccessible::SetCaretOffset(int32_t aOffset)
-{
-  Unused << mDoc->SendSetCaretOffset(mID, aOffset);
-}
-
-int32_t
-ProxyAccessible::CharacterCount()
-{
-  int32_t count = 0;
-  Unused << mDoc->SendCharacterCount(mID, &count);
-  return count;
-}
-
-int32_t
-ProxyAccessible::SelectionCount()
-{
-  int32_t count = 0;
-  Unused << mDoc->SendSelectionCount(mID, &count);
-  return count;
-}
-
-bool
-ProxyAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOfset,
-                               nsString& aText) const
-{
-  bool valid;
-  Unused << mDoc->SendTextSubstring(mID, aStartOffset, aEndOfset, &aText, &valid);
-  return valid;
-}
-
-void
-ProxyAccessible::GetTextAfterOffset(int32_t aOffset,
-                                    AccessibleTextBoundary aBoundaryType,
-                                    nsString& aText, int32_t* aStartOffset,
-                                    int32_t* aEndOffset)
-{
-  Unused << mDoc->SendGetTextAfterOffset(mID, aOffset, aBoundaryType,
-                                         &aText, aStartOffset, aEndOffset);
-}
-
-void
-ProxyAccessible::GetTextAtOffset(int32_t aOffset,
-                                 AccessibleTextBoundary aBoundaryType,
-                                 nsString& aText, int32_t* aStartOffset,
-                                 int32_t* aEndOffset)
-{
-  Unused << mDoc->SendGetTextAtOffset(mID, aOffset, aBoundaryType,
-                                      &aText, aStartOffset, aEndOffset);
-}
-
-void
-ProxyAccessible::GetTextBeforeOffset(int32_t aOffset,
-                                     AccessibleTextBoundary aBoundaryType,
-                                     nsString& aText, int32_t* aStartOffset,
-                                     int32_t* aEndOffset)
-{
-  Unused << mDoc->SendGetTextBeforeOffset(mID, aOffset, aBoundaryType,
-                                          &aText, aStartOffset, aEndOffset);
-}
-
-char16_t
-ProxyAccessible::CharAt(int32_t aOffset)
-{
-  uint16_t retval = 0;
-  Unused << mDoc->SendCharAt(mID, aOffset, &retval);
-  return static_cast<char16_t>(retval);
-}
-
-void
-ProxyAccessible::TextAttributes(bool aIncludeDefAttrs,
-                                int32_t aOffset,
-                                nsTArray<Attribute>* aAttributes,
-                                int32_t* aStartOffset,
-                                int32_t* aEndOffset)
-{
-  Unused << mDoc->SendTextAttributes(mID, aIncludeDefAttrs, aOffset,
-                                     aAttributes, aStartOffset, aEndOffset);
-}
-
-void
-ProxyAccessible::DefaultTextAttributes(nsTArray<Attribute>* aAttrs)
-{
-  Unused << mDoc->SendDefaultTextAttributes(mID, aAttrs);
-}
-
-nsIntRect
-ProxyAccessible::TextBounds(int32_t aStartOffset, int32_t aEndOffset,
-                            uint32_t aCoordType)
-{
-  nsIntRect rect;
-  Unused <<
-    mDoc->SendTextBounds(mID, aStartOffset, aEndOffset, aCoordType, &rect);
-  return rect;
-}
-
-nsIntRect
-ProxyAccessible::CharBounds(int32_t aOffset, uint32_t aCoordType)
-{
-  nsIntRect rect;
-  Unused <<
-    mDoc->SendCharBounds(mID, aOffset, aCoordType, &rect);
-  return rect;
-}
-
-int32_t
-ProxyAccessible::OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType)
-{
-  int32_t retVal = -1;
-  Unused << mDoc->SendOffsetAtPoint(mID, aX, aY, aCoordType, &retVal);
-  return retVal;
-}
-
-bool
-ProxyAccessible::SelectionBoundsAt(int32_t aSelectionNum,
-                                   nsString& aData,
-                                   int32_t* aStartOffset,
-                                   int32_t* aEndOffset)
-{
-  bool retVal = false;
-  Unused << mDoc->SendSelectionBoundsAt(mID, aSelectionNum, &retVal, &aData,
-                                        aStartOffset, aEndOffset);
-  return retVal;
-}
-
-bool
-ProxyAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
-                                      int32_t aStartOffset,
-                                      int32_t aEndOffset)
-{
-  bool retVal = false;
-  Unused << mDoc->SendSetSelectionBoundsAt(mID, aSelectionNum, aStartOffset,
-                                           aEndOffset, &retVal);
-  return retVal;
-}
-
-bool
-ProxyAccessible::AddToSelection(int32_t aStartOffset,
-                                int32_t aEndOffset)
-{
-  bool retVal = false;
-  Unused << mDoc->SendAddToSelection(mID, aStartOffset, aEndOffset, &retVal);
-  return retVal;
-}
-
-bool
-ProxyAccessible::RemoveFromSelection(int32_t aSelectionNum)
-{
-  bool retVal = false;
-  Unused << mDoc->SendRemoveFromSelection(mID, aSelectionNum, &retVal);
-  return retVal;
-}
-
-void
-ProxyAccessible::ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
-                                   uint32_t aScrollType)
-{
-  Unused << mDoc->SendScrollSubstringTo(mID, aStartOffset, aEndOffset, aScrollType);
-}
-
-void
-ProxyAccessible::ScrollSubstringToPoint(int32_t aStartOffset,
-                                        int32_t aEndOffset,
-                                        uint32_t aCoordinateType,
-                                        int32_t aX, int32_t aY)
-{
-  Unused << mDoc->SendScrollSubstringToPoint(mID, aStartOffset, aEndOffset,
-                                             aCoordinateType, aX, aY);
-}
-
-void
-ProxyAccessible::Text(nsString* aText)
-{
-  Unused << mDoc->SendText(mID, aText);
-}
-
-void
-ProxyAccessible::ReplaceText(const nsString& aText)
-{
-  Unused << mDoc->SendReplaceText(mID, aText);
-}
-
-bool
-ProxyAccessible::InsertText(const nsString& aText, int32_t aPosition)
-{
-  bool valid;
-  Unused << mDoc->SendInsertText(mID, aText, aPosition, &valid);
-  return valid;
-}
-
-bool
-ProxyAccessible::CopyText(int32_t aStartPos, int32_t aEndPos)
-{
-  bool valid;
-  Unused << mDoc->SendCopyText(mID, aStartPos, aEndPos, &valid);
-  return valid;
-}
-
-bool
-ProxyAccessible::CutText(int32_t aStartPos, int32_t aEndPos)
-{
-  bool valid;
-  Unused << mDoc->SendCutText(mID, aStartPos, aEndPos, &valid);
-  return valid;
-}
-
-bool
-ProxyAccessible::DeleteText(int32_t aStartPos, int32_t aEndPos)
-{
-  bool valid;
-  Unused << mDoc->SendDeleteText(mID, aStartPos, aEndPos, &valid);
-  return valid;
-}
-
-bool
-ProxyAccessible::PasteText(int32_t aPosition)
-{
-  bool valid;
-  Unused << mDoc->SendPasteText(mID, aPosition, &valid);
-  return valid;
-}
-
-nsIntPoint
-ProxyAccessible::ImagePosition(uint32_t aCoordType)
-{
-  nsIntPoint retVal;
-  Unused << mDoc->SendImagePosition(mID, aCoordType, &retVal);
-  return retVal;
-}
-
-nsIntSize
-ProxyAccessible::ImageSize()
-{
-  nsIntSize retVal;
-  Unused << mDoc->SendImageSize(mID, &retVal);
-  return retVal;
-}
-
-uint32_t
-ProxyAccessible::StartOffset(bool* aOk)
-{
-  uint32_t retVal = 0;
-  Unused << mDoc->SendStartOffset(mID, &retVal, aOk);
-  return retVal;
-}
-
-uint32_t
-ProxyAccessible::EndOffset(bool* aOk)
-{
-  uint32_t retVal = 0;
-  Unused << mDoc->SendEndOffset(mID, &retVal, aOk);
-  return retVal;
-}
-
-bool
-ProxyAccessible::IsLinkValid()
-{
-  bool retVal = false;
-  Unused << mDoc->SendIsLinkValid(mID, &retVal);
-  return retVal;
-}
-
-uint32_t
-ProxyAccessible::AnchorCount(bool* aOk)
-{
-  uint32_t retVal = 0;
-  Unused << mDoc->SendAnchorCount(mID, &retVal, aOk);
-  return retVal;
-}
-
-void
-ProxyAccessible::AnchorURIAt(uint32_t aIndex, nsCString& aURI, bool* aOk)
-{
-  Unused << mDoc->SendAnchorURIAt(mID, aIndex, &aURI, aOk);
-}
-
-ProxyAccessible*
-ProxyAccessible::AnchorAt(uint32_t aIndex)
-{
-  uint64_t id = 0;
-  bool ok = false;
-  Unused << mDoc->SendAnchorAt(mID, aIndex, &id, &ok);
-  return ok ? mDoc->GetAccessible(id) : nullptr;
-}
-
-uint32_t
-ProxyAccessible::LinkCount()
-{
-  uint32_t retVal = 0;
-  Unused << mDoc->SendLinkCount(mID, &retVal);
-  return retVal;
-}
-
-ProxyAccessible*
-ProxyAccessible::LinkAt(const uint32_t& aIndex)
-{
-  uint64_t linkID = 0;
-  bool ok = false;
-  Unused << mDoc->SendLinkAt(mID, aIndex, &linkID, &ok);
-  return ok ? mDoc->GetAccessible(linkID) : nullptr;
-}
-
-int32_t
-ProxyAccessible::LinkIndexOf(ProxyAccessible* aLink)
-{
-  int32_t retVal = -1;
-  if (aLink) {
-    Unused << mDoc->SendLinkIndexOf(mID, aLink->ID(), &retVal);
+  RefPtr<IAccessible> acc;
+  if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+    return state;
   }
 
-  return retVal;
-}
-
-int32_t
-ProxyAccessible::LinkIndexAtOffset(uint32_t aOffset)
-{
-  int32_t retVal = -1;
-  Unused << mDoc->SendLinkIndexAtOffset(mID, aOffset, &retVal);
-  return retVal;
-}
-
-ProxyAccessible*
-ProxyAccessible::TableOfACell()
-{
-  uint64_t tableID = 0;
-  bool ok = false;
-  Unused << mDoc->SendTableOfACell(mID, &tableID, &ok);
-  return ok ? mDoc->GetAccessible(tableID) : nullptr;
-}
-
-uint32_t
-ProxyAccessible::ColIdx()
-{
-  uint32_t index = 0;
-  Unused << mDoc->SendColIdx(mID, &index);
-  return index;
-}
-
-uint32_t
-ProxyAccessible::RowIdx()
-{
-  uint32_t index = 0;
-  Unused << mDoc->SendRowIdx(mID, &index);
-  return index;
-}
-
-uint32_t
-ProxyAccessible::ColExtent()
-{
-  uint32_t extent = 0;
-  Unused << mDoc->SendColExtent(mID, &extent);
-  return extent;
-}
-
-uint32_t
-ProxyAccessible::RowExtent()
-{
-  uint32_t extent = 0;
-  Unused << mDoc->SendRowExtent(mID, &extent);
-  return extent;
-}
-
-void
-ProxyAccessible::ColHeaderCells(nsTArray<ProxyAccessible*>* aCells)
-{
-  nsTArray<uint64_t> targetIDs;
-  Unused << mDoc->SendColHeaderCells(mID, &targetIDs);
-
-  size_t targetCount = targetIDs.Length();
-  for (size_t i = 0; i < targetCount; i++) {
-    aCells->AppendElement(mDoc->GetAccessible(targetIDs[i]));
-  }
-}
-
-void
-ProxyAccessible::RowHeaderCells(nsTArray<ProxyAccessible*>* aCells)
-{
-  nsTArray<uint64_t> targetIDs;
-  Unused << mDoc->SendRowHeaderCells(mID, &targetIDs);
-
-  size_t targetCount = targetIDs.Length();
-  for (size_t i = 0; i < targetCount; i++) {
-    aCells->AppendElement(mDoc->GetAccessible(targetIDs[i]));
-  }
-}
-
-bool
-ProxyAccessible::IsCellSelected()
-{
-  bool selected = false;
-  Unused << mDoc->SendIsCellSelected(mID, &selected);
-  return selected;
-}
-
-ProxyAccessible*
-ProxyAccessible::TableCaption()
-{
-  uint64_t captionID = 0;
-  bool ok = false;
-  Unused << mDoc->SendTableCaption(mID, &captionID, &ok);
-  return ok ? mDoc->GetAccessible(captionID) : nullptr;
-}
-
-void
-ProxyAccessible::TableSummary(nsString& aSummary)
-{
-  Unused << mDoc->SendTableSummary(mID, &aSummary);
-}
-
-uint32_t
-ProxyAccessible::TableColumnCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendTableColumnCount(mID, &count);
-  return count;
-}
-
-uint32_t
-ProxyAccessible::TableRowCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendTableRowCount(mID, &count);
-  return count;
-}
-
-ProxyAccessible*
-ProxyAccessible::TableCellAt(uint32_t aRow, uint32_t aCol)
-{
-  uint64_t cellID = 0;
-  bool ok = false;
-  Unused << mDoc->SendTableCellAt(mID, aRow, aCol, &cellID, &ok);
-  return ok ? mDoc->GetAccessible(cellID) : nullptr;
-}
-
-int32_t
-ProxyAccessible::TableCellIndexAt(uint32_t aRow, uint32_t aCol)
-{
-  int32_t index = 0;
-  Unused << mDoc->SendTableCellIndexAt(mID, aRow, aCol, &index);
-  return index;
-}
-
-int32_t
-ProxyAccessible::TableColumnIndexAt(uint32_t aCellIndex)
-{
-  int32_t index = 0;
-  Unused << mDoc->SendTableColumnIndexAt(mID, aCellIndex, &index);
-  return index;
-}
-
-int32_t
-ProxyAccessible::TableRowIndexAt(uint32_t aCellIndex)
-{
-  int32_t index = 0;
-  Unused << mDoc->SendTableRowIndexAt(mID, aCellIndex, &index);
-  return index;
-}
-
-void
-ProxyAccessible::TableRowAndColumnIndicesAt(uint32_t aCellIndex,
-                                            int32_t* aRow, int32_t* aCol)
-{
-  Unused << mDoc->SendTableRowAndColumnIndicesAt(mID, aCellIndex, aRow, aCol);
-}
-
-uint32_t
-ProxyAccessible::TableColumnExtentAt(uint32_t aRow, uint32_t aCol)
-{
-  uint32_t extent = 0;
-  Unused << mDoc->SendTableColumnExtentAt(mID, aRow, aCol, &extent);
-  return extent;
-}
-
-uint32_t
-ProxyAccessible::TableRowExtentAt(uint32_t aRow, uint32_t aCol)
-{
-  uint32_t extent = 0;
-  Unused << mDoc->SendTableRowExtentAt(mID, aRow, aCol, &extent);
-  return extent;
-}
-
-void
-ProxyAccessible::TableColumnDescription(uint32_t aCol, nsString& aDescription)
-{
-  Unused << mDoc->SendTableColumnDescription(mID, aCol, &aDescription);
-}
-
-void
-ProxyAccessible::TableRowDescription(uint32_t aRow, nsString& aDescription)
-{
-  Unused << mDoc->SendTableRowDescription(mID, aRow, &aDescription);
-}
-
-bool
-ProxyAccessible::TableColumnSelected(uint32_t aCol)
-{
-  bool selected = false;
-  Unused << mDoc->SendTableColumnSelected(mID, aCol, &selected);
-  return selected;
-}
-
-bool
-ProxyAccessible::TableRowSelected(uint32_t aRow)
-{
-  bool selected = false;
-  Unused << mDoc->SendTableRowSelected(mID, aRow, &selected);
-  return selected;
-}
-
-bool
-ProxyAccessible::TableCellSelected(uint32_t aRow, uint32_t aCol)
-{
-  bool selected = false;
-  Unused << mDoc->SendTableCellSelected(mID, aRow, aCol, &selected);
-  return selected;
-}
-
-uint32_t
-ProxyAccessible::TableSelectedCellCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendTableSelectedCellCount(mID, &count);
-  return count;
-}
-
-uint32_t
-ProxyAccessible::TableSelectedColumnCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendTableSelectedColumnCount(mID, &count);
-  return count;
-}
-
-uint32_t
-ProxyAccessible::TableSelectedRowCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendTableSelectedRowCount(mID, &count);
-  return count;
-}
-
-void
-ProxyAccessible::TableSelectedCells(nsTArray<ProxyAccessible*>* aCellIDs)
-{
-  AutoTArray<uint64_t, 30> cellIDs;
-  Unused << mDoc->SendTableSelectedCells(mID, &cellIDs);
-  aCellIDs->SetCapacity(cellIDs.Length());
-  for (uint32_t i = 0; i < cellIDs.Length(); ++i) {
-    aCellIDs->AppendElement(mDoc->GetAccessible(cellIDs[i]));
+  VARIANT id;
+  id.vt = VT_I4;
+  id.lVal = CHILDID_SELF;
+  VARIANT varState;
+  HRESULT hr = acc->get_accState(id, &varState);
+  if (FAILED(hr)) {
+    return state;
   }
-}
-
-void
-ProxyAccessible::TableSelectedCellIndices(nsTArray<uint32_t>* aCellIndices)
-{
-  Unused << mDoc->SendTableSelectedCellIndices(mID, aCellIndices);
-}
-
-void
-ProxyAccessible::TableSelectedColumnIndices(nsTArray<uint32_t>* aColumnIndices)
-{
-  Unused << mDoc->SendTableSelectedColumnIndices(mID, aColumnIndices);
-}
-
-void
-ProxyAccessible::TableSelectedRowIndices(nsTArray<uint32_t>* aRowIndices)
-{
-  Unused << mDoc->SendTableSelectedRowIndices(mID, aRowIndices);
-}
-
-void
-ProxyAccessible::TableSelectColumn(uint32_t aCol)
-{
-  Unused << mDoc->SendTableSelectColumn(mID, aCol);
-}
-
-void
-ProxyAccessible::TableSelectRow(uint32_t aRow)
-{
-  Unused << mDoc->SendTableSelectRow(mID, aRow);
-}
-
-void
-ProxyAccessible::TableUnselectColumn(uint32_t aCol)
-{
-  Unused << mDoc->SendTableUnselectColumn(mID, aCol);
-}
-
-void
-ProxyAccessible::TableUnselectRow(uint32_t aRow)
-{
-  Unused << mDoc->SendTableUnselectRow(mID, aRow);
-}
-
-bool
-ProxyAccessible::TableIsProbablyForLayout()
-{
-  bool forLayout = false;
-  Unused << mDoc->SendTableIsProbablyForLayout(mID, &forLayout);
-  return forLayout;
-}
-
-ProxyAccessible*
-ProxyAccessible::AtkTableColumnHeader(int32_t aCol)
-{
-  uint64_t headerID = 0;
-  bool ok = false;
-  Unused << mDoc->SendAtkTableColumnHeader(mID, aCol, &headerID, &ok);
-  return ok ? mDoc->GetAccessible(headerID) : nullptr;
-}
-
-ProxyAccessible*
-ProxyAccessible::AtkTableRowHeader(int32_t aRow)
-{
-  uint64_t headerID = 0;
-  bool ok = false;
-  Unused << mDoc->SendAtkTableRowHeader(mID, aRow, &headerID, &ok);
-  return ok ? mDoc->GetAccessible(headerID) : nullptr;
-}
-
-void
-ProxyAccessible::SelectedItems(nsTArray<ProxyAccessible*>* aSelectedItems)
-{
-  AutoTArray<uint64_t, 10> itemIDs;
-  Unused << mDoc->SendSelectedItems(mID, &itemIDs);
-  aSelectedItems->SetCapacity(itemIDs.Length());
-  for (size_t i = 0; i < itemIDs.Length(); ++i) {
-    aSelectedItems->AppendElement(mDoc->GetAccessible(itemIDs[i]));
-  }
-}
-
-uint32_t
-ProxyAccessible::SelectedItemCount()
-{
-  uint32_t count = 0;
-  Unused << mDoc->SendSelectedItemCount(mID, &count);
-  return count;
-}
-
-ProxyAccessible*
-ProxyAccessible::GetSelectedItem(uint32_t aIndex)
-{
-  uint64_t selectedItemID = 0;
-  bool ok = false;
-  Unused << mDoc->SendGetSelectedItem(mID, aIndex, &selectedItemID, &ok);
-  return ok ? mDoc->GetAccessible(selectedItemID) : nullptr;
-}
-
-bool
-ProxyAccessible::IsItemSelected(uint32_t aIndex)
-{
-  bool selected = false;
-  Unused << mDoc->SendIsItemSelected(mID, aIndex, &selected);
-  return selected;
-}
- 
-bool
-ProxyAccessible::AddItemToSelection(uint32_t aIndex)
-{
-  bool success = false;
-  Unused << mDoc->SendAddItemToSelection(mID, aIndex, &success);
-  return success;
-}
-
-bool
-ProxyAccessible::RemoveItemFromSelection(uint32_t aIndex)
-{
-  bool success = false;
-  Unused << mDoc->SendRemoveItemFromSelection(mID, aIndex, &success);
-  return success;
-}
-
-bool
-ProxyAccessible::SelectAll()
-{
-  bool success = false;
-  Unused << mDoc->SendSelectAll(mID, &success);
-  return success;
-}
-
-bool
-ProxyAccessible::UnselectAll()
-{
-  bool success = false;
-  Unused << mDoc->SendUnselectAll(mID, &success);
-  return success;
-}
-
-void
-ProxyAccessible::TakeSelection()
-{
-  Unused << mDoc->SendTakeSelection(mID);
-}
-
-void
-ProxyAccessible::SetSelected(bool aSelect)
-{
-  Unused << mDoc->SendSetSelected(mID, aSelect);
-}
-
-bool
-ProxyAccessible::DoAction(uint8_t aIndex)
-{
-  bool success = false;
-  Unused << mDoc->SendDoAction(mID, aIndex, &success);
-  return success;
-}
-
-uint8_t
-ProxyAccessible::ActionCount()
-{
-  uint8_t count = 0;
-  Unused << mDoc->SendActionCount(mID, &count);
-  return count;
-}
-
-void
-ProxyAccessible::ActionDescriptionAt(uint8_t aIndex, nsString& aDescription)
-{
-  Unused << mDoc->SendActionDescriptionAt(mID, aIndex, &aDescription);
-}
-
-void
-ProxyAccessible::ActionNameAt(uint8_t aIndex, nsString& aName)
-{
-  Unused << mDoc->SendActionNameAt(mID, aIndex, &aName);
-}
-
-KeyBinding
-ProxyAccessible::AccessKey()
-{
-  uint32_t key = 0;
-  uint32_t modifierMask = 0;
-  Unused << mDoc->SendAccessKey(mID, &key, &modifierMask);
-  return KeyBinding(key, modifierMask);
-}
-
-KeyBinding
-ProxyAccessible::KeyboardShortcut()
-{
-  uint32_t key = 0;
-  uint32_t modifierMask = 0;
-  Unused << mDoc->SendKeyboardShortcut(mID, &key, &modifierMask);
-  return KeyBinding(key, modifierMask);
-}
-
-void
-ProxyAccessible::AtkKeyBinding(nsString& aBinding)
-{
-  Unused << mDoc->SendAtkKeyBinding(mID, &aBinding);
-}
-
-double
-ProxyAccessible::CurValue()
-{
-  double val = UnspecifiedNaN<double>();
-  Unused << mDoc->SendCurValue(mID, &val);
-  return val;
-}
-
-bool
-ProxyAccessible::SetCurValue(double aValue)
-{
-  bool success = false;
-  Unused << mDoc->SendSetCurValue(mID, aValue, &success);
-  return success;
-}
-
-double
-ProxyAccessible::MinValue()
-{
-  double val = UnspecifiedNaN<double>();
-  Unused << mDoc->SendMinValue(mID, &val);
-  return val;
-}
-
-double
-ProxyAccessible::MaxValue()
-{
-  double val = UnspecifiedNaN<double>();
-  Unused << mDoc->SendMaxValue(mID, &val);
-  return val;
-}
-
-double
-ProxyAccessible::Step()
-{
-  double step = UnspecifiedNaN<double>();
-  Unused << mDoc->SendStep(mID, &step);
-  return step;
-}
-
-void
-ProxyAccessible::TakeFocus()
-{
-  Unused << mDoc->SendTakeFocus(mID);
-}
-
-uint32_t
-ProxyAccessible::EmbeddedChildCount() const
-{
-  size_t count = 0, kids = mChildren.Length();
-  for (size_t i = 0; i < kids; i++) {
-    if (mChildren[i]->IsEmbeddedObject()) {
-      count++;
-    }
-  }
-
-  return count;
-}
-
-int32_t
-ProxyAccessible::IndexOfEmbeddedChild(const ProxyAccessible* aChild)
-{
-  size_t index = 0, kids = mChildren.Length();
-  for (size_t i = 0; i < kids; i++) {
-    if (mChildren[i]->IsEmbeddedObject()) {
-      if (mChildren[i] == aChild) {
-        return index;
-      }
-
-      index++;
-    }
-  }
-
-  return -1;
-}
-
-ProxyAccessible*
-ProxyAccessible::EmbeddedChildAt(size_t aChildIdx)
-{
-  size_t index = 0, kids = mChildren.Length();
-  for (size_t i = 0; i < kids; i++) {
-    if (!mChildren[i]->IsEmbeddedObject()) {
-      continue;
-    }
-
-    if (index == aChildIdx) {
-      return mChildren[i];
-    }
-
-    index++;
-  }
-
-  return nullptr;
-}
-
-ProxyAccessible*
-ProxyAccessible::FocusedChild()
-{
-  uint64_t childID = 0;
-  bool ok = false;
-  Unused << mDoc->SendFocusedChild(mID, &childID, &ok);
-  return ok ? mDoc->GetAccessible(childID) : nullptr;
-}
-
-ProxyAccessible*
-ProxyAccessible::ChildAtPoint(int32_t aX, int32_t aY,
-                              Accessible::EWhichChildAtPoint aWhichChild)
-{
-  uint64_t childID = 0;
-  bool ok = false;
-  Unused << mDoc->SendAccessibleAtPoint(mID, aX, aY, false,
-                                        static_cast<uint32_t>(aWhichChild),
-                                        &childID, &ok);
-  return ok ? mDoc->GetAccessible(childID) : nullptr;
+  return uint64_t(varState.lVal);
 }
 
 nsIntRect
 ProxyAccessible::Bounds()
 {
   nsIntRect rect;
-  Unused << mDoc->SendExtents(mID, false,
-                              &(rect.x), &(rect.y),
-                              &(rect.width), &(rect.height));
+
+  RefPtr<IAccessible> acc;
+  if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+    return rect;
+  }
+
+  long left;
+  long top;
+  long width;
+  long height;
+  VARIANT id;
+  id.vt = VT_I4;
+  id.lVal = CHILDID_SELF;
+  HRESULT hr = acc->accLocation(&left, &top, &width, &height, id);
+  if (FAILED(hr)) {
+    return rect;
+  }
+  rect.x = left;
+  rect.y = top;
+  rect.width = width;
+  rect.height = height;
   return rect;
 }
 
 void
 ProxyAccessible::Language(nsString& aLocale)
 {
-  Unused << mDoc->SendLanguage(mID, &aLocale);
+  aLocale.Truncate();
+
+  RefPtr<IAccessible> acc;
+  if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+    return;
+  }
+
+  RefPtr<IAccessible2> acc2;
+  if (FAILED(acc->QueryInterface(IID_IAccessible2, (void**)getter_AddRefs(acc2)))) {
+    return;
+  }
+
+  IA2Locale locale;
+  HRESULT hr = acc2->get_locale(&locale);
+
+  _bstr_t langWrap(locale.language, false);
+  _bstr_t countryWrap(locale.country, false);
+  _bstr_t variantWrap(locale.variant, false);
+
+  if (FAILED(hr)) {
+    return;
+  }
+
+  // The remaining code should essentially be the inverse of the
+  // ia2Accessible::get_locale conversion to IA2Locale.
+
+  if (!!variantWrap) {
+    aLocale = (wchar_t*)variantWrap;
+    return;
+  }
+
+  if (!!langWrap) {
+    aLocale = (wchar_t*)langWrap;
+    if (!!countryWrap) {
+      aLocale += L"-";
+      aLocale += (wchar_t*)countryWrap;
+    }
+  }
 }
 
-void
-ProxyAccessible::DocType(nsString& aType)
+static bool
+IsEscapedChar(const wchar_t c)
 {
-  Unused << mDoc->SendDocType(mID, &aType);
+  return c == L'\\' || c == L':' || c == ',' || c == '=' || c == ';';
 }
 
-void
-ProxyAccessible::Title(nsString& aTitle)
+static bool
+ConvertBSTRAttributesToArray(const nsAString& aStr,
+                             nsTArray<Attribute>* aAttrs)
 {
-  Unused << mDoc->SendTitle(mID, &aTitle);
-}
+  if (!aAttrs) {
+    return false;
+  }
+
+  enum
+  {
+    eName = 0,
+    eValue = 1,
+    eNumStates
+  } state;
+  nsAutoString tokens[eNumStates];
+  auto itr = aStr.BeginReading(), end = aStr.EndReading();
 
-void
-ProxyAccessible::URL(nsString& aURL)
-{
-  Unused << mDoc->SendURL(mID, &aURL);
-}
-
-void
-ProxyAccessible::MimeType(nsString aMime)
-{
-  Unused << mDoc->SendMimeType(mID, &aMime);
+  state = eName;
+  while (itr != end) {
+    switch (*itr) {
+      case L'\\':
+        // Skip the backslash so that we're looking at the escaped char
+        ++itr;
+        if (itr == end || !IsEscapedChar(*itr)) {
+          // Invalid state
+          return false;
+        }
+        break;
+      case L':':
+        if (state != eName) {
+          // Bad, should be looking at name
+          return false;
+        }
+        state = eValue;
+        ++itr;
+        continue;
+      case L';':
+        if (state != eValue) {
+          // Bad, should be looking at value
+          return false;
+        }
+        state = eName;
+        aAttrs->AppendElement(Attribute(NS_ConvertUTF16toUTF8(tokens[eName]),
+                                        tokens[eValue]));
+        tokens[eName].Truncate();
+        tokens[eValue].Truncate();
+        ++itr;
+        continue;
+      default:
+        break;
+    }
+    tokens[state] += *itr;
+  }
+  return true;
 }
 
 void
-ProxyAccessible::URLDocTypeMimeType(nsString& aURL, nsString& aDocType,
-                                    nsString& aMimeType)
+ProxyAccessible::Attributes(nsTArray<Attribute>* aAttrs) const
 {
-  Unused << mDoc->SendURLDocTypeMimeType(mID, &aURL, &aDocType, &aMimeType);
-}
+  aAttrs->Clear();
+
+  RefPtr<IAccessible> acc;
+  if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+    return;
+  }
 
-ProxyAccessible*
-ProxyAccessible::AccessibleAtPoint(int32_t aX, int32_t aY,
-                                   bool aNeedsScreenCoords)
-{
-  uint64_t childID = 0;
-  bool ok = false;
-  Unused <<
-    mDoc->SendAccessibleAtPoint(mID, aX, aY, aNeedsScreenCoords,
-                                static_cast<uint32_t>(Accessible::eDirectChild),
-                                &childID, &ok);
-  return ok ? mDoc->GetAccessible(childID) : nullptr;
+  RefPtr<IAccessible2> acc2;
+  if (FAILED(acc->QueryInterface(IID_IAccessible2, (void**)getter_AddRefs(acc2)))) {
+    return;
+  }
+
+  BSTR attrs;
+  HRESULT hr = acc2->get_attributes(&attrs);
+  _bstr_t attrsWrap(attrs, false);
+  if (FAILED(hr)) {
+    return;
+  }
+
+  ConvertBSTRAttributesToArray(nsDependentString((wchar_t*)attrs,
+                                                 attrsWrap.length()),
+                               aAttrs);
 }
 
-void
-ProxyAccessible::Extents(bool aNeedsScreenCoords, int32_t* aX, int32_t* aY,
-                        int32_t* aWidth, int32_t* aHeight)
-{
-  Unused << mDoc->SendExtents(mID, aNeedsScreenCoords, aX, aY, aWidth, aHeight);
-}
-
-void
-ProxyAccessible::DOMNodeID(nsString& aID)
-{
-  Unused << mDoc->SendDOMNodeID(mID, &aID);
-}
-
-Accessible*
-ProxyAccessible::OuterDocOfRemoteBrowser() const
-{
-  auto tab = static_cast<dom::TabParent*>(mDoc->Manager());
-  dom::Element* frame = tab->GetOwnerElement();
-  NS_ASSERTION(frame, "why isn't the tab in a frame!");
-  if (!frame)
-    return nullptr;
-
-  DocAccessible* chromeDoc = GetExistingDocAccessible(frame->OwnerDoc());
-
-  return chromeDoc ? chromeDoc->GetAccessible(frame) : nullptr;
-}
-}
-}
+} // namespace a11y
+} // namespace mozilla
copy from accessible/ipc/ProxyAccessible.h
copy to accessible/ipc/win/ProxyAccessible.h
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/win/ProxyAccessible.h
@@ -2,453 +2,87 @@
 /* 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_ProxyAccessible_h
 #define mozilla_a11y_ProxyAccessible_h
 
+#include "Accessible.h"
+#include "mozilla/a11y/ProxyAccessibleBase.h"
 #include "mozilla/a11y/Role.h"
 #include "nsIAccessibleText.h"
 #include "nsIAccessibleTypes.h"
-#include "Accessible.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsRect.h"
-#include "Accessible.h"
+
+#include <oleacc.h>
 
 namespace mozilla {
 namespace a11y {
 
-class Accessible;
-class Attribute;
-class DocAccessibleParent;
-enum class RelationType;
-
-enum Interfaces
-{
-  HYPERTEXT = 1,
-  HYPERLINK = 1 << 1,
-  IMAGE = 1 << 2,
-  VALUE = 1 << 3,
-  TABLE = 1 << 4,
-  TABLECELL = 1 << 5,
-  DOCUMENT = 1 << 6,
-  SELECTION = 1 << 7,
-  ACTION = 1 << 8,
-};
-
-class ProxyAccessible
+class ProxyAccessible : public ProxyAccessibleBase<ProxyAccessible>
 {
 public:
+  ProxyAccessible(uint64_t aID, ProxyAccessible* aParent,
+                  DocAccessibleParent* aDoc, role aRole, uint32_t aInterfaces,
+                  const RefPtr<IAccessible>& aIAccessible)
+    : ProxyAccessibleBase(aID, aParent, aDoc, aRole, aInterfaces)
+    , mCOMProxy(aIAccessible)
 
-  ProxyAccessible(uint64_t aID, ProxyAccessible* aParent,
-                  DocAccessibleParent* aDoc, role aRole, uint32_t aInterfaces) :
-     mParent(aParent), mDoc(aDoc), mWrapper(0), mID(aID), mRole(aRole),
-     mOuterDoc(false), mIsDoc(false),
-     mHasValue(aInterfaces & Interfaces::VALUE),
-     mIsHyperLink(aInterfaces & Interfaces::HYPERLINK),
-     mIsHyperText(aInterfaces & Interfaces::HYPERTEXT)
   {
-    MOZ_COUNT_CTOR(ProxyAccessible);
-  }
-  ~ProxyAccessible()
-  {
-    MOZ_COUNT_DTOR(ProxyAccessible);
-    MOZ_ASSERT(!mWrapper);
+    MOZ_COUNT_CTOR_INHERITED(ProxyAccessible, ProxyAccessibleBase);
   }
 
-  void AddChildAt(uint32_t aIdx, ProxyAccessible* aChild)
-  { mChildren.InsertElementAt(aIdx, aChild); }
-
-  uint32_t ChildrenCount() const { return mChildren.Length(); }
-  ProxyAccessible* ChildAt(uint32_t aIdx) const { return mChildren[aIdx]; }
-  ProxyAccessible* FirstChild() const
-    { return mChildren.Length() ? mChildren[0] : nullptr; }
-  ProxyAccessible* LastChild() const
-    { return mChildren.Length() ? mChildren[mChildren.Length() - 1] : nullptr; }
-  ProxyAccessible* PrevSibling() const
-  {
-    size_t idx = IndexInParent();
-    return idx > 0 ? Parent()->mChildren[idx - 1] : nullptr;
-  }
-  ProxyAccessible* NextSibling() const
+  ~ProxyAccessible()
   {
-    size_t idx = IndexInParent();
-    return idx + 1 < Parent()->mChildren.Length() ? Parent()->mChildren[idx + 1]
-    : nullptr;
-  }
-
-  // XXX evaluate if this is fast enough.
-  size_t IndexInParent() const { return Parent()->mChildren.IndexOf(this); }
-  uint32_t EmbeddedChildCount() const;
-  int32_t IndexOfEmbeddedChild(const ProxyAccessible*);
-  ProxyAccessible* EmbeddedChildAt(size_t aChildIdx);
-  bool MustPruneChildren() const;
-
-  void Shutdown();
-
-  void SetChildDoc(DocAccessibleParent*);
-
-  /**
-   * Remove The given child.
-   */
-  void RemoveChild(ProxyAccessible* aChild)
-    { mChildren.RemoveElement(aChild); }
-
-  /**
-   * Return the proxy for the parent of the wrapped accessible.
-   */
-  ProxyAccessible* Parent() const { return mParent; }
-
-  Accessible* OuterDocOfRemoteBrowser() const;
-
-  /**
-   * Get the role of the accessible we're proxying.
-   */
-  role Role() const { return mRole; }
-
-  /**
-   * Return true if this is an embedded object.
-   */
-  bool IsEmbeddedObject() const
-  {
-    role role = Role();
-    return role != roles::TEXT_LEAF &&
-           role != roles::WHITESPACE &&
-           role != roles::STATICTEXT;
+    MOZ_COUNT_DTOR_INHERITED(ProxyAccessible, ProxyAccessibleBase);
   }
 
   /*
    * Return the states for the proxied accessible.
    */
   uint64_t State() const;
 
   /*
-   * Return the native states for the proxied accessible.
-   */
-  uint64_t NativeState() const;
-
-  /*
    * Set aName to the name of the proxied accessible.
    */
   void Name(nsString& aName) const;
 
   /*
    * Set aValue to the value of the proxied accessible.
    */
   void Value(nsString& aValue) const;
 
-  /*
-   * Set aHelp to the help string of the proxied accessible.
-   */
-  void Help(nsString& aHelp) const;
-
   /**
    * Set aDesc to the description of the proxied accessible.
    */
   void Description(nsString& aDesc) const;
 
   /**
    * Get the set of attributes on the proxied accessible.
    */
   void Attributes(nsTArray<Attribute> *aAttrs) const;
 
-  /**
-   * Return set of targets of given relation type.
-   */
-  nsTArray<ProxyAccessible*> RelationByType(RelationType aType) const;
-
-  /**
-   * Get all relations for this accessible.
-   */
-  void Relations(nsTArray<RelationType>* aTypes,
-                 nsTArray<nsTArray<ProxyAccessible*>>* aTargetSets) const;
-
-  bool IsSearchbox() const;
-
-  nsIAtom* LandmarkRole() const;
-
-  nsIAtom* ARIARoleAtom() const;
-
-  int32_t GetLevelInternal();
-  void ScrollTo(uint32_t aScrollType);
-  void ScrollToPoint(uint32_t aScrollType, int32_t aX, int32_t aY);
-
-  int32_t CaretLineNumber();
-  int32_t CaretOffset();
-  void SetCaretOffset(int32_t aOffset);
-
-  int32_t CharacterCount();
-  int32_t SelectionCount();
-
-  /**
-   * Get the text between the given offsets.
-   */
-  bool TextSubstring(int32_t aStartOffset, int32_t aEndOfset,
-                     nsString& aText) const;
-
-  void GetTextAfterOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
-                          nsString& aText, int32_t* aStartOffset,
-                          int32_t* aEndOffset);
-
-  void GetTextAtOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
-                       nsString& aText, int32_t* aStartOffset,
-                       int32_t* aEndOffset);
-
-  void GetTextBeforeOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
-                           nsString& aText, int32_t* aStartOffset,
-                           int32_t* aEndOffset);
-
-  char16_t CharAt(int32_t aOffset);
-
-  void TextAttributes(bool aIncludeDefAttrs,
-                      const int32_t aOffset,
-                      nsTArray<Attribute>* aAttributes,
-                      int32_t* aStartOffset,
-                      int32_t* aEndOffset);
-  void DefaultTextAttributes(nsTArray<Attribute>* aAttrs);
-
-  nsIntRect TextBounds(int32_t aStartOffset, int32_t aEndOffset,
-                       uint32_t aCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE);
-
-  nsIntRect CharBounds(int32_t aOffset, uint32_t aCoordType);
-
-  int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType);
-
-  bool SelectionBoundsAt(int32_t aSelectionNum,
-                         nsString& aData,
-                         int32_t* aStartOffset,
-                         int32_t* aEndOffset);
-
-  bool SetSelectionBoundsAt(int32_t aSelectionNum,
-                            int32_t aStartOffset,
-                            int32_t aEndOffset);
-
-  bool AddToSelection(int32_t aStartOffset,
-                      int32_t aEndOffset);
-
-  bool RemoveFromSelection(int32_t aSelectionNum);
-
-  void ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
-                         uint32_t aScrollType);
-
-  void ScrollSubstringToPoint(int32_t aStartOffset,
-                              int32_t aEndOffset,
-                              uint32_t aCoordinateType,
-                              int32_t aX, int32_t aY);
-
-  void Text(nsString* aText);
-
-  void ReplaceText(const nsString& aText);
-
-  bool InsertText(const nsString& aText, int32_t aPosition);
-
-  bool CopyText(int32_t aStartPos, int32_t aEndPos);
-
-  bool CutText(int32_t aStartPos, int32_t aEndPos);
-
-  bool DeleteText(int32_t aStartPos, int32_t aEndPos);
-
-  bool PasteText(int32_t aPosition);
-
-  nsIntPoint ImagePosition(uint32_t aCoordType);
-
-  nsIntSize ImageSize();
-
-  uint32_t StartOffset(bool* aOk);
-
-  uint32_t EndOffset(bool* aOk);
-
-  bool IsLinkValid();
-
-  // XXX checking mRole alone may not result in same behavior as Accessibles
-  // due to ARIA roles. See bug 1210477.
-  inline bool IsTable() const
-  {
-    return mRole == roles::TABLE || mRole == roles::MATHML_TABLE;
-  }
-  inline bool IsTableRow() const
-  {
-    return (mRole == roles::ROW ||
-            mRole == roles::MATHML_TABLE_ROW ||
-            mRole == roles::MATHML_LABELED_ROW);
-  }
-  inline bool IsTableCell() const
-  {
-    return (mRole == roles::CELL ||
-            mRole == roles::COLUMNHEADER ||
-            mRole == roles::ROWHEADER ||
-            mRole == roles::GRID_CELL ||
-            mRole == roles::MATHML_CELL);
-  }
-
-  uint32_t AnchorCount(bool* aOk);
-
-  void AnchorURIAt(uint32_t aIndex, nsCString& aURI, bool* aOk);
-
-  ProxyAccessible* AnchorAt(uint32_t aIndex);
-
-  uint32_t LinkCount();
-
-  ProxyAccessible* LinkAt(const uint32_t& aIndex);
-
-  int32_t LinkIndexOf(ProxyAccessible* aLink);
-
-  int32_t LinkIndexAtOffset(uint32_t aOffset);
-
-  ProxyAccessible* TableOfACell();
-
-  uint32_t ColIdx();
-
-  uint32_t RowIdx();
-
-  uint32_t ColExtent();
-
-  uint32_t RowExtent();
-
-  void ColHeaderCells(nsTArray<ProxyAccessible*>* aCells);
-
-  void RowHeaderCells(nsTArray<ProxyAccessible*>* aCells);
-
-  bool IsCellSelected();
-
-  ProxyAccessible* TableCaption();
-  void TableSummary(nsString& aSummary);
-  uint32_t TableColumnCount();
-  uint32_t TableRowCount();
-  ProxyAccessible* TableCellAt(uint32_t aRow, uint32_t aCol);
-  int32_t TableCellIndexAt(uint32_t aRow, uint32_t aCol);
-  int32_t TableColumnIndexAt(uint32_t aCellIndex);
-  int32_t TableRowIndexAt(uint32_t aCellIndex);
-  void TableRowAndColumnIndicesAt(uint32_t aCellIndex,
-                                  int32_t* aRow, int32_t* aCol);
-  uint32_t TableColumnExtentAt(uint32_t aRow, uint32_t aCol);
-  uint32_t TableRowExtentAt(uint32_t aRow, uint32_t aCol);
-  void TableColumnDescription(uint32_t aCol, nsString& aDescription);
-  void TableRowDescription(uint32_t aRow, nsString& aDescription);
-  bool TableColumnSelected(uint32_t aCol);
-  bool TableRowSelected(uint32_t aRow);
-  bool TableCellSelected(uint32_t aRow, uint32_t aCol);
-  uint32_t TableSelectedCellCount();
-  uint32_t TableSelectedColumnCount();
-  uint32_t TableSelectedRowCount();
-  void TableSelectedCells(nsTArray<ProxyAccessible*>* aCellIDs);
-  void TableSelectedCellIndices(nsTArray<uint32_t>* aCellIndices);
-  void TableSelectedColumnIndices(nsTArray<uint32_t>* aColumnIndices);
-  void TableSelectedRowIndices(nsTArray<uint32_t>* aRowIndices);
-  void TableSelectColumn(uint32_t aCol);
-  void TableSelectRow(uint32_t aRow);
-  void TableUnselectColumn(uint32_t aCol);
-  void TableUnselectRow(uint32_t aRow);
-  bool TableIsProbablyForLayout();
-  ProxyAccessible* AtkTableColumnHeader(int32_t aCol);
-  ProxyAccessible* AtkTableRowHeader(int32_t aRow);
-
-  void SelectedItems(nsTArray<ProxyAccessible*>* aSelectedItems);
-  uint32_t SelectedItemCount();
-  ProxyAccessible* GetSelectedItem(uint32_t aIndex);
-  bool IsItemSelected(uint32_t aIndex);
-  bool AddItemToSelection(uint32_t aIndex);
-  bool RemoveItemFromSelection(uint32_t aIndex);
-  bool SelectAll();
-  bool UnselectAll();
-
-  void TakeSelection();
-  void SetSelected(bool aSelect);
-
-  bool DoAction(uint8_t aIndex);
-  uint8_t ActionCount();
-  void ActionDescriptionAt(uint8_t aIndex, nsString& aDescription);
-  void ActionNameAt(uint8_t aIndex, nsString& aName);
-  KeyBinding AccessKey();
-  KeyBinding KeyboardShortcut();
-  void AtkKeyBinding(nsString& aBinding);
-
-  double CurValue();
-  bool SetCurValue(double aValue);
-  double MinValue();
-  double MaxValue();
-  double Step();
-
-  void TakeFocus();
-  ProxyAccessible* FocusedChild();
-  ProxyAccessible* ChildAtPoint(int32_t aX, int32_t aY,
-                                Accessible::EWhichChildAtPoint aWhichChild);
   nsIntRect Bounds();
 
   void Language(nsString& aLocale);
-  void DocType(nsString& aType);
-  void Title(nsString& aTitle);
-  void URL(nsString& aURL);
-  void MimeType(nsString aMime);
-  void URLDocTypeMimeType(nsString& aURL, nsString& aDocType,
-                          nsString& aMimeType);
 
-  ProxyAccessible* AccessibleAtPoint(int32_t aX, int32_t aY,
-                                     bool aNeedsScreenCoords);
-
-  void Extents(bool aNeedsScreenCoords, int32_t* aX, int32_t* aY,
-               int32_t* aWidth, int32_t* aHeight);
-
-  /**
-   * Return the id of the dom node this accessible represents.  Note this
-   * should probably only be used for testing.
-   */
-  void DOMNodeID(nsString& aID);
-
-  /**
-   * Allow the platform to store a pointers worth of data on us.
-   */
-  uintptr_t GetWrapper() const { return mWrapper; }
-  void SetWrapper(uintptr_t aWrapper) { mWrapper = aWrapper; }
-
-  /*
-   * Return the ID of the accessible being proxied.
-   */
-  uint64_t ID() const { return mID; }
-
-  /**
-   * Return the document containing this proxy, or the proxy itself if it is a
-   * document.
-   */
-  DocAccessibleParent* Document() const { return mDoc; }
-
-  /**
-   * Return true if this proxy is a DocAccessibleParent.
-   */
-  bool IsDoc() const { return mIsDoc; }
-  DocAccessibleParent* AsDoc() const { return IsDoc() ? mDoc : nullptr; }
+  bool GetCOMInterface(void** aOutAccessible) const;
 
 protected:
-  explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc) :
-    mParent(nullptr), mDoc(aThisAsDoc), mWrapper(0), mID(0),
-    mRole(roles::DOCUMENT), mOuterDoc(false), mIsDoc(true), mHasValue(false),
-    mIsHyperLink(false), mIsHyperText(false)
-  { MOZ_COUNT_CTOR(ProxyAccessible); }
+  explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc)
+    : ProxyAccessibleBase(aThisAsDoc)
+  { MOZ_COUNT_CTOR(ProxyAccessibleBase); }
 
-protected:
-  ProxyAccessible* mParent;
+  void SetCOMInterface(const RefPtr<IAccessible>& aIAccessible)
+  { mCOMProxy = aIAccessible; }
 
 private:
-  nsTArray<ProxyAccessible*> mChildren;
-  DocAccessibleParent* mDoc;
-  uintptr_t mWrapper;
-  uint64_t mID;
-protected:
-  // XXX DocAccessibleParent gets to change this to change the role of
-  // documents.
-  role mRole : 27;
-private:
-  bool mOuterDoc : 1;
-
-public:
-  const bool mIsDoc: 1;
-  const bool mHasValue: 1;
-  const bool mIsHyperLink: 1;
-  const bool mIsHyperText: 1;
+  RefPtr<IAccessible> mCOMProxy;
 };
 
 }
 }
 
 #endif
--- a/accessible/ipc/win/moz.build
+++ b/accessible/ipc/win/moz.build
@@ -7,21 +7,23 @@
 IPDL_SOURCES += ['PDocAccessible.ipdl']
 
 # with --disable-accessibility we need to compile PDocAccessible.ipdl, but not
 # the C++.
 if CONFIG['ACCESSIBILITY']:
     EXPORTS.mozilla.a11y += [
         'COMPtrTypes.h',
         'DocAccessibleChild.h',
+        'ProxyAccessible.h'
     ]
 
     SOURCES += [
         'COMPtrTypes.cpp',
         'DocAccessibleChild.cpp',
+        'ProxyAccessible.cpp',
     ]
 
     LOCAL_INCLUDES += [
         '/accessible/base',
         '/accessible/generic',
         '/accessible/windows/ia2',
         '/accessible/windows/msaa',
         '/accessible/xpcom',
--- a/accessible/windows/ProxyWrappers.h
+++ b/accessible/windows/ProxyWrappers.h
@@ -10,45 +10,55 @@
 
 #include "HyperTextAccessible.h"
 
 namespace mozilla {
 namespace a11y {
 
 class ProxyAccessibleWrap : public AccessibleWrap
 {
-  public:
+public:
   ProxyAccessibleWrap(ProxyAccessible* aProxy) :
     AccessibleWrap(nullptr, nullptr)
   {
     mType = eProxyType;
     mBits.proxy = aProxy;
   }
 
   virtual void Shutdown() override
   {
     mBits.proxy = nullptr;
     mStateFlags |= eIsDefunct;
   }
+
+  virtual void GetNativeInterface(void** aOutAccessible) override
+  {
+    mBits.proxy->GetCOMInterface(aOutAccessible);
+  }
 };
 
 class HyperTextProxyAccessibleWrap : public HyperTextAccessibleWrap
 {
 public:
   HyperTextProxyAccessibleWrap(ProxyAccessible* aProxy) :
     HyperTextAccessibleWrap(nullptr, nullptr)
   {
     mType = eProxyType;
     mBits.proxy = aProxy;
   }
 
   virtual void Shutdown() override
   {
     mBits.proxy = nullptr;
- mStateFlags |= eIsDefunct;
+    mStateFlags |= eIsDefunct;
+  }
+
+  virtual void GetNativeInterface(void** aOutAccessible) override
+  {
+    mBits.proxy->GetCOMInterface(aOutAccessible);
   }
 };
 
 class DocProxyAccessibleWrap : public HyperTextProxyAccessibleWrap
 {
 public:
   DocProxyAccessibleWrap(ProxyAccessible* aProxy) :
     HyperTextProxyAccessibleWrap(aProxy)
--- a/accessible/xpcom/xpcAccessibleDocument.h
+++ b/accessible/xpcom/xpcAccessibleDocument.h
@@ -91,16 +91,17 @@ private:
     }
 
     mCache.Remove(aProxy);
   }
 
   friend class DocManager;
   friend class DocAccessible;
   friend class ProxyAccessible;
+  friend class ProxyAccessibleBase<ProxyAccessible>;
 
   xpcAccessibleDocument(const xpcAccessibleDocument&) = delete;
   xpcAccessibleDocument& operator =(const xpcAccessibleDocument&) = delete;
 
   nsRefPtrHashtable<nsPtrHashKey<const void>, xpcAccessibleGeneric> mCache;
   bool mRemote;
 };