зеркало из https://github.com/mozilla/gecko-dev.git
208 строки
5.6 KiB
C++
208 строки
5.6 KiB
C++
/* -*- 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);
|
|
|
|
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;
|
|
|
|
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->ID()),
|
|
mDoc(aDoc),
|
|
mWrapper(0),
|
|
mID(aID),
|
|
mRole(aRole),
|
|
mOuterDoc(false),
|
|
mIsDoc(false),
|
|
mHasValue(aInterfaces & Interfaces::VALUE),
|
|
mIsHyperLink(aInterfaces & Interfaces::HYPERLINK),
|
|
mIsHyperText(aInterfaces & Interfaces::HYPERTEXT),
|
|
mIsSelection(aInterfaces & Interfaces::SELECTION) {}
|
|
|
|
explicit ProxyAccessibleBase(DocAccessibleParent* aThisAsDoc)
|
|
: mParent(kNoParent),
|
|
mDoc(aThisAsDoc),
|
|
mWrapper(0),
|
|
mID(0),
|
|
mRole(roles::DOCUMENT),
|
|
mOuterDoc(false),
|
|
mIsDoc(true),
|
|
mHasValue(false),
|
|
mIsHyperLink(false),
|
|
mIsHyperText(false),
|
|
mIsSelection(false) {}
|
|
|
|
protected:
|
|
void SetParent(Derived* aParent);
|
|
|
|
private:
|
|
uintptr_t mParent;
|
|
static const uintptr_t kNoParent = UINTPTR_MAX;
|
|
|
|
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;
|
|
const bool mIsSelection : 1;
|
|
};
|
|
|
|
extern template class ProxyAccessibleBase<ProxyAccessible>;
|
|
|
|
} // namespace a11y
|
|
} // namespace mozilla
|
|
|
|
#endif
|