mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-08 00:07:30 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
97
accessible/ipc/DocAccessibleChildBase.cpp
Normal file
97
accessible/ipc/DocAccessibleChildBase.cpp
Normal 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
|
||||
|
||||
81
accessible/ipc/DocAccessibleChildBase.h
Normal file
81
accessible/ipc/DocAccessibleChildBase.h
Normal 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
|
||||
526
accessible/ipc/DocAccessibleParent.cpp
Normal file
526
accessible/ipc/DocAccessibleParent.cpp
Normal 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
|
||||
198
accessible/ipc/DocAccessibleParent.h
Normal file
198
accessible/ipc/DocAccessibleParent.h
Normal 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
49
accessible/ipc/IPCTypes.h
Normal 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
|
||||
|
||||
175
accessible/ipc/ProxyAccessibleBase.cpp
Normal file
175
accessible/ipc/ProxyAccessibleBase.cpp
Normal 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
|
||||
211
accessible/ipc/ProxyAccessibleBase.h
Normal file
211
accessible/ipc/ProxyAccessibleBase.h
Normal 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
|
||||
277
accessible/ipc/ProxyAccessibleShared.h
Normal file
277
accessible/ipc/ProxyAccessibleShared.h
Normal 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
61
accessible/ipc/moz.build
Normal 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'
|
||||
1998
accessible/ipc/other/DocAccessibleChild.cpp
Normal file
1998
accessible/ipc/other/DocAccessibleChild.cpp
Normal file
File diff suppressed because it is too large
Load diff
489
accessible/ipc/other/DocAccessibleChild.h
Normal file
489
accessible/ipc/other/DocAccessibleChild.h
Normal 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
|
||||
264
accessible/ipc/other/PDocAccessible.ipdl
Normal file
264
accessible/ipc/other/PDocAccessible.ipdl
Normal 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);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
1080
accessible/ipc/other/ProxyAccessible.cpp
Normal file
1080
accessible/ipc/other/ProxyAccessible.cpp
Normal file
File diff suppressed because it is too large
Load diff
50
accessible/ipc/other/ProxyAccessible.h
Normal file
50
accessible/ipc/other/ProxyAccessible.h
Normal 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
|
||||
47
accessible/ipc/other/moz.build
Normal file
47
accessible/ipc/other/moz.build
Normal 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'
|
||||
|
||||
50
accessible/ipc/win/COMPtrTypes.cpp
Normal file
50
accessible/ipc/win/COMPtrTypes.cpp
Normal 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
|
||||
27
accessible/ipc/win/COMPtrTypes.h
Normal file
27
accessible/ipc/win/COMPtrTypes.h
Normal 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
|
||||
237
accessible/ipc/win/DocAccessibleChild.cpp
Normal file
237
accessible/ipc/win/DocAccessibleChild.cpp
Normal 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
|
||||
|
||||
318
accessible/ipc/win/DocAccessibleChild.h
Normal file
318
accessible/ipc/win/DocAccessibleChild.h
Normal 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
|
||||
75
accessible/ipc/win/PDocAccessible.ipdl
Normal file
75
accessible/ipc/win/PDocAccessible.ipdl
Normal 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__();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
62
accessible/ipc/win/PlatformChild.cpp
Normal file
62
accessible/ipc/win/PlatformChild.cpp
Normal 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
|
||||
|
||||
35
accessible/ipc/win/PlatformChild.h
Normal file
35
accessible/ipc/win/PlatformChild.h
Normal 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
|
||||
|
||||
599
accessible/ipc/win/ProxyAccessible.cpp
Normal file
599
accessible/ipc/win/ProxyAccessible.cpp
Normal 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(¤tValue);
|
||||
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(¤tValue);
|
||||
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
|
||||
58
accessible/ipc/win/ProxyAccessible.h
Normal file
58
accessible/ipc/win/ProxyAccessible.h
Normal 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
|
||||
39
accessible/ipc/win/moz.build
Normal file
39
accessible/ipc/win/moz.build
Normal 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'
|
||||
16
accessible/ipc/win/typelib/Accessible.idl
Normal file
16
accessible/ipc/win/typelib/Accessible.idl
Normal 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;
|
||||
};
|
||||
|
||||
31
accessible/ipc/win/typelib/Makefile.in
Normal file
31
accessible/ipc/win/typelib/Makefile.in
Normal 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
|
||||
13
accessible/ipc/win/typelib/moz.build
Normal file
13
accessible/ipc/win/typelib/moz.build
Normal 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',
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue