Mypal/accessible/ipc/ProxyAccessibleBase.h

211 lines
5.2 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/. */
#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