зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1268544: Refactor ProxyAccessible and dependencies; r=tbsaunde
MozReview-Commit-ID: EHV0JR6NmKf --HG-- rename : accessible/ipc/ProxyAccessible.cpp => accessible/ipc/ProxyAccessibleBase.cpp rename : accessible/ipc/ProxyAccessible.h => accessible/ipc/ProxyAccessibleBase.h rename : accessible/ipc/ProxyAccessible.cpp => accessible/ipc/other/ProxyAccessible.cpp rename : accessible/ipc/ProxyAccessible.h => accessible/ipc/other/ProxyAccessible.h rename : accessible/ipc/ProxyAccessible.cpp => accessible/ipc/win/ProxyAccessible.cpp rename : accessible/ipc/ProxyAccessible.h => accessible/ipc/win/ProxyAccessible.h
This commit is contained in:
Родитель
1d9ba42f65
Коммит
1597663492
|
@ -0,0 +1,159 @@
|
||||||
|
/* -*- 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/. */
|
||||||
|
|
||||||
|
#include "DocAccessible.h"
|
||||||
|
#include "mozilla/a11y/DocAccessibleParent.h"
|
||||||
|
#include "mozilla/a11y/DocManager.h"
|
||||||
|
#include "mozilla/a11y/Platform.h"
|
||||||
|
#include "mozilla/a11y/ProxyAccessibleBase.h"
|
||||||
|
#include "mozilla/a11y/ProxyAccessible.h"
|
||||||
|
#include "mozilla/a11y/Role.h"
|
||||||
|
#include "mozilla/dom/Element.h"
|
||||||
|
#include "mozilla/dom/TabParent.h"
|
||||||
|
#include "mozilla/unused.h"
|
||||||
|
#include "RelationType.h"
|
||||||
|
#include "xpcAccessibleDocument.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace a11y {
|
||||||
|
|
||||||
|
template <class Derived>
|
||||||
|
void
|
||||||
|
ProxyAccessibleBase<Derived>::Shutdown()
|
||||||
|
{
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(!IsDoc());
|
||||||
|
NS_ASSERTION(!mOuterDoc, "Why do we still have a child doc?");
|
||||||
|
xpcAccessibleDocument* xpcDoc =
|
||||||
|
GetAccService()->GetCachedXPCDocument(Document());
|
||||||
|
if (xpcDoc) {
|
||||||
|
xpcDoc->NotifyOfShutdown(static_cast<Derived*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX Ideally this wouldn't be necessary, but it seems OuterDoc accessibles
|
||||||
|
// can be destroyed before the doc they own.
|
||||||
|
if (!mOuterDoc) {
|
||||||
|
uint32_t childCount = mChildren.Length();
|
||||||
|
for (uint32_t idx = 0; idx < childCount; idx++)
|
||||||
|
mChildren[idx]->Shutdown();
|
||||||
|
} else {
|
||||||
|
if (mChildren.Length() != 1)
|
||||||
|
MOZ_CRASH("outer doc doesn't own adoc!");
|
||||||
|
|
||||||
|
mChildren[0]->AsDoc()->Unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
mChildren.Clear();
|
||||||
|
ProxyDestroyed(static_cast<Derived*>(this));
|
||||||
|
mDoc->RemoveAccessible(static_cast<Derived*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Derived>
|
||||||
|
void
|
||||||
|
ProxyAccessibleBase<Derived>::SetChildDoc(DocAccessibleParent* aParent)
|
||||||
|
{
|
||||||
|
if (aParent) {
|
||||||
|
MOZ_ASSERT(mChildren.IsEmpty());
|
||||||
|
mChildren.AppendElement(aParent);
|
||||||
|
mOuterDoc = true;
|
||||||
|
} else {
|
||||||
|
MOZ_ASSERT(mChildren.Length() == 1);
|
||||||
|
mChildren.Clear();
|
||||||
|
mOuterDoc = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Derived>
|
||||||
|
bool
|
||||||
|
ProxyAccessibleBase<Derived>::MustPruneChildren() const
|
||||||
|
{
|
||||||
|
// this is the equivalent to nsAccUtils::MustPrune for proxies and should be
|
||||||
|
// kept in sync with that.
|
||||||
|
if (mRole != roles::MENUITEM && mRole != roles::COMBOBOX_OPTION
|
||||||
|
&& mRole != roles::OPTION && mRole != roles::ENTRY
|
||||||
|
&& mRole != roles::FLAT_EQUATION && mRole != roles::PASSWORD_TEXT
|
||||||
|
&& mRole != roles::PUSHBUTTON && mRole != roles::TOGGLE_BUTTON
|
||||||
|
&& mRole != roles::GRAPHIC && mRole != roles::SLIDER
|
||||||
|
&& mRole != roles::PROGRESSBAR && mRole != roles::SEPARATOR)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mChildren.Length() != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return mChildren[0]->Role() == roles::TEXT_LEAF
|
||||||
|
|| mChildren[0]->Role() == roles::STATICTEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Derived>
|
||||||
|
uint32_t
|
||||||
|
ProxyAccessibleBase<Derived>::EmbeddedChildCount() const
|
||||||
|
{
|
||||||
|
size_t count = 0, kids = mChildren.Length();
|
||||||
|
for (size_t i = 0; i < kids; i++) {
|
||||||
|
if (mChildren[i]->IsEmbeddedObject()) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Derived>
|
||||||
|
int32_t
|
||||||
|
ProxyAccessibleBase<Derived>::IndexOfEmbeddedChild(const Derived* aChild)
|
||||||
|
{
|
||||||
|
size_t index = 0, kids = mChildren.Length();
|
||||||
|
for (size_t i = 0; i < kids; i++) {
|
||||||
|
if (mChildren[i]->IsEmbeddedObject()) {
|
||||||
|
if (mChildren[i] == aChild) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Derived>
|
||||||
|
Derived*
|
||||||
|
ProxyAccessibleBase<Derived>::EmbeddedChildAt(size_t aChildIdx)
|
||||||
|
{
|
||||||
|
size_t index = 0, kids = mChildren.Length();
|
||||||
|
for (size_t i = 0; i < kids; i++) {
|
||||||
|
if (!mChildren[i]->IsEmbeddedObject()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == aChildIdx) {
|
||||||
|
return mChildren[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Derived>
|
||||||
|
Accessible*
|
||||||
|
ProxyAccessibleBase<Derived>::OuterDocOfRemoteBrowser() const
|
||||||
|
{
|
||||||
|
auto tab = static_cast<dom::TabParent*>(mDoc->Manager());
|
||||||
|
dom::Element* frame = tab->GetOwnerElement();
|
||||||
|
NS_ASSERTION(frame, "why isn't the tab in a frame!");
|
||||||
|
if (!frame)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
DocAccessible* chromeDoc = GetExistingDocAccessible(frame->OwnerDoc());
|
||||||
|
|
||||||
|
return chromeDoc ? chromeDoc->GetAccessible(frame) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template class ProxyAccessibleBase<ProxyAccessible>;
|
||||||
|
|
||||||
|
} // namespace a11y
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,190 @@
|
||||||
|
/* -*- 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(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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~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*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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; }
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
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)
|
||||||
|
{ MOZ_COUNT_CTOR(ProxyAccessibleBase); }
|
||||||
|
|
||||||
|
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
|
|
@ -38,13 +38,13 @@ if CONFIG['ACCESSIBILITY']:
|
||||||
EXPORTS.mozilla.a11y += [
|
EXPORTS.mozilla.a11y += [
|
||||||
'DocAccessibleChildBase.h',
|
'DocAccessibleChildBase.h',
|
||||||
'DocAccessibleParent.h',
|
'DocAccessibleParent.h',
|
||||||
'ProxyAccessible.h'
|
'ProxyAccessibleBase.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'DocAccessibleChildBase.cpp',
|
'DocAccessibleChildBase.cpp',
|
||||||
'DocAccessibleParent.cpp',
|
'DocAccessibleParent.cpp',
|
||||||
'ProxyAccessible.cpp'
|
'ProxyAccessibleBase.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "ProxyAccessible.h"
|
#include "ProxyAccessible.h"
|
||||||
#include "DocAccessibleParent.h"
|
#include "mozilla/a11y/DocAccessibleParent.h"
|
||||||
#include "DocAccessible.h"
|
#include "DocAccessible.h"
|
||||||
#include "mozilla/a11y/DocManager.h"
|
#include "mozilla/a11y/DocManager.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
|
@ -19,69 +19,6 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace a11y {
|
namespace a11y {
|
||||||
|
|
||||||
void
|
|
||||||
ProxyAccessible::Shutdown()
|
|
||||||
{
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(!IsDoc());
|
|
||||||
NS_ASSERTION(!mOuterDoc, "Why do we still have a child doc?");
|
|
||||||
xpcAccessibleDocument* xpcDoc =
|
|
||||||
GetAccService()->GetCachedXPCDocument(Document());
|
|
||||||
if (xpcDoc) {
|
|
||||||
xpcDoc->NotifyOfShutdown(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX Ideally this wouldn't be necessary, but it seems OuterDoc accessibles
|
|
||||||
// can be destroyed before the doc they own.
|
|
||||||
if (!mOuterDoc) {
|
|
||||||
uint32_t childCount = mChildren.Length();
|
|
||||||
for (uint32_t idx = 0; idx < childCount; idx++)
|
|
||||||
mChildren[idx]->Shutdown();
|
|
||||||
} else {
|
|
||||||
if (mChildren.Length() != 1)
|
|
||||||
MOZ_CRASH("outer doc doesn't own adoc!");
|
|
||||||
|
|
||||||
mChildren[0]->AsDoc()->Unbind();
|
|
||||||
}
|
|
||||||
|
|
||||||
mChildren.Clear();
|
|
||||||
ProxyDestroyed(this);
|
|
||||||
mDoc->RemoveAccessible(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ProxyAccessible::SetChildDoc(DocAccessibleParent* aParent)
|
|
||||||
{
|
|
||||||
if (aParent) {
|
|
||||||
MOZ_ASSERT(mChildren.IsEmpty());
|
|
||||||
mChildren.AppendElement(aParent);
|
|
||||||
mOuterDoc = true;
|
|
||||||
} else {
|
|
||||||
MOZ_ASSERT(mChildren.Length() == 1);
|
|
||||||
mChildren.Clear();
|
|
||||||
mOuterDoc = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ProxyAccessible::MustPruneChildren() const
|
|
||||||
{
|
|
||||||
// this is the equivalent to nsAccUtils::MustPrune for proxies and should be
|
|
||||||
// kept in sync with that.
|
|
||||||
if (mRole != roles::MENUITEM && mRole != roles::COMBOBOX_OPTION
|
|
||||||
&& mRole != roles::OPTION && mRole != roles::ENTRY
|
|
||||||
&& mRole != roles::FLAT_EQUATION && mRole != roles::PASSWORD_TEXT
|
|
||||||
&& mRole != roles::PUSHBUTTON && mRole != roles::TOGGLE_BUTTON
|
|
||||||
&& mRole != roles::GRAPHIC && mRole != roles::SLIDER
|
|
||||||
&& mRole != roles::PROGRESSBAR && mRole != roles::SEPARATOR)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (mChildren.Length() != 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return mChildren[0]->Role() == roles::TEXT_LEAF
|
|
||||||
|| mChildren[0]->Role() == roles::STATICTEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
ProxyAccessible::State() const
|
ProxyAccessible::State() const
|
||||||
{
|
{
|
||||||
|
@ -1032,55 +969,6 @@ ProxyAccessible::TakeFocus()
|
||||||
Unused << mDoc->SendTakeFocus(mID);
|
Unused << mDoc->SendTakeFocus(mID);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
|
||||||
ProxyAccessible::EmbeddedChildCount() const
|
|
||||||
{
|
|
||||||
size_t count = 0, kids = mChildren.Length();
|
|
||||||
for (size_t i = 0; i < kids; i++) {
|
|
||||||
if (mChildren[i]->IsEmbeddedObject()) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t
|
|
||||||
ProxyAccessible::IndexOfEmbeddedChild(const ProxyAccessible* aChild)
|
|
||||||
{
|
|
||||||
size_t index = 0, kids = mChildren.Length();
|
|
||||||
for (size_t i = 0; i < kids; i++) {
|
|
||||||
if (mChildren[i]->IsEmbeddedObject()) {
|
|
||||||
if (mChildren[i] == aChild) {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProxyAccessible*
|
|
||||||
ProxyAccessible::EmbeddedChildAt(size_t aChildIdx)
|
|
||||||
{
|
|
||||||
size_t index = 0, kids = mChildren.Length();
|
|
||||||
for (size_t i = 0; i < kids; i++) {
|
|
||||||
if (!mChildren[i]->IsEmbeddedObject()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == aChildIdx) {
|
|
||||||
return mChildren[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProxyAccessible*
|
ProxyAccessible*
|
||||||
ProxyAccessible::FocusedChild()
|
ProxyAccessible::FocusedChild()
|
||||||
{
|
{
|
||||||
|
@ -1175,18 +1063,5 @@ ProxyAccessible::DOMNodeID(nsString& aID)
|
||||||
Unused << mDoc->SendDOMNodeID(mID, &aID);
|
Unused << mDoc->SendDOMNodeID(mID, &aID);
|
||||||
}
|
}
|
||||||
|
|
||||||
Accessible*
|
|
||||||
ProxyAccessible::OuterDocOfRemoteBrowser() const
|
|
||||||
{
|
|
||||||
auto tab = static_cast<dom::TabParent*>(mDoc->Manager());
|
|
||||||
dom::Element* frame = tab->GetOwnerElement();
|
|
||||||
NS_ASSERTION(frame, "why isn't the tab in a frame!");
|
|
||||||
if (!frame)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
DocAccessible* chromeDoc = GetExistingDocAccessible(frame->OwnerDoc());
|
|
||||||
|
|
||||||
return chromeDoc ? chromeDoc->GetAccessible(frame) : nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,115 +7,33 @@
|
||||||
#ifndef mozilla_a11y_ProxyAccessible_h
|
#ifndef mozilla_a11y_ProxyAccessible_h
|
||||||
#define mozilla_a11y_ProxyAccessible_h
|
#define mozilla_a11y_ProxyAccessible_h
|
||||||
|
|
||||||
|
#include "Accessible.h"
|
||||||
|
#include "mozilla/a11y/ProxyAccessibleBase.h"
|
||||||
#include "mozilla/a11y/Role.h"
|
#include "mozilla/a11y/Role.h"
|
||||||
#include "nsIAccessibleText.h"
|
#include "nsIAccessibleText.h"
|
||||||
#include "nsIAccessibleTypes.h"
|
#include "nsIAccessibleTypes.h"
|
||||||
#include "Accessible.h"
|
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsRect.h"
|
#include "nsRect.h"
|
||||||
#include "Accessible.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace a11y {
|
namespace a11y {
|
||||||
|
|
||||||
class Accessible;
|
class ProxyAccessible : public ProxyAccessibleBase<ProxyAccessible>
|
||||||
class Attribute;
|
|
||||||
class DocAccessibleParent;
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
|
|
||||||
class ProxyAccessible
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ProxyAccessible(uint64_t aID, ProxyAccessible* aParent,
|
ProxyAccessible(uint64_t aID, ProxyAccessible* aParent,
|
||||||
DocAccessibleParent* aDoc, role aRole, uint32_t aInterfaces) :
|
DocAccessibleParent* aDoc, role aRole, uint32_t aInterfaces)
|
||||||
mParent(aParent), mDoc(aDoc), mWrapper(0), mID(aID), mRole(aRole),
|
: ProxyAccessibleBase(aID, aParent, aDoc, aRole, aInterfaces)
|
||||||
mOuterDoc(false), mIsDoc(false),
|
|
||||||
mHasValue(aInterfaces & Interfaces::VALUE),
|
|
||||||
mIsHyperLink(aInterfaces & Interfaces::HYPERLINK),
|
|
||||||
mIsHyperText(aInterfaces & Interfaces::HYPERTEXT)
|
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(ProxyAccessible);
|
MOZ_COUNT_CTOR(ProxyAccessible);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ProxyAccessible()
|
~ProxyAccessible()
|
||||||
{
|
{
|
||||||
MOZ_COUNT_DTOR(ProxyAccessible);
|
MOZ_COUNT_DTOR(ProxyAccessible);
|
||||||
MOZ_ASSERT(!mWrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddChildAt(uint32_t aIdx, ProxyAccessible* aChild)
|
|
||||||
{ mChildren.InsertElementAt(aIdx, aChild); }
|
|
||||||
|
|
||||||
uint32_t ChildrenCount() const { return mChildren.Length(); }
|
|
||||||
ProxyAccessible* ChildAt(uint32_t aIdx) const { return mChildren[aIdx]; }
|
|
||||||
ProxyAccessible* FirstChild() const
|
|
||||||
{ return mChildren.Length() ? mChildren[0] : nullptr; }
|
|
||||||
ProxyAccessible* LastChild() const
|
|
||||||
{ return mChildren.Length() ? mChildren[mChildren.Length() - 1] : nullptr; }
|
|
||||||
ProxyAccessible* PrevSibling() const
|
|
||||||
{
|
|
||||||
size_t idx = IndexInParent();
|
|
||||||
return idx > 0 ? Parent()->mChildren[idx - 1] : nullptr;
|
|
||||||
}
|
|
||||||
ProxyAccessible* 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(this); }
|
|
||||||
uint32_t EmbeddedChildCount() const;
|
|
||||||
int32_t IndexOfEmbeddedChild(const ProxyAccessible*);
|
|
||||||
ProxyAccessible* EmbeddedChildAt(size_t aChildIdx);
|
|
||||||
bool MustPruneChildren() const;
|
|
||||||
|
|
||||||
void Shutdown();
|
|
||||||
|
|
||||||
void SetChildDoc(DocAccessibleParent*);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove The given child.
|
|
||||||
*/
|
|
||||||
void RemoveChild(ProxyAccessible* aChild)
|
|
||||||
{ mChildren.RemoveElement(aChild); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the proxy for the parent of the wrapped accessible.
|
|
||||||
*/
|
|
||||||
ProxyAccessible* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -396,56 +314,10 @@ public:
|
||||||
*/
|
*/
|
||||||
void DOMNodeID(nsString& aID);
|
void DOMNodeID(nsString& aID);
|
||||||
|
|
||||||
/**
|
|
||||||
* 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; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc) :
|
explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc)
|
||||||
mParent(nullptr), mDoc(aThisAsDoc), mWrapper(0), mID(0),
|
: ProxyAccessibleBase(aThisAsDoc)
|
||||||
mRole(roles::DOCUMENT), mOuterDoc(false), mIsDoc(true), mHasValue(false),
|
|
||||||
mIsHyperLink(false), mIsHyperText(false)
|
|
||||||
{ MOZ_COUNT_CTOR(ProxyAccessible); }
|
{ MOZ_COUNT_CTOR(ProxyAccessible); }
|
||||||
|
|
||||||
protected:
|
|
||||||
ProxyAccessible* mParent;
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsTArray<ProxyAccessible*> 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -11,12 +11,12 @@ IPDL_SOURCES += ['PDocAccessible.ipdl']
|
||||||
if CONFIG['ACCESSIBILITY']:
|
if CONFIG['ACCESSIBILITY']:
|
||||||
EXPORTS.mozilla.a11y += [
|
EXPORTS.mozilla.a11y += [
|
||||||
'DocAccessibleChild.h',
|
'DocAccessibleChild.h',
|
||||||
'ProxyAccessible.h'
|
'ProxyAccessible.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
'DocAccessibleChild.cpp',
|
'DocAccessibleChild.cpp',
|
||||||
'ProxyAccessible.cpp'
|
'ProxyAccessible.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
|
|
|
@ -0,0 +1,280 @@
|
||||||
|
/* -*- 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/. */
|
||||||
|
|
||||||
|
#include "Accessible2.h"
|
||||||
|
#include "ProxyAccessible.h"
|
||||||
|
#include "mozilla/a11y/DocAccessibleParent.h"
|
||||||
|
#include "DocAccessible.h"
|
||||||
|
#include "mozilla/a11y/DocManager.h"
|
||||||
|
#include "mozilla/dom/Element.h"
|
||||||
|
#include "mozilla/dom/TabParent.h"
|
||||||
|
#include "mozilla/unused.h"
|
||||||
|
#include "mozilla/a11y/Platform.h"
|
||||||
|
#include "RelationType.h"
|
||||||
|
#include "mozilla/a11y/Role.h"
|
||||||
|
#include "xpcAccessibleDocument.h"
|
||||||
|
|
||||||
|
#include <comutil.h>
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace a11y {
|
||||||
|
|
||||||
|
bool
|
||||||
|
ProxyAccessible::GetCOMInterface(void** aOutAccessible) const
|
||||||
|
{
|
||||||
|
if (!aOutAccessible) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RefPtr<IAccessible> addRefed = mCOMProxy;
|
||||||
|
addRefed.forget(aOutAccessible);
|
||||||
|
return !!mCOMProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ProxyAccessible::Name(nsString& aName) const
|
||||||
|
{
|
||||||
|
aName.Truncate();
|
||||||
|
RefPtr<IAccessible> acc;
|
||||||
|
if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VARIANT id;
|
||||||
|
id.vt = VT_I4;
|
||||||
|
id.lVal = CHILDID_SELF;
|
||||||
|
BSTR result;
|
||||||
|
HRESULT hr = acc->get_accName(id, &result);
|
||||||
|
_bstr_t resultWrap(result, false);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
aName = (wchar_t*)resultWrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ProxyAccessible::Value(nsString& aValue) const
|
||||||
|
{
|
||||||
|
aValue.Truncate();
|
||||||
|
RefPtr<IAccessible> acc;
|
||||||
|
if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VARIANT id;
|
||||||
|
id.vt = VT_I4;
|
||||||
|
id.lVal = CHILDID_SELF;
|
||||||
|
BSTR result;
|
||||||
|
HRESULT hr = acc->get_accValue(id, &result);
|
||||||
|
_bstr_t resultWrap(result, false);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
aValue = (wchar_t*)resultWrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ProxyAccessible::Description(nsString& aDesc) const
|
||||||
|
{
|
||||||
|
aDesc.Truncate();
|
||||||
|
RefPtr<IAccessible> acc;
|
||||||
|
if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VARIANT id;
|
||||||
|
id.vt = VT_I4;
|
||||||
|
id.lVal = CHILDID_SELF;
|
||||||
|
BSTR result;
|
||||||
|
HRESULT hr = acc->get_accDescription(id, &result);
|
||||||
|
_bstr_t resultWrap(result, false);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
aDesc = (wchar_t*)resultWrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
ProxyAccessible::State() const
|
||||||
|
{
|
||||||
|
uint64_t state = 0;
|
||||||
|
RefPtr<IAccessible> acc;
|
||||||
|
if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
VARIANT id;
|
||||||
|
id.vt = VT_I4;
|
||||||
|
id.lVal = CHILDID_SELF;
|
||||||
|
VARIANT varState;
|
||||||
|
HRESULT hr = acc->get_accState(id, &varState);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
return uint64_t(varState.lVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIntRect
|
||||||
|
ProxyAccessible::Bounds()
|
||||||
|
{
|
||||||
|
nsIntRect rect;
|
||||||
|
|
||||||
|
RefPtr<IAccessible> acc;
|
||||||
|
if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
long left;
|
||||||
|
long top;
|
||||||
|
long width;
|
||||||
|
long height;
|
||||||
|
VARIANT id;
|
||||||
|
id.vt = VT_I4;
|
||||||
|
id.lVal = CHILDID_SELF;
|
||||||
|
HRESULT hr = acc->accLocation(&left, &top, &width, &height, id);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
rect.x = left;
|
||||||
|
rect.y = top;
|
||||||
|
rect.width = width;
|
||||||
|
rect.height = height;
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ProxyAccessible::Language(nsString& aLocale)
|
||||||
|
{
|
||||||
|
aLocale.Truncate();
|
||||||
|
|
||||||
|
RefPtr<IAccessible> acc;
|
||||||
|
if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<IAccessible2> acc2;
|
||||||
|
if (FAILED(acc->QueryInterface(IID_IAccessible2, (void**)getter_AddRefs(acc2)))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IA2Locale locale;
|
||||||
|
HRESULT hr = acc2->get_locale(&locale);
|
||||||
|
|
||||||
|
_bstr_t langWrap(locale.language, false);
|
||||||
|
_bstr_t countryWrap(locale.country, false);
|
||||||
|
_bstr_t variantWrap(locale.variant, false);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The remaining code should essentially be the inverse of the
|
||||||
|
// ia2Accessible::get_locale conversion to IA2Locale.
|
||||||
|
|
||||||
|
if (!!variantWrap) {
|
||||||
|
aLocale = (wchar_t*)variantWrap;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!langWrap) {
|
||||||
|
aLocale = (wchar_t*)langWrap;
|
||||||
|
if (!!countryWrap) {
|
||||||
|
aLocale += L"-";
|
||||||
|
aLocale += (wchar_t*)countryWrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
IsEscapedChar(const wchar_t c)
|
||||||
|
{
|
||||||
|
return c == L'\\' || c == L':' || c == ',' || c == '=' || c == ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ConvertBSTRAttributesToArray(const nsAString& aStr,
|
||||||
|
nsTArray<Attribute>* aAttrs)
|
||||||
|
{
|
||||||
|
if (!aAttrs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
eName = 0,
|
||||||
|
eValue = 1,
|
||||||
|
eNumStates
|
||||||
|
} state;
|
||||||
|
nsAutoString tokens[eNumStates];
|
||||||
|
auto itr = aStr.BeginReading(), end = aStr.EndReading();
|
||||||
|
|
||||||
|
state = eName;
|
||||||
|
while (itr != end) {
|
||||||
|
switch (*itr) {
|
||||||
|
case L'\\':
|
||||||
|
// Skip the backslash so that we're looking at the escaped char
|
||||||
|
++itr;
|
||||||
|
if (itr == end || !IsEscapedChar(*itr)) {
|
||||||
|
// Invalid state
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case L':':
|
||||||
|
if (state != eName) {
|
||||||
|
// Bad, should be looking at name
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
state = eValue;
|
||||||
|
++itr;
|
||||||
|
continue;
|
||||||
|
case L';':
|
||||||
|
if (state != eValue) {
|
||||||
|
// Bad, should be looking at value
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
state = eName;
|
||||||
|
aAttrs->AppendElement(Attribute(NS_ConvertUTF16toUTF8(tokens[eName]),
|
||||||
|
tokens[eValue]));
|
||||||
|
tokens[eName].Truncate();
|
||||||
|
tokens[eValue].Truncate();
|
||||||
|
++itr;
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tokens[state] += *itr;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ProxyAccessible::Attributes(nsTArray<Attribute>* aAttrs) const
|
||||||
|
{
|
||||||
|
aAttrs->Clear();
|
||||||
|
|
||||||
|
RefPtr<IAccessible> acc;
|
||||||
|
if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<IAccessible2> acc2;
|
||||||
|
if (FAILED(acc->QueryInterface(IID_IAccessible2, (void**)getter_AddRefs(acc2)))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BSTR attrs;
|
||||||
|
HRESULT hr = acc2->get_attributes(&attrs);
|
||||||
|
_bstr_t attrsWrap(attrs, false);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConvertBSTRAttributesToArray(nsDependentString((wchar_t*)attrs,
|
||||||
|
attrsWrap.length()),
|
||||||
|
aAttrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace a11y
|
||||||
|
} // namespace mozilla
|
|
@ -0,0 +1,88 @@
|
||||||
|
/* -*- 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_ProxyAccessible_h
|
||||||
|
#define mozilla_a11y_ProxyAccessible_h
|
||||||
|
|
||||||
|
#include "Accessible.h"
|
||||||
|
#include "mozilla/a11y/ProxyAccessibleBase.h"
|
||||||
|
#include "mozilla/a11y/Role.h"
|
||||||
|
#include "nsIAccessibleText.h"
|
||||||
|
#include "nsIAccessibleTypes.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
#include "nsRect.h"
|
||||||
|
|
||||||
|
#include <oleacc.h>
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace a11y {
|
||||||
|
|
||||||
|
class ProxyAccessible : public ProxyAccessibleBase<ProxyAccessible>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProxyAccessible(uint64_t aID, ProxyAccessible* aParent,
|
||||||
|
DocAccessibleParent* aDoc, role aRole, uint32_t aInterfaces,
|
||||||
|
const RefPtr<IAccessible>& aIAccessible)
|
||||||
|
: ProxyAccessibleBase(aID, aParent, aDoc, aRole, aInterfaces)
|
||||||
|
, mCOMProxy(aIAccessible)
|
||||||
|
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(ProxyAccessible);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ProxyAccessible()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(ProxyAccessible);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the states for the proxied accessible.
|
||||||
|
*/
|
||||||
|
uint64_t State() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set aName to the name of the proxied accessible.
|
||||||
|
*/
|
||||||
|
void Name(nsString& aName) const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set aValue to the value of the proxied accessible.
|
||||||
|
*/
|
||||||
|
void Value(nsString& aValue) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set aDesc to the description of the proxied accessible.
|
||||||
|
*/
|
||||||
|
void Description(nsString& aDesc) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the set of attributes on the proxied accessible.
|
||||||
|
*/
|
||||||
|
void Attributes(nsTArray<Attribute> *aAttrs) const;
|
||||||
|
|
||||||
|
nsIntRect Bounds();
|
||||||
|
|
||||||
|
void Language(nsString& aLocale);
|
||||||
|
|
||||||
|
bool GetCOMInterface(void** aOutAccessible) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc)
|
||||||
|
: ProxyAccessibleBase(aThisAsDoc)
|
||||||
|
{ MOZ_COUNT_CTOR(ProxyAccessibleBase); }
|
||||||
|
|
||||||
|
void SetCOMInterface(const RefPtr<IAccessible>& aIAccessible)
|
||||||
|
{ mCOMProxy = aIAccessible; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
RefPtr<IAccessible> mCOMProxy;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -12,11 +12,13 @@ if CONFIG['ACCESSIBILITY']:
|
||||||
EXPORTS.mozilla.a11y += [
|
EXPORTS.mozilla.a11y += [
|
||||||
'COMPtrTypes.h',
|
'COMPtrTypes.h',
|
||||||
'DocAccessibleChild.h',
|
'DocAccessibleChild.h',
|
||||||
|
'ProxyAccessible.h'
|
||||||
]
|
]
|
||||||
|
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
'COMPtrTypes.cpp',
|
'COMPtrTypes.cpp',
|
||||||
'DocAccessibleChild.cpp',
|
'DocAccessibleChild.cpp',
|
||||||
|
'ProxyAccessible.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace a11y {
|
||||||
|
|
||||||
class ProxyAccessibleWrap : public AccessibleWrap
|
class ProxyAccessibleWrap : public AccessibleWrap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ProxyAccessibleWrap(ProxyAccessible* aProxy) :
|
ProxyAccessibleWrap(ProxyAccessible* aProxy) :
|
||||||
AccessibleWrap(nullptr, nullptr)
|
AccessibleWrap(nullptr, nullptr)
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,11 @@ class ProxyAccessibleWrap : public AccessibleWrap
|
||||||
mBits.proxy = nullptr;
|
mBits.proxy = nullptr;
|
||||||
mStateFlags |= eIsDefunct;
|
mStateFlags |= eIsDefunct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void GetNativeInterface(void** aOutAccessible) override
|
||||||
|
{
|
||||||
|
mBits.proxy->GetCOMInterface(aOutAccessible);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class HyperTextProxyAccessibleWrap : public HyperTextAccessibleWrap
|
class HyperTextProxyAccessibleWrap : public HyperTextAccessibleWrap
|
||||||
|
@ -43,7 +48,12 @@ public:
|
||||||
virtual void Shutdown() override
|
virtual void Shutdown() override
|
||||||
{
|
{
|
||||||
mBits.proxy = nullptr;
|
mBits.proxy = nullptr;
|
||||||
mStateFlags |= eIsDefunct;
|
mStateFlags |= eIsDefunct;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void GetNativeInterface(void** aOutAccessible) override
|
||||||
|
{
|
||||||
|
mBits.proxy->GetCOMInterface(aOutAccessible);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ private:
|
||||||
friend class DocManager;
|
friend class DocManager;
|
||||||
friend class DocAccessible;
|
friend class DocAccessible;
|
||||||
friend class ProxyAccessible;
|
friend class ProxyAccessible;
|
||||||
|
friend class ProxyAccessibleBase<ProxyAccessible>;
|
||||||
|
|
||||||
xpcAccessibleDocument(const xpcAccessibleDocument&) = delete;
|
xpcAccessibleDocument(const xpcAccessibleDocument&) = delete;
|
||||||
xpcAccessibleDocument& operator =(const xpcAccessibleDocument&) = delete;
|
xpcAccessibleDocument& operator =(const xpcAccessibleDocument&) = delete;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче