2014-03-07 13:35:19 -08:00
|
|
|
/* -*- 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 "ProxyAccessible.h"
|
|
|
|
#include "mozilla/a11y/PDocAccessibleParent.h"
|
|
|
|
#include "nsClassHashtable.h"
|
|
|
|
#include "nsHashKeys.h"
|
|
|
|
#include "nsISupportsImpl.h"
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace a11y {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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() :
|
2015-06-10 11:11:34 -07:00
|
|
|
ProxyAccessible(this), mParentDoc(nullptr),
|
|
|
|
mTopLevel(false), mShutdown(false)
|
2014-03-07 13:35:19 -08:00
|
|
|
{ MOZ_COUNT_CTOR_INHERITED(DocAccessibleParent, ProxyAccessible); }
|
|
|
|
~DocAccessibleParent()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR_INHERITED(DocAccessibleParent, ProxyAccessible);
|
|
|
|
MOZ_ASSERT(mChildDocs.Length() == 0);
|
2015-05-21 11:11:52 -07:00
|
|
|
MOZ_ASSERT(!ParentDoc());
|
2014-03-07 13:35:19 -08:00
|
|
|
}
|
|
|
|
|
2015-06-10 11:11:34 -07:00
|
|
|
void SetTopLevel() { mTopLevel = true; }
|
|
|
|
bool IsTopLevel() const { return mTopLevel; }
|
|
|
|
|
2014-03-07 13:35:19 -08:00
|
|
|
/*
|
|
|
|
* Called when a message from a document in a child process notifies the main
|
|
|
|
* process it is firing an event.
|
|
|
|
*/
|
2014-09-30 07:00:26 -07:00
|
|
|
virtual bool RecvEvent(const uint64_t& aID, const uint32_t& aType)
|
2015-03-21 09:28:04 -07:00
|
|
|
override;
|
2014-03-07 13:35:19 -08:00
|
|
|
|
2015-03-21 09:28:04 -07:00
|
|
|
virtual bool RecvShowEvent(const ShowEventData& aData) override;
|
|
|
|
virtual bool RecvHideEvent(const uint64_t& aRootID) override;
|
2015-05-13 11:21:23 -07:00
|
|
|
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;
|
2014-03-07 13:35:19 -08:00
|
|
|
|
2015-06-05 12:43:30 -07:00
|
|
|
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;
|
|
|
|
|
2015-03-24 10:52:59 -07:00
|
|
|
virtual bool RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID) override;
|
|
|
|
void Unbind()
|
|
|
|
{
|
|
|
|
mParent = nullptr;
|
2015-11-06 12:17:40 -08:00
|
|
|
if (DocAccessibleParent* parent = ParentDoc()) {
|
|
|
|
parent->mChildDocs.RemoveElement(this);
|
|
|
|
}
|
|
|
|
|
2015-03-24 10:52:59 -07:00
|
|
|
mParentDoc = nullptr;
|
|
|
|
}
|
|
|
|
|
2015-06-02 07:30:51 -07:00
|
|
|
virtual bool RecvShutdown() override;
|
2015-01-13 20:42:27 -08:00
|
|
|
void Destroy();
|
2015-03-21 09:28:04 -07:00
|
|
|
virtual void ActorDestroy(ActorDestroyReason aWhy) override
|
2015-01-13 20:42:27 -08:00
|
|
|
{
|
2015-08-17 13:10:55 -07:00
|
|
|
MOZ_DIAGNOSTIC_ASSERT(CheckDocTree());
|
2015-01-13 20:42:27 -08:00
|
|
|
if (!mShutdown)
|
|
|
|
Destroy();
|
|
|
|
}
|
2014-03-07 13:35:19 -08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Return the main processes representation of the parent document (if any)
|
|
|
|
* of the document this object represents.
|
|
|
|
*/
|
2015-05-21 11:11:52 -07:00
|
|
|
DocAccessibleParent* ParentDoc() const { return mParentDoc; }
|
2014-03-07 13:35:19 -08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Called when a document in a content process notifies the main process of a
|
|
|
|
* new child document.
|
|
|
|
*/
|
2015-03-24 10:52:59 -07:00
|
|
|
bool AddChildDoc(DocAccessibleParent* aChildDoc, uint64_t aParentID,
|
|
|
|
bool aCreating = true);
|
2014-03-07 13:35:19 -08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
{
|
2015-05-21 11:19:44 -07:00
|
|
|
aChildDoc->Parent()->SetChildDoc(nullptr);
|
2014-03-07 13:35:19 -08:00
|
|
|
mChildDocs.RemoveElement(aChildDoc);
|
|
|
|
aChildDoc->mParentDoc = nullptr;
|
|
|
|
MOZ_ASSERT(aChildDoc->mChildDocs.Length() == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RemoveAccessible(ProxyAccessible* aAccessible)
|
|
|
|
{
|
2015-09-11 12:22:51 -07:00
|
|
|
MOZ_DIAGNOSTIC_ASSERT(mAccessibles.GetEntry(aAccessible->ID()));
|
2014-03-07 13:35:19 -08:00
|
|
|
mAccessibles.RemoveEntry(aAccessible->ID());
|
|
|
|
}
|
|
|
|
|
2015-01-29 08:58:34 -08:00
|
|
|
/**
|
|
|
|
* Return the accessible for given id.
|
|
|
|
*/
|
2015-05-13 08:57:14 -07:00
|
|
|
ProxyAccessible* GetAccessible(uintptr_t aID)
|
2015-01-29 08:58:34 -08:00
|
|
|
{
|
2015-05-13 08:57:14 -07:00
|
|
|
if (!aID)
|
|
|
|
return this;
|
|
|
|
|
2015-01-29 08:58:34 -08:00
|
|
|
ProxyEntry* e = mAccessibles.GetEntry(aID);
|
|
|
|
return e ? e->mProxy : nullptr;
|
|
|
|
}
|
|
|
|
|
2015-05-13 08:57:14 -07:00
|
|
|
const ProxyAccessible* GetAccessible(uintptr_t aID) const
|
|
|
|
{ return const_cast<DocAccessibleParent*>(this)->GetAccessible(aID); }
|
|
|
|
|
2015-09-23 14:17:01 -07:00
|
|
|
size_t ChildDocCount() const { return mChildDocs.Length(); }
|
|
|
|
const DocAccessibleParent* ChildDocAt(size_t aIdx) const
|
|
|
|
{ return mChildDocs[aIdx]; }
|
|
|
|
|
2014-03-07 13:35:19 -08:00
|
|
|
private:
|
|
|
|
|
|
|
|
class ProxyEntry : public PLDHashEntryHdr
|
|
|
|
{
|
|
|
|
public:
|
2014-10-10 14:28:35 -07:00
|
|
|
explicit ProxyEntry(const void*) : mProxy(nullptr) {}
|
2014-03-07 13:35:19 -08:00
|
|
|
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);
|
2015-08-17 13:10:55 -07:00
|
|
|
MOZ_WARN_UNUSED_RESULT bool CheckDocTree() const;
|
2015-07-15 14:32:37 -07:00
|
|
|
|
2014-03-07 13:35:19 -08:00
|
|
|
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;
|
2015-06-10 11:11:34 -07:00
|
|
|
bool mTopLevel;
|
2015-01-13 20:42:27 -08:00
|
|
|
bool mShutdown;
|
2014-03-07 13:35:19 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|