mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 982842 - initial a11y ipc impl r=davidb, bent
This commit is contained in:
parent
308481a1f4
commit
619e12383a
@ -12,6 +12,7 @@
|
|||||||
#include "nsAccUtils.h"
|
#include "nsAccUtils.h"
|
||||||
#include "nsIAccessibleRelation.h"
|
#include "nsIAccessibleRelation.h"
|
||||||
#include "nsIAccessibleTable.h"
|
#include "nsIAccessibleTable.h"
|
||||||
|
#include "ProxyAccessible.h"
|
||||||
#include "RootAccessible.h"
|
#include "RootAccessible.h"
|
||||||
#include "nsIAccessibleValue.h"
|
#include "nsIAccessibleValue.h"
|
||||||
#include "nsMai.h"
|
#include "nsMai.h"
|
||||||
@ -20,6 +21,7 @@
|
|||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "prprf.h"
|
#include "prprf.h"
|
||||||
#include "nsStateMap.h"
|
#include "nsStateMap.h"
|
||||||
|
#include "mozilla/a11y/Platform.h"
|
||||||
#include "Relation.h"
|
#include "Relation.h"
|
||||||
#include "RootAccessible.h"
|
#include "RootAccessible.h"
|
||||||
#include "States.h"
|
#include "States.h"
|
||||||
@ -133,9 +135,13 @@ struct MaiAtkObject
|
|||||||
* The AccessibleWrap whose properties and features are exported
|
* The AccessibleWrap whose properties and features are exported
|
||||||
* via this object instance.
|
* via this object instance.
|
||||||
*/
|
*/
|
||||||
AccessibleWrap* accWrap;
|
uintptr_t accWrap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is or'd with the pointer in MaiAtkObject::accWrap if the wrap-ee is a
|
||||||
|
// proxy.
|
||||||
|
static const uintptr_t IS_PROXY = 1;
|
||||||
|
|
||||||
struct MaiAtkObjectClass
|
struct MaiAtkObjectClass
|
||||||
{
|
{
|
||||||
AtkObjectClass parent_class;
|
AtkObjectClass parent_class;
|
||||||
@ -248,7 +254,7 @@ AccessibleWrap::ShutdownAtkObject()
|
|||||||
{
|
{
|
||||||
if (mAtkObject) {
|
if (mAtkObject) {
|
||||||
if (IS_MAI_OBJECT(mAtkObject)) {
|
if (IS_MAI_OBJECT(mAtkObject)) {
|
||||||
MAI_ATK_OBJECT(mAtkObject)->accWrap = nullptr;
|
MAI_ATK_OBJECT(mAtkObject)->accWrap = 0;
|
||||||
}
|
}
|
||||||
SetMaiHyperlink(nullptr);
|
SetMaiHyperlink(nullptr);
|
||||||
g_object_unref(mAtkObject);
|
g_object_unref(mAtkObject);
|
||||||
@ -582,8 +588,7 @@ initializeCB(AtkObject *aAtkObj, gpointer aData)
|
|||||||
ATK_OBJECT_CLASS(parent_class)->initialize(aAtkObj, aData);
|
ATK_OBJECT_CLASS(parent_class)->initialize(aAtkObj, aData);
|
||||||
|
|
||||||
/* initialize object */
|
/* initialize object */
|
||||||
MAI_ATK_OBJECT(aAtkObj)->accWrap =
|
MAI_ATK_OBJECT(aAtkObj)->accWrap = reinterpret_cast<uintptr_t>(aData);
|
||||||
static_cast<AccessibleWrap*>(aData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -591,7 +596,7 @@ finalizeCB(GObject *aObj)
|
|||||||
{
|
{
|
||||||
if (!IS_MAI_OBJECT(aObj))
|
if (!IS_MAI_OBJECT(aObj))
|
||||||
return;
|
return;
|
||||||
NS_ASSERTION(MAI_ATK_OBJECT(aObj)->accWrap == nullptr, "AccWrap NOT null");
|
NS_ASSERTION(MAI_ATK_OBJECT(aObj)->accWrap == 0, "AccWrap NOT null");
|
||||||
|
|
||||||
// call parent finalize function
|
// call parent finalize function
|
||||||
// finalize of GObjectClass will unref the accessible parent if has
|
// finalize of GObjectClass will unref the accessible parent if has
|
||||||
@ -663,25 +668,33 @@ getDescriptionCB(AtkObject *aAtkObj)
|
|||||||
AtkRole
|
AtkRole
|
||||||
getRoleCB(AtkObject *aAtkObj)
|
getRoleCB(AtkObject *aAtkObj)
|
||||||
{
|
{
|
||||||
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
|
|
||||||
if (!accWrap)
|
|
||||||
return ATK_ROLE_INVALID;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(accWrap),
|
|
||||||
"Does not support nsIAccessibleText when it should");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (aAtkObj->role != ATK_ROLE_INVALID)
|
if (aAtkObj->role != ATK_ROLE_INVALID)
|
||||||
return aAtkObj->role;
|
return aAtkObj->role;
|
||||||
|
|
||||||
|
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
|
||||||
|
a11y::role role;
|
||||||
|
if (!accWrap) {
|
||||||
|
ProxyAccessible* proxy = GetProxy(aAtkObj);
|
||||||
|
if (!proxy)
|
||||||
|
return ATK_ROLE_INVALID;
|
||||||
|
|
||||||
|
role = proxy->Role();
|
||||||
|
} else {
|
||||||
|
#ifdef DEBUG
|
||||||
|
NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(accWrap),
|
||||||
|
"Does not support nsIAccessibleText when it should");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
role = accWrap->Role();
|
||||||
|
}
|
||||||
|
|
||||||
#define ROLE(geckoRole, stringRole, atkRole, macRole, \
|
#define ROLE(geckoRole, stringRole, atkRole, macRole, \
|
||||||
msaaRole, ia2Role, nameRule) \
|
msaaRole, ia2Role, nameRule) \
|
||||||
case roles::geckoRole: \
|
case roles::geckoRole: \
|
||||||
aAtkObj->role = atkRole; \
|
aAtkObj->role = atkRole; \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (accWrap->Role()) {
|
switch (role) {
|
||||||
#include "RoleMap.h"
|
#include "RoleMap.h"
|
||||||
default:
|
default:
|
||||||
MOZ_CRASH("Unknown role.");
|
MOZ_CRASH("Unknown role.");
|
||||||
@ -946,7 +959,13 @@ AccessibleWrap*
|
|||||||
GetAccessibleWrap(AtkObject* aAtkObj)
|
GetAccessibleWrap(AtkObject* aAtkObj)
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(IS_MAI_OBJECT(aAtkObj), nullptr);
|
NS_ENSURE_TRUE(IS_MAI_OBJECT(aAtkObj), nullptr);
|
||||||
AccessibleWrap* accWrap = MAI_ATK_OBJECT(aAtkObj)->accWrap;
|
|
||||||
|
// Make sure its native is an AccessibleWrap not a proxy.
|
||||||
|
if (MAI_ATK_OBJECT(aAtkObj)->accWrap & IS_PROXY)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
AccessibleWrap* accWrap =
|
||||||
|
reinterpret_cast<AccessibleWrap*>(MAI_ATK_OBJECT(aAtkObj)->accWrap);
|
||||||
|
|
||||||
// Check if the accessible was deconstructed.
|
// Check if the accessible was deconstructed.
|
||||||
if (!accWrap)
|
if (!accWrap)
|
||||||
@ -961,6 +980,49 @@ GetAccessibleWrap(AtkObject* aAtkObj)
|
|||||||
return accWrap;
|
return accWrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProxyAccessible*
|
||||||
|
GetProxy(AtkObject* aObj)
|
||||||
|
{
|
||||||
|
if (!aObj || !(MAI_ATK_OBJECT(aObj)->accWrap & IS_PROXY))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return reinterpret_cast<ProxyAccessible*>(MAI_ATK_OBJECT(aObj)->accWrap
|
||||||
|
& ~IS_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t
|
||||||
|
GetInterfacesForProxy(ProxyAccessible* aProxy)
|
||||||
|
{
|
||||||
|
return MAI_INTERFACE_COMPONENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
a11y::ProxyCreated(ProxyAccessible* aProxy)
|
||||||
|
{
|
||||||
|
GType type = GetMaiAtkType(GetInterfacesForProxy(aProxy));
|
||||||
|
NS_ASSERTION(type, "why don't we have a type!");
|
||||||
|
|
||||||
|
AtkObject* obj =
|
||||||
|
reinterpret_cast<AtkObject *>
|
||||||
|
(g_object_new(type, nullptr));
|
||||||
|
if (!obj)
|
||||||
|
return;
|
||||||
|
|
||||||
|
atk_object_initialize(obj, aProxy);
|
||||||
|
obj->role = ATK_ROLE_INVALID;
|
||||||
|
obj->layer = ATK_LAYER_INVALID;
|
||||||
|
aProxy->SetWrapper(reinterpret_cast<uintptr_t>(obj) | IS_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
a11y::ProxyDestroyed(ProxyAccessible* aProxy)
|
||||||
|
{
|
||||||
|
auto obj = reinterpret_cast<MaiAtkObject*>(aProxy->GetWrapper() & ~IS_PROXY);
|
||||||
|
obj->accWrap = 0;
|
||||||
|
g_object_unref(obj);
|
||||||
|
aProxy->SetWrapper(0);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
|
AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
|
||||||
{
|
{
|
||||||
|
@ -97,7 +97,7 @@ private:
|
|||||||
|
|
||||||
static EAvailableAtkSignals gAvailableAtkSignals;
|
static EAvailableAtkSignals gAvailableAtkSignals;
|
||||||
|
|
||||||
uint16_t CreateMaiInterfaces(void);
|
uint16_t CreateMaiInterfaces();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace a11y
|
} // namespace a11y
|
||||||
|
@ -35,6 +35,7 @@ LOCAL_INCLUDES += [
|
|||||||
'/accessible/base',
|
'/accessible/base',
|
||||||
'/accessible/generic',
|
'/accessible/generic',
|
||||||
'/accessible/html',
|
'/accessible/html',
|
||||||
|
'/accessible/ipc',
|
||||||
'/accessible/xpcom',
|
'/accessible/xpcom',
|
||||||
'/accessible/xul',
|
'/accessible/xul',
|
||||||
'/other-licenses/atk-1.0',
|
'/other-licenses/atk-1.0',
|
||||||
|
@ -13,6 +13,12 @@
|
|||||||
|
|
||||||
#include "AccessibleWrap.h"
|
#include "AccessibleWrap.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace a11y {
|
||||||
|
class ProxyAccessible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define MAI_TYPE_ATK_OBJECT (mai_atk_object_get_type ())
|
#define MAI_TYPE_ATK_OBJECT (mai_atk_object_get_type ())
|
||||||
#define MAI_ATK_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
#define MAI_ATK_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||||
MAI_TYPE_ATK_OBJECT, MaiAtkObject))
|
MAI_TYPE_ATK_OBJECT, MaiAtkObject))
|
||||||
@ -29,6 +35,7 @@
|
|||||||
GType mai_atk_object_get_type(void);
|
GType mai_atk_object_get_type(void);
|
||||||
GType mai_util_get_type();
|
GType mai_util_get_type();
|
||||||
mozilla::a11y::AccessibleWrap* GetAccessibleWrap(AtkObject* aAtkObj);
|
mozilla::a11y::AccessibleWrap* GetAccessibleWrap(AtkObject* aAtkObj);
|
||||||
|
mozilla::a11y::ProxyAccessible* GetProxy(AtkObject* aAtkObj);
|
||||||
|
|
||||||
extern int atkMajorVersion, atkMinorVersion;
|
extern int atkMajorVersion, atkMinorVersion;
|
||||||
|
|
||||||
|
@ -232,6 +232,8 @@ public:
|
|||||||
bool IsShow() const { return mEventType == nsIAccessibleEvent::EVENT_SHOW; }
|
bool IsShow() const { return mEventType == nsIAccessibleEvent::EVENT_SHOW; }
|
||||||
bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
|
bool IsHide() const { return mEventType == nsIAccessibleEvent::EVENT_HIDE; }
|
||||||
|
|
||||||
|
Accessible* Parent() const { return mParent; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsCOMPtr<nsINode> mNode;
|
nsCOMPtr<nsINode> mNode;
|
||||||
nsRefPtr<Accessible> mParent;
|
nsRefPtr<Accessible> mParent;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "ApplicationAccessible.h"
|
#include "ApplicationAccessible.h"
|
||||||
#include "ARIAMap.h"
|
#include "ARIAMap.h"
|
||||||
#include "DocAccessible-inl.h"
|
#include "DocAccessible-inl.h"
|
||||||
|
#include "DocAccessibleChild.h"
|
||||||
#include "nsAccessibilityService.h"
|
#include "nsAccessibilityService.h"
|
||||||
#include "RootAccessibleWrap.h"
|
#include "RootAccessibleWrap.h"
|
||||||
|
|
||||||
@ -27,6 +28,8 @@
|
|||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsIWebProgress.h"
|
#include "nsIWebProgress.h"
|
||||||
#include "nsCoreUtils.h"
|
#include "nsCoreUtils.h"
|
||||||
|
#include "nsXULAppAPI.h"
|
||||||
|
#include "mozilla/dom/ContentChild.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::a11y;
|
using namespace mozilla::a11y;
|
||||||
@ -418,6 +421,12 @@ DocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
|
|||||||
docAcc->FireDelayedEvent(nsIAccessibleEvent::EVENT_REORDER,
|
docAcc->FireDelayedEvent(nsIAccessibleEvent::EVENT_REORDER,
|
||||||
ApplicationAcc());
|
ApplicationAcc());
|
||||||
|
|
||||||
|
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||||
|
DocAccessibleChild* ipcDoc = new DocAccessibleChild(docAcc);
|
||||||
|
docAcc->SetIPCDoc(ipcDoc);
|
||||||
|
auto contentChild = dom::ContentChild::GetSingleton();
|
||||||
|
contentChild->SendPDocAccessibleConstructor(ipcDoc, nullptr, 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
parentDocAcc->BindChildDocument(docAcc);
|
parentDocAcc->BindChildDocument(docAcc);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ namespace a11y {
|
|||||||
|
|
||||||
class Accessible;
|
class Accessible;
|
||||||
class DocAccessible;
|
class DocAccessible;
|
||||||
|
class DocAccessibleParent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage the document accessible life cycle.
|
* Manage the document accessible life cycle.
|
||||||
@ -65,6 +66,25 @@ public:
|
|||||||
RemoveListeners(aDocument);
|
RemoveListeners(aDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notification that a top level document in a content process has gone away.
|
||||||
|
*/
|
||||||
|
void RemoteDocShutdown(DocAccessibleParent* aDoc)
|
||||||
|
{
|
||||||
|
DebugOnly<bool> result = mRemoteDocuments.RemoveElement(aDoc);
|
||||||
|
MOZ_ASSERT(result, "Why didn't we find the document!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notify of a new top level document in a content process.
|
||||||
|
*/
|
||||||
|
void RemoteDocAdded(DocAccessibleParent* aDoc)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!mRemoteDocuments.Contains(aDoc),
|
||||||
|
"How did we already have the doc!");
|
||||||
|
mRemoteDocuments.AppendElement(aDoc);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool IsProcessingRefreshDriverNotification() const;
|
bool IsProcessingRefreshDriverNotification() const;
|
||||||
#endif
|
#endif
|
||||||
@ -144,6 +164,11 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
DocAccessibleHashtable mDocAccessibleCache;
|
DocAccessibleHashtable mDocAccessibleCache;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The list of remote top level documents.
|
||||||
|
*/
|
||||||
|
nsTArray<DocAccessibleParent*> mRemoteDocuments;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "Accessible-inl.h"
|
#include "Accessible-inl.h"
|
||||||
#include "nsEventShell.h"
|
#include "nsEventShell.h"
|
||||||
#include "DocAccessible.h"
|
#include "DocAccessible.h"
|
||||||
|
#include "DocAccessibleChild.h"
|
||||||
#include "nsAccessibilityService.h"
|
#include "nsAccessibilityService.h"
|
||||||
#include "nsTextEquivUtils.h"
|
#include "nsTextEquivUtils.h"
|
||||||
#ifdef A11Y_LOG
|
#ifdef A11Y_LOG
|
||||||
@ -555,5 +556,15 @@ EventQueue::ProcessEventQueue()
|
|||||||
|
|
||||||
if (!mDocument)
|
if (!mDocument)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||||
|
DocAccessibleChild* ipcDoc = mDocument->IPCDoc();
|
||||||
|
if (event->mEventType == nsIAccessibleEvent::EVENT_SHOW)
|
||||||
|
ipcDoc->ShowEvent(downcast_accEvent(event));
|
||||||
|
else if (event->mEventType == nsIAccessibleEvent::EVENT_HIDE)
|
||||||
|
ipcDoc->SendHideEvent(reinterpret_cast<uintptr_t>(event->GetAccessible()));
|
||||||
|
else
|
||||||
|
ipcDoc->SendEvent(event->GetEventType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,11 @@
|
|||||||
#include "NotificationController.h"
|
#include "NotificationController.h"
|
||||||
|
|
||||||
#include "DocAccessible-inl.h"
|
#include "DocAccessible-inl.h"
|
||||||
|
#include "DocAccessibleChild.h"
|
||||||
#include "TextLeafAccessible.h"
|
#include "TextLeafAccessible.h"
|
||||||
#include "TextUpdater.h"
|
#include "TextUpdater.h"
|
||||||
|
|
||||||
|
#include "mozilla/dom/ContentChild.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
|
|
||||||
@ -217,8 +219,19 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||||||
if (ownerContent) {
|
if (ownerContent) {
|
||||||
Accessible* outerDocAcc = mDocument->GetAccessible(ownerContent);
|
Accessible* outerDocAcc = mDocument->GetAccessible(ownerContent);
|
||||||
if (outerDocAcc && outerDocAcc->AppendChild(childDoc)) {
|
if (outerDocAcc && outerDocAcc->AppendChild(childDoc)) {
|
||||||
if (mDocument->AppendChildDocument(childDoc))
|
if (mDocument->AppendChildDocument(childDoc)) {
|
||||||
|
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||||
|
DocAccessibleChild* ipcDoc = new DocAccessibleChild(childDoc);
|
||||||
|
childDoc->SetIPCDoc(ipcDoc);
|
||||||
|
auto contentChild = dom::ContentChild::GetSingleton();
|
||||||
|
DocAccessibleChild* parentIPCDoc = mDocument->IPCDoc();
|
||||||
|
uint64_t id = reinterpret_cast<uintptr_t>(outerDocAcc->UniqueID());
|
||||||
|
contentChild->SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc,
|
||||||
|
id);
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
outerDocAcc->RemoveChild(childDoc);
|
outerDocAcc->RemoveChild(childDoc);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace a11y {
|
namespace a11y {
|
||||||
|
|
||||||
|
class ProxyAccessible;
|
||||||
|
|
||||||
enum EPlatformDisabledState {
|
enum EPlatformDisabledState {
|
||||||
ePlatformIsForceEnabled = -1,
|
ePlatformIsForceEnabled = -1,
|
||||||
ePlatformIsEnabled = 0,
|
ePlatformIsEnabled = 0,
|
||||||
@ -47,6 +49,17 @@ void PlatformInit();
|
|||||||
*/
|
*/
|
||||||
void PlatformShutdown();
|
void PlatformShutdown();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* called when a new ProxyAccessible is created, so the platform may setup a
|
||||||
|
* wrapper for it, or take other action.
|
||||||
|
*/
|
||||||
|
void ProxyCreated(ProxyAccessible*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called just before a ProxyAccessible is destroyed so its wrapper can be
|
||||||
|
* disposed of and other action taken.
|
||||||
|
*/
|
||||||
|
void ProxyDestroyed(ProxyAccessible*);
|
||||||
} // namespace a11y
|
} // namespace a11y
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
@ -783,7 +783,9 @@ enum Role {
|
|||||||
/**
|
/**
|
||||||
* Represent a keyboard or keypad key (ARIA role "key").
|
* Represent a keyboard or keypad key (ARIA role "key").
|
||||||
*/
|
*/
|
||||||
KEY = 129
|
KEY = 129,
|
||||||
|
|
||||||
|
LAST_ROLE = KEY
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace role
|
} // namespace role
|
||||||
|
@ -60,6 +60,7 @@ if CONFIG['A11Y_LOG']:
|
|||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'/accessible/generic',
|
'/accessible/generic',
|
||||||
'/accessible/html',
|
'/accessible/html',
|
||||||
|
'/accessible/ipc',
|
||||||
'/accessible/xpcom',
|
'/accessible/xpcom',
|
||||||
'/accessible/xul',
|
'/accessible/xul',
|
||||||
'/dom/xbl',
|
'/dom/xbl',
|
||||||
@ -93,3 +94,5 @@ FINAL_LIBRARY = 'xul'
|
|||||||
|
|
||||||
if CONFIG['MOZ_ENABLE_GTK']:
|
if CONFIG['MOZ_ENABLE_GTK']:
|
||||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
||||||
|
|
||||||
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "Accessible-inl.h"
|
#include "Accessible-inl.h"
|
||||||
#include "AccIterator.h"
|
#include "AccIterator.h"
|
||||||
#include "DocAccessible-inl.h"
|
#include "DocAccessible-inl.h"
|
||||||
|
#include "DocAccessibleChild.h"
|
||||||
#include "HTMLImageMapAccessible.h"
|
#include "HTMLImageMapAccessible.h"
|
||||||
#include "nsAccCache.h"
|
#include "nsAccCache.h"
|
||||||
#include "nsAccessiblePivot.h"
|
#include "nsAccessiblePivot.h"
|
||||||
@ -83,7 +84,7 @@ DocAccessible::
|
|||||||
mScrollPositionChangedTicks(0),
|
mScrollPositionChangedTicks(0),
|
||||||
mLoadState(eTreeConstructionPending), mDocFlags(0), mLoadEventType(0),
|
mLoadState(eTreeConstructionPending), mDocFlags(0), mLoadEventType(0),
|
||||||
mVirtualCursor(nullptr),
|
mVirtualCursor(nullptr),
|
||||||
mPresShell(aPresShell)
|
mPresShell(aPresShell), mIPCDoc(nullptr)
|
||||||
{
|
{
|
||||||
mGenericTypes |= eDocument;
|
mGenericTypes |= eDocument;
|
||||||
mStateFlags |= eNotNodeMapEntry;
|
mStateFlags |= eNotNodeMapEntry;
|
||||||
@ -473,6 +474,12 @@ DocAccessible::Shutdown()
|
|||||||
|
|
||||||
mChildDocuments.Clear();
|
mChildDocuments.Clear();
|
||||||
|
|
||||||
|
// XXX thinking about ordering?
|
||||||
|
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||||
|
DocAccessibleChild::Send__delete__(mIPCDoc);
|
||||||
|
MOZ_ASSERT(!mIPCDoc);
|
||||||
|
}
|
||||||
|
|
||||||
if (mVirtualCursor) {
|
if (mVirtualCursor) {
|
||||||
mVirtualCursor->RemoveObserver(this);
|
mVirtualCursor->RemoveObserver(this);
|
||||||
mVirtualCursor = nullptr;
|
mVirtualCursor = nullptr;
|
||||||
@ -1436,6 +1443,13 @@ DocAccessible::DoInitialUpdate()
|
|||||||
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(Parent());
|
nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(Parent());
|
||||||
ParentDocument()->FireDelayedEvent(reorderEvent);
|
ParentDocument()->FireDelayedEvent(reorderEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t childCount = ChildCount();
|
||||||
|
for (uint32_t i = 0; i < childCount; i++) {
|
||||||
|
Accessible* child = GetChildAt(i);
|
||||||
|
nsRefPtr<AccShowEvent> event = new AccShowEvent(child, child->GetContent());
|
||||||
|
FireDelayedEvent(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -33,6 +33,7 @@ namespace a11y {
|
|||||||
|
|
||||||
class DocManager;
|
class DocManager;
|
||||||
class NotificationController;
|
class NotificationController;
|
||||||
|
class DocAccessibleChild;
|
||||||
class RelatedAccIterator;
|
class RelatedAccIterator;
|
||||||
template<class Class, class Arg>
|
template<class Class, class Arg>
|
||||||
class TNotification;
|
class TNotification;
|
||||||
@ -519,6 +520,20 @@ protected:
|
|||||||
*/
|
*/
|
||||||
bool IsLoadEventTarget() const;
|
bool IsLoadEventTarget() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this document is in a content process return the object responsible for
|
||||||
|
* communicating with the main process for it.
|
||||||
|
*/
|
||||||
|
DocAccessibleChild* IPCDoc() const { return mIPCDoc; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the object responsible for communicating with the main process on
|
||||||
|
* behalf of this document.
|
||||||
|
*/
|
||||||
|
void SetIPCDoc(DocAccessibleChild* aIPCDoc) { mIPCDoc = aIPCDoc; }
|
||||||
|
|
||||||
|
friend class DocAccessibleChild;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to fire scrolling end event after page scroll.
|
* Used to fire scrolling end event after page scroll.
|
||||||
*
|
*
|
||||||
@ -642,6 +657,9 @@ protected:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
nsIPresShell* mPresShell;
|
nsIPresShell* mPresShell;
|
||||||
|
|
||||||
|
// Exclusively owned by IPDL so don't manually delete it!
|
||||||
|
DocAccessibleChild* mIPCDoc;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline DocAccessible*
|
inline DocAccessible*
|
||||||
|
@ -28,6 +28,7 @@ UNIFIED_SOURCES += [
|
|||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'/accessible/base',
|
'/accessible/base',
|
||||||
'/accessible/html',
|
'/accessible/html',
|
||||||
|
'/accessible/ipc',
|
||||||
'/accessible/xpcom',
|
'/accessible/xpcom',
|
||||||
'/accessible/xul',
|
'/accessible/xul',
|
||||||
'/content/base/src',
|
'/content/base/src',
|
||||||
@ -54,3 +55,5 @@ else:
|
|||||||
]
|
]
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
|
|
||||||
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
40
accessible/ipc/DocAccessibleChild.cpp
Normal file
40
accessible/ipc/DocAccessibleChild.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* -*- 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 "DocAccessibleChild.h"
|
||||||
|
|
||||||
|
#include "Accessible-inl.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace a11y {
|
||||||
|
|
||||||
|
void
|
||||||
|
SerializeTree(Accessible* aRoot, nsTArray<AccessibleData>& aTree)
|
||||||
|
{
|
||||||
|
uint64_t id = reinterpret_cast<uint64_t>(aRoot->UniqueID());
|
||||||
|
uint32_t role = aRoot->Role();
|
||||||
|
uint32_t childCount = aRoot->ChildCount();
|
||||||
|
|
||||||
|
nsString name;
|
||||||
|
aRoot->Name(name);
|
||||||
|
aTree.AppendElement(AccessibleData(id, role, childCount, name));
|
||||||
|
for (uint32_t i = 0; i < childCount; i++)
|
||||||
|
SerializeTree(aRoot->GetChildAt(i), aTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DocAccessibleChild::ShowEvent(AccShowEvent* aShowEvent)
|
||||||
|
{
|
||||||
|
Accessible* parent = aShowEvent->Parent();
|
||||||
|
uint64_t parentID = parent->IsDoc() ? 0 : reinterpret_cast<uint64_t>(parent->UniqueID());
|
||||||
|
uint32_t idxInParent = aShowEvent->GetAccessible()->IndexInParent();
|
||||||
|
nsTArray<AccessibleData> shownTree;
|
||||||
|
ShowEventData data(parentID, idxInParent, shownTree);
|
||||||
|
SerializeTree(aShowEvent->GetAccessible(), data.NewTree());
|
||||||
|
SendShowEvent(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
accessible/ipc/DocAccessibleChild.h
Normal file
43
accessible/ipc/DocAccessibleChild.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/* -*- 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_DocAccessibleChild_h
|
||||||
|
#define mozilla_a11y_DocAccessibleChild_h
|
||||||
|
|
||||||
|
#include "mozilla/a11y/DocAccessible.h"
|
||||||
|
#include "mozilla/a11y/PDocAccessibleChild.h"
|
||||||
|
#include "nsISupportsImpl.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace a11y {
|
||||||
|
class AccShowEvent;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These objects handle content side communication for an accessible document,
|
||||||
|
* and their lifetime is the same as the document they represent.
|
||||||
|
*/
|
||||||
|
class DocAccessibleChild : public PDocAccessibleChild
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DocAccessibleChild(DocAccessible* aDoc) :
|
||||||
|
mDoc(aDoc)
|
||||||
|
{ MOZ_COUNT_CTOR(DocAccessibleChild); }
|
||||||
|
~DocAccessibleChild()
|
||||||
|
{
|
||||||
|
mDoc->SetIPCDoc(nullptr);
|
||||||
|
MOZ_COUNT_DTOR(DocAccessibleChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowEvent(AccShowEvent* aShowEvent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DocAccessible* mDoc;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
112
accessible/ipc/DocAccessibleParent.cpp
Normal file
112
accessible/ipc/DocAccessibleParent.cpp
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/* -*- 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 "DocAccessibleParent.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "mozilla/a11y/Platform.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace a11y {
|
||||||
|
|
||||||
|
bool
|
||||||
|
DocAccessibleParent::RecvShowEvent(const ShowEventData& aData)
|
||||||
|
{
|
||||||
|
if (aData.NewTree().IsEmpty()) {
|
||||||
|
NS_ERROR("no children being added");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProxyAccessible* parent = nullptr;
|
||||||
|
if (aData.ID()) {
|
||||||
|
ProxyEntry* e = mAccessibles.GetEntry(aData.ID());
|
||||||
|
if (e)
|
||||||
|
parent = e->mProxy;
|
||||||
|
} else {
|
||||||
|
parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX This should really never happen, but sometimes we fail to fire the
|
||||||
|
// required show events.
|
||||||
|
if (!parent) {
|
||||||
|
NS_ERROR("adding child to unknown accessible");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t newChildIdx = aData.Idx();
|
||||||
|
if (newChildIdx > parent->ChildrenCount()) {
|
||||||
|
NS_ERROR("invalid index to add child at");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t consumed = AddSubtree(parent, aData.NewTree(), 0, newChildIdx);
|
||||||
|
MOZ_ASSERT(consumed == aData.NewTree().Length());
|
||||||
|
for (uint32_t i = 0; i < consumed; i++) {
|
||||||
|
uint64_t id = aData.NewTree()[i].ID();
|
||||||
|
MOZ_ASSERT(mAccessibles.GetEntry(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
DocAccessibleParent::AddSubtree(ProxyAccessible* aParent,
|
||||||
|
const nsTArray<a11y::AccessibleData>& aNewTree,
|
||||||
|
uint32_t aIdx, uint32_t aIdxInParent)
|
||||||
|
{
|
||||||
|
if (aNewTree.Length() <= aIdx) {
|
||||||
|
NS_ERROR("bad index in serialized tree!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AccessibleData& newChild = aNewTree[aIdx];
|
||||||
|
if (newChild.Role() > roles::LAST_ROLE) {
|
||||||
|
NS_ERROR("invalid role");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto role = static_cast<a11y::role>(newChild.Role());
|
||||||
|
ProxyAccessible* newProxy =
|
||||||
|
new ProxyAccessible(newChild.ID(), aParent, this, role, newChild.Name());
|
||||||
|
aParent->AddChildAt(aIdxInParent, newProxy);
|
||||||
|
mAccessibles.PutEntry(newChild.ID())->mProxy = newProxy;
|
||||||
|
ProxyCreated(newProxy);
|
||||||
|
|
||||||
|
uint32_t accessibles = 1;
|
||||||
|
uint32_t kids = newChild.ChildrenCount();
|
||||||
|
for (uint32_t i = 0; i < kids; i++) {
|
||||||
|
uint32_t consumed = AddSubtree(newProxy, aNewTree, aIdx + accessibles, i);
|
||||||
|
if (!consumed)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
accessibles += consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(newProxy->ChildrenCount() == kids);
|
||||||
|
|
||||||
|
return accessibles;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
DocAccessibleParent::RecvHideEvent(const uint64_t& aRootID)
|
||||||
|
{
|
||||||
|
ProxyEntry* rootEntry = mAccessibles.GetEntry(aRootID);
|
||||||
|
if (!rootEntry) {
|
||||||
|
NS_ERROR("invalid root being removed!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProxyAccessible* root = rootEntry->mProxy;
|
||||||
|
if (!root) {
|
||||||
|
NS_ERROR("invalid root being removed!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
root->Shutdown();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
141
accessible/ipc/DocAccessibleParent.h
Normal file
141
accessible/ipc/DocAccessibleParent.h
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/* -*- 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() :
|
||||||
|
mParentDoc(nullptr)
|
||||||
|
{ MOZ_COUNT_CTOR_INHERITED(DocAccessibleParent, ProxyAccessible); }
|
||||||
|
~DocAccessibleParent()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR_INHERITED(DocAccessibleParent, ProxyAccessible);
|
||||||
|
MOZ_ASSERT(mChildDocs.Length() == 0);
|
||||||
|
MOZ_ASSERT(!mParentDoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called when a message from a document in a child process notifies the main
|
||||||
|
* process it is firing an event.
|
||||||
|
*/
|
||||||
|
virtual bool RecvEvent(const uint32_t& aType) MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool RecvShowEvent(const ShowEventData& aData) MOZ_OVERRIDE;
|
||||||
|
virtual bool RecvHideEvent(const uint64_t& aRootID) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mChildDocs.IsEmpty(),
|
||||||
|
"why wheren't the child docs destroyed already?");
|
||||||
|
mParentDoc ? mParentDoc->RemoveChildDoc(this)
|
||||||
|
: GetAccService()->RemoteDocShutdown(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the main processes representation of the parent document (if any)
|
||||||
|
* of the document this object represents.
|
||||||
|
*/
|
||||||
|
DocAccessibleParent* Parent() const { return mParentDoc; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called when a document in a content process notifies the main process of a
|
||||||
|
* new child document.
|
||||||
|
*/
|
||||||
|
bool AddChildDoc(DocAccessibleParent* aChildDoc, uint64_t aParentID)
|
||||||
|
{
|
||||||
|
ProxyAccessible* outerDoc = mAccessibles.GetEntry(aParentID)->mProxy;
|
||||||
|
if (!outerDoc)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
aChildDoc->mParent = outerDoc;
|
||||||
|
outerDoc->SetChildDoc(aChildDoc);
|
||||||
|
mChildDocs.AppendElement(aChildDoc);
|
||||||
|
aChildDoc->mParentDoc = this;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
aChildDoc->mParent->SetChildDoc(nullptr);
|
||||||
|
mChildDocs.RemoveElement(aChildDoc);
|
||||||
|
aChildDoc->mParentDoc = nullptr;
|
||||||
|
MOZ_ASSERT(aChildDoc->mChildDocs.Length() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveAccessible(ProxyAccessible* aAccessible)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mAccessibles.GetEntry(aAccessible->ID()));
|
||||||
|
mAccessibles.RemoveEntry(aAccessible->ID());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
class ProxyEntry : public PLDHashEntryHdr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProxyEntry(const void*) : mProxy(nullptr) {}
|
||||||
|
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);
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
44
accessible/ipc/PDocAccessible.ipdl
Normal file
44
accessible/ipc/PDocAccessible.ipdl
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* -*- 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 protocol PContent;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace a11y {
|
||||||
|
|
||||||
|
struct AccessibleData
|
||||||
|
{
|
||||||
|
uint64_t ID;
|
||||||
|
uint32_t Role;
|
||||||
|
uint32_t ChildrenCount;
|
||||||
|
nsString Name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ShowEventData
|
||||||
|
{
|
||||||
|
uint64_t ID;
|
||||||
|
uint32_t Idx;
|
||||||
|
AccessibleData[] NewTree;
|
||||||
|
};
|
||||||
|
|
||||||
|
protocol PDocAccessible
|
||||||
|
{
|
||||||
|
manager PContent;
|
||||||
|
|
||||||
|
parent:
|
||||||
|
__delete__();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notify the parent process the document in the child process is firing an
|
||||||
|
* event.
|
||||||
|
*/
|
||||||
|
Event(uint32_t type);
|
||||||
|
ShowEvent(ShowEventData data);
|
||||||
|
HideEvent(uint64_t aRootID);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
42
accessible/ipc/ProxyAccessible.cpp
Normal file
42
accessible/ipc/ProxyAccessible.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* -*- 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 "ProxyAccessible.h"
|
||||||
|
#include "DocAccessibleParent.h"
|
||||||
|
#include "mozilla/a11y/Platform.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace a11y {
|
||||||
|
|
||||||
|
void
|
||||||
|
ProxyAccessible::Shutdown()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!mOuterDoc);
|
||||||
|
|
||||||
|
uint32_t childCount = mChildren.Length();
|
||||||
|
for (uint32_t idx = 0; idx < childCount; idx++)
|
||||||
|
mChildren[idx]->Shutdown();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
77
accessible/ipc/ProxyAccessible.h
Normal file
77
accessible/ipc/ProxyAccessible.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/* -*- 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 "mozilla/a11y/Role.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace a11y {
|
||||||
|
|
||||||
|
class DocAccessibleParent;
|
||||||
|
|
||||||
|
class ProxyAccessible
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ProxyAccessible(uint64_t aID, ProxyAccessible* aParent,
|
||||||
|
DocAccessibleParent* aDoc, role aRole,
|
||||||
|
const nsString& aName) :
|
||||||
|
mParent(aParent), mDoc(aDoc), mID(aID), mRole(aRole), mOuterDoc(false), mName(aName)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(ProxyAccessible);
|
||||||
|
}
|
||||||
|
~ProxyAccessible() { MOZ_COUNT_DTOR(ProxyAccessible); }
|
||||||
|
|
||||||
|
void AddChildAt(uint32_t aIdx, ProxyAccessible* aChild)
|
||||||
|
{ mChildren.InsertElementAt(aIdx, aChild); }
|
||||||
|
|
||||||
|
uint32_t ChildrenCount() const { return mChildren.Length(); }
|
||||||
|
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
void SetChildDoc(DocAccessibleParent*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the role of the accessible we're proxying.
|
||||||
|
*/
|
||||||
|
role Role() const { return mRole; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ProxyAccessible() :
|
||||||
|
mParent(nullptr), mDoc(nullptr) { MOZ_COUNT_CTOR(ProxyAccessible); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ProxyAccessible* mParent;
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsTArray<ProxyAccessible*> mChildren;
|
||||||
|
DocAccessibleParent* mDoc;
|
||||||
|
uintptr_t mWrapper;
|
||||||
|
uint64_t mID;
|
||||||
|
role mRole : 31;
|
||||||
|
bool mOuterDoc : 1;
|
||||||
|
nsString mName;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
28
accessible/ipc/moz.build
Normal file
28
accessible/ipc/moz.build
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||||
|
# vim: set filetype=python:
|
||||||
|
# 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/.
|
||||||
|
|
||||||
|
IPDL_SOURCES += ['PDocAccessible.ipdl']
|
||||||
|
|
||||||
|
EXPORTS.mozilla.a11y += [
|
||||||
|
'DocAccessibleChild.h',
|
||||||
|
'DocAccessibleParent.h',
|
||||||
|
'ProxyAccessible.h'
|
||||||
|
]
|
||||||
|
|
||||||
|
SOURCES += [
|
||||||
|
'DocAccessibleChild.cpp',
|
||||||
|
'DocAccessibleParent.cpp',
|
||||||
|
'ProxyAccessible.cpp'
|
||||||
|
]
|
||||||
|
|
||||||
|
LOCAL_INCLUDES += [
|
||||||
|
'../base',
|
||||||
|
'../generic',
|
||||||
|
]
|
||||||
|
|
||||||
|
FINAL_LIBRARY = 'xul'
|
||||||
|
|
||||||
|
include('/ipc/chromium/chromium-config.mozbuild')
|
@ -33,6 +33,15 @@ PlatformShutdown()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ProxyCreated(ProxyAccessible*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ProxyDestroyed(ProxyAccessible*)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ elif toolkit == 'cocoa':
|
|||||||
else:
|
else:
|
||||||
DIRS += ['other']
|
DIRS += ['other']
|
||||||
|
|
||||||
DIRS += ['base', 'generic', 'html', 'interfaces', 'jsat', 'xpcom']
|
DIRS += ['base', 'generic', 'html', 'interfaces', 'ipc', 'jsat', 'xpcom']
|
||||||
|
|
||||||
if CONFIG['MOZ_XUL']:
|
if CONFIG['MOZ_XUL']:
|
||||||
DIRS += ['xul']
|
DIRS += ['xul']
|
||||||
|
@ -18,3 +18,13 @@ void
|
|||||||
a11y::PlatformShutdown()
|
a11y::PlatformShutdown()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
a11y::ProxyCreated(ProxyAccessible*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
a11y::ProxyDestroyed(ProxyAccessible*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -34,3 +34,12 @@ a11y::PlatformShutdown()
|
|||||||
nsWinUtils::ShutdownWindowEmulation();
|
nsWinUtils::ShutdownWindowEmulation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
a11y::ProxyCreated(ProxyAccessible*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
a11y::ProxyDestroyed(ProxyAccessible*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "TabChild.h"
|
#include "TabChild.h"
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/a11y/DocAccessibleChild.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/dom/ContentBridgeChild.h"
|
#include "mozilla/dom/ContentBridgeChild.h"
|
||||||
#include "mozilla/dom/ContentBridgeParent.h"
|
#include "mozilla/dom/ContentBridgeParent.h"
|
||||||
@ -705,6 +706,20 @@ ContentChild::InitXPCOM()
|
|||||||
InitOnContentProcessCreated();
|
InitOnContentProcessCreated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a11y::PDocAccessibleChild*
|
||||||
|
ContentChild::AllocPDocAccessibleChild(PDocAccessibleChild*, const uint64_t&)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(false, "should never call this!");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContentChild::DeallocPDocAccessibleChild(a11y::PDocAccessibleChild* aChild)
|
||||||
|
{
|
||||||
|
delete static_cast<mozilla::a11y::DocAccessibleChild*>(aChild);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
PMemoryReportRequestChild*
|
PMemoryReportRequestChild*
|
||||||
ContentChild::AllocPMemoryReportRequestChild(const uint32_t& aGeneration,
|
ContentChild::AllocPMemoryReportRequestChild(const uint32_t& aGeneration,
|
||||||
const bool &aAnonymize,
|
const bool &aAnonymize,
|
||||||
|
@ -376,6 +376,8 @@ public:
|
|||||||
const uint64_t& aID,
|
const uint64_t& aID,
|
||||||
const bool& aIsForApp,
|
const bool& aIsForApp,
|
||||||
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
const bool& aIsForBrowser) MOZ_OVERRIDE;
|
||||||
|
virtual PDocAccessibleChild* AllocPDocAccessibleChild(PDocAccessibleChild*, const uint64_t&) MOZ_OVERRIDE;
|
||||||
|
virtual bool DeallocPDocAccessibleChild(PDocAccessibleChild*) MOZ_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include "CrashReporterParent.h"
|
#include "CrashReporterParent.h"
|
||||||
#include "IHistory.h"
|
#include "IHistory.h"
|
||||||
#include "mozIApplication.h"
|
#include "mozIApplication.h"
|
||||||
|
#include "mozilla/a11y/DocAccessibleParent.h"
|
||||||
|
#include "nsAccessibilityService.h"
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
#include "mozilla/dom/asmjscache/AsmJSCache.h"
|
#include "mozilla/dom/asmjscache/AsmJSCache.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
@ -2695,6 +2697,34 @@ ContentParent::Observe(nsISupports* aSubject,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a11y::PDocAccessibleParent*
|
||||||
|
ContentParent::AllocPDocAccessibleParent(PDocAccessibleParent* aParent, const uint64_t&)
|
||||||
|
{
|
||||||
|
return new a11y::DocAccessibleParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContentParent::DeallocPDocAccessibleParent(PDocAccessibleParent* aParent)
|
||||||
|
{
|
||||||
|
delete static_cast<a11y::DocAccessibleParent*>(aParent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContentParent::RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc, PDocAccessibleParent* aParentDoc, const uint64_t& aParentID)
|
||||||
|
{
|
||||||
|
auto doc = static_cast<a11y::DocAccessibleParent*>(aDoc);
|
||||||
|
if (aParentDoc) {
|
||||||
|
MOZ_ASSERT(aParentID);
|
||||||
|
auto parentDoc = static_cast<a11y::DocAccessibleParent*>(aParentDoc);
|
||||||
|
return parentDoc->AddChildDoc(doc, aParentID);
|
||||||
|
} else {
|
||||||
|
MOZ_ASSERT(!aParentID);
|
||||||
|
GetAccService()->RemoteDocAdded(doc);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
PCompositorParent*
|
PCompositorParent*
|
||||||
ContentParent::AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
|
ContentParent::AllocPCompositorParent(mozilla::ipc::Transport* aTransport,
|
||||||
base::ProcessId aOtherProcess)
|
base::ProcessId aOtherProcess)
|
||||||
|
@ -662,6 +662,11 @@ private:
|
|||||||
int32_t* aSliceRefCnt,
|
int32_t* aSliceRefCnt,
|
||||||
bool* aResult) MOZ_OVERRIDE;
|
bool* aResult) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
virtual PDocAccessibleParent* AllocPDocAccessibleParent(PDocAccessibleParent*, const uint64_t&) MOZ_OVERRIDE;
|
||||||
|
virtual bool DeallocPDocAccessibleParent(PDocAccessibleParent*) MOZ_OVERRIDE;
|
||||||
|
virtual bool RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc,
|
||||||
|
PDocAccessibleParent* aParentDoc, const uint64_t& aParentID) MOZ_OVERRIDE;
|
||||||
|
|
||||||
// If you add strong pointers to cycle collected objects here, be sure to
|
// If you add strong pointers to cycle collected objects here, be sure to
|
||||||
// release these objects in ShutDownProcess. See the comment there for more
|
// release these objects in ShutDownProcess. See the comment there for more
|
||||||
// details.
|
// details.
|
||||||
|
@ -13,6 +13,7 @@ include protocol PCompositor;
|
|||||||
include protocol PContentBridge;
|
include protocol PContentBridge;
|
||||||
include protocol PCycleCollectWithLogs;
|
include protocol PCycleCollectWithLogs;
|
||||||
include protocol PCrashReporter;
|
include protocol PCrashReporter;
|
||||||
|
include protocol PDocAccessible;
|
||||||
include protocol PExternalHelperApp;
|
include protocol PExternalHelperApp;
|
||||||
include protocol PDeviceStorageRequest;
|
include protocol PDeviceStorageRequest;
|
||||||
include protocol PFileDescriptorSet;
|
include protocol PFileDescriptorSet;
|
||||||
@ -325,6 +326,7 @@ intr protocol PContent
|
|||||||
manages PBrowser;
|
manages PBrowser;
|
||||||
manages PCrashReporter;
|
manages PCrashReporter;
|
||||||
manages PCycleCollectWithLogs;
|
manages PCycleCollectWithLogs;
|
||||||
|
manages PDocAccessible;
|
||||||
manages PDeviceStorageRequest;
|
manages PDeviceStorageRequest;
|
||||||
manages PFileSystemRequest;
|
manages PFileSystemRequest;
|
||||||
manages PExternalHelperApp;
|
manages PExternalHelperApp;
|
||||||
@ -481,6 +483,14 @@ child:
|
|||||||
OnAppThemeChanged();
|
OnAppThemeChanged();
|
||||||
|
|
||||||
parent:
|
parent:
|
||||||
|
/**
|
||||||
|
* Tell the parent process a new accessible document has been created.
|
||||||
|
* aParentDoc is the accessible document it was created in if any, and
|
||||||
|
* aParentAcc is the id of the accessible in that document the new document
|
||||||
|
* is a child of.
|
||||||
|
*/
|
||||||
|
PDocAccessible(nullable PDocAccessible aParentDoc, uint64_t aParentAcc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell the content process some attributes of itself. This is
|
* Tell the content process some attributes of itself. This is
|
||||||
* among the first information queried by content processes after
|
* among the first information queried by content processes after
|
||||||
|
Loading…
Reference in New Issue
Block a user