diff options
Diffstat (limited to 'accessible/ipc/ProxyAccessibleBase.h')
-rw-r--r-- | accessible/ipc/ProxyAccessibleBase.h | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/accessible/ipc/ProxyAccessibleBase.h b/accessible/ipc/ProxyAccessibleBase.h new file mode 100644 index 0000000000..c3ddd817ba --- /dev/null +++ b/accessible/ipc/ProxyAccessibleBase.h @@ -0,0 +1,219 @@ +/* -*- 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 { + int32_t idx = IndexInParent(); + if (idx == -1) { + return nullptr; // No parent. + } + return idx > 0 ? Parent()->mChildren[idx - 1] : nullptr; + } + Derived* NextSibling() const { + int32_t idx = IndexInParent(); + if (idx == -1) { + return nullptr; // No parent. + } + MOZ_ASSERT(idx >= 0); + size_t newIdx = idx + 1; + return newIdx < Parent()->mChildren.Length() ? Parent()->mChildren[newIdx] + : nullptr; + } + + // XXX evaluate if this is fast enough. + int32_t IndexInParent() const { + Derived* parent = Parent(); + if (!parent) { + return -1; + } + 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 |