summaryrefslogtreecommitdiff
path: root/accessible/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/ipc')
-rw-r--r--accessible/ipc/DocAccessibleChildBase.cpp97
-rw-r--r--accessible/ipc/DocAccessibleChildBase.h81
-rw-r--r--accessible/ipc/DocAccessibleParent.cpp526
-rw-r--r--accessible/ipc/DocAccessibleParent.h198
-rw-r--r--accessible/ipc/IPCTypes.h49
-rw-r--r--accessible/ipc/ProxyAccessibleBase.cpp175
-rw-r--r--accessible/ipc/ProxyAccessibleBase.h211
-rw-r--r--accessible/ipc/ProxyAccessibleShared.h277
-rw-r--r--accessible/ipc/moz.build61
-rw-r--r--accessible/ipc/other/DocAccessibleChild.cpp1998
-rw-r--r--accessible/ipc/other/DocAccessibleChild.h489
-rw-r--r--accessible/ipc/other/PDocAccessible.ipdl264
-rw-r--r--accessible/ipc/other/ProxyAccessible.cpp1080
-rw-r--r--accessible/ipc/other/ProxyAccessible.h50
-rw-r--r--accessible/ipc/other/moz.build47
-rw-r--r--accessible/ipc/win/COMPtrTypes.cpp50
-rw-r--r--accessible/ipc/win/COMPtrTypes.h27
-rw-r--r--accessible/ipc/win/DocAccessibleChild.cpp237
-rw-r--r--accessible/ipc/win/DocAccessibleChild.h318
-rw-r--r--accessible/ipc/win/PDocAccessible.ipdl75
-rw-r--r--accessible/ipc/win/PlatformChild.cpp62
-rw-r--r--accessible/ipc/win/PlatformChild.h35
-rw-r--r--accessible/ipc/win/ProxyAccessible.cpp599
-rw-r--r--accessible/ipc/win/ProxyAccessible.h58
-rw-r--r--accessible/ipc/win/moz.build39
-rw-r--r--accessible/ipc/win/typelib/Accessible.idl16
-rw-r--r--accessible/ipc/win/typelib/Makefile.in31
-rw-r--r--accessible/ipc/win/typelib/moz.build13
28 files changed, 7163 insertions, 0 deletions
diff --git a/accessible/ipc/DocAccessibleChildBase.cpp b/accessible/ipc/DocAccessibleChildBase.cpp
new file mode 100644
index 0000000000..6a0ad9b7db
--- /dev/null
+++ b/accessible/ipc/DocAccessibleChildBase.cpp
@@ -0,0 +1,97 @@
+/* -*- 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 "mozilla/a11y/DocAccessibleChildBase.h"
+#include "mozilla/a11y/ProxyAccessible.h"
+
+#include "Accessible-inl.h"
+
+namespace mozilla {
+namespace a11y {
+
+/* static */ uint32_t
+DocAccessibleChildBase::InterfacesFor(Accessible* aAcc)
+{
+ uint32_t interfaces = 0;
+ if (aAcc->IsHyperText() && aAcc->AsHyperText()->IsTextRole())
+ interfaces |= Interfaces::HYPERTEXT;
+
+ if (aAcc->IsLink())
+ interfaces |= Interfaces::HYPERLINK;
+
+ if (aAcc->HasNumericValue())
+ interfaces |= Interfaces::VALUE;
+
+ if (aAcc->IsImage())
+ interfaces |= Interfaces::IMAGE;
+
+ if (aAcc->IsTable()) {
+ interfaces |= Interfaces::TABLE;
+ }
+
+ if (aAcc->IsTableCell())
+ interfaces |= Interfaces::TABLECELL;
+
+ if (aAcc->IsDoc())
+ interfaces |= Interfaces::DOCUMENT;
+
+ if (aAcc->IsSelect()) {
+ interfaces |= Interfaces::SELECTION;
+ }
+
+ if (aAcc->ActionCount()) {
+ interfaces |= Interfaces::ACTION;
+ }
+
+ return interfaces;
+}
+
+/* static */ void
+DocAccessibleChildBase::SerializeTree(Accessible* aRoot,
+ nsTArray<AccessibleData>& aTree)
+{
+ uint64_t id = reinterpret_cast<uint64_t>(aRoot->UniqueID());
+#if defined(XP_WIN)
+ int32_t msaaId = AccessibleWrap::GetChildIDFor(aRoot);
+#endif
+ uint32_t role = aRoot->Role();
+ uint32_t childCount = aRoot->ChildCount();
+ uint32_t interfaces = InterfacesFor(aRoot);
+
+ // OuterDocAccessibles are special because we don't want to serialize the
+ // child doc here, we'll call PDocAccessibleConstructor in
+ // NotificationController.
+ MOZ_ASSERT(!aRoot->IsDoc(), "documents shouldn't be serialized");
+ if (aRoot->IsOuterDoc()) {
+ childCount = 0;
+ }
+
+#if defined(XP_WIN)
+ aTree.AppendElement(AccessibleData(id, msaaId, role, childCount, interfaces));
+#else
+ aTree.AppendElement(AccessibleData(id, role, childCount, interfaces));
+#endif
+
+ for (uint32_t i = 0; i < childCount; i++) {
+ SerializeTree(aRoot->GetChildAt(i), aTree);
+ }
+}
+
+void
+DocAccessibleChildBase::ShowEvent(AccShowEvent* aShowEvent)
+{
+ Accessible* parent = aShowEvent->Parent();
+ uint64_t parentID = parent->IsDoc() ? 0 : reinterpret_cast<uint64_t>(parent->UniqueID());
+ uint32_t idxInParent = aShowEvent->GetAccessible()->IndexInParent();
+ nsTArray<AccessibleData> shownTree;
+ ShowEventData data(parentID, idxInParent, shownTree);
+ SerializeTree(aShowEvent->GetAccessible(), data.NewTree());
+ MaybeSendShowEvent(data, aShowEvent->IsFromUserInput());
+}
+
+} // namespace a11y
+} // namespace mozilla
+
diff --git a/accessible/ipc/DocAccessibleChildBase.h b/accessible/ipc/DocAccessibleChildBase.h
new file mode 100644
index 0000000000..b8a8bfde1d
--- /dev/null
+++ b/accessible/ipc/DocAccessibleChildBase.h
@@ -0,0 +1,81 @@
+/* -*- 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_DocAccessibleChildBase_h
+#define mozilla_a11y_DocAccessibleChildBase_h
+
+#include "mozilla/a11y/DocAccessible.h"
+#include "mozilla/a11y/PDocAccessibleChild.h"
+#include "mozilla/Unused.h"
+#include "nsISupportsImpl.h"
+
+namespace mozilla {
+namespace a11y {
+
+class Accessible;
+class AccShowEvent;
+
+class DocAccessibleChildBase : public PDocAccessibleChild
+{
+public:
+ explicit DocAccessibleChildBase(DocAccessible* aDoc)
+ : mDoc(aDoc)
+ {
+ MOZ_COUNT_CTOR(DocAccessibleChildBase);
+ }
+
+ ~DocAccessibleChildBase()
+ {
+ // Shutdown() should have been called, but maybe it isn't if the process is
+ // killed?
+ MOZ_ASSERT(!mDoc);
+ if (mDoc) {
+ mDoc->SetIPCDoc(nullptr);
+ }
+
+ MOZ_COUNT_DTOR(DocAccessibleChildBase);
+ }
+
+ virtual void Shutdown()
+ {
+ DetachDocument();
+ SendShutdown();
+ }
+
+ void ShowEvent(AccShowEvent* aShowEvent);
+
+ virtual void ActorDestroy(ActorDestroyReason) override
+ {
+ if (!mDoc) {
+ return;
+ }
+
+ mDoc->SetIPCDoc(nullptr);
+ mDoc = nullptr;
+ }
+
+protected:
+ static uint32_t InterfacesFor(Accessible* aAcc);
+ static void SerializeTree(Accessible* aRoot, nsTArray<AccessibleData>& aTree);
+
+ virtual void MaybeSendShowEvent(ShowEventData& aData, bool aFromUser)
+ { Unused << SendShowEvent(aData, aFromUser); }
+
+ void DetachDocument()
+ {
+ if (mDoc) {
+ mDoc->SetIPCDoc(nullptr);
+ mDoc = nullptr;
+ }
+ }
+
+ DocAccessible* mDoc;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif // mozilla_a11y_DocAccessibleChildBase_h
diff --git a/accessible/ipc/DocAccessibleParent.cpp b/accessible/ipc/DocAccessibleParent.cpp
new file mode 100644
index 0000000000..0e9dfc0806
--- /dev/null
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -0,0 +1,526 @@
+/* -*- 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 "DocAccessibleParent.h"
+#include "mozilla/a11y/Platform.h"
+#include "mozilla/dom/TabParent.h"
+#include "xpcAccessibleDocument.h"
+#include "xpcAccEvents.h"
+#include "nsAccUtils.h"
+#include "nsCoreUtils.h"
+
+namespace mozilla {
+namespace a11y {
+
+bool
+DocAccessibleParent::RecvShowEvent(const ShowEventData& aData,
+ const bool& aFromUser)
+{
+ if (mShutdown)
+ return true;
+
+ MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());
+
+ if (aData.NewTree().IsEmpty()) {
+ NS_ERROR("no children being added");
+ return false;
+ }
+
+ ProxyAccessible* parent = GetAccessible(aData.ID());
+
+ // XXX This should really never happen, but sometimes we fail to fire the
+ // required show events.
+ if (!parent) {
+ NS_ERROR("adding child to unknown accessible");
+ return true;
+ }
+
+ uint32_t newChildIdx = aData.Idx();
+ if (newChildIdx > parent->ChildrenCount()) {
+ NS_ERROR("invalid index to add child at");
+ return true;
+ }
+
+ uint32_t consumed = AddSubtree(parent, aData.NewTree(), 0, newChildIdx);
+ MOZ_ASSERT(consumed == aData.NewTree().Length());
+
+ // XXX This shouldn't happen, but if we failed to add children then the below
+ // is pointless and can crash.
+ if (!consumed) {
+ return true;
+ }
+
+#ifdef DEBUG
+ for (uint32_t i = 0; i < consumed; i++) {
+ uint64_t id = aData.NewTree()[i].ID();
+ MOZ_ASSERT(mAccessibles.GetEntry(id));
+ }
+#endif
+
+ MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());
+
+ ProxyAccessible* target = parent->ChildAt(newChildIdx);
+ ProxyShowHideEvent(target, parent, true, aFromUser);
+
+ if (!nsCoreUtils::AccEventObserversExist()) {
+ return true;
+ }
+
+ uint32_t type = nsIAccessibleEvent::EVENT_SHOW;
+ xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(target);
+ xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
+ nsIDOMNode* node = nullptr;
+ RefPtr<xpcAccEvent> event = new xpcAccEvent(type, xpcAcc, doc, node,
+ aFromUser);
+ nsCoreUtils::DispatchAccEvent(Move(event));
+
+ return true;
+}
+
+uint32_t
+DocAccessibleParent::AddSubtree(ProxyAccessible* aParent,
+ const nsTArray<a11y::AccessibleData>& aNewTree,
+ uint32_t aIdx, uint32_t aIdxInParent)
+{
+ if (aNewTree.Length() <= aIdx) {
+ NS_ERROR("bad index in serialized tree!");
+ return 0;
+ }
+
+ const AccessibleData& newChild = aNewTree[aIdx];
+ if (newChild.Role() > roles::LAST_ROLE) {
+ NS_ERROR("invalid role");
+ return 0;
+ }
+
+ if (mAccessibles.Contains(newChild.ID())) {
+ NS_ERROR("ID already in use");
+ return 0;
+ }
+
+ auto role = static_cast<a11y::role>(newChild.Role());
+
+ ProxyAccessible* newProxy =
+ new ProxyAccessible(newChild.ID(), aParent, this, role,
+ newChild.Interfaces());
+
+ aParent->AddChildAt(aIdxInParent, newProxy);
+ mAccessibles.PutEntry(newChild.ID())->mProxy = newProxy;
+ ProxyCreated(newProxy, newChild.Interfaces());
+
+#if defined(XP_WIN)
+ WrapperFor(newProxy)->SetID(newChild.MsaaID());
+#endif
+
+ uint32_t accessibles = 1;
+ uint32_t kids = newChild.ChildrenCount();
+ for (uint32_t i = 0; i < kids; i++) {
+ uint32_t consumed = AddSubtree(newProxy, aNewTree, aIdx + accessibles, i);
+ if (!consumed)
+ return 0;
+
+ accessibles += consumed;
+ }
+
+ MOZ_ASSERT(newProxy->ChildrenCount() == kids);
+
+ return accessibles;
+}
+
+bool
+DocAccessibleParent::RecvHideEvent(const uint64_t& aRootID,
+ const bool& aFromUser)
+{
+ if (mShutdown)
+ return true;
+
+ MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());
+
+ // We shouldn't actually need this because mAccessibles shouldn't have an
+ // entry for the document itself, but it doesn't hurt to be explicit.
+ if (!aRootID) {
+ NS_ERROR("trying to hide entire document?");
+ return false;
+ }
+
+ ProxyEntry* rootEntry = mAccessibles.GetEntry(aRootID);
+ if (!rootEntry) {
+ NS_ERROR("invalid root being removed!");
+ return true;
+ }
+
+ ProxyAccessible* root = rootEntry->mProxy;
+ if (!root) {
+ NS_ERROR("invalid root being removed!");
+ return true;
+ }
+
+ ProxyAccessible* parent = root->Parent();
+ ProxyShowHideEvent(root, parent, false, aFromUser);
+
+ RefPtr<xpcAccHideEvent> event = nullptr;
+ if (nsCoreUtils::AccEventObserversExist()) {
+ uint32_t type = nsIAccessibleEvent::EVENT_HIDE;
+ xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(root);
+ xpcAccessibleGeneric* xpcParent = GetXPCAccessible(parent);
+ ProxyAccessible* next = root->NextSibling();
+ xpcAccessibleGeneric* xpcNext = next ? GetXPCAccessible(next) : nullptr;
+ ProxyAccessible* prev = root->PrevSibling();
+ xpcAccessibleGeneric* xpcPrev = prev ? GetXPCAccessible(prev) : nullptr;
+ xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
+ nsIDOMNode* node = nullptr;
+ event = new xpcAccHideEvent(type, xpcAcc, doc, node, aFromUser, xpcParent,
+ xpcNext, xpcPrev);
+ }
+
+ parent->RemoveChild(root);
+ root->Shutdown();
+
+ MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());
+
+ if (event) {
+ nsCoreUtils::DispatchAccEvent(Move(event));
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleParent::RecvEvent(const uint64_t& aID, const uint32_t& aEventType)
+{
+ ProxyAccessible* proxy = GetAccessible(aID);
+ if (!proxy) {
+ NS_ERROR("no proxy for event!");
+ return true;
+ }
+
+ ProxyEvent(proxy, aEventType);
+
+ if (!nsCoreUtils::AccEventObserversExist()) {
+ return true;
+ }
+
+ xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(proxy);
+ xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
+ nsIDOMNode* node = nullptr;
+ bool fromUser = true; // XXX fix me
+ RefPtr<xpcAccEvent> event = new xpcAccEvent(aEventType, xpcAcc, doc, node,
+ fromUser);
+ nsCoreUtils::DispatchAccEvent(Move(event));
+
+ return true;
+}
+
+bool
+DocAccessibleParent::RecvStateChangeEvent(const uint64_t& aID,
+ const uint64_t& aState,
+ const bool& aEnabled)
+{
+ ProxyAccessible* target = GetAccessible(aID);
+ if (!target) {
+ NS_ERROR("we don't know about the target of a state change event!");
+ return true;
+ }
+
+ ProxyStateChangeEvent(target, aState, aEnabled);
+
+ if (!nsCoreUtils::AccEventObserversExist()) {
+ return true;
+ }
+
+ xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(target);
+ xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
+ uint32_t type = nsIAccessibleEvent::EVENT_STATE_CHANGE;
+ bool extra;
+ uint32_t state = nsAccUtils::To32States(aState, &extra);
+ bool fromUser = true; // XXX fix this
+ nsIDOMNode* node = nullptr; // XXX can we do better?
+ RefPtr<xpcAccStateChangeEvent> event =
+ new xpcAccStateChangeEvent(type, xpcAcc, doc, node, fromUser, state, extra,
+ aEnabled);
+ nsCoreUtils::DispatchAccEvent(Move(event));
+
+ return true;
+}
+
+bool
+DocAccessibleParent::RecvCaretMoveEvent(const uint64_t& aID, const int32_t& aOffset)
+{
+ ProxyAccessible* proxy = GetAccessible(aID);
+ if (!proxy) {
+ NS_ERROR("unknown caret move event target!");
+ return true;
+ }
+
+ ProxyCaretMoveEvent(proxy, aOffset);
+
+ if (!nsCoreUtils::AccEventObserversExist()) {
+ return true;
+ }
+
+ xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(proxy);
+ xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
+ nsIDOMNode* node = nullptr;
+ bool fromUser = true; // XXX fix me
+ uint32_t type = nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED;
+ RefPtr<xpcAccCaretMoveEvent> event =
+ new xpcAccCaretMoveEvent(type, xpcAcc, doc, node, fromUser, aOffset);
+ nsCoreUtils::DispatchAccEvent(Move(event));
+
+ return true;
+}
+
+bool
+DocAccessibleParent::RecvTextChangeEvent(const uint64_t& aID,
+ const nsString& aStr,
+ const int32_t& aStart,
+ const uint32_t& aLen,
+ const bool& aIsInsert,
+ const bool& aFromUser)
+{
+ ProxyAccessible* target = GetAccessible(aID);
+ if (!target) {
+ NS_ERROR("text change event target is unknown!");
+ return true;
+ }
+
+ ProxyTextChangeEvent(target, aStr, aStart, aLen, aIsInsert, aFromUser);
+
+ if (!nsCoreUtils::AccEventObserversExist()) {
+ return true;
+ }
+
+ xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(target);
+ xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
+ uint32_t type = aIsInsert ? nsIAccessibleEvent::EVENT_TEXT_INSERTED :
+ nsIAccessibleEvent::EVENT_TEXT_REMOVED;
+ nsIDOMNode* node = nullptr;
+ RefPtr<xpcAccTextChangeEvent> event =
+ new xpcAccTextChangeEvent(type, xpcAcc, doc, node, aFromUser, aStart, aLen,
+ aIsInsert, aStr);
+ nsCoreUtils::DispatchAccEvent(Move(event));
+
+ return true;
+}
+
+bool
+DocAccessibleParent::RecvSelectionEvent(const uint64_t& aID,
+ const uint64_t& aWidgetID,
+ const uint32_t& aType)
+{
+ ProxyAccessible* target = GetAccessible(aID);
+ ProxyAccessible* widget = GetAccessible(aWidgetID);
+ if (!target || !widget) {
+ NS_ERROR("invalid id in selection event");
+ return true;
+ }
+
+ ProxySelectionEvent(target, widget, aType);
+ if (!nsCoreUtils::AccEventObserversExist()) {
+ return true;
+ }
+ xpcAccessibleGeneric* xpcTarget = GetXPCAccessible(target);
+ xpcAccessibleDocument* xpcDoc = GetAccService()->GetXPCDocument(this);
+ RefPtr<xpcAccEvent> event = new xpcAccEvent(aType, xpcTarget, xpcDoc,
+ nullptr, false);
+ nsCoreUtils::DispatchAccEvent(Move(event));
+
+ return true;
+}
+
+bool
+DocAccessibleParent::RecvRoleChangedEvent(const uint32_t& aRole)
+{
+ if (aRole >= roles::LAST_ROLE) {
+ NS_ERROR("child sent bad role in RoleChangedEvent");
+ return false;
+ }
+
+ mRole = static_cast<a11y::role>(aRole);
+ return true;
+}
+
+bool
+DocAccessibleParent::RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID)
+{
+ // One document should never directly be the child of another.
+ // We should always have at least an outer doc accessible in between.
+ MOZ_ASSERT(aID);
+ if (!aID)
+ return false;
+
+ MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());
+
+ auto childDoc = static_cast<DocAccessibleParent*>(aChildDoc);
+ childDoc->Unbind();
+ bool result = AddChildDoc(childDoc, aID, false);
+ MOZ_ASSERT(result);
+ MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());
+ return result;
+}
+
+bool
+DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc,
+ uint64_t aParentID, bool aCreating)
+{
+ // We do not use GetAccessible here because we want to be sure to not get the
+ // document it self.
+ ProxyEntry* e = mAccessibles.GetEntry(aParentID);
+ if (!e)
+ return false;
+
+ ProxyAccessible* outerDoc = e->mProxy;
+ MOZ_ASSERT(outerDoc);
+
+ // OuterDocAccessibles are expected to only have a document as a child.
+ // However for compatibility we tolerate replacing one document with another
+ // here.
+ if (outerDoc->ChildrenCount() > 1 ||
+ (outerDoc->ChildrenCount() == 1 && !outerDoc->ChildAt(0)->IsDoc())) {
+ return false;
+ }
+
+ aChildDoc->mParent = outerDoc;
+ outerDoc->SetChildDoc(aChildDoc);
+ mChildDocs.AppendElement(aChildDoc);
+ aChildDoc->mParentDoc = this;
+
+ if (aCreating) {
+ ProxyCreated(aChildDoc, Interfaces::DOCUMENT | Interfaces::HYPERTEXT);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleParent::RecvShutdown()
+{
+ Destroy();
+
+ if (!static_cast<dom::TabParent*>(Manager())->IsDestroyed()) {
+ return PDocAccessibleParent::Send__delete__(this);
+ }
+
+ return true;
+}
+
+void
+DocAccessibleParent::Destroy()
+{
+ NS_ASSERTION(mChildDocs.IsEmpty(),
+ "why weren't the child docs destroyed already?");
+ MOZ_ASSERT(!mShutdown);
+ mShutdown = true;
+
+ uint32_t childDocCount = mChildDocs.Length();
+ for (uint32_t i = childDocCount - 1; i < childDocCount; i--)
+ mChildDocs[i]->Destroy();
+
+ for (auto iter = mAccessibles.Iter(); !iter.Done(); iter.Next()) {
+ MOZ_ASSERT(iter.Get()->mProxy != this);
+ ProxyDestroyed(iter.Get()->mProxy);
+ iter.Remove();
+ }
+
+ DocManager::NotifyOfRemoteDocShutdown(this);
+ ProxyDestroyed(this);
+ if (mParentDoc)
+ mParentDoc->RemoveChildDoc(this);
+ else if (IsTopLevel())
+ GetAccService()->RemoteDocShutdown(this);
+}
+
+bool
+DocAccessibleParent::CheckDocTree() const
+{
+ size_t childDocs = mChildDocs.Length();
+ for (size_t i = 0; i < childDocs; i++) {
+ if (!mChildDocs[i] || mChildDocs[i]->mParentDoc != this)
+ return false;
+
+ if (!mChildDocs[i]->CheckDocTree()) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+xpcAccessibleGeneric*
+DocAccessibleParent::GetXPCAccessible(ProxyAccessible* aProxy)
+{
+ xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this);
+ MOZ_ASSERT(doc);
+
+ return doc->GetXPCAccessible(aProxy);
+}
+
+#if defined(XP_WIN)
+/**
+ * @param aCOMProxy COM Proxy to the document in the content process.
+ */
+void
+DocAccessibleParent::SetCOMProxy(const RefPtr<IAccessible>& aCOMProxy)
+{
+ SetCOMInterface(aCOMProxy);
+
+ // Make sure that we're not racing with a tab shutdown
+ auto tab = static_cast<dom::TabParent*>(Manager());
+ MOZ_ASSERT(tab);
+ if (tab->IsDestroyed()) {
+ return;
+ }
+
+ Accessible* outerDoc = OuterDocOfRemoteBrowser();
+ MOZ_ASSERT(outerDoc);
+
+ IAccessible* rawNative = nullptr;
+ if (outerDoc) {
+ outerDoc->GetNativeInterface((void**) &rawNative);
+ MOZ_ASSERT(rawNative);
+ }
+
+ IAccessibleHolder::COMPtrType ptr(rawNative);
+ IAccessibleHolder holder(Move(ptr));
+ Unused << SendParentCOMProxy(holder);
+}
+
+bool
+DocAccessibleParent::RecvGetWindowedPluginIAccessible(
+ const WindowsHandle& aHwnd, IAccessibleHolder* aPluginCOMProxy)
+{
+#if defined(MOZ_CONTENT_SANDBOX)
+ // We don't actually want the accessible object for aHwnd, but rather the
+ // one that belongs to its child (see HTMLWin32ObjectAccessible).
+ HWND childWnd = ::GetWindow(reinterpret_cast<HWND>(aHwnd), GW_CHILD);
+ if (!childWnd) {
+ // We're seeing this in the wild - the plugin is windowed but we no longer
+ // have a window.
+ return true;
+ }
+
+ IAccessible* rawAccPlugin = nullptr;
+ HRESULT hr = ::AccessibleObjectFromWindow(childWnd, OBJID_WINDOW,
+ IID_IAccessible,
+ (void**)&rawAccPlugin);
+ if (FAILED(hr)) {
+ // This might happen if the plugin doesn't handle WM_GETOBJECT properly.
+ // We should not consider that a failure.
+ return true;
+ }
+
+ aPluginCOMProxy->Set(IAccessibleHolder::COMPtrType(rawAccPlugin));
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+#endif // defined(XP_WIN)
+
+} // a11y
+} // mozilla
diff --git a/accessible/ipc/DocAccessibleParent.h b/accessible/ipc/DocAccessibleParent.h
new file mode 100644
index 0000000000..3686e8a2f2
--- /dev/null
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -0,0 +1,198 @@
+/* -*- 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_DocAccessibleParent_h
+#define mozilla_a11y_DocAccessibleParent_h
+
+#include "nsAccessibilityService.h"
+#include "mozilla/a11y/PDocAccessibleParent.h"
+#include "mozilla/a11y/ProxyAccessible.h"
+#include "nsClassHashtable.h"
+#include "nsHashKeys.h"
+#include "nsISupportsImpl.h"
+
+namespace mozilla {
+namespace a11y {
+
+class xpcAccessibleGeneric;
+
+/*
+ * These objects live in the main process and comunicate with and represent
+ * an accessible document in a content process.
+ */
+class DocAccessibleParent : public ProxyAccessible,
+ public PDocAccessibleParent
+{
+public:
+ DocAccessibleParent() :
+ ProxyAccessible(this), mParentDoc(nullptr),
+ mTopLevel(false), mShutdown(false)
+ { MOZ_COUNT_CTOR_INHERITED(DocAccessibleParent, ProxyAccessible); }
+ ~DocAccessibleParent()
+ {
+ MOZ_COUNT_DTOR_INHERITED(DocAccessibleParent, ProxyAccessible);
+ MOZ_ASSERT(mChildDocs.Length() == 0);
+ MOZ_ASSERT(!ParentDoc());
+ }
+
+ void SetTopLevel() { mTopLevel = true; }
+ bool IsTopLevel() const { return mTopLevel; }
+
+ bool IsShutdown() const { return mShutdown; }
+
+ /*
+ * Called when a message from a document in a child process notifies the main
+ * process it is firing an event.
+ */
+ virtual bool RecvEvent(const uint64_t& aID, const uint32_t& aType)
+ override;
+
+ virtual bool RecvShowEvent(const ShowEventData& aData, const bool& aFromUser)
+ override;
+ virtual bool RecvHideEvent(const uint64_t& aRootID, const bool& aFromUser)
+ override;
+ virtual bool RecvStateChangeEvent(const uint64_t& aID,
+ const uint64_t& aState,
+ const bool& aEnabled) override final;
+
+ virtual bool RecvCaretMoveEvent(const uint64_t& aID, const int32_t& aOffset)
+ override final;
+
+ virtual bool RecvTextChangeEvent(const uint64_t& aID, const nsString& aStr,
+ const int32_t& aStart, const uint32_t& aLen,
+ const bool& aIsInsert,
+ const bool& aFromUser) override;
+
+ virtual bool RecvSelectionEvent(const uint64_t& aID,
+ const uint64_t& aWidgetID,
+ const uint32_t& aType) override;
+
+ virtual bool RecvRoleChangedEvent(const uint32_t& aRole) override final;
+
+ virtual bool RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID) override;
+
+ void Unbind()
+ {
+ if (DocAccessibleParent* parent = ParentDoc()) {
+ parent->RemoveChildDoc(this);
+ }
+
+ mParent = nullptr;
+ }
+
+ virtual bool RecvShutdown() override;
+ void Destroy();
+ virtual void ActorDestroy(ActorDestroyReason aWhy) override
+ {
+ MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());
+ if (!mShutdown)
+ Destroy();
+ }
+
+ /*
+ * Return the main processes representation of the parent document (if any)
+ * of the document this object represents.
+ */
+ DocAccessibleParent* ParentDoc() const { return mParentDoc; }
+
+ /*
+ * Called when a document in a content process notifies the main process of a
+ * new child document.
+ */
+ bool AddChildDoc(DocAccessibleParent* aChildDoc, uint64_t aParentID,
+ bool aCreating = true);
+
+ /*
+ * Called when the document in the content process this object represents
+ * notifies the main process a child document has been removed.
+ */
+ void RemoveChildDoc(DocAccessibleParent* aChildDoc)
+ {
+ aChildDoc->Parent()->ClearChildDoc(aChildDoc);
+ mChildDocs.RemoveElement(aChildDoc);
+ aChildDoc->mParentDoc = nullptr;
+ MOZ_ASSERT(aChildDoc->mChildDocs.Length() == 0);
+ }
+
+ void RemoveAccessible(ProxyAccessible* aAccessible)
+ {
+ MOZ_DIAGNOSTIC_ASSERT(mAccessibles.GetEntry(aAccessible->ID()));
+ mAccessibles.RemoveEntry(aAccessible->ID());
+ }
+
+ /**
+ * Return the accessible for given id.
+ */
+ ProxyAccessible* GetAccessible(uintptr_t aID)
+ {
+ if (!aID)
+ return this;
+
+ ProxyEntry* e = mAccessibles.GetEntry(aID);
+ return e ? e->mProxy : nullptr;
+ }
+
+ const ProxyAccessible* GetAccessible(uintptr_t aID) const
+ { return const_cast<DocAccessibleParent*>(this)->GetAccessible(aID); }
+
+ size_t ChildDocCount() const { return mChildDocs.Length(); }
+ const DocAccessibleParent* ChildDocAt(size_t aIdx) const
+ { return mChildDocs[aIdx]; }
+
+#if defined(XP_WIN)
+ void SetCOMProxy(const RefPtr<IAccessible>& aCOMProxy);
+
+ virtual bool RecvGetWindowedPluginIAccessible(
+ const WindowsHandle& aHwnd, IAccessibleHolder* aPluginCOMProxy) override;
+#endif
+
+private:
+
+ class ProxyEntry : public PLDHashEntryHdr
+ {
+ public:
+ explicit ProxyEntry(const void*) : mProxy(nullptr) {}
+ ProxyEntry(ProxyEntry&& aOther) :
+ mProxy(aOther.mProxy) { aOther.mProxy = nullptr; }
+ ~ProxyEntry() { delete mProxy; }
+
+ typedef uint64_t KeyType;
+ typedef const void* KeyTypePointer;
+
+ bool KeyEquals(const void* aKey) const
+ { return mProxy->ID() == (uint64_t)aKey; }
+
+ static const void* KeyToPointer(uint64_t aKey) { return (void*)aKey; }
+
+ static PLDHashNumber HashKey(const void* aKey) { return (uint64_t)aKey; }
+
+ enum { ALLOW_MEMMOVE = true };
+
+ ProxyAccessible* mProxy;
+ };
+
+ uint32_t AddSubtree(ProxyAccessible* aParent,
+ const nsTArray<AccessibleData>& aNewTree, uint32_t aIdx,
+ uint32_t aIdxInParent);
+ MOZ_MUST_USE bool CheckDocTree() const;
+ xpcAccessibleGeneric* GetXPCAccessible(ProxyAccessible* aProxy);
+
+ nsTArray<DocAccessibleParent*> mChildDocs;
+ DocAccessibleParent* mParentDoc;
+
+ /*
+ * Conceptually this is a map from IDs to proxies, but we store the ID in the
+ * proxy object so we can't use a real map.
+ */
+ nsTHashtable<ProxyEntry> mAccessibles;
+ bool mTopLevel;
+ bool mShutdown;
+};
+
+}
+}
+
+#endif
diff --git a/accessible/ipc/IPCTypes.h b/accessible/ipc/IPCTypes.h
new file mode 100644
index 0000000000..0e77c6348b
--- /dev/null
+++ b/accessible/ipc/IPCTypes.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_IPCTypes_h
+#define mozilla_a11y_IPCTypes_h
+
+/**
+ * Since IPDL does not support preprocessing, this header file allows us to
+ * define types used by PDocAccessible differently depending on platform.
+ */
+
+#if defined(XP_WIN) && defined(ACCESSIBILITY)
+
+// So that we don't include a bunch of other Windows junk.
+#if !defined(COM_NO_WINDOWS_H)
+#define COM_NO_WINDOWS_H
+#endif // !defined(COM_NO_WINDOWS_H)
+
+// COM headers pull in MSXML which conflicts with our own XMLDocument class.
+// This define excludes those conflicting definitions.
+#if !defined(__XMLDocument_FWD_DEFINED__)
+#define __XMLDocument_FWD_DEFINED__
+#endif // !defined(__XMLDocument_FWD_DEFINED__)
+
+#include "mozilla/a11y/COMPtrTypes.h"
+
+// This define in rpcndr.h messes up our code, so we must undefine it after
+// COMPtrTypes.h has been included.
+#if defined(small)
+#undef small
+#endif // defined(small)
+
+#else
+
+namespace mozilla {
+namespace a11y {
+
+typedef uint32_t IAccessibleHolder;
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif // defined(XP_WIN) && defined(ACCESSIBILITY)
+
+#endif // mozilla_a11y_IPCTypes_h
+
diff --git a/accessible/ipc/ProxyAccessibleBase.cpp b/accessible/ipc/ProxyAccessibleBase.cpp
new file mode 100644
index 0000000000..8f1a2b7eda
--- /dev/null
+++ b/accessible/ipc/ProxyAccessibleBase.cpp
@@ -0,0 +1,175 @@
+/* -*- 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 "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 "RelationType.h"
+#include "xpcAccessibleDocument.h"
+
+namespace mozilla {
+namespace a11y {
+
+template <class Derived>
+void
+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(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(static_cast<Derived*>(this));
+ mDoc->RemoveAccessible(static_cast<Derived*>(this));
+}
+
+template <class Derived>
+void
+ProxyAccessibleBase<Derived>::SetChildDoc(DocAccessibleParent* aChildDoc)
+{
+ // DocAccessibleParent::AddChildDoc tolerates replacing one document with
+ // another. We must reflect that here.
+ MOZ_ASSERT(aChildDoc);
+ MOZ_ASSERT(mChildren.Length() <= 1);
+ if (mChildren.IsEmpty()) {
+ mChildren.AppendElement(aChildDoc);
+ } else {
+ mChildren.ReplaceElementAt(0, aChildDoc);
+ }
+ mOuterDoc = true;
+}
+
+template <class Derived>
+void
+ProxyAccessibleBase<Derived>::ClearChildDoc(DocAccessibleParent* aChildDoc)
+{
+ MOZ_ASSERT(aChildDoc);
+ // This is possible if we're replacing one document with another: Doc 1
+ // has not had a chance to remove itself, but was already replaced by Doc 2
+ // in SetChildDoc(). This could result in two subsequent calls to
+ // ClearChildDoc() even though mChildren.Length() == 1.
+ MOZ_ASSERT(mChildren.Length() <= 1);
+ if (mChildren.RemoveElement(aChildDoc)) {
+ mOuterDoc = false;
+ }
+}
+
+template <class Derived>
+bool
+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
+ && 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;
+}
+
+template <class Derived>
+uint32_t
+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
+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;
+}
+
+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) {
+ return mChildren[i];
+ }
+
+ index++;
+ }
+
+ return nullptr;
+}
+
+template <class Derived>
+Accessible*
+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;
+}
+
+template class ProxyAccessibleBase<ProxyAccessible>;
+
+} // namespace a11y
+} // namespace mozilla
diff --git a/accessible/ipc/ProxyAccessibleBase.h b/accessible/ipc/ProxyAccessibleBase.h
new file mode 100644
index 0000000000..bea669ffac
--- /dev/null
+++ b/accessible/ipc/ProxyAccessibleBase.h
@@ -0,0 +1,211 @@
+/* -*- 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_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,
+};
+
+template <class Derived>
+class ProxyAccessibleBase
+{
+public:
+ ~ProxyAccessibleBase()
+ {
+ MOZ_ASSERT(!mWrapper);
+ }
+
+ void AddChildAt(uint32_t aIdx, Derived* aChild)
+ { mChildren.InsertElementAt(aIdx, aChild); }
+
+ uint32_t ChildrenCount() const { return mChildren.Length(); }
+ Derived* ChildAt(uint32_t aIdx) const { return mChildren[aIdx]; }
+ Derived* FirstChild() const
+ { return mChildren.Length() ? mChildren[0] : nullptr; }
+ Derived* LastChild() const
+ { return mChildren.Length() ? mChildren[mChildren.Length() - 1] : nullptr; }
+ Derived* PrevSibling() const
+ {
+ size_t idx = IndexInParent();
+ return idx > 0 ? Parent()->mChildren[idx - 1] : nullptr;
+ }
+ 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(static_cast<const Derived*>(this)); }
+ uint32_t EmbeddedChildCount() const;
+ int32_t IndexOfEmbeddedChild(const Derived* aChild);
+ Derived* EmbeddedChildAt(size_t aChildIdx);
+ bool MustPruneChildren() const;
+
+ void Shutdown();
+
+ void SetChildDoc(DocAccessibleParent* aChildDoc);
+ void ClearChildDoc(DocAccessibleParent* aChildDoc);
+
+ /**
+ * Remove The given child.
+ */
+ void RemoveChild(Derived* aChild)
+ { mChildren.RemoveElement(aChild); }
+
+ /**
+ * Return the proxy for the parent of the wrapped accessible.
+ */
+ Derived* 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;
+ }
+
+ /**
+ * 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; }
+
+ // 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);
+ }
+
+protected:
+ 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)
+ {
+ }
+
+ 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)
+ {}
+
+protected:
+ Derived* mParent;
+
+private:
+ 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;
+};
+
+extern template class ProxyAccessibleBase<ProxyAccessible>;
+
+}
+}
+
+#endif
diff --git a/accessible/ipc/ProxyAccessibleShared.h b/accessible/ipc/ProxyAccessibleShared.h
new file mode 100644
index 0000000000..e940d72ed3
--- /dev/null
+++ b/accessible/ipc/ProxyAccessibleShared.h
@@ -0,0 +1,277 @@
+/* -*- 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_ProxyAccessibleShared_h
+#define mozilla_a11y_ProxyAccessibleShared_h
+
+/**
+ * These are function declarations shared between win/ProxyAccessible.h and
+ * other/ProxyAccessible.h.
+ */
+
+/*
+ * 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();
+
+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();
+
+void GetPosition(uint32_t* aColIdx, uint32_t* aRowIdx);
+
+uint32_t ColExtent();
+
+uint32_t RowExtent();
+
+void GetColRowExtents(uint32_t* aColIdx, uint32_t* aRowIdx,
+ uint32_t* aColExtent, uint32_t* aRowExtent);
+
+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);
+
+#endif
diff --git a/accessible/ipc/moz.build b/accessible/ipc/moz.build
new file mode 100644
index 0000000000..bb0632cd23
--- /dev/null
+++ b/accessible/ipc/moz.build
@@ -0,0 +1,61 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+if CONFIG['OS_ARCH'] == 'WINNT':
+ DIRS += ['win']
+ LOCAL_INCLUDES += [
+ '/accessible/ipc/win',
+ '/accessible/windows/ia2',
+ '/accessible/windows/msaa',
+ ]
+else:
+ DIRS += ['other']
+ LOCAL_INCLUDES += [
+ '/accessible/ipc/other',
+ ]
+ if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
+ LOCAL_INCLUDES += [
+ '/accessible/atk',
+ ]
+ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+ LOCAL_INCLUDES += [
+ '/accessible/mac',
+ ]
+ else:
+ LOCAL_INCLUDES += [
+ '/accessible/other',
+ ]
+
+EXPORTS.mozilla.a11y += [
+ 'IPCTypes.h',
+]
+
+if CONFIG['GNU_CXX']:
+ CXXFLAGS += ['-Wno-error=shadow']
+
+if CONFIG['ACCESSIBILITY']:
+ EXPORTS.mozilla.a11y += [
+ 'DocAccessibleChildBase.h',
+ 'DocAccessibleParent.h',
+ 'ProxyAccessibleBase.h',
+ 'ProxyAccessibleShared.h',
+ ]
+
+ UNIFIED_SOURCES += [
+ 'DocAccessibleChildBase.cpp',
+ 'DocAccessibleParent.cpp',
+ 'ProxyAccessibleBase.cpp',
+ ]
+
+ LOCAL_INCLUDES += [
+ '/accessible/base',
+ '/accessible/generic',
+ '/accessible/xpcom',
+ ]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FINAL_LIBRARY = 'xul'
diff --git a/accessible/ipc/other/DocAccessibleChild.cpp b/accessible/ipc/other/DocAccessibleChild.cpp
new file mode 100644
index 0000000000..045b789394
--- /dev/null
+++ b/accessible/ipc/other/DocAccessibleChild.cpp
@@ -0,0 +1,1998 @@
+/* -*- 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 "DocAccessibleChild.h"
+
+#include "Accessible-inl.h"
+#include "ProxyAccessible.h"
+#include "Relation.h"
+#include "HyperTextAccessible-inl.h"
+#include "TextLeafAccessible.h"
+#include "ImageAccessible.h"
+#include "TableAccessible.h"
+#include "TableCellAccessible.h"
+#include "nsIPersistentProperties2.h"
+#include "nsISimpleEnumerator.h"
+#include "nsAccUtils.h"
+#ifdef MOZ_ACCESSIBILITY_ATK
+#include "AccessibleWrap.h"
+#endif
+
+namespace mozilla {
+namespace a11y {
+
+Accessible*
+DocAccessibleChild::IdToAccessible(const uint64_t& aID) const
+{
+ if (!aID)
+ return mDoc;
+
+ if (!mDoc)
+ return nullptr;
+
+ return mDoc->GetAccessibleByUniqueID(reinterpret_cast<void*>(aID));
+}
+
+Accessible*
+DocAccessibleChild::IdToAccessibleLink(const uint64_t& aID) const
+{
+ Accessible* acc = IdToAccessible(aID);
+ return acc && acc->IsLink() ? acc : nullptr;
+}
+
+Accessible*
+DocAccessibleChild::IdToAccessibleSelect(const uint64_t& aID) const
+{
+ Accessible* acc = IdToAccessible(aID);
+ return acc && acc->IsSelect() ? acc : nullptr;
+}
+
+HyperTextAccessible*
+DocAccessibleChild::IdToHyperTextAccessible(const uint64_t& aID) const
+{
+ Accessible* acc = IdToAccessible(aID);
+ return acc && acc->IsHyperText() ? acc->AsHyperText() : nullptr;
+}
+
+TextLeafAccessible*
+DocAccessibleChild::IdToTextLeafAccessible(const uint64_t& aID) const
+{
+ Accessible* acc = IdToAccessible(aID);
+ return acc && acc->IsTextLeaf() ? acc->AsTextLeaf() : nullptr;
+}
+
+ImageAccessible*
+DocAccessibleChild::IdToImageAccessible(const uint64_t& aID) const
+{
+ Accessible* acc = IdToAccessible(aID);
+ return (acc && acc->IsImage()) ? acc->AsImage() : nullptr;
+}
+
+TableCellAccessible*
+DocAccessibleChild::IdToTableCellAccessible(const uint64_t& aID) const
+{
+ Accessible* acc = IdToAccessible(aID);
+ return (acc && acc->IsTableCell()) ? acc->AsTableCell() : nullptr;
+}
+
+TableAccessible*
+DocAccessibleChild::IdToTableAccessible(const uint64_t& aID) const
+{
+ Accessible* acc = IdToAccessible(aID);
+ return (acc && acc->IsTable()) ? acc->AsTable() : nullptr;
+}
+
+bool
+DocAccessibleChild::RecvState(const uint64_t& aID, uint64_t* aState)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc) {
+ *aState = states::DEFUNCT;
+ return true;
+ }
+
+ *aState = acc->State();
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvNativeState(const uint64_t& aID, uint64_t* aState)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc) {
+ *aState = states::DEFUNCT;
+ return true;
+ }
+
+ *aState = acc->NativeState();
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvName(const uint64_t& aID, nsString* aName)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc)
+ return true;
+
+ acc->Name(*aName);
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvValue(const uint64_t& aID, nsString* aValue)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc) {
+ return true;
+ }
+
+ acc->Value(*aValue);
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvHelp(const uint64_t& aID, nsString* aHelp)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc) {
+ return true;
+ }
+
+ acc->Help(*aHelp);
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvDescription(const uint64_t& aID, nsString* aDesc)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc)
+ return true;
+
+ acc->Description(*aDesc);
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvAttributes(const uint64_t& aID, nsTArray<Attribute>* aAttributes)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc)
+ return true;
+
+ nsCOMPtr<nsIPersistentProperties> props = acc->Attributes();
+ return PersistentPropertiesToArray(props, aAttributes);
+}
+
+bool
+DocAccessibleChild::PersistentPropertiesToArray(nsIPersistentProperties* aProps,
+ nsTArray<Attribute>* aAttributes)
+{
+ if (!aProps) {
+ return true;
+ }
+ nsCOMPtr<nsISimpleEnumerator> propEnum;
+ nsresult rv = aProps->Enumerate(getter_AddRefs(propEnum));
+ NS_ENSURE_SUCCESS(rv, false);
+
+ bool hasMore;
+ while (NS_SUCCEEDED(propEnum->HasMoreElements(&hasMore)) && hasMore) {
+ nsCOMPtr<nsISupports> sup;
+ rv = propEnum->GetNext(getter_AddRefs(sup));
+ NS_ENSURE_SUCCESS(rv, false);
+
+ nsCOMPtr<nsIPropertyElement> propElem(do_QueryInterface(sup));
+ NS_ENSURE_TRUE(propElem, false);
+
+ nsAutoCString name;
+ rv = propElem->GetKey(name);
+ NS_ENSURE_SUCCESS(rv, false);
+
+ nsAutoString value;
+ rv = propElem->GetValue(value);
+ NS_ENSURE_SUCCESS(rv, false);
+
+ aAttributes->AppendElement(Attribute(name, value));
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvRelationByType(const uint64_t& aID,
+ const uint32_t& aType,
+ nsTArray<uint64_t>* aTargets)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc)
+ return true;
+
+ auto type = static_cast<RelationType>(aType);
+ Relation rel = acc->RelationByType(type);
+ while (Accessible* target = rel.Next())
+ aTargets->AppendElement(reinterpret_cast<uintptr_t>(target));
+
+ return true;
+}
+
+static void
+AddRelation(Accessible* aAcc, RelationType aType,
+ nsTArray<RelationTargets>* aTargets)
+{
+ Relation rel = aAcc->RelationByType(aType);
+ nsTArray<uint64_t> targets;
+ while (Accessible* target = rel.Next())
+ targets.AppendElement(reinterpret_cast<uintptr_t>(target));
+
+ if (!targets.IsEmpty()) {
+ RelationTargets* newRelation =
+ aTargets->AppendElement(RelationTargets(static_cast<uint32_t>(aType),
+ nsTArray<uint64_t>()));
+ newRelation->Targets().SwapElements(targets);
+ }
+}
+
+bool
+DocAccessibleChild::RecvRelations(const uint64_t& aID,
+ nsTArray<RelationTargets>* aRelations)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc)
+ return true;
+
+#define RELATIONTYPE(gecko, s, a, m, i) AddRelation(acc, RelationType::gecko, aRelations);
+
+#include "RelationTypeMap.h"
+#undef RELATIONTYPE
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvIsSearchbox(const uint64_t& aID, bool* aRetVal)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc)
+ return true;
+
+ *aRetVal = acc->IsSearchbox();
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvLandmarkRole(const uint64_t& aID, nsString* aLandmark)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc) {
+ return true;
+ }
+
+ if (nsIAtom* roleAtom = acc->LandmarkRole()) {
+ roleAtom->ToString(*aLandmark);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvARIARoleAtom(const uint64_t& aID, nsString* aRole)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc) {
+ return true;
+ }
+
+ if (const nsRoleMapEntry* roleMap = acc->ARIARoleMap()) {
+ if (nsIAtom* roleAtom = *(roleMap->roleAtom)) {
+ roleAtom->ToString(*aRole);
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvGetLevelInternal(const uint64_t& aID, int32_t* aLevel)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ *aLevel = acc->GetLevelInternal();
+ }
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvScrollTo(const uint64_t& aID,
+ const uint32_t& aScrollType)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ nsCoreUtils::ScrollTo(acc->Document()->PresShell(), acc->GetContent(),
+ aScrollType);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvScrollToPoint(const uint64_t& aID, const uint32_t& aScrollType, const int32_t& aX, const int32_t& aY)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ acc->ScrollToPoint(aScrollType, aX, aY);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvCaretLineNumber(const uint64_t& aID, int32_t* aLineNumber)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ *aLineNumber = acc && acc->IsTextRole() ? acc->CaretLineNumber() : 0;
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvCaretOffset(const uint64_t& aID, int32_t* aOffset)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ *aOffset = acc && acc->IsTextRole() ? acc->CaretOffset() : 0;
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvSetCaretOffset(const uint64_t& aID,
+ const int32_t& aOffset)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole() && acc->IsValidOffset(aOffset)) {
+ acc->SetCaretOffset(aOffset);
+ }
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvCharacterCount(const uint64_t& aID, int32_t* aCount)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ *aCount = acc ? acc->CharacterCount() : 0;
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvSelectionCount(const uint64_t& aID, int32_t* aCount)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ *aCount = acc ? acc->SelectionCount() : 0;
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTextSubstring(const uint64_t& aID,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset,
+ nsString* aText, bool* aValid)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (!acc) {
+ return true;
+ }
+
+ *aValid = acc->IsValidRange(aStartOffset, aEndOffset);
+ acc->TextSubstring(aStartOffset, aEndOffset, *aText);
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvGetTextAfterOffset(const uint64_t& aID,
+ const int32_t& aOffset,
+ const int32_t& aBoundaryType,
+ nsString* aText,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset)
+{
+ *aStartOffset = 0;
+ *aEndOffset = 0;
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc) {
+ acc->TextAfterOffset(aOffset, aBoundaryType,
+ aStartOffset, aEndOffset, *aText);
+ }
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvGetTextAtOffset(const uint64_t& aID,
+ const int32_t& aOffset,
+ const int32_t& aBoundaryType,
+ nsString* aText,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset)
+{
+ *aStartOffset = 0;
+ *aEndOffset = 0;
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc) {
+ acc->TextAtOffset(aOffset, aBoundaryType,
+ aStartOffset, aEndOffset, *aText);
+ }
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvGetTextBeforeOffset(const uint64_t& aID,
+ const int32_t& aOffset,
+ const int32_t& aBoundaryType,
+ nsString* aText,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset)
+{
+ *aStartOffset = 0;
+ *aEndOffset = 0;
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc) {
+ acc->TextBeforeOffset(aOffset, aBoundaryType,
+ aStartOffset, aEndOffset, *aText);
+ }
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvCharAt(const uint64_t& aID,
+ const int32_t& aOffset,
+ uint16_t* aChar)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ *aChar = acc && acc->IsTextRole() ?
+ static_cast<uint16_t>(acc->CharAt(aOffset)) : 0;
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTextAttributes(const uint64_t& aID,
+ const bool& aIncludeDefAttrs,
+ const int32_t& aOffset,
+ nsTArray<Attribute>* aAttributes,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (!acc || !acc->IsTextRole()) {
+ return true;
+ }
+
+ nsCOMPtr<nsIPersistentProperties> props =
+ acc->TextAttributes(aIncludeDefAttrs, aOffset, aStartOffset, aEndOffset);
+ return PersistentPropertiesToArray(props, aAttributes);
+}
+
+bool
+DocAccessibleChild::RecvDefaultTextAttributes(const uint64_t& aID,
+ nsTArray<Attribute> *aAttributes)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (!acc || !acc->IsTextRole()) {
+ return true;
+ }
+
+ nsCOMPtr<nsIPersistentProperties> props = acc->DefaultTextAttributes();
+ return PersistentPropertiesToArray(props, aAttributes);
+}
+
+bool
+DocAccessibleChild::RecvTextBounds(const uint64_t& aID,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset,
+ const uint32_t& aCoordType,
+ nsIntRect* aRetVal)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ *aRetVal = acc->TextBounds(aStartOffset, aEndOffset, aCoordType);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvCharBounds(const uint64_t& aID,
+ const int32_t& aOffset,
+ const uint32_t& aCoordType,
+ nsIntRect* aRetVal)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ *aRetVal = acc->CharBounds(aOffset, aCoordType);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvOffsetAtPoint(const uint64_t& aID,
+ const int32_t& aX,
+ const int32_t& aY,
+ const uint32_t& aCoordType,
+ int32_t* aRetVal)
+{
+ *aRetVal = -1;
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ *aRetVal = acc->OffsetAtPoint(aX, aY, aCoordType);
+ }
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvSelectionBoundsAt(const uint64_t& aID,
+ const int32_t& aSelectionNum,
+ bool* aSucceeded,
+ nsString* aData,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset)
+{
+ *aSucceeded = false;
+ *aStartOffset = 0;
+ *aEndOffset = 0;
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ *aSucceeded =
+ acc->SelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
+ if (*aSucceeded) {
+ acc->TextSubstring(*aStartOffset, *aEndOffset, *aData);
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvSetSelectionBoundsAt(const uint64_t& aID,
+ const int32_t& aSelectionNum,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset,
+ bool* aSucceeded)
+{
+ *aSucceeded = false;
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ *aSucceeded =
+ acc->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvAddToSelection(const uint64_t& aID,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset,
+ bool* aSucceeded)
+{
+ *aSucceeded = false;
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ *aSucceeded = acc->AddToSelection(aStartOffset, aEndOffset);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvRemoveFromSelection(const uint64_t& aID,
+ const int32_t& aSelectionNum,
+ bool* aSucceeded)
+{
+ *aSucceeded = false;
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ *aSucceeded = acc->RemoveFromSelection(aSelectionNum);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvScrollSubstringTo(const uint64_t& aID,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset,
+ const uint32_t& aScrollType)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc) {
+ acc->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvScrollSubstringToPoint(const uint64_t& aID,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset,
+ const uint32_t& aCoordinateType,
+ const int32_t& aX,
+ const int32_t& aY)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc) {
+ acc->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoordinateType,
+ aX, aY);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvText(const uint64_t& aID,
+ nsString* aText)
+{
+ TextLeafAccessible* acc = IdToTextLeafAccessible(aID);
+ if (acc) {
+ *aText = acc->Text();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvReplaceText(const uint64_t& aID,
+ const nsString& aText)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ acc->ReplaceText(aText);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvInsertText(const uint64_t& aID,
+ const nsString& aText,
+ const int32_t& aPosition, bool* aValid)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ *aValid = acc->IsValidOffset(aPosition);
+ acc->InsertText(aText, aPosition);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvCopyText(const uint64_t& aID,
+ const int32_t& aStartPos,
+ const int32_t& aEndPos, bool* aValid)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ acc->CopyText(aStartPos, aEndPos);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvCutText(const uint64_t& aID,
+ const int32_t& aStartPos,
+ const int32_t& aEndPos, bool* aValid)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ *aValid = acc->IsValidRange(aStartPos, aEndPos);
+ acc->CutText(aStartPos, aEndPos);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvDeleteText(const uint64_t& aID,
+ const int32_t& aStartPos,
+ const int32_t& aEndPos, bool* aValid)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ *aValid = acc->IsValidRange(aStartPos, aEndPos);
+ acc->DeleteText(aStartPos, aEndPos);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvPasteText(const uint64_t& aID,
+ const int32_t& aPosition, bool* aValid)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc && acc->IsTextRole()) {
+ *aValid = acc->IsValidOffset(aPosition);
+ acc->PasteText(aPosition);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvImagePosition(const uint64_t& aID,
+ const uint32_t& aCoordType,
+ nsIntPoint* aRetVal)
+{
+ ImageAccessible* acc = IdToImageAccessible(aID);
+ if (acc) {
+ *aRetVal = acc->Position(aCoordType);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvImageSize(const uint64_t& aID,
+ nsIntSize* aRetVal)
+{
+
+ ImageAccessible* acc = IdToImageAccessible(aID);
+ if (acc) {
+ *aRetVal = acc->Size();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvStartOffset(const uint64_t& aID,
+ uint32_t* aRetVal,
+ bool* aOk)
+{
+ Accessible* acc = IdToAccessibleLink(aID);
+ if (acc) {
+ *aRetVal = acc->StartOffset();
+ *aOk = true;
+ } else {
+ *aRetVal = 0;
+ *aOk = false;
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvEndOffset(const uint64_t& aID,
+ uint32_t* aRetVal,
+ bool* aOk)
+{
+ Accessible* acc = IdToAccessibleLink(aID);
+ if (acc) {
+ *aRetVal = acc->EndOffset();
+ *aOk = true;
+ } else {
+ *aRetVal = 0;
+ *aOk = false;
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvIsLinkValid(const uint64_t& aID,
+ bool* aRetVal)
+{
+ Accessible* acc = IdToAccessibleLink(aID);
+ if (acc) {
+ *aRetVal = acc->IsLinkValid();
+ } else {
+ *aRetVal = false;
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvAnchorCount(const uint64_t& aID,
+ uint32_t* aRetVal,
+ bool* aOk)
+{
+ Accessible* acc = IdToAccessibleLink(aID);
+ if (acc) {
+ *aRetVal = acc->AnchorCount();
+ *aOk = true;
+ } else {
+ *aRetVal = 0;
+ *aOk = false;
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvAnchorURIAt(const uint64_t& aID,
+ const uint32_t& aIndex,
+ nsCString* aURI,
+ bool* aOk)
+{
+ Accessible* acc = IdToAccessibleLink(aID);
+ *aOk = false;
+ if (acc) {
+ nsCOMPtr<nsIURI> uri = acc->AnchorURIAt(aIndex);
+ if (uri) {
+ uri->GetSpec(*aURI);
+ *aOk = true;
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvAnchorAt(const uint64_t& aID,
+ const uint32_t& aIndex,
+ uint64_t* aIDOfAnchor,
+ bool* aOk)
+{
+ *aIDOfAnchor = 0;
+ *aOk = false;
+ Accessible* acc = IdToAccessibleLink(aID);
+ if (acc) {
+ Accessible* anchor = acc->AnchorAt(aIndex);
+ if (anchor) {
+ *aIDOfAnchor = reinterpret_cast<uint64_t>(anchor->UniqueID());
+ *aOk = true;
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvLinkCount(const uint64_t& aID,
+ uint32_t* aCount)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ *aCount = acc ? acc->LinkCount() : 0;
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvLinkAt(const uint64_t& aID,
+ const uint32_t& aIndex,
+ uint64_t* aIDOfLink,
+ bool* aOk)
+{
+ *aIDOfLink = 0;
+ *aOk = false;
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ if (acc) {
+ Accessible* link = acc->LinkAt(aIndex);
+ if (link) {
+ *aIDOfLink = reinterpret_cast<uint64_t>(link->UniqueID());
+ *aOk = true;
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvLinkIndexOf(const uint64_t& aID,
+ const uint64_t& aLinkID,
+ int32_t* aIndex)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ Accessible* link = IdToAccessible(aLinkID);
+ *aIndex = -1;
+ if (acc && link) {
+ *aIndex = acc->LinkIndexOf(link);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvLinkIndexAtOffset(const uint64_t& aID,
+ const uint32_t& aOffset,
+ int32_t* aIndex)
+{
+ HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+ *aIndex = acc ? acc->LinkIndexAtOffset(aOffset) : -1;
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableOfACell(const uint64_t& aID,
+ uint64_t* aTableID,
+ bool* aOk)
+{
+ *aTableID = 0;
+ *aOk = false;
+ TableCellAccessible* acc = IdToTableCellAccessible(aID);
+ if (acc) {
+ TableAccessible* table = acc->Table();
+ if (table) {
+ *aTableID = reinterpret_cast<uint64_t>(table->AsAccessible()->UniqueID());
+ *aOk = true;
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvColIdx(const uint64_t& aID,
+ uint32_t* aIndex)
+{
+ *aIndex = 0;
+ TableCellAccessible* acc = IdToTableCellAccessible(aID);
+ if (acc) {
+ *aIndex = acc->ColIdx();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvRowIdx(const uint64_t& aID,
+ uint32_t* aIndex)
+{
+ *aIndex = 0;
+ TableCellAccessible* acc = IdToTableCellAccessible(aID);
+ if (acc) {
+ *aIndex = acc->RowIdx();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvGetPosition(const uint64_t& aID,
+ uint32_t* aColIdx, uint32_t* aRowIdx)
+{
+ *aColIdx = 0;
+ *aRowIdx = 0;
+ TableCellAccessible* acc = IdToTableCellAccessible(aID);
+ if (acc) {
+ *aColIdx = acc->ColIdx();
+ *aRowIdx = acc->RowIdx();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvGetColRowExtents(const uint64_t& aID,
+ uint32_t* aColIdx, uint32_t* aRowIdx,
+ uint32_t* aColExtent, uint32_t* aRowExtent)
+{
+ *aColIdx = 0;
+ *aRowIdx = 0;
+ *aColExtent = 0;
+ *aRowExtent = 0;
+ TableCellAccessible* acc = IdToTableCellAccessible(aID);
+ if (acc) {
+ *aColIdx = acc->ColIdx();
+ *aRowIdx = acc->RowIdx();
+ *aColExtent = acc->ColExtent();
+ *aRowExtent = acc->RowExtent();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvColExtent(const uint64_t& aID,
+ uint32_t* aExtent)
+{
+ *aExtent = 0;
+ TableCellAccessible* acc = IdToTableCellAccessible(aID);
+ if (acc) {
+ *aExtent = acc->ColExtent();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvRowExtent(const uint64_t& aID,
+ uint32_t* aExtent)
+{
+ *aExtent = 0;
+ TableCellAccessible* acc = IdToTableCellAccessible(aID);
+ if (acc) {
+ *aExtent = acc->RowExtent();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvColHeaderCells(const uint64_t& aID,
+ nsTArray<uint64_t>* aCells)
+{
+ TableCellAccessible* acc = IdToTableCellAccessible(aID);
+ if (acc) {
+ AutoTArray<Accessible*, 10> headerCells;
+ acc->ColHeaderCells(&headerCells);
+ aCells->SetCapacity(headerCells.Length());
+ for (uint32_t i = 0; i < headerCells.Length(); ++i) {
+ aCells->AppendElement(
+ reinterpret_cast<uint64_t>(headerCells[i]->UniqueID()));
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvRowHeaderCells(const uint64_t& aID,
+ nsTArray<uint64_t>* aCells)
+{
+ TableCellAccessible* acc = IdToTableCellAccessible(aID);
+ if (acc) {
+ AutoTArray<Accessible*, 10> headerCells;
+ acc->RowHeaderCells(&headerCells);
+ aCells->SetCapacity(headerCells.Length());
+ for (uint32_t i = 0; i < headerCells.Length(); ++i) {
+ aCells->AppendElement(
+ reinterpret_cast<uint64_t>(headerCells[i]->UniqueID()));
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvIsCellSelected(const uint64_t& aID,
+ bool* aSelected)
+{
+ TableCellAccessible* acc = IdToTableCellAccessible(aID);
+ *aSelected = acc && acc->Selected();
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableCaption(const uint64_t& aID,
+ uint64_t* aCaptionID,
+ bool* aOk)
+{
+ *aCaptionID = 0;
+ *aOk = false;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ Accessible* caption = acc->Caption();
+ if (caption) {
+ *aCaptionID = reinterpret_cast<uint64_t>(caption->UniqueID());
+ *aOk = true;
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableSummary(const uint64_t& aID,
+ nsString* aSummary)
+{
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ acc->Summary(*aSummary);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableColumnCount(const uint64_t& aID,
+ uint32_t* aColCount)
+{
+ *aColCount = 0;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aColCount = acc->ColCount();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableRowCount(const uint64_t& aID,
+ uint32_t* aRowCount)
+{
+ *aRowCount = 0;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aRowCount = acc->RowCount();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableCellAt(const uint64_t& aID,
+ const uint32_t& aRow,
+ const uint32_t& aCol,
+ uint64_t* aCellID,
+ bool* aOk)
+{
+ *aCellID = 0;
+ *aOk = false;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ Accessible* cell = acc->CellAt(aRow, aCol);
+ if (cell) {
+ *aCellID = reinterpret_cast<uint64_t>(cell->UniqueID());
+ *aOk = true;
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableCellIndexAt(const uint64_t& aID,
+ const uint32_t& aRow,
+ const uint32_t& aCol,
+ int32_t* aIndex)
+{
+ *aIndex = -1;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aIndex = acc->CellIndexAt(aRow, aCol);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableColumnIndexAt(const uint64_t& aID,
+ const uint32_t& aCellIndex,
+ int32_t* aCol)
+{
+ *aCol = -1;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aCol = acc->ColIndexAt(aCellIndex);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableRowIndexAt(const uint64_t& aID,
+ const uint32_t& aCellIndex,
+ int32_t* aRow)
+{
+ *aRow = -1;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aRow = acc->RowIndexAt(aCellIndex);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableRowAndColumnIndicesAt(const uint64_t& aID,
+ const uint32_t& aCellIndex,
+ int32_t* aRow,
+ int32_t* aCol)
+{
+ *aRow = -1;
+ *aCol = -1;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ acc->RowAndColIndicesAt(aCellIndex, aRow, aCol);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableColumnExtentAt(const uint64_t& aID,
+ const uint32_t& aRow,
+ const uint32_t& aCol,
+ uint32_t* aExtent)
+{
+ *aExtent = 0;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aExtent = acc->ColExtentAt(aRow, aCol);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableRowExtentAt(const uint64_t& aID,
+ const uint32_t& aRow,
+ const uint32_t& aCol,
+ uint32_t* aExtent)
+{
+ *aExtent = 0;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aExtent = acc->RowExtentAt(aRow, aCol);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableColumnDescription(const uint64_t& aID,
+ const uint32_t& aCol,
+ nsString* aDescription)
+{
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ acc->ColDescription(aCol, *aDescription);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableRowDescription(const uint64_t& aID,
+ const uint32_t& aRow,
+ nsString* aDescription)
+{
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ acc->RowDescription(aRow, *aDescription);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableColumnSelected(const uint64_t& aID,
+ const uint32_t& aCol,
+ bool* aSelected)
+{
+ *aSelected = false;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aSelected = acc->IsColSelected(aCol);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableRowSelected(const uint64_t& aID,
+ const uint32_t& aRow,
+ bool* aSelected)
+{
+ *aSelected = false;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aSelected = acc->IsRowSelected(aRow);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableCellSelected(const uint64_t& aID,
+ const uint32_t& aRow,
+ const uint32_t& aCol,
+ bool* aSelected)
+{
+ *aSelected = false;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aSelected = acc->IsCellSelected(aRow, aCol);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableSelectedCellCount(const uint64_t& aID,
+ uint32_t* aSelectedCells)
+{
+ *aSelectedCells = 0;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aSelectedCells = acc->SelectedCellCount();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableSelectedColumnCount(const uint64_t& aID,
+ uint32_t* aSelectedColumns)
+{
+ *aSelectedColumns = 0;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aSelectedColumns = acc->SelectedColCount();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableSelectedRowCount(const uint64_t& aID,
+ uint32_t* aSelectedRows)
+{
+ *aSelectedRows = 0;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aSelectedRows = acc->SelectedRowCount();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableSelectedCells(const uint64_t& aID,
+ nsTArray<uint64_t>* aCellIDs)
+{
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ AutoTArray<Accessible*, 30> cells;
+ acc->SelectedCells(&cells);
+ aCellIDs->SetCapacity(cells.Length());
+ for (uint32_t i = 0; i < cells.Length(); ++i) {
+ aCellIDs->AppendElement(
+ reinterpret_cast<uint64_t>(cells[i]->UniqueID()));
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableSelectedCellIndices(const uint64_t& aID,
+ nsTArray<uint32_t>* aCellIndices)
+{
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ acc->SelectedCellIndices(aCellIndices);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableSelectedColumnIndices(const uint64_t& aID,
+ nsTArray<uint32_t>* aColumnIndices)
+{
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ acc->SelectedColIndices(aColumnIndices);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableSelectedRowIndices(const uint64_t& aID,
+ nsTArray<uint32_t>* aRowIndices)
+{
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ acc->SelectedRowIndices(aRowIndices);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableSelectColumn(const uint64_t& aID,
+ const uint32_t& aCol)
+{
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ acc->SelectCol(aCol);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableSelectRow(const uint64_t& aID,
+ const uint32_t& aRow)
+{
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ acc->SelectRow(aRow);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableUnselectColumn(const uint64_t& aID,
+ const uint32_t& aCol)
+{
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ acc->UnselectCol(aCol);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableUnselectRow(const uint64_t& aID,
+ const uint32_t& aRow)
+{
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ acc->UnselectRow(aRow);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTableIsProbablyForLayout(const uint64_t& aID,
+ bool* aForLayout)
+{
+ *aForLayout = false;
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ *aForLayout = acc->IsProbablyLayoutTable();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvAtkTableColumnHeader(const uint64_t& aID,
+ const int32_t& aCol,
+ uint64_t* aHeader,
+ bool* aOk)
+{
+ *aHeader = 0;
+ *aOk = false;
+
+#ifdef MOZ_ACCESSIBILITY_ATK
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ Accessible* header = AccessibleWrap::GetColumnHeader(acc, aCol);
+ if (header) {
+ *aHeader = reinterpret_cast<uint64_t>(header->UniqueID());
+ *aOk = true;
+ }
+ }
+#endif
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvAtkTableRowHeader(const uint64_t& aID,
+ const int32_t& aRow,
+ uint64_t* aHeader,
+ bool* aOk)
+{
+ *aHeader = 0;
+ *aOk = false;
+
+#ifdef MOZ_ACCESSIBILITY_ATK
+ TableAccessible* acc = IdToTableAccessible(aID);
+ if (acc) {
+ Accessible* header = AccessibleWrap::GetRowHeader(acc, aRow);
+ if (header) {
+ *aHeader = reinterpret_cast<uint64_t>(header->UniqueID());
+ *aOk = true;
+ }
+ }
+#endif
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvSelectedItems(const uint64_t& aID,
+ nsTArray<uint64_t>* aSelectedItemIDs)
+{
+ Accessible* acc = IdToAccessibleSelect(aID);
+ if (acc) {
+ AutoTArray<Accessible*, 10> selectedItems;
+ acc->SelectedItems(&selectedItems);
+ aSelectedItemIDs->SetCapacity(selectedItems.Length());
+ for (size_t i = 0; i < selectedItems.Length(); ++i) {
+ aSelectedItemIDs->AppendElement(
+ reinterpret_cast<uint64_t>(selectedItems[i]->UniqueID()));
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvSelectedItemCount(const uint64_t& aID,
+ uint32_t* aCount)
+{
+ *aCount = 0;
+ Accessible* acc = IdToAccessibleSelect(aID);
+ if (acc) {
+ *aCount = acc->SelectedItemCount();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvGetSelectedItem(const uint64_t& aID,
+ const uint32_t& aIndex,
+ uint64_t* aSelected,
+ bool* aOk)
+{
+ *aSelected = 0;
+ *aOk = false;
+ Accessible* acc = IdToAccessibleSelect(aID);
+ if (acc) {
+ Accessible* item = acc->GetSelectedItem(aIndex);
+ if (item) {
+ *aSelected = reinterpret_cast<uint64_t>(item->UniqueID());
+ *aOk = true;
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvIsItemSelected(const uint64_t& aID,
+ const uint32_t& aIndex,
+ bool* aSelected)
+{
+ *aSelected = false;
+ Accessible* acc = IdToAccessibleSelect(aID);
+ if (acc) {
+ *aSelected = acc->IsItemSelected(aIndex);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvAddItemToSelection(const uint64_t& aID,
+ const uint32_t& aIndex,
+ bool* aSuccess)
+{
+ *aSuccess = false;
+ Accessible* acc = IdToAccessibleSelect(aID);
+ if (acc) {
+ *aSuccess = acc->AddItemToSelection(aIndex);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvRemoveItemFromSelection(const uint64_t& aID,
+ const uint32_t& aIndex,
+ bool* aSuccess)
+{
+ *aSuccess = false;
+ Accessible* acc = IdToAccessibleSelect(aID);
+ if (acc) {
+ *aSuccess = acc->RemoveItemFromSelection(aIndex);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvSelectAll(const uint64_t& aID,
+ bool* aSuccess)
+{
+ *aSuccess = false;
+ Accessible* acc = IdToAccessibleSelect(aID);
+ if (acc) {
+ *aSuccess = acc->SelectAll();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvUnselectAll(const uint64_t& aID,
+ bool* aSuccess)
+{
+ *aSuccess = false;
+ Accessible* acc = IdToAccessibleSelect(aID);
+ if (acc) {
+ *aSuccess = acc->UnselectAll();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTakeSelection(const uint64_t& aID)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ acc->TakeSelection();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvSetSelected(const uint64_t& aID, const bool& aSelect)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ acc->SetSelected(aSelect);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvDoAction(const uint64_t& aID,
+ const uint8_t& aIndex,
+ bool* aSuccess)
+{
+ *aSuccess = false;
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ *aSuccess = acc->DoAction(aIndex);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvActionCount(const uint64_t& aID,
+ uint8_t* aCount)
+{
+ *aCount = 0;
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ *aCount = acc->ActionCount();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvActionDescriptionAt(const uint64_t& aID,
+ const uint8_t& aIndex,
+ nsString* aDescription)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ acc->ActionDescriptionAt(aIndex, *aDescription);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvActionNameAt(const uint64_t& aID,
+ const uint8_t& aIndex,
+ nsString* aName)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ acc->ActionNameAt(aIndex, *aName);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvAccessKey(const uint64_t& aID,
+ uint32_t* aKey,
+ uint32_t* aModifierMask)
+{
+ *aKey = 0;
+ *aModifierMask = 0;
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ KeyBinding kb = acc->AccessKey();
+ *aKey = kb.Key();
+ *aModifierMask = kb.ModifierMask();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvKeyboardShortcut(const uint64_t& aID,
+ uint32_t* aKey,
+ uint32_t* aModifierMask)
+{
+ *aKey = 0;
+ *aModifierMask = 0;
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ KeyBinding kb = acc->KeyboardShortcut();
+ *aKey = kb.Key();
+ *aModifierMask = kb.ModifierMask();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvAtkKeyBinding(const uint64_t& aID,
+ nsString* aResult)
+{
+#ifdef MOZ_ACCESSIBILITY_ATK
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ AccessibleWrap::GetKeyBinding(acc, *aResult);
+ }
+#endif
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvCurValue(const uint64_t& aID,
+ double* aValue)
+{
+ *aValue = UnspecifiedNaN<double>();
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ *aValue = acc->CurValue();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvSetCurValue(const uint64_t& aID,
+ const double& aValue,
+ bool* aRetVal)
+{
+ *aRetVal = false;
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ *aRetVal = acc->SetCurValue(aValue);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvMinValue(const uint64_t& aID,
+ double* aValue)
+{
+ *aValue = UnspecifiedNaN<double>();
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ *aValue = acc->MinValue();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvMaxValue(const uint64_t& aID,
+ double* aValue)
+{
+ *aValue = UnspecifiedNaN<double>();
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ *aValue = acc->MaxValue();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvStep(const uint64_t& aID,
+ double* aStep)
+{
+ *aStep = UnspecifiedNaN<double>();
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ *aStep = acc->Step();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTakeFocus(const uint64_t& aID)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ acc->TakeFocus();
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvFocusedChild(const uint64_t& aID,
+ uint64_t* aChild,
+ bool* aOk)
+{
+ *aChild = 0;
+ *aOk = false;
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ Accessible* child = acc->FocusedChild();
+ if (child) {
+ *aChild = reinterpret_cast<uint64_t>(child->UniqueID());
+ *aOk = true;
+ }
+ }
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvLanguage(const uint64_t& aID,
+ nsString* aLocale)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ acc->Language(*aLocale);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvDocType(const uint64_t& aID,
+ nsString* aType)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc && acc->IsDoc()) {
+ acc->AsDoc()->DocType(*aType);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvTitle(const uint64_t& aID,
+ nsString* aTitle)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc) {
+ mozilla::ErrorResult rv;
+ acc->GetContent()->GetTextContent(*aTitle, rv);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvURL(const uint64_t& aID,
+ nsString* aURL)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc && acc->IsDoc()) {
+ acc->AsDoc()->URL(*aURL);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvMimeType(const uint64_t& aID,
+ nsString* aMime)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc && acc->IsDoc()) {
+ acc->AsDoc()->MimeType(*aMime);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvURLDocTypeMimeType(const uint64_t& aID,
+ nsString* aURL,
+ nsString* aDocType,
+ nsString* aMimeType)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (acc && acc->IsDoc()) {
+ DocAccessible* doc = acc->AsDoc();
+ doc->URL(*aURL);
+ doc->DocType(*aDocType);
+ doc->MimeType(*aMimeType);
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvAccessibleAtPoint(const uint64_t& aID,
+ const int32_t& aX,
+ const int32_t& aY,
+ const bool& aNeedsScreenCoords,
+ const uint32_t& aWhich,
+ uint64_t* aResult,
+ bool* aOk)
+{
+ *aResult = 0;
+ *aOk = false;
+ Accessible* acc = IdToAccessible(aID);
+ if (acc && !acc->IsDefunct() && !nsAccUtils::MustPrune(acc)) {
+ int32_t x = aX;
+ int32_t y = aY;
+ if (aNeedsScreenCoords) {
+ nsIntPoint winCoords =
+ nsCoreUtils::GetScreenCoordsForWindow(acc->GetNode());
+ x += winCoords.x;
+ y += winCoords.y;
+ }
+
+ Accessible* result =
+ acc->ChildAtPoint(x, y,
+ static_cast<Accessible::EWhichChildAtPoint>(aWhich));
+ if (result) {
+ *aResult = reinterpret_cast<uint64_t>(result->UniqueID());
+ *aOk = true;
+ }
+ }
+
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvExtents(const uint64_t& aID,
+ const bool& aNeedsScreenCoords,
+ int32_t* aX,
+ int32_t* aY,
+ int32_t* aWidth,
+ int32_t* aHeight)
+{
+ *aX = 0;
+ *aY = 0;
+ *aWidth = 0;
+ *aHeight = 0;
+ Accessible* acc = IdToAccessible(aID);
+ if (acc && !acc->IsDefunct()) {
+ nsIntRect screenRect = acc->Bounds();
+ if (!screenRect.IsEmpty()) {
+ if (aNeedsScreenCoords) {
+ nsIntPoint winCoords =
+ nsCoreUtils::GetScreenCoordsForWindow(acc->GetNode());
+ screenRect.x -= winCoords.x;
+ screenRect.y -= winCoords.y;
+ }
+
+ *aX = screenRect.x;
+ *aY = screenRect.y;
+ *aWidth = screenRect.width;
+ *aHeight = screenRect.height;
+ }
+ }
+ return true;
+}
+
+bool
+DocAccessibleChild::RecvDOMNodeID(const uint64_t& aID, nsString* aDOMNodeID)
+{
+ Accessible* acc = IdToAccessible(aID);
+ if (!acc) {
+ return true;
+ }
+
+ nsIContent* content = acc->GetContent();
+ if (!content) {
+ return true;
+ }
+
+ nsIAtom* id = content->GetID();
+ if (id) {
+ id->ToString(*aDOMNodeID);
+ }
+
+ return true;
+}
+
+}
+}
diff --git a/accessible/ipc/other/DocAccessibleChild.h b/accessible/ipc/other/DocAccessibleChild.h
new file mode 100644
index 0000000000..7c9d61da7f
--- /dev/null
+++ b/accessible/ipc/other/DocAccessibleChild.h
@@ -0,0 +1,489 @@
+/* -*- 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_DocAccessibleChild_h
+#define mozilla_a11y_DocAccessibleChild_h
+
+#include "mozilla/a11y/DocAccessibleChildBase.h"
+
+namespace mozilla {
+namespace a11y {
+
+class Accessible;
+class HyperTextAccessible;
+class TextLeafAccessible;
+class ImageAccessible;
+class TableAccessible;
+class TableCellAccessible;
+
+/*
+ * These objects handle content side communication for an accessible document,
+ * and their lifetime is the same as the document they represent.
+ */
+class DocAccessibleChild : public DocAccessibleChildBase
+{
+public:
+ explicit DocAccessibleChild(DocAccessible* aDoc)
+ : DocAccessibleChildBase(aDoc)
+ {
+ MOZ_COUNT_CTOR_INHERITED(DocAccessibleChild, DocAccessibleChildBase);
+ }
+
+ ~DocAccessibleChild()
+ {
+ MOZ_COUNT_DTOR_INHERITED(DocAccessibleChild, DocAccessibleChildBase);
+ }
+
+ /*
+ * Return the state for the accessible with given ID.
+ */
+ virtual bool RecvState(const uint64_t& aID, uint64_t* aState) override;
+
+ /*
+ * Return the native state for the accessible with given ID.
+ */
+ virtual bool RecvNativeState(const uint64_t& aID, uint64_t* aState) override;
+
+ /*
+ * Get the name for the accessible with given id.
+ */
+ virtual bool RecvName(const uint64_t& aID, nsString* aName) override;
+
+ virtual bool RecvValue(const uint64_t& aID, nsString* aValue) override;
+
+ virtual bool RecvHelp(const uint64_t& aID, nsString* aHelp) override;
+
+ /*
+ * Get the description for the accessible with given id.
+ */
+ virtual bool RecvDescription(const uint64_t& aID, nsString* aDesc) override;
+ virtual bool RecvRelationByType(const uint64_t& aID, const uint32_t& aType,
+ nsTArray<uint64_t>* aTargets) override;
+ virtual bool RecvRelations(const uint64_t& aID,
+ nsTArray<RelationTargets>* aRelations)
+ override;
+
+ virtual bool RecvIsSearchbox(const uint64_t& aID, bool* aRetVal) override;
+
+ virtual bool RecvLandmarkRole(const uint64_t& aID, nsString* aLandmark) override;
+
+ virtual bool RecvARIARoleAtom(const uint64_t& aID, nsString* aRole) override;
+
+ virtual bool RecvGetLevelInternal(const uint64_t& aID, int32_t* aLevel) override;
+
+ virtual bool RecvAttributes(const uint64_t& aID,
+ nsTArray<Attribute> *aAttributes) override;
+ virtual bool RecvScrollTo(const uint64_t& aID, const uint32_t& aScrollType)
+ override;
+ virtual bool RecvScrollToPoint(const uint64_t& aID,
+ const uint32_t& aScrollType,
+ const int32_t& aX, const int32_t& aY) override;
+
+ virtual bool RecvCaretLineNumber(const uint64_t& aID, int32_t* aLineNumber)
+ override;
+ virtual bool RecvCaretOffset(const uint64_t& aID, int32_t* aOffset)
+ override;
+ virtual bool RecvSetCaretOffset(const uint64_t& aID, const int32_t& aOffset)
+ override;
+
+ virtual bool RecvCharacterCount(const uint64_t& aID, int32_t* aCount)
+ override;
+ virtual bool RecvSelectionCount(const uint64_t& aID, int32_t* aCount)
+ override;
+
+ virtual bool RecvTextSubstring(const uint64_t& aID,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset, nsString* aText,
+ bool* aValid) override;
+
+ virtual bool RecvGetTextAfterOffset(const uint64_t& aID,
+ const int32_t& aOffset,
+ const int32_t& aBoundaryType,
+ nsString* aText, int32_t* aStartOffset,
+ int32_t* aEndOffset) override;
+ virtual bool RecvGetTextAtOffset(const uint64_t& aID,
+ const int32_t& aOffset,
+ const int32_t& aBoundaryType,
+ nsString* aText, int32_t* aStartOffset,
+ int32_t* aEndOffset) override;
+ virtual bool RecvGetTextBeforeOffset(const uint64_t& aID,
+ const int32_t& aOffset,
+ const int32_t& aBoundaryType,
+ nsString* aText, int32_t* aStartOffset,
+ int32_t* aEndOffset) override;
+
+ virtual bool RecvCharAt(const uint64_t& aID,
+ const int32_t& aOffset,
+ uint16_t* aChar) override;
+
+ virtual bool RecvTextAttributes(const uint64_t& aID,
+ const bool& aIncludeDefAttrs,
+ const int32_t& aOffset,
+ nsTArray<Attribute>* aAttributes,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset)
+ override;
+
+ virtual bool RecvDefaultTextAttributes(const uint64_t& aID,
+ nsTArray<Attribute>* aAttributes)
+ override;
+
+ virtual bool RecvTextBounds(const uint64_t& aID,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset,
+ const uint32_t& aCoordType,
+ nsIntRect* aRetVal) override;
+
+ virtual bool RecvCharBounds(const uint64_t& aID,
+ const int32_t& aOffset,
+ const uint32_t& aCoordType,
+ nsIntRect* aRetVal) override;
+
+ virtual bool RecvOffsetAtPoint(const uint64_t& aID,
+ const int32_t& aX,
+ const int32_t& aY,
+ const uint32_t& aCoordType,
+ int32_t* aRetVal) override;
+
+ virtual bool RecvSelectionBoundsAt(const uint64_t& aID,
+ const int32_t& aSelectionNum,
+ bool* aSucceeded,
+ nsString* aData,
+ int32_t* aStartOffset,
+ int32_t* aEndOffset) override;
+
+ virtual bool RecvSetSelectionBoundsAt(const uint64_t& aID,
+ const int32_t& aSelectionNum,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset,
+ bool* aSucceeded) override;
+
+ virtual bool RecvAddToSelection(const uint64_t& aID,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset,
+ bool* aSucceeded) override;
+
+ virtual bool RecvRemoveFromSelection(const uint64_t& aID,
+ const int32_t& aSelectionNum,
+ bool* aSucceeded) override;
+
+ virtual bool RecvScrollSubstringTo(const uint64_t& aID,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset,
+ const uint32_t& aScrollType) override;
+
+ virtual bool RecvScrollSubstringToPoint(const uint64_t& aID,
+ const int32_t& aStartOffset,
+ const int32_t& aEndOffset,
+ const uint32_t& aCoordinateType,
+ const int32_t& aX,
+ const int32_t& aY) override;
+
+ virtual bool RecvText(const uint64_t& aID,
+ nsString* aText) override;
+
+ virtual bool RecvReplaceText(const uint64_t& aID,
+ const nsString& aText) override;
+
+ virtual bool RecvInsertText(const uint64_t& aID,
+ const nsString& aText,
+ const int32_t& aPosition, bool* aValid) override;
+
+ virtual bool RecvCopyText(const uint64_t& aID,
+ const int32_t& aStartPos,
+ const int32_t& aEndPos, bool* aValid) override;
+
+ virtual bool RecvCutText(const uint64_t& aID,
+ const int32_t& aStartPos,
+ const int32_t& aEndPos, bool* aValid) override;
+
+ virtual bool RecvDeleteText(const uint64_t& aID,
+ const int32_t& aStartPos,
+ const int32_t& aEndPos, bool* aValid) override;
+
+ virtual bool RecvPasteText(const uint64_t& aID,
+ const int32_t& aPosition, bool* aValid) override;
+
+ virtual bool RecvImagePosition(const uint64_t& aID,
+ const uint32_t& aCoordType,
+ nsIntPoint* aRetVal) override;
+
+ virtual bool RecvImageSize(const uint64_t& aID,
+ nsIntSize* aRetVal) override;
+
+ virtual bool RecvStartOffset(const uint64_t& aID,
+ uint32_t* aRetVal,
+ bool* aOk) override;
+ virtual bool RecvEndOffset(const uint64_t& aID,
+ uint32_t* aRetVal,
+ bool* aOk) override;
+ virtual bool RecvIsLinkValid(const uint64_t& aID,
+ bool* aRetVal) override;
+ virtual bool RecvAnchorCount(const uint64_t& aID,
+ uint32_t* aRetVal, bool* aOk) override;
+ virtual bool RecvAnchorURIAt(const uint64_t& aID,
+ const uint32_t& aIndex,
+ nsCString* aURI,
+ bool* aOk) override;
+ virtual bool RecvAnchorAt(const uint64_t& aID,
+ const uint32_t& aIndex,
+ uint64_t* aIDOfAnchor,
+ bool* aOk) override;
+
+ virtual bool RecvLinkCount(const uint64_t& aID,
+ uint32_t* aCount) override;
+
+ virtual bool RecvLinkAt(const uint64_t& aID,
+ const uint32_t& aIndex,
+ uint64_t* aIDOfLink,
+ bool* aOk) override;
+
+ virtual bool RecvLinkIndexOf(const uint64_t& aID,
+ const uint64_t& aLinkID,
+ int32_t* aIndex) override;
+
+ virtual bool RecvLinkIndexAtOffset(const uint64_t& aID,
+ const uint32_t& aOffset,
+ int32_t* aIndex) override;
+
+ virtual bool RecvTableOfACell(const uint64_t& aID,
+ uint64_t* aTableID,
+ bool* aOk) override;
+
+ virtual bool RecvColIdx(const uint64_t& aID, uint32_t* aIndex) override;
+
+ virtual bool RecvRowIdx(const uint64_t& aID, uint32_t* aIndex) override;
+
+ virtual bool RecvColExtent(const uint64_t& aID, uint32_t* aExtent) override;
+
+ virtual bool RecvGetPosition(const uint64_t& aID,
+ uint32_t* aColIdx, uint32_t* aRowIdx) override;
+
+ virtual bool RecvGetColRowExtents(const uint64_t& aID,
+ uint32_t* aColIdx, uint32_t* aRowIdx,
+ uint32_t* aColExtent, uint32_t* aRowExtent) override;
+
+ virtual bool RecvRowExtent(const uint64_t& aID, uint32_t* aExtent) override;
+
+ virtual bool RecvColHeaderCells(const uint64_t& aID,
+ nsTArray<uint64_t>* aCells) override;
+
+ virtual bool RecvRowHeaderCells(const uint64_t& aID,
+ nsTArray<uint64_t>* aCells) override;
+
+ virtual bool RecvIsCellSelected(const uint64_t& aID,
+ bool* aSelected) override;
+
+ virtual bool RecvTableCaption(const uint64_t& aID,
+ uint64_t* aCaptionID,
+ bool* aOk) override;
+ virtual bool RecvTableSummary(const uint64_t& aID,
+ nsString* aSummary) override;
+ virtual bool RecvTableColumnCount(const uint64_t& aID,
+ uint32_t* aColCount) override;
+ virtual bool RecvTableRowCount(const uint64_t& aID,
+ uint32_t* aRowCount) override;
+ virtual bool RecvTableCellAt(const uint64_t& aID,
+ const uint32_t& aRow,
+ const uint32_t& aCol,
+ uint64_t* aCellID,
+ bool* aOk) override;
+ virtual bool RecvTableCellIndexAt(const uint64_t& aID,
+ const uint32_t& aRow,
+ const uint32_t& aCol,
+ int32_t* aIndex) override;
+ virtual bool RecvTableColumnIndexAt(const uint64_t& aID,
+ const uint32_t& aCellIndex,
+ int32_t* aCol) override;
+ virtual bool RecvTableRowIndexAt(const uint64_t& aID,
+ const uint32_t& aCellIndex,
+ int32_t* aRow) override;
+ virtual bool RecvTableRowAndColumnIndicesAt(const uint64_t& aID,
+ const uint32_t& aCellIndex,
+ int32_t* aRow,
+ int32_t* aCol) override;
+ virtual bool RecvTableColumnExtentAt(const uint64_t& aID,
+ const uint32_t& aRow,
+ const uint32_t& aCol,
+ uint32_t* aExtent) override;
+ virtual bool RecvTableRowExtentAt(const uint64_t& aID,
+ const uint32_t& aRow,
+ const uint32_t& aCol,
+ uint32_t* aExtent) override;
+ virtual bool RecvTableColumnDescription(const uint64_t& aID,
+ const uint32_t& aCol,
+ nsString* aDescription) override;
+ virtual bool RecvTableRowDescription(const uint64_t& aID,
+ const uint32_t& aRow,
+ nsString* aDescription) override;
+ virtual bool RecvTableColumnSelected(const uint64_t& aID,
+ const uint32_t& aCol,
+ bool* aSelected) override;
+ virtual bool RecvTableRowSelected(const uint64_t& aID,
+ const uint32_t& aRow,
+ bool* aSelected) override;
+ virtual bool RecvTableCellSelected(const uint64_t& aID,
+ const uint32_t& aRow,
+ const uint32_t& aCol,
+ bool* aSelected) override;
+ virtual bool RecvTableSelectedCellCount(const uint64_t& aID,
+ uint32_t* aSelectedCells) override;
+ virtual bool RecvTableSelectedColumnCount(const uint64_t& aID,
+ uint32_t* aSelectedColumns) override;
+ virtual bool RecvTableSelectedRowCount(const uint64_t& aID,
+ uint32_t* aSelectedRows) override;
+ virtual bool RecvTableSelectedCells(const uint64_t& aID,
+ nsTArray<uint64_t>* aCellIDs) override;
+ virtual bool RecvTableSelectedCellIndices(const uint64_t& aID,
+ nsTArray<uint32_t>* aCellIndices) override;
+ virtual bool RecvTableSelectedColumnIndices(const uint64_t& aID,
+ nsTArray<uint32_t>* aColumnIndices) override;
+ virtual bool RecvTableSelectedRowIndices(const uint64_t& aID,
+ nsTArray<uint32_t>* aRowIndices) override;
+ virtual bool RecvTableSelectColumn(const uint64_t& aID,
+ const uint32_t& aCol) override;
+ virtual bool RecvTableSelectRow(const uint64_t& aID,
+ const uint32_t& aRow) override;
+ virtual bool RecvTableUnselectColumn(const uint64_t& aID,
+ const uint32_t& aCol) override;
+ virtual bool RecvTableUnselectRow(const uint64_t& aID,
+ const uint32_t& aRow) override;
+ virtual bool RecvTableIsProbablyForLayout(const uint64_t& aID,
+ bool* aForLayout) override;
+ virtual bool RecvAtkTableColumnHeader(const uint64_t& aID,
+ const int32_t& aCol,
+ uint64_t* aHeader,
+ bool* aOk) override;
+ virtual bool RecvAtkTableRowHeader(const uint64_t& aID,
+ const int32_t& aRow,
+ uint64_t* aHeader,
+ bool* aOk) override;
+
+ virtual bool RecvSelectedItems(const uint64_t& aID,
+ nsTArray<uint64_t>* aSelectedItemIDs) override;
+
+ virtual bool RecvSelectedItemCount(const uint64_t& aID,
+ uint32_t* aCount) override;
+
+ virtual bool RecvGetSelectedItem(const uint64_t& aID,
+ const uint32_t& aIndex,
+ uint64_t* aSelected,
+ bool* aOk) override;
+
+ virtual bool RecvIsItemSelected(const uint64_t& aID,
+ const uint32_t& aIndex,
+ bool* aSelected) override;
+
+ virtual bool RecvAddItemToSelection(const uint64_t& aID,
+ const uint32_t& aIndex,
+ bool* aSuccess) override;
+
+ virtual bool RecvRemoveItemFromSelection(const uint64_t& aID,
+ const uint32_t& aIndex,
+ bool* aSuccess) override;
+
+ virtual bool RecvSelectAll(const uint64_t& aID,
+ bool* aSuccess) override;
+
+ virtual bool RecvUnselectAll(const uint64_t& aID,
+ bool* aSuccess) override;
+
+ virtual bool RecvTakeSelection(const uint64_t& aID) override;
+ virtual bool RecvSetSelected(const uint64_t& aID,
+ const bool& aSelect) override;
+
+ virtual bool RecvDoAction(const uint64_t& aID,
+ const uint8_t& aIndex,
+ bool* aSuccess) override;
+
+ virtual bool RecvActionCount(const uint64_t& aID,
+ uint8_t* aCount) override;
+
+ virtual bool RecvActionDescriptionAt(const uint64_t& aID,
+ const uint8_t& aIndex,
+ nsString* aDescription) override;
+
+ virtual bool RecvActionNameAt(const uint64_t& aID,
+ const uint8_t& aIndex,
+ nsString* aName) override;
+
+ virtual bool RecvAccessKey(const uint64_t& aID,
+ uint32_t* aKey,
+ uint32_t* aModifierMask) override;
+
+ virtual bool RecvKeyboardShortcut(const uint64_t& aID,
+ uint32_t* aKey,
+ uint32_t* aModifierMask) override;
+
+ virtual bool RecvAtkKeyBinding(const uint64_t& aID,
+ nsString* aResult) override;
+
+ virtual bool RecvCurValue(const uint64_t& aID,
+ double* aValue) override;
+
+ virtual bool RecvSetCurValue(const uint64_t& aID,
+ const double& aValue,
+ bool* aRetVal) override;
+
+ virtual bool RecvMinValue(const uint64_t& aID,
+ double* aValue) override;
+
+ virtual bool RecvMaxValue(const uint64_t& aID,
+ double* aValue) override;
+
+ virtual bool RecvStep(const uint64_t& aID,
+ double* aStep) override;
+
+ virtual bool RecvTakeFocus(const uint64_t& aID) override;
+
+ virtual bool RecvFocusedChild(const uint64_t& aID,
+ uint64_t* aChild,
+ bool* aOk) override;
+
+ virtual bool RecvLanguage(const uint64_t& aID, nsString* aLocale) override;
+ virtual bool RecvDocType(const uint64_t& aID, nsString* aType) override;
+ virtual bool RecvTitle(const uint64_t& aID, nsString* aTitle) override;
+ virtual bool RecvURL(const uint64_t& aID, nsString* aURL) override;
+ virtual bool RecvMimeType(const uint64_t& aID, nsString* aMime) override;
+ virtual bool RecvURLDocTypeMimeType(const uint64_t& aID,
+ nsString* aURL,
+ nsString* aDocType,
+ nsString* aMimeType) override;
+
+ virtual bool RecvAccessibleAtPoint(const uint64_t& aID,
+ const int32_t& aX,
+ const int32_t& aY,
+ const bool& aNeedsScreenCoords,
+ const uint32_t& aWhich,
+ uint64_t* aResult,
+ bool* aOk) override;
+
+ virtual bool RecvExtents(const uint64_t& aID,
+ const bool& aNeedsScreenCoords,
+ int32_t* aX,
+ int32_t* aY,
+ int32_t* aWidth,
+ int32_t* aHeight) override;
+ virtual bool RecvDOMNodeID(const uint64_t& aID, nsString* aDOMNodeID) override;
+private:
+
+ Accessible* IdToAccessible(const uint64_t& aID) const;
+ Accessible* IdToAccessibleLink(const uint64_t& aID) const;
+ Accessible* IdToAccessibleSelect(const uint64_t& aID) const;
+ HyperTextAccessible* IdToHyperTextAccessible(const uint64_t& aID) const;
+ TextLeafAccessible* IdToTextLeafAccessible(const uint64_t& aID) const;
+ ImageAccessible* IdToImageAccessible(const uint64_t& aID) const;
+ TableCellAccessible* IdToTableCellAccessible(const uint64_t& aID) const;
+ TableAccessible* IdToTableAccessible(const uint64_t& aID) const;
+
+ bool PersistentPropertiesToArray(nsIPersistentProperties* aProps,
+ nsTArray<Attribute>* aAttributes);
+};
+
+}
+}
+
+#endif
diff --git a/accessible/ipc/other/PDocAccessible.ipdl b/accessible/ipc/other/PDocAccessible.ipdl
new file mode 100644
index 0000000000..1885ed7863
--- /dev/null
+++ b/accessible/ipc/other/PDocAccessible.ipdl
@@ -0,0 +1,264 @@
+/* -*- 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 protocol PFileDescriptorSet;
+include protocol PBrowser;
+
+include "mozilla/GfxMessageUtils.h";
+
+using nsIntRect from "nsRect.h";
+using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
+using mozilla::gfx::IntPoint from "mozilla/gfx/Point.h";
+
+namespace mozilla {
+namespace a11y {
+
+struct AccessibleData
+{
+ uint64_t ID;
+ uint32_t Role;
+ uint32_t ChildrenCount;
+ uint32_t Interfaces;
+};
+
+struct ShowEventData
+{
+ uint64_t ID;
+ uint32_t Idx;
+ AccessibleData[] NewTree;
+};
+
+struct Attribute
+{
+ nsCString Name;
+ nsString Value;
+};
+
+struct RelationTargets
+{
+ uint32_t Type;
+ uint64_t[] Targets;
+};
+
+nested(upto inside_sync) sync protocol PDocAccessible
+{
+ manager PBrowser;
+
+parent:
+ async Shutdown();
+
+ /*
+ * Notify the parent process the document in the child process is firing an
+ * event.
+ */
+ async Event(uint64_t aID, uint32_t type);
+ async ShowEvent(ShowEventData data, bool aFromuser);
+ async HideEvent(uint64_t aRootID, bool aFromUser);
+ async StateChangeEvent(uint64_t aID, uint64_t aState, bool aEnabled);
+ async CaretMoveEvent(uint64_t aID, int32_t aOffset);
+ async TextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart, uint32_t aLen,
+ bool aIsInsert, bool aFromUser);
+ async SelectionEvent(uint64_t aID, uint64_t aWidgetID, uint32_t aType);
+ async RoleChangedEvent(uint32_t aRole);
+
+ /*
+ * Tell the parent document to bind the existing document as a new child
+ * document.
+ */
+ async BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);
+
+child:
+ async __delete__();
+
+ // Accessible
+ nested(inside_sync) sync State(uint64_t aID) returns(uint64_t states);
+ nested(inside_sync) sync NativeState(uint64_t aID) returns(uint64_t states);
+ nested(inside_sync) sync Name(uint64_t aID) returns(nsString name);
+ nested(inside_sync) sync Value(uint64_t aID) returns(nsString value);
+ nested(inside_sync) sync Help(uint64_t aID) returns(nsString help);
+ nested(inside_sync) sync Description(uint64_t aID) returns(nsString desc);
+ nested(inside_sync) sync Attributes(uint64_t aID) returns(Attribute[] attributes);
+ nested(inside_sync) sync RelationByType(uint64_t aID, uint32_t aRelationType)
+ returns(uint64_t[] targets);
+ nested(inside_sync) sync Relations(uint64_t aID) returns(RelationTargets[] relations);
+ nested(inside_sync) sync IsSearchbox(uint64_t aID) returns(bool retval);
+ nested(inside_sync) sync LandmarkRole(uint64_t aID) returns(nsString landmark);
+ nested(inside_sync) sync ARIARoleAtom(uint64_t aID) returns(nsString role);
+ nested(inside_sync) sync GetLevelInternal(uint64_t aID) returns(int32_t aLevel);
+ async ScrollTo(uint64_t aID, uint32_t aScrollType);
+ async ScrollToPoint(uint64_t aID, uint32_t aScrollType, int32_t aX,
+ int32_t aY);
+
+ // AccessibleText
+
+ // TextSubstring is getText in IDL.
+ nested(inside_sync) sync CaretLineNumber(uint64_t aID) returns(int32_t aLineNumber);
+ nested(inside_sync) sync CaretOffset(uint64_t aID) returns(int32_t aOffset);
+ async SetCaretOffset(uint64_t aID, int32_t aOffset);
+ nested(inside_sync) sync CharacterCount(uint64_t aID) returns(int32_t aCount);
+ nested(inside_sync) sync SelectionCount(uint64_t aID) returns(int32_t aCount);
+ nested(inside_sync) sync TextSubstring(uint64_t aID, int32_t aStartOffset, int32_t
+ aEndOffset) returns(nsString aText, bool aValid);
+ nested(inside_sync) sync GetTextAfterOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
+ returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
+ nested(inside_sync) sync GetTextAtOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
+ returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
+
+ nested(inside_sync) sync GetTextBeforeOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
+ returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
+ nested(inside_sync) sync CharAt(uint64_t aID, int32_t aOffset) returns(uint16_t aChar);
+
+ nested(inside_sync) sync TextAttributes(uint64_t aID, bool aIncludeDefAttrs, int32_t aOffset)
+ returns(Attribute[] aAttributes, int32_t aStartOffset, int32_t aEndOffset);
+ nested(inside_sync) sync DefaultTextAttributes(uint64_t aID) returns(Attribute[] aAttributes);
+
+ nested(inside_sync) sync TextBounds(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset,
+ uint32_t aCoordType)
+ returns(nsIntRect aRetVal);
+ nested(inside_sync) sync CharBounds(uint64_t aID, int32_t aOffset, uint32_t aCoordType)
+ returns(nsIntRect aRetVal);
+
+ nested(inside_sync) sync OffsetAtPoint(uint64_t aID, int32_t aX, int32_t aY, uint32_t aCoordType)
+ returns(int32_t aRetVal);
+
+ nested(inside_sync) sync SelectionBoundsAt(uint64_t aID, int32_t aSelectionNum)
+ returns(bool aSucceeded, nsString aData, int32_t aStartOffset, int32_t aEndOffset);
+ nested(inside_sync) sync SetSelectionBoundsAt(uint64_t aID, int32_t aSelectionNum,
+ int32_t aStartOffset, int32_t aEndOffset)
+ returns(bool aSucceeded);
+ nested(inside_sync) sync AddToSelection(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset)
+ returns(bool aSucceeded);
+ nested(inside_sync) sync RemoveFromSelection(uint64_t aID, int32_t aSelectionNum)
+ returns(bool aSucceeded);
+
+ async ScrollSubstringTo(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset,
+ uint32_t aScrollType);
+ async ScrollSubstringToPoint(uint64_t aID,
+ int32_t aStartOffset,
+ int32_t aEndOffset,
+ uint32_t aCoordinateType,
+ int32_t aX, int32_t aY);
+
+ nested(inside_sync) sync Text(uint64_t aID) returns(nsString aText);
+ nested(inside_sync) sync ReplaceText(uint64_t aID, nsString aText);
+ nested(inside_sync) sync InsertText(uint64_t aID, nsString aText, int32_t aPosition)
+ returns(bool aValid);
+ nested(inside_sync) sync CopyText(uint64_t aID, int32_t aStartPos, int32_t aEndPos)
+ returns(bool aValid);
+ nested(inside_sync) sync CutText(uint64_t aID, int32_t aStartPos, int32_t aEndPos)
+ returns(bool aValid);
+ nested(inside_sync) sync DeleteText(uint64_t aID, int32_t aStartPos, int32_t aEndPos)
+ returns(bool aValid);
+ nested(inside_sync) sync PasteText(uint64_t aID, int32_t aPosition)
+ returns(bool aValid);
+
+ nested(inside_sync) sync ImagePosition(uint64_t aID, uint32_t aCoordType) returns(IntPoint aRetVal);
+ nested(inside_sync) sync ImageSize(uint64_t aID) returns(IntSize aRetVal);
+
+ nested(inside_sync) sync StartOffset(uint64_t aID) returns(uint32_t aRetVal, bool aOk);
+ nested(inside_sync) sync EndOffset(uint64_t aID) returns(uint32_t aRetVal, bool aOk);
+ nested(inside_sync) sync IsLinkValid(uint64_t aID) returns(bool aRetVal);
+ nested(inside_sync) sync AnchorCount(uint64_t aID) returns(uint32_t aRetVal, bool aOk);
+ nested(inside_sync) sync AnchorURIAt(uint64_t aID, uint32_t aIndex) returns(nsCString aURI, bool aOk);
+ nested(inside_sync) sync AnchorAt(uint64_t aID, uint32_t aIndex) returns(uint64_t aIDOfAnchor, bool aOk);
+
+ nested(inside_sync) sync LinkCount(uint64_t aID) returns(uint32_t aCount);
+ nested(inside_sync) sync LinkAt(uint64_t aID, uint32_t aIndex) returns(uint64_t aIDOfLink, bool aOk);
+ nested(inside_sync) sync LinkIndexOf(uint64_t aID, uint64_t aLinkID) returns(int32_t aIndex);
+ nested(inside_sync) sync LinkIndexAtOffset(uint64_t aID, uint32_t aOffset) returns(int32_t aIndex);
+
+ nested(inside_sync) sync TableOfACell(uint64_t aID) returns(uint64_t aTableID, bool aOk);
+ nested(inside_sync) sync ColIdx(uint64_t aID) returns(uint32_t aIndex);
+ nested(inside_sync) sync RowIdx(uint64_t aID) returns(uint32_t aIndex);
+ nested(inside_sync) sync GetPosition(uint64_t aID) returns(uint32_t aRow, uint32_t aCol);
+ nested(inside_sync) sync ColExtent(uint64_t aID) returns(uint32_t aExtent);
+ nested(inside_sync) sync RowExtent(uint64_t aID) returns(uint32_t aExtent);
+ nested(inside_sync) sync GetColRowExtents(uint64_t aID)
+ returns(uint32_t aCol, uint32_t aRow, uint32_t aColExtent, uint32_t aRowExtent);
+ nested(inside_sync) sync ColHeaderCells(uint64_t aID) returns(uint64_t[] aCells);
+ nested(inside_sync) sync RowHeaderCells(uint64_t aID) returns(uint64_t[] aCells);
+ nested(inside_sync) sync IsCellSelected(uint64_t aID) returns(bool aSelected);
+
+ nested(inside_sync) sync TableCaption(uint64_t aID) returns(uint64_t aCaptionID, bool aOk);
+ nested(inside_sync) sync TableSummary(uint64_t aID) returns(nsString aSummary);
+ nested(inside_sync) sync TableColumnCount(uint64_t aID) returns(uint32_t aColCount);
+ nested(inside_sync) sync TableRowCount(uint64_t aID) returns(uint32_t aRowCount);
+ nested(inside_sync) sync TableCellAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(uint64_t aCellID, bool aOk);
+ nested(inside_sync) sync TableCellIndexAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(int32_t aIndex);
+ nested(inside_sync) sync TableColumnIndexAt(uint64_t aID, uint32_t aCellIndex) returns(int32_t aCol);
+ nested(inside_sync) sync TableRowIndexAt(uint64_t aID, uint32_t aCellIndex) returns(int32_t aRow);
+ nested(inside_sync) sync TableRowAndColumnIndicesAt(uint64_t aID, uint32_t aCellIndex) returns(int32_t aRow, int32_t aCol);
+ nested(inside_sync) sync TableColumnExtentAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(uint32_t aExtent);
+ nested(inside_sync) sync TableRowExtentAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(uint32_t aExtent);
+ nested(inside_sync) sync TableColumnDescription(uint64_t aID, uint32_t aCol) returns(nsString aDescription);
+ nested(inside_sync) sync TableRowDescription(uint64_t aID, uint32_t aRow) returns(nsString aDescription);
+ nested(inside_sync) sync TableColumnSelected(uint64_t aID, uint32_t aCol) returns(bool aSelected);
+ nested(inside_sync) sync TableRowSelected(uint64_t aID, uint32_t aRow) returns(bool aSelected);
+ nested(inside_sync) sync TableCellSelected(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(bool aSelected);
+ nested(inside_sync) sync TableSelectedCellCount(uint64_t aID) returns(uint32_t aSelectedCells);
+ nested(inside_sync) sync TableSelectedColumnCount(uint64_t aID) returns(uint32_t aSelectedColumns);
+ nested(inside_sync) sync TableSelectedRowCount(uint64_t aID) returns(uint32_t aSelectedRows);
+ nested(inside_sync) sync TableSelectedCells(uint64_t aID) returns(uint64_t[] aCellIDs);
+ nested(inside_sync) sync TableSelectedCellIndices(uint64_t aID) returns(uint32_t[] aCellIndeces);
+ nested(inside_sync) sync TableSelectedColumnIndices(uint64_t aID) returns(uint32_t[] aColumnIndeces);
+ nested(inside_sync) sync TableSelectedRowIndices(uint64_t aID) returns(uint32_t[] aRowIndeces);
+ nested(inside_sync) sync TableSelectColumn(uint64_t aID, uint32_t aCol);
+ nested(inside_sync) sync TableSelectRow(uint64_t aID, uint32_t aRow);
+ nested(inside_sync) sync TableUnselectColumn(uint64_t aID, uint32_t aCol);
+ nested(inside_sync) sync TableUnselectRow(uint64_t aID, uint32_t aRow);
+ nested(inside_sync) sync TableIsProbablyForLayout(uint64_t aID) returns(bool aForLayout);
+ nested(inside_sync) sync AtkTableColumnHeader(uint64_t aID, int32_t aCol)
+ returns(uint64_t aHeaderID, bool aOk);
+ nested(inside_sync) sync AtkTableRowHeader(uint64_t aID, int32_t aRow)
+ returns(uint64_t aHeaderID, bool aOk);
+
+ nested(inside_sync) sync SelectedItems(uint64_t aID) returns(uint64_t[] aSelectedItemIDs);
+ nested(inside_sync) sync SelectedItemCount(uint64_t aID) returns(uint32_t aCount);
+ nested(inside_sync) sync GetSelectedItem(uint64_t aID, uint32_t aIndex) returns(uint64_t aSelected, bool aOk);
+ nested(inside_sync) sync IsItemSelected(uint64_t aID, uint32_t aIndex) returns(bool aSelected);
+ nested(inside_sync) sync AddItemToSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
+ nested(inside_sync) sync RemoveItemFromSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
+ nested(inside_sync) sync SelectAll(uint64_t aID) returns(bool aSuccess);
+ nested(inside_sync) sync UnselectAll(uint64_t aID) returns(bool aSuccess);
+
+ async TakeSelection(uint64_t aID);
+ async SetSelected(uint64_t aID, bool aSelected);
+
+ nested(inside_sync) sync DoAction(uint64_t aID, uint8_t aIndex) returns(bool aSuccess);
+ nested(inside_sync) sync ActionCount(uint64_t aID) returns(uint8_t aCount);
+ nested(inside_sync) sync ActionDescriptionAt(uint64_t aID, uint8_t aIndex) returns(nsString aDescription);
+ nested(inside_sync) sync ActionNameAt(uint64_t aID, uint8_t aIndex) returns(nsString aName);
+ nested(inside_sync) sync AccessKey(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
+ nested(inside_sync) sync KeyboardShortcut(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
+ nested(inside_sync) sync AtkKeyBinding(uint64_t aID) returns(nsString aResult);
+
+ nested(inside_sync) sync CurValue(uint64_t aID) returns(double aValue);
+ nested(inside_sync) sync SetCurValue(uint64_t aID, double aValue) returns(bool aRetVal);
+ nested(inside_sync) sync MinValue(uint64_t aID) returns(double aValue);
+ nested(inside_sync) sync MaxValue(uint64_t aID) returns(double aValue);
+ nested(inside_sync) sync Step(uint64_t aID) returns(double aStep);
+
+ async TakeFocus(uint64_t aID);
+ nested(inside_sync) sync FocusedChild(uint64_t aID)
+ returns(uint64_t aChild, bool aOk);
+
+ nested(inside_sync) sync Language(uint64_t aID) returns(nsString aLocale);
+ nested(inside_sync) sync DocType(uint64_t aID) returns(nsString aType);
+ nested(inside_sync) sync Title(uint64_t aID) returns(nsString aTitle);
+ nested(inside_sync) sync URL(uint64_t aID) returns(nsString aURL);
+ nested(inside_sync) sync MimeType(uint64_t aID) returns(nsString aMime);
+ nested(inside_sync) sync URLDocTypeMimeType(uint64_t aID) returns(nsString aURL, nsString aDocType, nsString aMimeType);
+
+ nested(inside_sync) sync AccessibleAtPoint(uint64_t aID, int32_t aX, int32_t aY, bool aNeedsScreenCoords, uint32_t aWhich)
+ returns(uint64_t aResult, bool aOk);
+
+ nested(inside_sync) sync Extents(uint64_t aID, bool aNeedsScreenCoords)
+ returns(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight);
+ nested(inside_sync) sync DOMNodeID(uint64_t aID) returns(nsString aDOMNodeID);
+};
+
+}
+}
diff --git a/accessible/ipc/other/ProxyAccessible.cpp b/accessible/ipc/other/ProxyAccessible.cpp
new file mode 100644
index 0000000000..2eb93dfdad
--- /dev/null
+++ b/accessible/ipc/other/ProxyAccessible.cpp
@@ -0,0 +1,1080 @@
+/* -*- 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 "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 {
+
+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);
+ }
+
+ 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;
+}
+
+void
+ProxyAccessible::GetColRowExtents(uint32_t* aColIdx, uint32_t* aRowIdx,
+ uint32_t* aColExtent, uint32_t* aRowExtent)
+{
+ Unused << mDoc->SendGetColRowExtents(mID, aColIdx, aRowIdx, aColExtent, aRowExtent);
+}
+
+void
+ProxyAccessible::GetPosition(uint32_t* aColIdx, uint32_t* aRowIdx)
+{
+ Unused << mDoc->SendGetPosition(mID, aColIdx, aRowIdx);
+}
+
+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);
+}
+
+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);
+}
+
+}
+}
diff --git a/accessible/ipc/other/ProxyAccessible.h b/accessible/ipc/other/ProxyAccessible.h
new file mode 100644
index 0000000000..25fd71fbf1
--- /dev/null
+++ b/accessible/ipc/other/ProxyAccessible.h
@@ -0,0 +1,50 @@
+/* -*- 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
+
+#include "Accessible.h"
+#include "mozilla/a11y/ProxyAccessibleBase.h"
+#include "mozilla/a11y/Role.h"
+#include "nsIAccessibleText.h"
+#include "nsIAccessibleTypes.h"
+#include "nsString.h"
+#include "nsTArray.h"
+#include "nsRect.h"
+
+namespace mozilla {
+namespace a11y {
+
+class ProxyAccessible : public ProxyAccessibleBase<ProxyAccessible>
+{
+public:
+
+ ProxyAccessible(uint64_t aID, ProxyAccessible* aParent,
+ DocAccessibleParent* aDoc, role aRole, uint32_t aInterfaces)
+ : ProxyAccessibleBase(aID, aParent, aDoc, aRole, aInterfaces)
+
+ {
+ MOZ_COUNT_CTOR(ProxyAccessible);
+ }
+
+ ~ProxyAccessible()
+ {
+ MOZ_COUNT_DTOR(ProxyAccessible);
+ }
+
+#include "mozilla/a11y/ProxyAccessibleShared.h"
+
+protected:
+ explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc)
+ : ProxyAccessibleBase(aThisAsDoc)
+ { MOZ_COUNT_CTOR(ProxyAccessible); }
+};
+
+}
+}
+
+#endif
diff --git a/accessible/ipc/other/moz.build b/accessible/ipc/other/moz.build
new file mode 100644
index 0000000000..65021145c9
--- /dev/null
+++ b/accessible/ipc/other/moz.build
@@ -0,0 +1,47 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+# With --disable-accessibility, we need to compile PDocAccessible.ipdl, but
+# not the C++.
+IPDL_SOURCES += ['PDocAccessible.ipdl']
+
+if CONFIG['ACCESSIBILITY']:
+ EXPORTS.mozilla.a11y += [
+ 'DocAccessibleChild.h',
+ 'ProxyAccessible.h',
+ ]
+
+ SOURCES += [
+ 'DocAccessibleChild.cpp',
+ 'ProxyAccessible.cpp',
+ ]
+
+ LOCAL_INCLUDES += [
+ '../../base',
+ '../../generic',
+ '../../xpcom',
+ ]
+
+ if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
+ LOCAL_INCLUDES += [
+ '/accessible/atk',
+ ]
+ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+ LOCAL_INCLUDES += [
+ '/accessible/mac',
+ ]
+ else:
+ LOCAL_INCLUDES += [
+ '/accessible/other',
+ ]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+if CONFIG['GNU_CXX']:
+ CXXFLAGS += ['-Wno-error=shadow']
+
+FINAL_LIBRARY = 'xul'
+
diff --git a/accessible/ipc/win/COMPtrTypes.cpp b/accessible/ipc/win/COMPtrTypes.cpp
new file mode 100644
index 0000000000..857f4235e4
--- /dev/null
+++ b/accessible/ipc/win/COMPtrTypes.cpp
@@ -0,0 +1,50 @@
+/* -*- 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 "mozilla/a11y/COMPtrTypes.h"
+
+#include "MainThreadUtils.h"
+#include "mozilla/a11y/Accessible.h"
+#include "mozilla/Move.h"
+#include "mozilla/mscom/MainThreadHandoff.h"
+#include "mozilla/RefPtr.h"
+
+using mozilla::mscom::MainThreadHandoff;
+using mozilla::mscom::STAUniquePtr;
+
+namespace mozilla {
+namespace a11y {
+
+IAccessibleHolder
+CreateHolderFromAccessible(Accessible* aAccToWrap)
+{
+ MOZ_ASSERT(aAccToWrap && NS_IsMainThread());
+ if (!aAccToWrap) {
+ return nullptr;
+ }
+
+ IAccessible* rawNative = nullptr;
+ aAccToWrap->GetNativeInterface((void**)&rawNative);
+ MOZ_ASSERT(rawNative);
+ if (!rawNative) {
+ return nullptr;
+ }
+
+ STAUniquePtr<IAccessible> iaToProxy(rawNative);
+
+ IAccessible* rawIntercepted = nullptr;
+ HRESULT hr = MainThreadHandoff::WrapInterface(Move(iaToProxy), &rawIntercepted);
+ MOZ_ASSERT(SUCCEEDED(hr));
+ if (FAILED(hr)) {
+ return nullptr;
+ }
+
+ IAccessibleHolder::COMPtrType iaIntercepted(rawIntercepted);
+ return IAccessibleHolder(Move(iaIntercepted));
+}
+
+} // namespace a11y
+} // namespace mozilla
diff --git a/accessible/ipc/win/COMPtrTypes.h b/accessible/ipc/win/COMPtrTypes.h
new file mode 100644
index 0000000000..122e1ea5ec
--- /dev/null
+++ b/accessible/ipc/win/COMPtrTypes.h
@@ -0,0 +1,27 @@
+/* -*- 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_COMPtrTypes_h
+#define mozilla_a11y_COMPtrTypes_h
+
+#include "mozilla/mscom/COMPtrHolder.h"
+
+#include <oleacc.h>
+
+namespace mozilla {
+namespace a11y {
+
+typedef mozilla::mscom::COMPtrHolder<IAccessible, IID_IAccessible> IAccessibleHolder;
+
+class Accessible;
+
+IAccessibleHolder
+CreateHolderFromAccessible(Accessible* aAccToWrap);
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif // mozilla_a11y_COMPtrTypes_h
diff --git a/accessible/ipc/win/DocAccessibleChild.cpp b/accessible/ipc/win/DocAccessibleChild.cpp
new file mode 100644
index 0000000000..e8b8bebe58
--- /dev/null
+++ b/accessible/ipc/win/DocAccessibleChild.cpp
@@ -0,0 +1,237 @@
+/* -*- 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 "DocAccessibleChild.h"
+
+#include "Accessible-inl.h"
+#include "mozilla/a11y/PlatformChild.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "RootAccessible.h"
+
+namespace mozilla {
+namespace a11y {
+
+static StaticAutoPtr<PlatformChild> sPlatformChild;
+
+DocAccessibleChild::DocAccessibleChild(DocAccessible* aDoc)
+ : DocAccessibleChildBase(aDoc)
+ , mIsRemoteConstructed(false)
+{
+ MOZ_COUNT_CTOR_INHERITED(DocAccessibleChild, DocAccessibleChildBase);
+ if (!sPlatformChild) {
+ sPlatformChild = new PlatformChild();
+ ClearOnShutdown(&sPlatformChild, ShutdownPhase::Shutdown);
+ }
+}
+
+DocAccessibleChild::~DocAccessibleChild()
+{
+ MOZ_COUNT_DTOR_INHERITED(DocAccessibleChild, DocAccessibleChildBase);
+}
+
+void
+DocAccessibleChild::Shutdown()
+{
+ if (IsConstructedInParentProcess()) {
+ DocAccessibleChildBase::Shutdown();
+ return;
+ }
+
+ PushDeferredEvent(MakeUnique<SerializedShutdown>(this));
+ DetachDocument();
+}
+
+bool
+DocAccessibleChild::RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy)
+{
+ MOZ_ASSERT(!mParentProxy && !aParentCOMProxy.IsNull());
+ mParentProxy.reset(const_cast<IAccessibleHolder&>(aParentCOMProxy).Release());
+ SetConstructedInParentProcess();
+
+ for (uint32_t i = 0, l = mDeferredEvents.Length(); i < l; ++i) {
+ mDeferredEvents[i]->Dispatch();
+ }
+
+ mDeferredEvents.Clear();
+
+ return true;
+}
+
+void
+DocAccessibleChild::PushDeferredEvent(UniquePtr<DeferredEvent> aEvent)
+{
+ DocAccessibleChild* topLevelIPCDoc = nullptr;
+
+ if (mDoc && mDoc->IsRoot()) {
+ topLevelIPCDoc = this;
+ } else {
+ auto tabChild = static_cast<dom::TabChild*>(Manager());
+ if (!tabChild) {
+ return;
+ }
+
+ nsTArray<PDocAccessibleChild*> ipcDocAccs;
+ tabChild->ManagedPDocAccessibleChild(ipcDocAccs);
+
+ // Look for the top-level DocAccessibleChild - there will only be one
+ // per TabChild.
+ for (uint32_t i = 0, l = ipcDocAccs.Length(); i < l; ++i) {
+ auto ipcDocAcc = static_cast<DocAccessibleChild*>(ipcDocAccs[i]);
+ if (ipcDocAcc->mDoc && ipcDocAcc->mDoc->IsRoot()) {
+ topLevelIPCDoc = ipcDocAcc;
+ break;
+ }
+ }
+ }
+
+ if (topLevelIPCDoc) {
+ topLevelIPCDoc->mDeferredEvents.AppendElement(Move(aEvent));
+ }
+}
+
+bool
+DocAccessibleChild::SendEvent(const uint64_t& aID, const uint32_t& aType)
+{
+ if (IsConstructedInParentProcess()) {
+ return PDocAccessibleChild::SendEvent(aID, aType);
+ }
+
+ PushDeferredEvent(MakeUnique<SerializedEvent>(this, aID, aType));
+ return false;
+}
+
+void
+DocAccessibleChild::MaybeSendShowEvent(ShowEventData& aData, bool aFromUser)
+{
+ if (IsConstructedInParentProcess()) {
+ Unused << SendShowEvent(aData, aFromUser);
+ return;
+ }
+
+ PushDeferredEvent(MakeUnique<SerializedShow>(this, aData, aFromUser));
+}
+
+bool
+DocAccessibleChild::SendHideEvent(const uint64_t& aRootID,
+ const bool& aFromUser)
+{
+ if (IsConstructedInParentProcess()) {
+ return PDocAccessibleChild::SendHideEvent(aRootID, aFromUser);
+ }
+
+ PushDeferredEvent(MakeUnique<SerializedHide>(this, aRootID, aFromUser));
+ return true;
+}
+
+bool
+DocAccessibleChild::SendStateChangeEvent(const uint64_t& aID,
+ const uint64_t& aState,
+ const bool& aEnabled)
+{
+ if (IsConstructedInParentProcess()) {
+ return PDocAccessibleChild::SendStateChangeEvent(aID, aState, aEnabled);
+ }
+
+ PushDeferredEvent(MakeUnique<SerializedStateChange>(this, aID, aState,
+ aEnabled));
+ return true;
+}
+
+bool
+DocAccessibleChild::SendCaretMoveEvent(const uint64_t& aID,
+ const int32_t& aOffset)
+{
+ if (IsConstructedInParentProcess()) {
+ return PDocAccessibleChild::SendCaretMoveEvent(aID, aOffset);
+ }
+
+ PushDeferredEvent(MakeUnique<SerializedCaretMove>(this, aID, aOffset));
+ return true;
+}
+
+bool
+DocAccessibleChild::SendTextChangeEvent(const uint64_t& aID,
+ const nsString& aStr,
+ const int32_t& aStart,
+ const uint32_t& aLen,
+ const bool& aIsInsert,
+ const bool& aFromUser)
+{
+ if (IsConstructedInParentProcess()) {
+ return PDocAccessibleChild::SendTextChangeEvent(aID, aStr, aStart,
+ aLen, aIsInsert, aFromUser);
+ }
+
+ PushDeferredEvent(MakeUnique<SerializedTextChange>(this, aID, aStr, aStart,
+ aLen, aIsInsert, aFromUser));
+ return true;
+}
+
+bool
+DocAccessibleChild::SendSelectionEvent(const uint64_t& aID,
+ const uint64_t& aWidgetID,
+ const uint32_t& aType)
+{
+ if (IsConstructedInParentProcess()) {
+ return PDocAccessibleChild::SendSelectionEvent(aID, aWidgetID, aType);
+ }
+
+ PushDeferredEvent(MakeUnique<SerializedSelection>(this, aID,
+ aWidgetID,
+ aType));
+ return true;
+}
+
+bool
+DocAccessibleChild::SendRoleChangedEvent(const uint32_t& aRole)
+{
+ if (IsConstructedInParentProcess()) {
+ return PDocAccessibleChild::SendRoleChangedEvent(aRole);
+ }
+
+ PushDeferredEvent(MakeUnique<SerializedRoleChanged>(this, aRole));
+ return true;
+}
+
+bool
+DocAccessibleChild::ConstructChildDocInParentProcess(
+ DocAccessibleChild* aNewChildDoc,
+ uint64_t aUniqueID, uint32_t aMsaaID)
+{
+ if (IsConstructedInParentProcess()) {
+ // We may send the constructor immediately
+ auto tabChild = static_cast<dom::TabChild*>(Manager());
+ MOZ_ASSERT(tabChild);
+ bool result = tabChild->SendPDocAccessibleConstructor(aNewChildDoc, this,
+ aUniqueID, aMsaaID,
+ IAccessibleHolder());
+ if (result) {
+ aNewChildDoc->SetConstructedInParentProcess();
+ }
+ return result;
+ }
+
+ PushDeferredEvent(MakeUnique<SerializedChildDocConstructor>(aNewChildDoc, this,
+ aUniqueID, aMsaaID));
+ return true;
+}
+
+bool
+DocAccessibleChild::SendBindChildDoc(DocAccessibleChild* aChildDoc,
+ const uint64_t& aNewParentID)
+{
+ if (IsConstructedInParentProcess()) {
+ return DocAccessibleChildBase::SendBindChildDoc(aChildDoc, aNewParentID);
+ }
+
+ PushDeferredEvent(MakeUnique<SerializedBindChildDoc>(this, aChildDoc,
+ aNewParentID));
+ return true;
+}
+
+} // namespace a11y
+} // namespace mozilla
+
diff --git a/accessible/ipc/win/DocAccessibleChild.h b/accessible/ipc/win/DocAccessibleChild.h
new file mode 100644
index 0000000000..7a3da01725
--- /dev/null
+++ b/accessible/ipc/win/DocAccessibleChild.h
@@ -0,0 +1,318 @@
+/* -*- 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_DocAccessibleChild_h
+#define mozilla_a11y_DocAccessibleChild_h
+
+#include "mozilla/a11y/COMPtrTypes.h"
+#include "mozilla/a11y/DocAccessibleChildBase.h"
+#include "mozilla/dom/TabChild.h"
+#include "mozilla/mscom/Ptr.h"
+
+namespace mozilla {
+namespace a11y {
+
+/*
+ * These objects handle content side communication for an accessible document,
+ * and their lifetime is the same as the document they represent.
+ */
+class DocAccessibleChild : public DocAccessibleChildBase
+{
+public:
+ explicit DocAccessibleChild(DocAccessible* aDoc);
+ ~DocAccessibleChild();
+
+ virtual void Shutdown() override;
+
+ virtual bool
+ RecvParentCOMProxy(const IAccessibleHolder& aParentCOMProxy) override;
+
+ IAccessible* GetParentIAccessible() const { return mParentProxy.get(); }
+
+ bool SendEvent(const uint64_t& aID, const uint32_t& type);
+ bool SendHideEvent(const uint64_t& aRootID, const bool& aFromUser);
+ bool SendStateChangeEvent(const uint64_t& aID, const uint64_t& aState,
+ const bool& aEnabled);
+ bool SendCaretMoveEvent(const uint64_t& aID, const int32_t& aOffset);
+ bool SendTextChangeEvent(const uint64_t& aID, const nsString& aStr,
+ const int32_t& aStart, const uint32_t& aLen,
+ const bool& aIsInsert, const bool& aFromUser);
+ bool SendSelectionEvent(const uint64_t& aID, const uint64_t& aWidgetID,
+ const uint32_t& aType);
+ bool SendRoleChangedEvent(const uint32_t& aRole);
+
+ bool ConstructChildDocInParentProcess(DocAccessibleChild* aNewChildDoc,
+ uint64_t aUniqueID, uint32_t aMsaaID);
+
+ bool SendBindChildDoc(DocAccessibleChild* aChildDoc,
+ const uint64_t& aNewParentID);
+
+protected:
+ virtual void MaybeSendShowEvent(ShowEventData& aData, bool aFromUser) override;
+
+private:
+ void RemoveDeferredConstructor();
+
+ bool IsConstructedInParentProcess() const { return mIsRemoteConstructed; }
+ void SetConstructedInParentProcess() { mIsRemoteConstructed = true; }
+
+ /**
+ * DocAccessibleChild should not fire events until it has asynchronously
+ * received the COM proxy for its parent. OTOH, content a11y may still be
+ * attempting to fire events during this window of time. If this object does
+ * not yet have its parent proxy, instead of immediately sending the events to
+ * our parent, we enqueue them to mDeferredEvents. As soon as
+ * RecvParentCOMProxy is called, we play back mDeferredEvents.
+ */
+ struct DeferredEvent
+ {
+ void Dispatch()
+ {
+ Dispatch(mTarget);
+ }
+
+ virtual ~DeferredEvent() {}
+
+ protected:
+ explicit DeferredEvent(DocAccessibleChild* aTarget)
+ : mTarget(aTarget)
+ {}
+
+ virtual void Dispatch(DocAccessibleChild* aIPCDoc) = 0;
+
+ private:
+ DocAccessibleChild* mTarget;
+ };
+
+ void PushDeferredEvent(UniquePtr<DeferredEvent> aEvent);
+
+ struct SerializedShow final : public DeferredEvent
+ {
+ SerializedShow(DocAccessibleChild* aTarget,
+ ShowEventData& aEventData, bool aFromUser)
+ : DeferredEvent(aTarget)
+ , mEventData(aEventData.ID(), aEventData.Idx(), nsTArray<AccessibleData>())
+ , mFromUser(aFromUser)
+ {
+ // Since IPDL doesn't generate a move constructor for ShowEventData,
+ // we move NewTree manually (ugh). We still construct with an empty
+ // NewTree above so that the compiler catches any changes made to the
+ // ShowEventData structure in IPDL.
+ mEventData.NewTree() = Move(aEventData.NewTree());
+ }
+
+ void Dispatch(DocAccessibleChild* aIPCDoc) override
+ {
+ Unused << aIPCDoc->SendShowEvent(mEventData, mFromUser);
+ }
+
+ ShowEventData mEventData;
+ bool mFromUser;
+ };
+
+ struct SerializedHide final : public DeferredEvent
+ {
+ SerializedHide(DocAccessibleChild* aTarget, uint64_t aRootID, bool aFromUser)
+ : DeferredEvent(aTarget)
+ , mRootID(aRootID)
+ , mFromUser(aFromUser)
+ {}
+
+ void Dispatch(DocAccessibleChild* aIPCDoc) override
+ {
+ Unused << aIPCDoc->SendHideEvent(mRootID, mFromUser);
+ }
+
+ uint64_t mRootID;
+ bool mFromUser;
+ };
+
+ struct SerializedStateChange final : public DeferredEvent
+ {
+ SerializedStateChange(DocAccessibleChild* aTarget, uint64_t aID,
+ uint64_t aState, bool aEnabled)
+ : DeferredEvent(aTarget)
+ , mID(aID)
+ , mState(aState)
+ , mEnabled(aEnabled)
+ {}
+
+ void Dispatch(DocAccessibleChild* aIPCDoc) override
+ {
+ Unused << aIPCDoc->SendStateChangeEvent(mID, mState, mEnabled);
+ }
+
+ uint64_t mID;
+ uint64_t mState;
+ bool mEnabled;
+ };
+
+ struct SerializedCaretMove final : public DeferredEvent
+ {
+ SerializedCaretMove(DocAccessibleChild* aTarget, uint64_t aID,
+ int32_t aOffset)
+ : DeferredEvent(aTarget)
+ , mID(aID)
+ , mOffset(aOffset)
+ {}
+
+ void Dispatch(DocAccessibleChild* aIPCDoc) override
+ {
+ Unused << aIPCDoc->SendCaretMoveEvent(mID, mOffset);
+ }
+
+ uint64_t mID;
+ int32_t mOffset;
+ };
+
+ struct SerializedTextChange final : public DeferredEvent
+ {
+ SerializedTextChange(DocAccessibleChild* aTarget, uint64_t aID,
+ const nsString& aStr, int32_t aStart, uint32_t aLen,
+ bool aIsInsert, bool aFromUser)
+ : DeferredEvent(aTarget)
+ , mID(aID)
+ , mStr(aStr)
+ , mStart(aStart)
+ , mLen(aLen)
+ , mIsInsert(aIsInsert)
+ , mFromUser(aFromUser)
+ {}
+
+ void Dispatch(DocAccessibleChild* aIPCDoc) override
+ {
+ Unused << aIPCDoc->SendTextChangeEvent(mID, mStr, mStart, mLen, mIsInsert,
+ mFromUser);
+ }
+
+ uint64_t mID;
+ nsString mStr;
+ int32_t mStart;
+ uint32_t mLen;
+ bool mIsInsert;
+ bool mFromUser;
+ };
+
+ struct SerializedSelection final : public DeferredEvent
+ {
+ SerializedSelection(DocAccessibleChild* aTarget, uint64_t aID,
+ uint64_t aWidgetID, uint32_t aType)
+ : DeferredEvent(aTarget)
+ , mID(aID)
+ , mWidgetID(aWidgetID)
+ , mType(aType)
+ {}
+
+ void Dispatch(DocAccessibleChild* aIPCDoc) override
+ {
+ Unused << aIPCDoc->SendSelectionEvent(mID, mWidgetID, mType);
+ }
+
+ uint64_t mID;
+ uint64_t mWidgetID;
+ uint32_t mType;
+ };
+
+ struct SerializedRoleChanged final : public DeferredEvent
+ {
+ explicit SerializedRoleChanged(DocAccessibleChild* aTarget, uint32_t aRole)
+ : DeferredEvent(aTarget)
+ , mRole(aRole)
+ {}
+
+ void Dispatch(DocAccessibleChild* aIPCDoc) override
+ {
+ Unused << aIPCDoc->SendRoleChangedEvent(mRole);
+ }
+
+ uint32_t mRole;
+ };
+
+ struct SerializedEvent final : public DeferredEvent
+ {
+ SerializedEvent(DocAccessibleChild* aTarget, uint64_t aID, uint32_t aType)
+ : DeferredEvent(aTarget)
+ , mID(aID)
+ , mType(aType)
+ {}
+
+ void Dispatch(DocAccessibleChild* aIPCDoc) override
+ {
+ Unused << aIPCDoc->SendEvent(mID, mType);
+ }
+
+ uint64_t mID;
+ uint32_t mType;
+ };
+
+ struct SerializedChildDocConstructor final : public DeferredEvent
+ {
+ SerializedChildDocConstructor(DocAccessibleChild* aIPCDoc,
+ DocAccessibleChild* aParentIPCDoc,
+ uint64_t aUniqueID, uint32_t aMsaaID)
+ : DeferredEvent(aParentIPCDoc)
+ , mIPCDoc(aIPCDoc)
+ , mUniqueID(aUniqueID)
+ , mMsaaID(aMsaaID)
+ {}
+
+ void Dispatch(DocAccessibleChild* aParentIPCDoc) override
+ {
+ auto tabChild = static_cast<dom::TabChild*>(aParentIPCDoc->Manager());
+ MOZ_ASSERT(tabChild);
+ Unused << tabChild->SendPDocAccessibleConstructor(mIPCDoc, aParentIPCDoc,
+ mUniqueID, mMsaaID,
+ IAccessibleHolder());
+ mIPCDoc->SetConstructedInParentProcess();
+ }
+
+ DocAccessibleChild* mIPCDoc;
+ uint64_t mUniqueID;
+ uint32_t mMsaaID;
+ };
+
+ friend struct SerializedChildDocConstructor;
+
+ struct SerializedBindChildDoc final : public DeferredEvent
+ {
+ SerializedBindChildDoc(DocAccessibleChild* aParentDoc,
+ DocAccessibleChild* aChildDoc, uint64_t aNewParentID)
+ : DeferredEvent(aParentDoc)
+ , mChildDoc(aChildDoc)
+ , mNewParentID(aNewParentID)
+ {}
+
+ void Dispatch(DocAccessibleChild* aParentIPCDoc) override
+ {
+ Unused << aParentIPCDoc->SendBindChildDoc(mChildDoc, mNewParentID);
+ }
+
+ DocAccessibleChild* mChildDoc;
+ uint64_t mNewParentID;
+ };
+
+ struct SerializedShutdown final : public DeferredEvent
+ {
+ explicit SerializedShutdown(DocAccessibleChild* aTarget)
+ : DeferredEvent(aTarget)
+ {
+ }
+
+ void Dispatch(DocAccessibleChild* aIPCDoc) override
+ {
+ aIPCDoc->Shutdown();
+ }
+ };
+
+ bool mIsRemoteConstructed;
+ mscom::ProxyUniquePtr<IAccessible> mParentProxy;
+ nsTArray<UniquePtr<DeferredEvent>> mDeferredEvents;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif // mozilla_a11y_DocAccessibleChild_h
diff --git a/accessible/ipc/win/PDocAccessible.ipdl b/accessible/ipc/win/PDocAccessible.ipdl
new file mode 100644
index 0000000000..3389abd234
--- /dev/null
+++ b/accessible/ipc/win/PDocAccessible.ipdl
@@ -0,0 +1,75 @@
+/* -*- 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 protocol PFileDescriptorSet;
+include protocol PBrowser;
+
+using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h";
+using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
+
+namespace mozilla {
+namespace a11y {
+
+struct AccessibleData
+{
+ uint64_t ID;
+ int32_t MsaaID;
+ uint32_t Role;
+ uint32_t ChildrenCount;
+ uint32_t Interfaces;
+};
+
+struct ShowEventData
+{
+ uint64_t ID;
+ uint32_t Idx;
+ AccessibleData[] NewTree;
+};
+
+struct Attribute
+{
+ nsCString Name;
+ nsString Value;
+};
+
+sync protocol PDocAccessible
+{
+ manager PBrowser;
+
+parent:
+ async Shutdown();
+
+ /*
+ * Notify the parent process the document in the child process is firing an
+ * event.
+ */
+ async Event(uint64_t aID, uint32_t type);
+ async ShowEvent(ShowEventData data, bool aFromUser);
+ async HideEvent(uint64_t aRootID, bool aFromUser);
+ async StateChangeEvent(uint64_t aID, uint64_t aState, bool aEnabled);
+ async CaretMoveEvent(uint64_t aID, int32_t aOffset);
+ async TextChangeEvent(uint64_t aID, nsString aStr, int32_t aStart, uint32_t aLen,
+ bool aIsInsert, bool aFromUser);
+ async SelectionEvent(uint64_t aID, uint64_t aWidgetID, uint32_t aType);
+ async RoleChangedEvent(uint32_t aRole);
+
+ /*
+ * Tell the parent document to bind the existing document as a new child
+ * document.
+ */
+ async BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);
+
+ sync GetWindowedPluginIAccessible(WindowsHandle aHwnd)
+ returns (IAccessibleHolder aPluginCOMProxy);
+
+child:
+ async ParentCOMProxy(IAccessibleHolder aParentCOMProxy);
+
+ async __delete__();
+};
+
+}
+}
diff --git a/accessible/ipc/win/PlatformChild.cpp b/accessible/ipc/win/PlatformChild.cpp
new file mode 100644
index 0000000000..01434a0811
--- /dev/null
+++ b/accessible/ipc/win/PlatformChild.cpp
@@ -0,0 +1,62 @@
+/* -*- 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 "mozilla/a11y/PlatformChild.h"
+#include "mozilla/mscom/EnsureMTA.h"
+#include "mozilla/mscom/InterceptorLog.h"
+
+#include "Accessible2.h"
+#include "Accessible2_2.h"
+#include "AccessibleHypertext2.h"
+#include "AccessibleTableCell.h"
+
+#include "AccessibleHypertext2_i.c"
+
+namespace mozilla {
+namespace a11y {
+
+/**
+ * Unfortunately the COM interceptor does not intrinsically handle array
+ * outparams. Instead we manually define the relevant metadata here, and
+ * register it in a call to mozilla::mscom::RegisterArrayData.
+ * @see mozilla::mscom::ArrayData
+ */
+static const mozilla::mscom::ArrayData sPlatformChildArrayData[] = {
+ {IID_IEnumVARIANT, 3, 1, VT_DISPATCH, IID_IDispatch, 2},
+ {IID_IAccessible2, 30, 1, VT_UNKNOWN | VT_BYREF, IID_IAccessibleRelation, 2},
+ {IID_IAccessibleRelation, 7, 1, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 2},
+ {IID_IAccessible2_2, 48, 2, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 3,
+ mozilla::mscom::ArrayData::Flag::eAllocatedByServer},
+ {IID_IAccessibleTableCell, 4, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1,
+ mozilla::mscom::ArrayData::Flag::eAllocatedByServer},
+ {IID_IAccessibleTableCell, 7, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1,
+ mozilla::mscom::ArrayData::Flag::eAllocatedByServer},
+ {IID_IAccessibleHypertext2, 25, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1,
+ mozilla::mscom::ArrayData::Flag::eAllocatedByServer}
+};
+
+// Type libraries are thread-neutral, so we can register those from any
+// apartment. OTOH, proxies must be registered from within the apartment where
+// we intend to instantiate them. Therefore RegisterProxy() must be called
+// via EnsureMTA.
+PlatformChild::PlatformChild()
+ : mAccTypelib(mozilla::mscom::RegisterTypelib(L"oleacc.dll",
+ mozilla::mscom::RegistrationFlags::eUseSystemDirectory))
+ , mMiscTypelib(mozilla::mscom::RegisterTypelib(L"Accessible.tlb"))
+{
+ mozilla::mscom::InterceptorLog::Init();
+ mozilla::mscom::RegisterArrayData(sPlatformChildArrayData);
+
+ UniquePtr<mozilla::mscom::RegisteredProxy> ia2Proxy;
+ mozilla::mscom::EnsureMTA([&ia2Proxy]() -> void {
+ ia2Proxy = Move(mozilla::mscom::RegisterProxy(L"ia2marshal.dll"));
+ });
+ mIA2Proxy = Move(ia2Proxy);
+}
+
+} // namespace a11y
+} // namespace mozilla
+
diff --git a/accessible/ipc/win/PlatformChild.h b/accessible/ipc/win/PlatformChild.h
new file mode 100644
index 0000000000..49daf161d7
--- /dev/null
+++ b/accessible/ipc/win/PlatformChild.h
@@ -0,0 +1,35 @@
+/* -*- 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_PlatformChild_h
+#define mozilla_a11y_PlatformChild_h
+
+#include "mozilla/mscom/Registration.h"
+
+namespace mozilla {
+namespace a11y {
+
+class PlatformChild
+{
+public:
+ PlatformChild();
+
+ PlatformChild(PlatformChild&) = delete;
+ PlatformChild(PlatformChild&&) = delete;
+ PlatformChild& operator=(PlatformChild&) = delete;
+ PlatformChild& operator=(PlatformChild&&) = delete;
+
+private:
+ UniquePtr<mozilla::mscom::RegisteredProxy> mIA2Proxy;
+ UniquePtr<mozilla::mscom::RegisteredProxy> mAccTypelib;
+ UniquePtr<mozilla::mscom::RegisteredProxy> mMiscTypelib;
+};
+
+} // namespace mozilla
+} // namespace a11y
+
+#endif // mozilla_a11y_PlatformChild_h
+
diff --git a/accessible/ipc/win/ProxyAccessible.cpp b/accessible/ipc/win/ProxyAccessible.cpp
new file mode 100644
index 0000000000..dcdf20ef95
--- /dev/null
+++ b/accessible/ipc/win/ProxyAccessible.cpp
@@ -0,0 +1,599 @@
+/* -*- 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 "ia2AccessibleValue.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>
+
+static const VARIANT kChildIdSelf = {VT_I4};
+
+namespace mozilla {
+namespace a11y {
+
+bool
+ProxyAccessible::GetCOMInterface(void** aOutAccessible) const
+{
+ if (!aOutAccessible) {
+ return false;
+ }
+
+ if (!mCOMProxy) {
+ // See if we can lazily obtain a COM proxy
+ AccessibleWrap* wrap = WrapperFor(this);
+ bool isDefunct = false;
+ ProxyAccessible* thisPtr = const_cast<ProxyAccessible*>(this);
+ // NB: Don't pass CHILDID_SELF here, use the absolute MSAA ID. Otherwise
+ // GetIAccessibleFor will recurse into this function and we will just
+ // overflow the stack.
+ VARIANT realId = {VT_I4};
+ realId.ulVal = wrap->GetExistingID();
+ thisPtr->mCOMProxy = wrap->GetIAccessibleFor(realId, &isDefunct);
+ }
+
+ RefPtr<IAccessible> addRefed = mCOMProxy;
+ addRefed.forget(aOutAccessible);
+ return !!mCOMProxy;
+}
+
+/**
+ * Specializations of this template map an IAccessible type to its IID
+ */
+template<typename Interface> struct InterfaceIID {};
+
+template<>
+struct InterfaceIID<IAccessibleValue>
+{
+ static REFIID Value() { return IID_IAccessibleValue; }
+};
+
+template<>
+struct InterfaceIID<IAccessibleText>
+{
+ static REFIID Value() { return IID_IAccessibleText; }
+};
+
+/**
+ * Get the COM proxy for this proxy accessible and QueryInterface it with the
+ * correct IID
+ */
+template<typename Interface>
+static already_AddRefed<Interface>
+QueryInterface(const ProxyAccessible* aProxy)
+{
+ RefPtr<IAccessible> acc;
+ if (!aProxy->GetCOMInterface((void**)getter_AddRefs(acc))) {
+ return nullptr;
+ }
+
+ RefPtr<Interface> acc2;
+ if (FAILED(acc->QueryInterface(InterfaceIID<Interface>::Value(),
+ (void**)getter_AddRefs(acc2)))) {
+ return nullptr;
+ }
+
+ return acc2.forget();
+}
+
+void
+ProxyAccessible::Name(nsString& aName) const
+{
+ aName.Truncate();
+ RefPtr<IAccessible> acc;
+ if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+ return;
+ }
+
+ BSTR result;
+ HRESULT hr = acc->get_accName(kChildIdSelf, &result);
+ _bstr_t resultWrap(result, false);
+ if (FAILED(hr)) {
+ return;
+ }
+ aName = (wchar_t*)resultWrap;
+}
+
+void
+ProxyAccessible::Value(nsString& aValue) const
+{
+ aValue.Truncate();
+ RefPtr<IAccessible> acc;
+ if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+ return;
+ }
+
+ BSTR result;
+ HRESULT hr = acc->get_accValue(kChildIdSelf, &result);
+ _bstr_t resultWrap(result, false);
+ if (FAILED(hr)) {
+ return;
+ }
+ aValue = (wchar_t*)resultWrap;
+}
+
+void
+ProxyAccessible::Description(nsString& aDesc) const
+{
+ aDesc.Truncate();
+ RefPtr<IAccessible> acc;
+ if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+ return;
+ }
+
+ BSTR result;
+ HRESULT hr = acc->get_accDescription(kChildIdSelf, &result);
+ _bstr_t resultWrap(result, false);
+ if (FAILED(hr)) {
+ return;
+ }
+ aDesc = (wchar_t*)resultWrap;
+}
+
+uint64_t
+ProxyAccessible::State() const
+{
+ uint64_t state = 0;
+ RefPtr<IAccessible> acc;
+ if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+ return state;
+ }
+
+ VARIANT varState;
+ HRESULT hr = acc->get_accState(kChildIdSelf, &varState);
+ if (FAILED(hr)) {
+ return state;
+ }
+ return uint64_t(varState.lVal);
+}
+
+nsIntRect
+ProxyAccessible::Bounds()
+{
+ nsIntRect rect;
+
+ RefPtr<IAccessible> acc;
+ if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+ return rect;
+ }
+
+ long left;
+ long top;
+ long width;
+ long height;
+ HRESULT hr = acc->accLocation(&left, &top, &width, &height, kChildIdSelf);
+ if (FAILED(hr)) {
+ return rect;
+ }
+ rect.x = left;
+ rect.y = top;
+ rect.width = width;
+ rect.height = height;
+ return rect;
+}
+
+void
+ProxyAccessible::Language(nsString& 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;
+ }
+ }
+}
+
+static bool
+IsEscapedChar(const wchar_t c)
+{
+ return c == L'\\' || c == L':' || c == ',' || c == '=' || c == ';';
+}
+
+static bool
+ConvertBSTRAttributesToArray(const nsAString& aStr,
+ nsTArray<Attribute>* aAttrs)
+{
+ if (!aAttrs) {
+ return false;
+ }
+
+ enum
+ {
+ eName = 0,
+ eValue = 1,
+ eNumStates
+ } state;
+ nsAutoString tokens[eNumStates];
+ auto itr = aStr.BeginReading(), end = aStr.EndReading();
+
+ 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::Attributes(nsTArray<Attribute>* aAttrs) const
+{
+ aAttrs->Clear();
+
+ RefPtr<IAccessible> acc;
+ if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
+ return;
+ }
+
+ 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);
+}
+
+double
+ProxyAccessible::CurValue()
+{
+ RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+ if (!acc) {
+ return UnspecifiedNaN<double>();
+ }
+
+ VARIANT currentValue;
+ HRESULT hr = acc->get_currentValue(&currentValue);
+ if (FAILED(hr) || currentValue.vt != VT_R8) {
+ return UnspecifiedNaN<double>();
+ }
+
+ return currentValue.dblVal;
+}
+
+bool
+ProxyAccessible::SetCurValue(double aValue)
+{
+ RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+ if (!acc) {
+ return false;
+ }
+
+ VARIANT currentValue;
+ VariantInit(&currentValue);
+ currentValue.vt = VT_R8;
+ currentValue.dblVal = aValue;
+ HRESULT hr = acc->setCurrentValue(currentValue);
+ return SUCCEEDED(hr);
+}
+
+double
+ProxyAccessible::MinValue()
+{
+ RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+ if (!acc) {
+ return UnspecifiedNaN<double>();
+ }
+
+ VARIANT minimumValue;
+ HRESULT hr = acc->get_minimumValue(&minimumValue);
+ if (FAILED(hr) || minimumValue.vt != VT_R8) {
+ return UnspecifiedNaN<double>();
+ }
+
+ return minimumValue.dblVal;
+}
+
+double
+ProxyAccessible::MaxValue()
+{
+ RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+ if (!acc) {
+ return UnspecifiedNaN<double>();
+ }
+
+ VARIANT maximumValue;
+ HRESULT hr = acc->get_maximumValue(&maximumValue);
+ if (FAILED(hr) || maximumValue.vt != VT_R8) {
+ return UnspecifiedNaN<double>();
+ }
+
+ return maximumValue.dblVal;
+}
+
+static IA2TextBoundaryType
+GetIA2TextBoundary(AccessibleTextBoundary aGeckoBoundaryType)
+{
+ switch (aGeckoBoundaryType) {
+ case nsIAccessibleText::BOUNDARY_CHAR:
+ return IA2_TEXT_BOUNDARY_CHAR;
+ case nsIAccessibleText::BOUNDARY_WORD_START:
+ return IA2_TEXT_BOUNDARY_WORD;
+ case nsIAccessibleText::BOUNDARY_LINE_START:
+ return IA2_TEXT_BOUNDARY_LINE;
+ default:
+ MOZ_RELEASE_ASSERT(false);
+ }
+}
+
+bool
+ProxyAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOffset,
+ nsString& aText) const
+{
+ RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+ if (!acc) {
+ return false;
+ }
+
+ BSTR result;
+ HRESULT hr = acc->get_text(static_cast<long>(aStartOffset),
+ static_cast<long>(aEndOffset), &result);
+ if (FAILED(hr)) {
+ return false;
+ }
+
+ _bstr_t resultWrap(result, false);
+ aText = (wchar_t*)result;
+
+ return true;
+}
+
+void
+ProxyAccessible::GetTextBeforeOffset(int32_t aOffset,
+ AccessibleTextBoundary aBoundaryType,
+ nsString& aText, int32_t* aStartOffset,
+ int32_t* aEndOffset)
+{
+ RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+ if (!acc) {
+ return;
+ }
+
+ BSTR result;
+ long start, end;
+ HRESULT hr = acc->get_textBeforeOffset(aOffset,
+ GetIA2TextBoundary(aBoundaryType),
+ &start, &end, &result);
+ if (FAILED(hr)) {
+ return;
+ }
+
+ _bstr_t resultWrap(result, false);
+ *aStartOffset = start;
+ *aEndOffset = end;
+ aText = (wchar_t*)result;
+}
+
+void
+ProxyAccessible::GetTextAfterOffset(int32_t aOffset,
+ AccessibleTextBoundary aBoundaryType,
+ nsString& aText, int32_t* aStartOffset,
+ int32_t* aEndOffset)
+{
+ RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+ if (!acc) {
+ return;
+ }
+
+ BSTR result;
+ long start, end;
+ HRESULT hr = acc->get_textAfterOffset(aOffset,
+ GetIA2TextBoundary(aBoundaryType),
+ &start, &end, &result);
+ if (FAILED(hr)) {
+ return;
+ }
+
+ _bstr_t resultWrap(result, false);
+ aText = (wchar_t*)result;
+ *aStartOffset = start;
+ *aEndOffset = end;
+}
+
+void
+ProxyAccessible::GetTextAtOffset(int32_t aOffset,
+ AccessibleTextBoundary aBoundaryType,
+ nsString& aText, int32_t* aStartOffset,
+ int32_t* aEndOffset)
+{
+ RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+ if (!acc) {
+ return;
+ }
+
+ BSTR result;
+ long start, end;
+ HRESULT hr = acc->get_textAtOffset(aOffset, GetIA2TextBoundary(aBoundaryType),
+ &start, &end, &result);
+ if (FAILED(hr)) {
+ return;
+ }
+
+ _bstr_t resultWrap(result, false);
+ aText = (wchar_t*)result;
+ *aStartOffset = start;
+ *aEndOffset = end;
+}
+
+bool
+ProxyAccessible::AddToSelection(int32_t aStartOffset, int32_t aEndOffset)
+{
+ RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+ if (!acc) {
+ return false;
+ }
+
+ return SUCCEEDED(acc->addSelection(static_cast<long>(aStartOffset),
+ static_cast<long>(aEndOffset)));
+}
+
+bool
+ProxyAccessible::RemoveFromSelection(int32_t aSelectionNum)
+{
+ RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+ if (!acc) {
+ return false;
+ }
+
+ return SUCCEEDED(acc->removeSelection(static_cast<long>(aSelectionNum)));
+}
+
+int32_t
+ProxyAccessible::CaretOffset()
+{
+ RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+ if (!acc) {
+ return -1;
+ }
+
+ long offset;
+ HRESULT hr = acc->get_caretOffset(&offset);
+ if (FAILED(hr)) {
+ return -1;
+ }
+
+ return static_cast<int32_t>(offset);
+}
+
+void
+ProxyAccessible::SetCaretOffset(int32_t aOffset)
+{
+ RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+ if (!acc) {
+ return;
+ }
+
+ acc->setCaretOffset(static_cast<long>(aOffset));
+}
+
+/**
+ * aScrollType should be one of the nsIAccessiblescrollType constants.
+ */
+void
+ProxyAccessible::ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset,
+ uint32_t aScrollType)
+{
+ RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+ if (!acc) {
+ return;
+ }
+
+ acc->scrollSubstringTo(static_cast<long>(aStartOffset),
+ static_cast<long>(aEndOffset),
+ static_cast<IA2ScrollType>(aScrollType));
+}
+
+/**
+ * aCoordinateType is one of the nsIAccessibleCoordinateType constants.
+ */
+void
+ProxyAccessible::ScrollSubstringToPoint(int32_t aStartOffset, int32_t aEndOffset,
+ uint32_t aCoordinateType, int32_t aX,
+ int32_t aY)
+{
+ RefPtr<IAccessibleText> acc = QueryInterface<IAccessibleText>(this);
+ if (!acc) {
+ return;
+ }
+
+ IA2CoordinateType coordType;
+ if (aCoordinateType == nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE) {
+ coordType = IA2_COORDTYPE_SCREEN_RELATIVE;
+ } else if (aCoordinateType == nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE) {
+ coordType = IA2_COORDTYPE_PARENT_RELATIVE;
+ } else {
+ MOZ_RELEASE_ASSERT(false, "unsupported coord type");
+ }
+
+ acc->scrollSubstringToPoint(static_cast<long>(aStartOffset),
+ static_cast<long>(aEndOffset),
+ coordType,
+ static_cast<long>(aX),
+ static_cast<long>(aY));
+}
+
+} // namespace a11y
+} // namespace mozilla
diff --git a/accessible/ipc/win/ProxyAccessible.h b/accessible/ipc/win/ProxyAccessible.h
new file mode 100644
index 0000000000..c8e5a43b1f
--- /dev/null
+++ b/accessible/ipc/win/ProxyAccessible.h
@@ -0,0 +1,58 @@
+/* -*- 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
+
+#include "Accessible.h"
+#include "mozilla/a11y/ProxyAccessibleBase.h"
+#include "mozilla/a11y/Role.h"
+#include "nsIAccessibleText.h"
+#include "nsIAccessibleTypes.h"
+#include "nsString.h"
+#include "nsTArray.h"
+#include "nsRect.h"
+
+#include <oleacc.h>
+
+namespace mozilla {
+namespace a11y {
+
+class ProxyAccessible : public ProxyAccessibleBase<ProxyAccessible>
+{
+public:
+ ProxyAccessible(uint64_t aID, ProxyAccessible* aParent,
+ DocAccessibleParent* aDoc, role aRole, uint32_t aInterfaces)
+ : ProxyAccessibleBase(aID, aParent, aDoc, aRole, aInterfaces)
+ {
+ MOZ_COUNT_CTOR(ProxyAccessible);
+ }
+
+ ~ProxyAccessible()
+ {
+ MOZ_COUNT_DTOR(ProxyAccessible);
+ }
+
+#include "mozilla/a11y/ProxyAccessibleShared.h"
+
+ bool GetCOMInterface(void** aOutAccessible) const;
+
+protected:
+ explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc)
+ : ProxyAccessibleBase(aThisAsDoc)
+ { MOZ_COUNT_CTOR(ProxyAccessible); }
+
+ void SetCOMInterface(const RefPtr<IAccessible>& aIAccessible)
+ { mCOMProxy = aIAccessible; }
+
+private:
+ RefPtr<IAccessible> mCOMProxy;
+};
+
+}
+}
+
+#endif
diff --git a/accessible/ipc/win/moz.build b/accessible/ipc/win/moz.build
new file mode 100644
index 0000000000..4bbcec417c
--- /dev/null
+++ b/accessible/ipc/win/moz.build
@@ -0,0 +1,39 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+if CONFIG['COMPILE_ENVIRONMENT']:
+ DIRS += ['typelib']
+
+# With --disable-accessibility, we need to compile PDocAccessible.ipdl (which
+# also depends on COMPtrTypes.h), but not the C++.
+IPDL_SOURCES += ['PDocAccessible.ipdl']
+EXPORTS.mozilla.a11y += ['COMPtrTypes.h']
+
+if CONFIG['ACCESSIBILITY']:
+ EXPORTS.mozilla.a11y += [
+ 'DocAccessibleChild.h',
+ 'PlatformChild.h',
+ 'ProxyAccessible.h'
+ ]
+
+ SOURCES += [
+ 'COMPtrTypes.cpp',
+ 'DocAccessibleChild.cpp',
+ 'PlatformChild.cpp',
+ 'ProxyAccessible.cpp',
+ ]
+
+ LOCAL_INCLUDES += [
+ '/accessible/base',
+ '/accessible/generic',
+ '/accessible/windows/ia2',
+ '/accessible/windows/msaa',
+ '/accessible/xpcom',
+ ]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FINAL_LIBRARY = 'xul'
diff --git a/accessible/ipc/win/typelib/Accessible.idl b/accessible/ipc/win/typelib/Accessible.idl
new file mode 100644
index 0000000000..82ddcf5065
--- /dev/null
+++ b/accessible/ipc/win/typelib/Accessible.idl
@@ -0,0 +1,16 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import "oaidl.idl";
+import "servprov.idl";
+
+[uuid(b4d37cda-0dac-45e6-b613-158a5eb94293)]
+library Accessible
+{
+ interface IEnumVARIANT;
+ interface IServiceProvider;
+};
+
diff --git a/accessible/ipc/win/typelib/Makefile.in b/accessible/ipc/win/typelib/Makefile.in
new file mode 100644
index 0000000000..78e0cea299
--- /dev/null
+++ b/accessible/ipc/win/typelib/Makefile.in
@@ -0,0 +1,31 @@
+# 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/.
+
+GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c
+
+MIDL_GENERATED_FILES = \
+ Accessible.h \
+ Accessible_i.c \
+ Accessible_p.c \
+ Accessible.tlb \
+ $(NULL)
+
+$(MIDL_GENERATED_FILES): done_gen
+
+done_gen: Accessible.idl
+ $(MIDL) $(MIDL_FLAGS) -Oicf $(srcdir)/Accessible.idl
+ touch $@
+
+export:: done_gen
+
+midl_exports := \
+ Accessible.tlb \
+ $(NULL)
+
+INSTALL_TARGETS += midl_exports
+midl_exports_FILES := $(midl_exports)
+midl_exports_DEST = $(DIST)/bin
+midl_exports_TARGET := export
+
+include $(topsrcdir)/config/rules.mk
diff --git a/accessible/ipc/win/typelib/moz.build b/accessible/ipc/win/typelib/moz.build
new file mode 100644
index 0000000000..3bc45a136d
--- /dev/null
+++ b/accessible/ipc/win/typelib/moz.build
@@ -0,0 +1,13 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+FINAL_TARGET_FILES += [
+ '!Accessible.tlb',
+]
+
+GENERATED_FILES += [
+ 'Accessible.tlb',
+]