import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

49
accessible/ipc/IPCTypes.h Normal file
View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

61
accessible/ipc/moz.build Normal file
View file

@ -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'

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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);
};
}
}

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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'

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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__();
};
}
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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'

View file

@ -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;
};

View file

@ -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

View file

@ -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',
]