Mypal/accessible/ipc/win/DocAccessibleChild.cpp
2021-02-04 16:48:36 +02:00

237 lines
6.9 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "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