mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:25:44 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1153255 - set a build configuration flag when MOZ_TSAN is enabled; r=jorendorff (6b787252a5) - bug 1155829 - remove AccessibleWrap::SetMaiHyperlink r=surkov (69718cc37e) - bug 1155829 - remove MaiHyperlink::Initialize r=surkov (cf770ba16e) - bug 1155829 - inline MaiHyperlink::GetAtkHyperlink r=surkov (2eb9846a7e) - bug 1155829 - add shutdown method to MaiAtkObject r=yzen (f4e35f223d) - bug 1155829 - declare MaiAtkObject in nsMai.h r=yzen (fdb5cd60c7) - bug 1155829 - move AccessibleWrap::GetMaiHyperlink to MaiAtkObject::GetAtkHyperlink r=surkov (e00ba50a1a) - bug 1164976 - move AccessibleWrap::FireStateChangeEvent to be a member of MaiAtkObject r=davidb (5aee8b6119) - Bug 1128365 - MOZ_TOOLS is unnecessary. r=glandium (d7c8d8798d) - bug 1169376 - Allow getting the OuterDocAccessible for the tab's top level document r=davidb (630780f18e) - bug 1171728 - Only look for an OuterDoc accessible parent of a proxy if it doesn't have a proxy parent r=lsocks (76a55151bd) - bug 1107337 - Teach refChildCB to deal with proxies r=lsocks, davidb (1a5cfddb63) - bug 1172053 - don't call malloc in FireAtkShowHideEvent r=lsocks (350bbd99e1) - bug 1172053 - don't malloc the signal name in FireAtkTextChangedEvent r=lsocks (9035d29090) - bug 1107337 - support downcasting Accessible to OuterDocAccessible r=lsocks, davidb (d946ce3bf4) - bug 1107337 - Add OuterDocAccessible::RemoteChildDoc() r=lsocks, davidb (9fd40de39d) - bug 1172523 - Move AccessibleWrap::FireAtkTextChangedEvent to MaiAtkObject::FireTextChangeEvent r=lsocks (021898bef4) - bug 1146518 - allow MaiHyperlink to store references to proxies r=surkov (e068e47855) - bug 1146518 - make atk hyper link impl support proxies r=surkov (7e4d74efb3) - bug 1146518 - create MaiHyperlinks for proxies r=surkov (1b2b0ef5fa) - bug 1146518 - Only pass hyper links to MaiHyperlink::MaiHyperlink r=surkov (2c506d17b7) - bug 1163070 - fix AtkHyperlinkImpl::getHyperlink after bug 1146518 r=surkov (0a33758e48) - bug 1172523 - Allow getting the modified text from an AccTextChangeEvent without copying r=lsocks (aa0bf42335) - bug 1170153 - check documents have a docshell before trying to tell the parent process about new remote DocAccessibles r=davidb (8c35f9cec4) - bug 1181177 - null check tabChild in DocManager::CreateDocOrRootAccessible r=davidb (6c3e309edb) - bug 1186528 - don't create a DocAccessibleChild if we can't tell the parent process about it r=lsocks (d3954843b9) - bug 1164976 - fire useful state change and caret move events for proxies r=davidb (ef2e39e6d9) - bug 1172525 - rework forwarding events to the parent process r=davidb, lsocks (36537fb8f9)
This commit is contained in:
+155
-122
@@ -11,6 +11,7 @@
|
||||
#include "InterfaceInitFuncs.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "mozilla/a11y/PDocAccessible.h"
|
||||
#include "OuterDocAccessible.h"
|
||||
#include "ProxyAccessible.h"
|
||||
#include "RootAccessible.h"
|
||||
#include "nsMai.h"
|
||||
@@ -33,7 +34,7 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
AccessibleWrap::EAvailableAtkSignals AccessibleWrap::gAvailableAtkSignals =
|
||||
MaiAtkObject::EAvailableAtkSignals MaiAtkObject::gAvailableAtkSignals =
|
||||
eUnknown;
|
||||
|
||||
//defined in ApplicationAccessibleWrap.cpp
|
||||
@@ -96,7 +97,7 @@ static GType GetAtkTypeForMai(MaiInterfaceType type)
|
||||
return G_TYPE_INVALID;
|
||||
}
|
||||
|
||||
static const char* kNonUserInputEvent = ":system";
|
||||
#define NON_USER_EVENT ":system"
|
||||
|
||||
static const GInterfaceInfo atk_if_infos[] = {
|
||||
{(GInterfaceInitFunc)componentInterfaceInitCB,
|
||||
@@ -123,22 +124,33 @@ static const GInterfaceInfo atk_if_infos[] = {
|
||||
(GInterfaceFinalizeFunc) nullptr, nullptr}
|
||||
};
|
||||
|
||||
/**
|
||||
* This MaiAtkObject is a thin wrapper, in the MAI namespace, for AtkObject
|
||||
*/
|
||||
struct MaiAtkObject
|
||||
{
|
||||
AtkObject parent;
|
||||
/*
|
||||
* The AccessibleWrap whose properties and features are exported
|
||||
* via this object instance.
|
||||
*/
|
||||
uintptr_t accWrap;
|
||||
};
|
||||
static GQuark quark_mai_hyperlink = 0;
|
||||
|
||||
// This is or'd with the pointer in MaiAtkObject::accWrap if the wrap-ee is a
|
||||
// proxy.
|
||||
static const uintptr_t IS_PROXY = 1;
|
||||
AtkHyperlink*
|
||||
MaiAtkObject::GetAtkHyperlink()
|
||||
{
|
||||
NS_ASSERTION(quark_mai_hyperlink, "quark_mai_hyperlink not initialized");
|
||||
MaiHyperlink* maiHyperlink =
|
||||
(MaiHyperlink*)g_object_get_qdata(G_OBJECT(this), quark_mai_hyperlink);
|
||||
if (!maiHyperlink) {
|
||||
maiHyperlink = new MaiHyperlink(accWrap);
|
||||
g_object_set_qdata(G_OBJECT(this), quark_mai_hyperlink, maiHyperlink);
|
||||
}
|
||||
|
||||
return maiHyperlink->GetAtkHyperlink();
|
||||
}
|
||||
|
||||
void
|
||||
MaiAtkObject::Shutdown()
|
||||
{
|
||||
accWrap = 0;
|
||||
MaiHyperlink* maiHyperlink =
|
||||
(MaiHyperlink*)g_object_get_qdata(G_OBJECT(this), quark_mai_hyperlink);
|
||||
if (maiHyperlink) {
|
||||
delete maiHyperlink;
|
||||
g_object_set_qdata(G_OBJECT(this), quark_mai_hyperlink, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
struct MaiAtkObjectClass
|
||||
{
|
||||
@@ -208,8 +220,6 @@ static const char * GetUniqueMaiAtkTypeName(uint16_t interfacesBits);
|
||||
|
||||
static gpointer parent_class = nullptr;
|
||||
|
||||
static GQuark quark_mai_hyperlink = 0;
|
||||
|
||||
GType
|
||||
mai_atk_object_get_type(void)
|
||||
{
|
||||
@@ -250,14 +260,15 @@ AccessibleWrap::~AccessibleWrap()
|
||||
void
|
||||
AccessibleWrap::ShutdownAtkObject()
|
||||
{
|
||||
if (mAtkObject) {
|
||||
if (IS_MAI_OBJECT(mAtkObject)) {
|
||||
MAI_ATK_OBJECT(mAtkObject)->accWrap = 0;
|
||||
}
|
||||
SetMaiHyperlink(nullptr);
|
||||
g_object_unref(mAtkObject);
|
||||
mAtkObject = nullptr;
|
||||
}
|
||||
if (!mAtkObject)
|
||||
return;
|
||||
|
||||
NS_ASSERTION(IS_MAI_OBJECT(mAtkObject), "wrong type of atk object");
|
||||
if (IS_MAI_OBJECT(mAtkObject))
|
||||
MAI_ATK_OBJECT(mAtkObject)->Shutdown();
|
||||
|
||||
g_object_unref(mAtkObject);
|
||||
mAtkObject = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -267,42 +278,6 @@ AccessibleWrap::Shutdown()
|
||||
Accessible::Shutdown();
|
||||
}
|
||||
|
||||
MaiHyperlink*
|
||||
AccessibleWrap::GetMaiHyperlink(bool aCreate /* = true */)
|
||||
{
|
||||
// make sure mAtkObject is created
|
||||
GetAtkObject();
|
||||
|
||||
NS_ASSERTION(quark_mai_hyperlink, "quark_mai_hyperlink not initialized");
|
||||
NS_ASSERTION(IS_MAI_OBJECT(mAtkObject), "Invalid AtkObject");
|
||||
MaiHyperlink* maiHyperlink = nullptr;
|
||||
if (quark_mai_hyperlink && IS_MAI_OBJECT(mAtkObject)) {
|
||||
maiHyperlink = (MaiHyperlink*)g_object_get_qdata(G_OBJECT(mAtkObject),
|
||||
quark_mai_hyperlink);
|
||||
if (!maiHyperlink && aCreate) {
|
||||
maiHyperlink = new MaiHyperlink(this);
|
||||
SetMaiHyperlink(maiHyperlink);
|
||||
}
|
||||
}
|
||||
return maiHyperlink;
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleWrap::SetMaiHyperlink(MaiHyperlink* aMaiHyperlink)
|
||||
{
|
||||
NS_ASSERTION(quark_mai_hyperlink, "quark_mai_hyperlink not initialized");
|
||||
NS_ASSERTION(IS_MAI_OBJECT(mAtkObject), "Invalid AtkObject");
|
||||
if (quark_mai_hyperlink && IS_MAI_OBJECT(mAtkObject)) {
|
||||
MaiHyperlink* maiHyperlink = GetMaiHyperlink(false);
|
||||
if (!maiHyperlink && !aMaiHyperlink) {
|
||||
return; // Never set and we're shutting down
|
||||
}
|
||||
delete maiHyperlink;
|
||||
g_object_set_qdata(G_OBJECT(mAtkObject), quark_mai_hyperlink,
|
||||
aMaiHyperlink);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleWrap::GetNativeInterface(void** aOutAccessible)
|
||||
{
|
||||
@@ -826,7 +801,12 @@ getParentCB(AtkObject *aAtkObj)
|
||||
atkParent = parent ? AccessibleWrap::GetAtkObject(parent) : nullptr;
|
||||
} else if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
|
||||
ProxyAccessible* parent = proxy->Parent();
|
||||
atkParent = parent ? GetWrapperFor(parent) : nullptr;
|
||||
if (parent) {
|
||||
atkParent = GetWrapperFor(parent);
|
||||
} else {
|
||||
// Otherwise this should be the proxy for the tab's top level document.
|
||||
atkParent = AccessibleWrap::GetAtkObject(proxy->OuterDocOfRemoteBrowser());
|
||||
}
|
||||
}
|
||||
|
||||
if (atkParent)
|
||||
@@ -849,26 +829,45 @@ getChildCountCB(AtkObject *aAtkObj)
|
||||
AtkObject *
|
||||
refChildCB(AtkObject *aAtkObj, gint aChildIndex)
|
||||
{
|
||||
// aChildIndex should not be less than zero
|
||||
if (aChildIndex < 0) {
|
||||
// aChildIndex should not be less than zero
|
||||
if (aChildIndex < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AtkObject* childAtkObj = nullptr;
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
|
||||
if (accWrap) {
|
||||
if (nsAccUtils::MustPrune(accWrap)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
|
||||
if (!accWrap || nsAccUtils::MustPrune(accWrap)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Accessible* accChild = accWrap->GetEmbeddedChildAt(aChildIndex);
|
||||
if (!accChild)
|
||||
return nullptr;
|
||||
if (accChild) {
|
||||
childAtkObj = AccessibleWrap::GetAtkObject(accChild);
|
||||
} else {
|
||||
OuterDocAccessible* docOwner = accWrap->AsOuterDoc();
|
||||
if (docOwner) {
|
||||
ProxyAccessible* proxyDoc = docOwner->RemoteChildDoc();
|
||||
if (proxyDoc)
|
||||
childAtkObj = GetWrapperFor(proxyDoc);
|
||||
}
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
|
||||
if (proxy->MustPruneChildren())
|
||||
return nullptr;
|
||||
|
||||
AtkObject* childAtkObj = AccessibleWrap::GetAtkObject(accChild);
|
||||
ProxyAccessible* child = proxy->EmbeddedChildAt(aChildIndex);
|
||||
if (child)
|
||||
childAtkObj = GetWrapperFor(child);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NS_ASSERTION(childAtkObj, "Fail to get AtkObj");
|
||||
if (!childAtkObj)
|
||||
return nullptr;
|
||||
g_object_ref(childAtkObj);
|
||||
NS_ASSERTION(childAtkObj, "Fail to get AtkObj");
|
||||
if (!childAtkObj)
|
||||
return nullptr;
|
||||
|
||||
g_object_ref(childAtkObj);
|
||||
|
||||
if (aAtkObj != childAtkObj->accessible_parent)
|
||||
atk_object_set_parent(childAtkObj, aAtkObj);
|
||||
@@ -885,6 +884,9 @@ getIndexInParentCB(AtkObject* aAtkObj)
|
||||
if (ProxyAccessible* parent = proxy->Parent())
|
||||
return parent->IndexOfEmbeddedChild(proxy);
|
||||
|
||||
if (proxy->OuterDocOfRemoteBrowser())
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1100,7 +1102,7 @@ void
|
||||
a11y::ProxyDestroyed(ProxyAccessible* aProxy)
|
||||
{
|
||||
auto obj = reinterpret_cast<MaiAtkObject*>(aProxy->GetWrapper() & ~IS_PROXY);
|
||||
obj->accWrap = 0;
|
||||
obj->Shutdown();
|
||||
g_object_unref(obj);
|
||||
aProxy->SetWrapper(0);
|
||||
}
|
||||
@@ -1139,11 +1141,27 @@ AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
|
||||
|
||||
switch (type) {
|
||||
case nsIAccessibleEvent::EVENT_STATE_CHANGE:
|
||||
return FireAtkStateChangeEvent(aEvent, atkObj);
|
||||
{
|
||||
AccStateChangeEvent* event = downcast_accEvent(aEvent);
|
||||
MAI_ATK_OBJECT(atkObj)->FireStateChangeEvent(event->GetState(),
|
||||
event->IsStateEnabled());
|
||||
break;
|
||||
}
|
||||
|
||||
case nsIAccessibleEvent::EVENT_TEXT_REMOVED:
|
||||
case nsIAccessibleEvent::EVENT_TEXT_INSERTED:
|
||||
return FireAtkTextChangedEvent(aEvent, atkObj);
|
||||
{
|
||||
AccTextChangeEvent* event = downcast_accEvent(aEvent);
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
|
||||
|
||||
MAI_ATK_OBJECT(atkObj)-> FireTextChangeEvent(event->ModifiedText(),
|
||||
event->GetStartOffset(),
|
||||
event->GetLength(),
|
||||
event->IsTextInserted(),
|
||||
event->IsFromUserInput());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case nsIAccessibleEvent::EVENT_FOCUS:
|
||||
{
|
||||
@@ -1370,15 +1388,25 @@ a11y::ProxyEvent(ProxyAccessible* aTarget, uint32_t aEventType)
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
AccessibleWrap::FireAtkStateChangeEvent(AccEvent* aEvent,
|
||||
AtkObject* aObject)
|
||||
void
|
||||
a11y::ProxyStateChangeEvent(ProxyAccessible* aTarget, uint64_t aState,
|
||||
bool aEnabled)
|
||||
{
|
||||
AccStateChangeEvent* event = downcast_accEvent(aEvent);
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
|
||||
MaiAtkObject* atkObj = MAI_ATK_OBJECT(GetWrapperFor(aTarget));
|
||||
atkObj->FireStateChangeEvent(aState, aEnabled);
|
||||
}
|
||||
|
||||
bool isEnabled = event->IsStateEnabled();
|
||||
int32_t stateIndex = AtkStateMap::GetStateIndexFor(event->GetState());
|
||||
void
|
||||
a11y::ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
|
||||
{
|
||||
AtkObject* wrapper = GetWrapperFor(aTarget);
|
||||
g_signal_emit_by_name(wrapper, "text_caret_moved", aOffset);
|
||||
}
|
||||
|
||||
void
|
||||
MaiAtkObject::FireStateChangeEvent(uint64_t aState, bool aEnabled)
|
||||
{
|
||||
int32_t stateIndex = AtkStateMap::GetStateIndexFor(aState);
|
||||
if (stateIndex >= 0) {
|
||||
NS_ASSERTION(gAtkStateMap[stateIndex].stateMapEntryType != kNoSuchState,
|
||||
"No such state");
|
||||
@@ -1388,57 +1416,64 @@ AccessibleWrap::FireAtkStateChangeEvent(AccEvent* aEvent,
|
||||
"State changes should not fired for this state");
|
||||
|
||||
if (gAtkStateMap[stateIndex].stateMapEntryType == kMapOpposite)
|
||||
isEnabled = !isEnabled;
|
||||
aEnabled = !aEnabled;
|
||||
|
||||
// Fire state change for first state if there is one to map
|
||||
atk_object_notify_state_change(aObject,
|
||||
atk_object_notify_state_change(&parent,
|
||||
gAtkStateMap[stateIndex].atkState,
|
||||
isEnabled);
|
||||
aEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
AccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent,
|
||||
AtkObject* aObject)
|
||||
#define OLD_TEXT_INSERTED "text_changed::insert"
|
||||
#define OLD_TEXT_REMOVED "text_changed::delete"
|
||||
static const char* oldTextChangeStrings[2][2] = {
|
||||
{ OLD_TEXT_REMOVED NON_USER_EVENT, OLD_TEXT_INSERTED NON_USER_EVENT },
|
||||
{ OLD_TEXT_REMOVED, OLD_TEXT_INSERTED }
|
||||
};
|
||||
|
||||
#define TEXT_INSERTED "text-insert"
|
||||
#define TEXT_REMOVED "text-remove"
|
||||
#define NON_USER_DETAIL "::system"
|
||||
static const char* textChangedStrings[2][2] = {
|
||||
{ TEXT_REMOVED NON_USER_DETAIL, TEXT_INSERTED NON_USER_DETAIL },
|
||||
{ TEXT_REMOVED, TEXT_INSERTED}
|
||||
};
|
||||
|
||||
void
|
||||
MaiAtkObject::FireTextChangeEvent(const nsString& aStr, int32_t aStart,
|
||||
uint32_t aLen, bool aIsInsert,
|
||||
bool aFromUser)
|
||||
{
|
||||
AccTextChangeEvent* event = downcast_accEvent(aEvent);
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
|
||||
|
||||
int32_t start = event->GetStartOffset();
|
||||
uint32_t length = event->GetLength();
|
||||
bool isInserted = event->IsTextInserted();
|
||||
bool isFromUserInput = aEvent->IsFromUserInput();
|
||||
char* signal_name = nullptr;
|
||||
|
||||
if (gAvailableAtkSignals == eUnknown)
|
||||
gAvailableAtkSignals =
|
||||
g_signal_lookup("text-insert", G_OBJECT_TYPE(aObject)) ?
|
||||
g_signal_lookup("text-insert", G_OBJECT_TYPE(this)) ?
|
||||
eHaveNewAtkTextSignals : eNoNewAtkSignals;
|
||||
|
||||
if (gAvailableAtkSignals == eNoNewAtkSignals) {
|
||||
// XXX remove this code and the gHaveNewTextSignals check when we can
|
||||
// stop supporting old atk since it doesn't really work anyway
|
||||
// see bug 619002
|
||||
signal_name = g_strconcat(isInserted ? "text_changed::insert" :
|
||||
"text_changed::delete",
|
||||
isFromUserInput ? "" : kNonUserInputEvent, nullptr);
|
||||
g_signal_emit_by_name(aObject, signal_name, start, length);
|
||||
const char* signal_name =
|
||||
oldTextChangeStrings[aFromUser][aIsInsert];
|
||||
g_signal_emit_by_name(this, signal_name, aStart, aLen);
|
||||
} else {
|
||||
nsAutoString text;
|
||||
event->GetModifiedText(text);
|
||||
signal_name = g_strconcat(isInserted ? "text-insert" : "text-remove",
|
||||
isFromUserInput ? "" : "::system", nullptr);
|
||||
g_signal_emit_by_name(aObject, signal_name, start, length,
|
||||
NS_ConvertUTF16toUTF8(text).get());
|
||||
const char* signal_name =
|
||||
textChangedStrings[aFromUser][aIsInsert];
|
||||
g_signal_emit_by_name(this, signal_name, aStart, aLen,
|
||||
NS_ConvertUTF16toUTF8(aStr).get());
|
||||
}
|
||||
|
||||
g_free(signal_name);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define ADD_EVENT "children_changed::add"
|
||||
#define HIDE_EVENT "children_changed::remove"
|
||||
|
||||
static const char *kMutationStrings[2][2] = {
|
||||
{ HIDE_EVENT NON_USER_EVENT, ADD_EVENT NON_USER_EVENT },
|
||||
{ HIDE_EVENT, ADD_EVENT },
|
||||
};
|
||||
|
||||
nsresult
|
||||
AccessibleWrap::FireAtkShowHideEvent(AccEvent* aEvent,
|
||||
AtkObject* aObject, bool aIsAdded)
|
||||
@@ -1448,10 +1483,8 @@ AccessibleWrap::FireAtkShowHideEvent(AccEvent* aEvent,
|
||||
NS_ENSURE_STATE(parentObject);
|
||||
|
||||
bool isFromUserInput = aEvent->IsFromUserInput();
|
||||
char *signal_name = g_strconcat(aIsAdded ? "children_changed::add" : "children_changed::remove",
|
||||
isFromUserInput ? "" : kNonUserInputEvent, nullptr);
|
||||
const char *signal_name = kMutationStrings[isFromUserInput][aIsAdded];
|
||||
g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, nullptr);
|
||||
g_free(signal_name);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -63,10 +63,6 @@ public:
|
||||
|
||||
bool IsValidObject();
|
||||
|
||||
// get/set the MaiHyperlink object for this AccessibleWrap
|
||||
MaiHyperlink* GetMaiHyperlink(bool aCreate = true);
|
||||
void SetMaiHyperlink(MaiHyperlink* aMaiHyperlink);
|
||||
|
||||
static const char * ReturnString(nsAString &aString) {
|
||||
static nsCString returnedString;
|
||||
returnedString = NS_ConvertUTF16toUTF8(aString);
|
||||
@@ -83,20 +79,6 @@ protected:
|
||||
AtkObject *mAtkObject;
|
||||
|
||||
private:
|
||||
|
||||
/*
|
||||
* do we have text-remove and text-insert signals if not we need to use
|
||||
* text-changed see AccessibleWrap::FireAtkTextChangedEvent() and
|
||||
* bug 619002
|
||||
*/
|
||||
enum EAvailableAtkSignals {
|
||||
eUnknown,
|
||||
eHaveNewAtkTextSignals,
|
||||
eNoNewAtkSignals
|
||||
};
|
||||
|
||||
static EAvailableAtkSignals gAvailableAtkSignals;
|
||||
|
||||
uint16_t CreateMaiInterfaces();
|
||||
};
|
||||
|
||||
|
||||
@@ -51,4 +51,56 @@ IsAtkVersionAtLeast(int aMajor, int aMinor)
|
||||
(aMajor == atkMajorVersion && aMinor <= atkMinorVersion);
|
||||
}
|
||||
|
||||
// This is or'd with the pointer in MaiAtkObject::accWrap if the wrap-ee is a
|
||||
// proxy.
|
||||
static const uintptr_t IS_PROXY = 1;
|
||||
|
||||
/**
|
||||
* This MaiAtkObject is a thin wrapper, in the MAI namespace, for AtkObject
|
||||
*/
|
||||
struct MaiAtkObject
|
||||
{
|
||||
AtkObject parent;
|
||||
/*
|
||||
* The AccessibleWrap whose properties and features are exported
|
||||
* via this object instance.
|
||||
*/
|
||||
uintptr_t accWrap;
|
||||
|
||||
/*
|
||||
* Get the AtkHyperlink for this atk object.
|
||||
*/
|
||||
AtkHyperlink* GetAtkHyperlink();
|
||||
|
||||
/*
|
||||
* Shutdown this AtkObject.
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
/*
|
||||
* Notify atk of a state change on this AtkObject.
|
||||
*/
|
||||
void FireStateChangeEvent(uint64_t aState, bool aEnabled);
|
||||
|
||||
/*
|
||||
* Notify ATK of a text change within this ATK object.
|
||||
*/
|
||||
void FireTextChangeEvent(const nsString& aStr, int32_t aStart, uint32_t aLen,
|
||||
bool aIsInsert, bool aIsFromUser);
|
||||
|
||||
private:
|
||||
/*
|
||||
* do we have text-remove and text-insert signals if not we need to use
|
||||
* text-changed see AccessibleWrap::FireAtkTextChangedEvent() and
|
||||
* bug 619002
|
||||
*/
|
||||
enum EAvailableAtkSignals {
|
||||
eUnknown,
|
||||
eHaveNewAtkTextSignals,
|
||||
eNoNewAtkSignals
|
||||
};
|
||||
|
||||
static EAvailableAtkSignals gAvailableAtkSignals;
|
||||
};
|
||||
|
||||
#endif /* __NS_MAI_H__ */
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "nsMaiHyperlink.h"
|
||||
#include "mozilla/a11y/ProxyAccessible.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
@@ -61,8 +62,17 @@ static gint getAnchorCountCB(AtkHyperlink *aLink);
|
||||
G_END_DECLS
|
||||
|
||||
static gpointer parent_class = nullptr;
|
||||
static Accessible*
|
||||
get_accessible_hyperlink(AtkHyperlink *aHyperlink);
|
||||
|
||||
static MaiHyperlink*
|
||||
GetMaiHyperlink(AtkHyperlink *aHyperlink)
|
||||
{
|
||||
NS_ENSURE_TRUE(MAI_IS_ATK_HYPERLINK(aHyperlink), nullptr);
|
||||
MaiHyperlink * maiHyperlink =
|
||||
MAI_ATK_HYPERLINK(aHyperlink)->maiHyperlink;
|
||||
NS_ENSURE_TRUE(maiHyperlink != nullptr, nullptr);
|
||||
NS_ENSURE_TRUE(maiHyperlink->GetAtkHyperlink() == aHyperlink, nullptr);
|
||||
return maiHyperlink;
|
||||
}
|
||||
|
||||
GType
|
||||
mai_atk_hyperlink_get_type(void)
|
||||
@@ -90,60 +100,29 @@ mai_atk_hyperlink_get_type(void)
|
||||
return type;
|
||||
}
|
||||
|
||||
MaiHyperlink::MaiHyperlink(Accessible* aHyperLink) :
|
||||
MaiHyperlink::MaiHyperlink(uintptr_t aHyperLink) :
|
||||
mHyperlink(aHyperLink),
|
||||
mMaiAtkHyperlink(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
MaiHyperlink::~MaiHyperlink()
|
||||
{
|
||||
if (mMaiAtkHyperlink) {
|
||||
MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = nullptr;
|
||||
g_object_unref(mMaiAtkHyperlink);
|
||||
}
|
||||
}
|
||||
|
||||
AtkHyperlink*
|
||||
MaiHyperlink::GetAtkHyperlink(void)
|
||||
{
|
||||
NS_ENSURE_TRUE(mHyperlink, nullptr);
|
||||
|
||||
if (mMaiAtkHyperlink)
|
||||
return mMaiAtkHyperlink;
|
||||
|
||||
if (!mHyperlink->IsLink())
|
||||
return nullptr;
|
||||
|
||||
mMaiAtkHyperlink =
|
||||
reinterpret_cast<AtkHyperlink *>
|
||||
(g_object_new(mai_atk_hyperlink_get_type(), nullptr));
|
||||
NS_ASSERTION(mMaiAtkHyperlink, "OUT OF MEMORY");
|
||||
NS_ENSURE_TRUE(mMaiAtkHyperlink, nullptr);
|
||||
if (!mMaiAtkHyperlink)
|
||||
return;
|
||||
|
||||
/* be sure to initialize it with "this" */
|
||||
MaiHyperlink::Initialize(mMaiAtkHyperlink, this);
|
||||
|
||||
return mMaiAtkHyperlink;
|
||||
MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = this;
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
||||
/* remember to call this static function when a MaiAtkHyperlink
|
||||
* is created
|
||||
*/
|
||||
|
||||
nsresult
|
||||
MaiHyperlink::Initialize(AtkHyperlink *aObj, MaiHyperlink *aHyperlink)
|
||||
MaiHyperlink::~MaiHyperlink()
|
||||
{
|
||||
NS_ENSURE_ARG(MAI_IS_ATK_HYPERLINK(aObj));
|
||||
NS_ENSURE_ARG(aHyperlink);
|
||||
|
||||
/* initialize hyperlink */
|
||||
MAI_ATK_HYPERLINK(aObj)->maiHyperlink = aHyperlink;
|
||||
return NS_OK;
|
||||
if (mMaiAtkHyperlink) {
|
||||
MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = nullptr;
|
||||
g_object_unref(mMaiAtkHyperlink);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* static functions for ATK callbacks */
|
||||
|
||||
void
|
||||
@@ -181,79 +160,102 @@ finalizeCB(GObject *aObj)
|
||||
gchar *
|
||||
getUriCB(AtkHyperlink *aLink, gint aLinkIndex)
|
||||
{
|
||||
Accessible* hyperlink = get_accessible_hyperlink(aLink);
|
||||
NS_ENSURE_TRUE(hyperlink, nullptr);
|
||||
MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
|
||||
if (!maiLink)
|
||||
return nullptr;
|
||||
|
||||
nsAutoCString cautoStr;
|
||||
if (Accessible* hyperlink = maiLink->GetAccHyperlink()) {
|
||||
nsCOMPtr<nsIURI> uri = hyperlink->AnchorURIAt(aLinkIndex);
|
||||
if (!uri)
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
|
||||
nsAutoCString cautoStr;
|
||||
nsresult rv = uri->GetSpec(cautoStr);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
return g_strdup(cautoStr.get());
|
||||
}
|
||||
|
||||
bool valid;
|
||||
maiLink->Proxy()->AnchorURIAt(aLinkIndex, cautoStr, &valid);
|
||||
if (!valid)
|
||||
return nullptr;
|
||||
|
||||
return g_strdup(cautoStr.get());
|
||||
}
|
||||
|
||||
AtkObject *
|
||||
getObjectCB(AtkHyperlink *aLink, gint aLinkIndex)
|
||||
{
|
||||
Accessible* hyperlink = get_accessible_hyperlink(aLink);
|
||||
NS_ENSURE_TRUE(hyperlink, nullptr);
|
||||
MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
|
||||
if (!maiLink)
|
||||
return nullptr;
|
||||
|
||||
Accessible* anchor = hyperlink->AnchorAt(aLinkIndex);
|
||||
NS_ENSURE_TRUE(anchor, nullptr);
|
||||
if (Accessible* hyperlink = maiLink->GetAccHyperlink()) {
|
||||
Accessible* anchor = hyperlink->AnchorAt(aLinkIndex);
|
||||
NS_ENSURE_TRUE(anchor, nullptr);
|
||||
|
||||
AtkObject* atkObj = AccessibleWrap::GetAtkObject(anchor);
|
||||
//no need to add ref it, because it is "get" not "ref"
|
||||
return atkObj;
|
||||
return AccessibleWrap::GetAtkObject(anchor);
|
||||
}
|
||||
|
||||
ProxyAccessible* anchor = maiLink->Proxy()->AnchorAt(aLinkIndex);
|
||||
return anchor ? GetWrapperFor(anchor) : nullptr;
|
||||
}
|
||||
|
||||
gint
|
||||
getEndIndexCB(AtkHyperlink *aLink)
|
||||
{
|
||||
Accessible* hyperlink = get_accessible_hyperlink(aLink);
|
||||
NS_ENSURE_TRUE(hyperlink, -1);
|
||||
MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
|
||||
if (!maiLink)
|
||||
return false;
|
||||
|
||||
if (Accessible* hyperlink = maiLink->GetAccHyperlink())
|
||||
return static_cast<gint>(hyperlink->EndOffset());
|
||||
|
||||
bool valid = false;
|
||||
uint32_t endIdx = maiLink->Proxy()->EndOffset(&valid);
|
||||
return valid ? static_cast<gint>(endIdx) : -1;
|
||||
}
|
||||
|
||||
gint
|
||||
getStartIndexCB(AtkHyperlink *aLink)
|
||||
{
|
||||
Accessible* hyperlink = get_accessible_hyperlink(aLink);
|
||||
NS_ENSURE_TRUE(hyperlink, -1);
|
||||
MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
|
||||
if (maiLink)
|
||||
return -1;
|
||||
|
||||
if (Accessible* hyperlink = maiLink->GetAccHyperlink())
|
||||
return static_cast<gint>(hyperlink->StartOffset());
|
||||
|
||||
bool valid = false;
|
||||
uint32_t startIdx = maiLink->Proxy()->StartOffset(&valid);
|
||||
return valid ? static_cast<gint>(startIdx) : -1;
|
||||
}
|
||||
|
||||
gboolean
|
||||
isValidCB(AtkHyperlink *aLink)
|
||||
{
|
||||
Accessible* hyperlink = get_accessible_hyperlink(aLink);
|
||||
NS_ENSURE_TRUE(hyperlink, FALSE);
|
||||
MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
|
||||
if (!maiLink)
|
||||
return false;
|
||||
|
||||
if (Accessible* hyperlink = maiLink->GetAccHyperlink())
|
||||
return static_cast<gboolean>(hyperlink->IsLinkValid());
|
||||
|
||||
return static_cast<gboolean>(maiLink->Proxy()->IsLinkValid());
|
||||
}
|
||||
|
||||
gint
|
||||
getAnchorCountCB(AtkHyperlink *aLink)
|
||||
{
|
||||
Accessible* hyperlink = get_accessible_hyperlink(aLink);
|
||||
NS_ENSURE_TRUE(hyperlink, -1);
|
||||
MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
|
||||
if (!maiLink)
|
||||
return -1;
|
||||
|
||||
if (Accessible* hyperlink = maiLink->GetAccHyperlink())
|
||||
return static_cast<gint>(hyperlink->AnchorCount());
|
||||
}
|
||||
|
||||
// Check if aHyperlink is a valid MaiHyperlink, and return the
|
||||
// HyperLinkAccessible related.
|
||||
Accessible*
|
||||
get_accessible_hyperlink(AtkHyperlink *aHyperlink)
|
||||
{
|
||||
NS_ENSURE_TRUE(MAI_IS_ATK_HYPERLINK(aHyperlink), nullptr);
|
||||
MaiHyperlink * maiHyperlink =
|
||||
MAI_ATK_HYPERLINK(aHyperlink)->maiHyperlink;
|
||||
NS_ENSURE_TRUE(maiHyperlink != nullptr, nullptr);
|
||||
NS_ENSURE_TRUE(maiHyperlink->GetAtkHyperlink() == aHyperlink, nullptr);
|
||||
return maiHyperlink->GetAccHyperlink();
|
||||
bool valid = false;
|
||||
uint32_t anchorCount = maiLink->Proxy()->AnchorCount(&valid);
|
||||
return valid ? static_cast<gint>(anchorCount) : -1;
|
||||
}
|
||||
|
||||
@@ -23,19 +23,32 @@ namespace a11y {
|
||||
class MaiHyperlink
|
||||
{
|
||||
public:
|
||||
explicit MaiHyperlink(Accessible* aHyperLink);
|
||||
explicit MaiHyperlink(uintptr_t aHyperLink);
|
||||
~MaiHyperlink();
|
||||
|
||||
public:
|
||||
AtkHyperlink *GetAtkHyperlink(void);
|
||||
AtkHyperlink* GetAtkHyperlink() const { return mMaiAtkHyperlink; }
|
||||
Accessible* GetAccHyperlink()
|
||||
{ return mHyperlink && mHyperlink->IsLink() ? mHyperlink : nullptr; }
|
||||
{
|
||||
if (!mHyperlink || mHyperlink & IS_PROXY)
|
||||
return nullptr;
|
||||
|
||||
Accessible* link = reinterpret_cast<Accessible*>(mHyperlink);
|
||||
NS_ASSERTION(link->IsLink(), "Why isn't it a link!");
|
||||
return link;
|
||||
}
|
||||
|
||||
ProxyAccessible* Proxy() const
|
||||
{
|
||||
if (!(mHyperlink & IS_PROXY))
|
||||
return nullptr;
|
||||
|
||||
return reinterpret_cast<ProxyAccessible*>(mHyperlink & ~IS_PROXY);
|
||||
}
|
||||
|
||||
protected:
|
||||
Accessible* mHyperlink;
|
||||
uintptr_t mHyperlink;
|
||||
AtkHyperlink* mMaiAtkHyperlink;
|
||||
public:
|
||||
static nsresult Initialize(AtkHyperlink *aObj, MaiHyperlink *aClass);
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
|
||||
@@ -16,14 +16,13 @@ static AtkHyperlink*
|
||||
getHyperlinkCB(AtkHyperlinkImpl* aImpl)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aImpl));
|
||||
if (!accWrap)
|
||||
if (!accWrap && !GetProxy(ATK_OBJECT(aImpl)))
|
||||
return nullptr;
|
||||
|
||||
NS_ENSURE_TRUE(accWrap->IsLink(), nullptr);
|
||||
if (accWrap)
|
||||
NS_ASSERTION(accWrap->IsLink(), "why isn't it a link!");
|
||||
|
||||
MaiHyperlink* maiHyperlink = accWrap->GetMaiHyperlink();
|
||||
NS_ENSURE_TRUE(maiHyperlink, nullptr);
|
||||
return maiHyperlink->GetAtkHyperlink();
|
||||
return MAI_ATK_OBJECT(aImpl)->GetAtkHyperlink();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,34 +22,27 @@ static AtkHyperlink*
|
||||
getLinkCB(AtkHypertext *aText, gint aLinkIndex)
|
||||
{
|
||||
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
|
||||
AtkObject* atkHyperLink = nullptr;
|
||||
if (accWrap) {
|
||||
HyperTextAccessible* hyperText = accWrap->AsHyperText();
|
||||
NS_ENSURE_TRUE(hyperText, nullptr);
|
||||
|
||||
Accessible* hyperLink = hyperText->LinkAt(aLinkIndex);
|
||||
if (!hyperLink) {
|
||||
if (!hyperLink || !hyperLink->IsLink()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AtkObject* hyperLinkAtkObj = AccessibleWrap::GetAtkObject(hyperLink);
|
||||
AccessibleWrap* accChild = GetAccessibleWrap(hyperLinkAtkObj);
|
||||
NS_ENSURE_TRUE(accChild, nullptr);
|
||||
|
||||
MaiHyperlink* maiHyperlink = accChild->GetMaiHyperlink();
|
||||
NS_ENSURE_TRUE(maiHyperlink, nullptr);
|
||||
return maiHyperlink->GetAtkHyperlink();
|
||||
}
|
||||
|
||||
if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
atkHyperLink = AccessibleWrap::GetAtkObject(hyperLink);
|
||||
} else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
|
||||
ProxyAccessible* proxyLink = proxy->LinkAt(aLinkIndex);
|
||||
if (proxyLink) {
|
||||
NS_WARNING("IMPLEMENT ME! See bug 1146518.");
|
||||
// We should somehow get from ProxyAccessible* to AtkHyperlink*.
|
||||
}
|
||||
return nullptr;
|
||||
if (!proxyLink)
|
||||
return nullptr;
|
||||
|
||||
atkHyperLink = GetWrapperFor(proxyLink);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
NS_ENSURE_TRUE(IS_MAI_OBJECT(atkHyperLink), nullptr);
|
||||
return MAI_ATK_OBJECT(atkHyperLink)->GetAtkHyperlink();
|
||||
}
|
||||
|
||||
static gint
|
||||
|
||||
@@ -194,6 +194,7 @@ public:
|
||||
bool IsTextInserted() const { return mIsInserted; }
|
||||
void GetModifiedText(nsAString& aModifiedText)
|
||||
{ aModifiedText = mModifiedText; }
|
||||
const nsString& ModifiedText() const { return mModifiedText; }
|
||||
|
||||
private:
|
||||
int32_t mStart;
|
||||
|
||||
@@ -455,12 +455,20 @@ DocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
|
||||
ApplicationAcc());
|
||||
|
||||
if (IPCAccessibilityActive()) {
|
||||
DocAccessibleChild* ipcDoc = new DocAccessibleChild(docAcc);
|
||||
docAcc->SetIPCDoc(ipcDoc);
|
||||
nsCOMPtr<nsITabChild> tabChild =
|
||||
do_GetInterface(aDocument->GetDocShell());
|
||||
static_cast<TabChild*>(tabChild.get())->
|
||||
SendPDocAccessibleConstructor(ipcDoc, nullptr, 0);
|
||||
nsIDocShell* docShell = aDocument->GetDocShell();
|
||||
if (docShell) {
|
||||
nsCOMPtr<nsITabChild> tabChild = do_GetInterface(docShell);
|
||||
|
||||
// XXX We may need to handle the case that we don't have a tab child
|
||||
// differently. It may be that this will cause us to fail to notify
|
||||
// the parent process about important accessible documents.
|
||||
if (tabChild) {
|
||||
DocAccessibleChild* ipcDoc = new DocAccessibleChild(docAcc);
|
||||
docAcc->SetIPCDoc(ipcDoc);
|
||||
static_cast<TabChild*>(tabChild.get())->
|
||||
SendPDocAccessibleConstructor(ipcDoc, nullptr, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
parentDocAcc->BindChildDocument(docAcc);
|
||||
|
||||
@@ -480,33 +480,6 @@ EventQueue::CreateTextChangeEventFor(AccMutationEvent* aEvent)
|
||||
aEvent->mIsFromUserInput ? eFromUserInput : eNoUserInput);
|
||||
}
|
||||
|
||||
void
|
||||
EventQueue::SendIPCEvent(AccEvent* aEvent) const
|
||||
{
|
||||
DocAccessibleChild* ipcDoc = mDocument->IPCDoc();
|
||||
uint64_t id = aEvent->GetAccessible()->IsDoc() ? 0 :
|
||||
reinterpret_cast<uintptr_t>(aEvent->GetAccessible());
|
||||
|
||||
switch(aEvent->GetEventType()) {
|
||||
case nsIAccessibleEvent::EVENT_SHOW:
|
||||
ipcDoc->ShowEvent(downcast_accEvent(aEvent));
|
||||
break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_HIDE:
|
||||
ipcDoc->SendHideEvent(id);
|
||||
break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_REORDER:
|
||||
// reorder events on the application acc aren't necessary to tell the parent
|
||||
// about new top level documents.
|
||||
if (!aEvent->GetAccessible()->IsApplication())
|
||||
ipcDoc->SendEvent(id, aEvent->GetEventType());
|
||||
break;
|
||||
default:
|
||||
ipcDoc->SendEvent(id, aEvent->GetEventType());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// EventQueue: event queue
|
||||
|
||||
@@ -583,8 +556,5 @@ EventQueue::ProcessEventQueue()
|
||||
|
||||
if (!mDocument)
|
||||
return;
|
||||
|
||||
if (IPCAccessibilityActive())
|
||||
SendIPCEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,11 +53,6 @@ private:
|
||||
AccSelChangeEvent* aThisEvent,
|
||||
uint32_t aThisIndex);
|
||||
|
||||
/**
|
||||
* Notify the parent process of events being fired by this event queue.
|
||||
*/
|
||||
void SendIPCEvent(AccEvent* aEvent) const;
|
||||
|
||||
/**
|
||||
* Coalesce text change events caused by sibling hide events.
|
||||
*/
|
||||
|
||||
@@ -67,6 +67,9 @@ void ProxyDestroyed(ProxyAccessible*);
|
||||
* Callied when an event is fired on a proxied accessible.
|
||||
*/
|
||||
void ProxyEvent(ProxyAccessible* aTarget, uint32_t aEventType);
|
||||
void ProxyStateChangeEvent(ProxyAccessible* aTarget, uint64_t aState,
|
||||
bool aEnabled);
|
||||
void ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset);
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "ApplicationAccessible.h"
|
||||
#include "nsEventShell.h"
|
||||
#include "nsTextEquivUtils.h"
|
||||
#include "DocAccessibleChild.h"
|
||||
#include "Relation.h"
|
||||
#include "Role.h"
|
||||
#include "RootAccessible.h"
|
||||
@@ -832,6 +833,42 @@ Accessible::HandleAccEvent(AccEvent* aEvent)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEvent);
|
||||
|
||||
if (IPCAccessibilityActive() && Document()) {
|
||||
DocAccessibleChild* ipcDoc = mDoc->IPCDoc();
|
||||
uint64_t id = aEvent->GetAccessible()->IsDoc() ? 0 :
|
||||
reinterpret_cast<uintptr_t>(aEvent->GetAccessible());
|
||||
|
||||
switch(aEvent->GetEventType()) {
|
||||
case nsIAccessibleEvent::EVENT_SHOW:
|
||||
ipcDoc->ShowEvent(downcast_accEvent(aEvent));
|
||||
break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_HIDE:
|
||||
ipcDoc->SendHideEvent(id);
|
||||
break;
|
||||
|
||||
case nsIAccessibleEvent::EVENT_REORDER:
|
||||
// reorder events on the application acc aren't necessary to tell the parent
|
||||
// about new top level documents.
|
||||
if (!aEvent->GetAccessible()->IsApplication())
|
||||
ipcDoc->SendEvent(id, aEvent->GetEventType());
|
||||
break;
|
||||
case nsIAccessibleEvent::EVENT_STATE_CHANGE: {
|
||||
AccStateChangeEvent* event = downcast_accEvent(aEvent);
|
||||
ipcDoc->SendStateChangeEvent(id, event->GetState(),
|
||||
event->IsStateEnabled());
|
||||
break;
|
||||
}
|
||||
case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED: {
|
||||
AccCaretMoveEvent* event = downcast_accEvent(aEvent);
|
||||
ipcDoc->SendEvent(id, event->GetCaretOffset());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ipcDoc->SendEvent(id, aEvent->GetEventType());
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
|
||||
NS_ENSURE_TRUE(obsService, NS_ERROR_FAILURE);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ class HTMLLIAccessible;
|
||||
class HyperTextAccessible;
|
||||
class ImageAccessible;
|
||||
class KeyBinding;
|
||||
class OuterDocAccessible;
|
||||
class ProxyAccessible;
|
||||
class Relation;
|
||||
class RootAccessible;
|
||||
@@ -619,6 +620,9 @@ public:
|
||||
return mBits.proxy;
|
||||
}
|
||||
|
||||
bool IsOuterDoc() const { return mType == eOuterDocType; }
|
||||
OuterDocAccessible* AsOuterDoc();
|
||||
|
||||
bool IsProgress() const { return mType == eProgressType; }
|
||||
|
||||
bool IsRoot() const { return mType == eRootType; }
|
||||
|
||||
@@ -336,6 +336,12 @@ public:
|
||||
*/
|
||||
void RecreateAccessible(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* 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; }
|
||||
|
||||
protected:
|
||||
virtual ~DocAccessible();
|
||||
|
||||
@@ -519,12 +525,6 @@ protected:
|
||||
*/
|
||||
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.
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "Accessible-inl.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "DocAccessible-inl.h"
|
||||
#include "mozilla/a11y/DocAccessibleParent.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "Role.h"
|
||||
#include "States.h"
|
||||
|
||||
@@ -26,6 +28,7 @@ OuterDocAccessible::
|
||||
OuterDocAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
AccessibleWrap(aContent, aDoc)
|
||||
{
|
||||
mType = eOuterDocType;
|
||||
}
|
||||
|
||||
OuterDocAccessible::~OuterDocAccessible()
|
||||
@@ -181,3 +184,24 @@ OuterDocAccessible::CacheChildren()
|
||||
GetAccService()->GetDocAccessible(innerDoc);
|
||||
}
|
||||
}
|
||||
|
||||
ProxyAccessible*
|
||||
OuterDocAccessible::RemoteChildDoc() const
|
||||
{
|
||||
dom::TabParent* tab = dom::TabParent::GetFrom(GetContent());
|
||||
if (!tab)
|
||||
return nullptr;
|
||||
|
||||
// XXX Consider managing non top level remote documents with there parent
|
||||
// document.
|
||||
const nsTArray<PDocAccessibleParent*>& docs = tab->ManagedPDocAccessibleParent();
|
||||
size_t docCount = docs.Length();
|
||||
for (size_t i = 0; i < docCount; i++) {
|
||||
auto doc = static_cast<DocAccessibleParent*>(docs[i]);
|
||||
if (!doc->ParentDoc())
|
||||
return doc;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(false, "no top level tab document?");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
class ProxyAccessible;
|
||||
|
||||
/**
|
||||
* Used for <browser>, <frame>, <iframe>, <page> or editor> elements.
|
||||
@@ -27,6 +28,8 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
ProxyAccessible* RemoteChildDoc() const;
|
||||
|
||||
// Accessible
|
||||
virtual void Shutdown() override;
|
||||
virtual mozilla::a11y::role NativeRole() override;
|
||||
@@ -44,6 +47,11 @@ protected:
|
||||
virtual void CacheChildren() override;
|
||||
};
|
||||
|
||||
inline OuterDocAccessible*
|
||||
Accessible::AsOuterDoc()
|
||||
{
|
||||
return IsOuterDoc() ? static_cast<OuterDocAccessible*>(this) : nullptr;
|
||||
}
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
@@ -141,6 +141,30 @@ DocAccessibleParent::RecvEvent(const uint64_t& aID, const uint32_t& aEventType)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleParent::RecvStateChangeEvent(const uint64_t& aID,
|
||||
const uint64_t& aState,
|
||||
const bool& aEnabled)
|
||||
{
|
||||
ProxyAccessible* target = GetAccessible(aID);
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
ProxyStateChangeEvent(target, aState, aEnabled);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleParent::RecvCaretMoveEvent(const uint64_t& aID, const int32_t& aOffset)
|
||||
{
|
||||
ProxyAccessible* proxy = GetAccessible(aID);
|
||||
if (!proxy)
|
||||
return false;
|
||||
|
||||
ProxyCaretMoveEvent(proxy, aOffset);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleParent::RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID)
|
||||
{
|
||||
|
||||
@@ -48,6 +48,12 @@ public:
|
||||
|
||||
virtual bool RecvShowEvent(const ShowEventData& aData) override;
|
||||
virtual bool RecvHideEvent(const uint64_t& aRootID) override;
|
||||
virtual bool RecvStateChangeEvent(const uint64_t& aID,
|
||||
const uint64_t& aState,
|
||||
const bool& aEnabled) override final;
|
||||
|
||||
virtual bool RecvCaretMoveEvent(const uint64_t& aID, const int32_t& aOffset)
|
||||
override final;
|
||||
|
||||
virtual bool RecvBindChildDoc(PDocAccessibleParent* aChildDoc, const uint64_t& aID) override;
|
||||
void Unbind()
|
||||
|
||||
@@ -57,6 +57,8 @@ parent:
|
||||
Event(uint64_t aID, uint32_t type);
|
||||
ShowEvent(ShowEventData data);
|
||||
HideEvent(uint64_t aRootID);
|
||||
StateChangeEvent(uint64_t aID, uint64_t aState, bool aEnabled);
|
||||
CaretMoveEvent(uint64_t aID, int32_t aOffset);
|
||||
|
||||
/*
|
||||
* Tell the parent document to bind the existing document as a new child
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
#include "ProxyAccessible.h"
|
||||
#include "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"
|
||||
@@ -992,5 +996,19 @@ ProxyAccessible::URLDocTypeMimeType(nsString& aURL, nsString& aDocType,
|
||||
unused << mDoc->SendURLDocTypeMimeType(mID, &aURL, &aDocType, &aMimeType);
|
||||
}
|
||||
|
||||
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());
|
||||
NS_ASSERTION(chromeDoc, "accessible tab in not accessible chromeDocument");
|
||||
|
||||
return chromeDoc ? chromeDoc->GetAccessible(frame) : nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class Accessible;
|
||||
class Attribute;
|
||||
class DocAccessibleParent;
|
||||
enum class RelationType;
|
||||
@@ -66,6 +67,8 @@ public:
|
||||
*/
|
||||
ProxyAccessible* Parent() const { return mParent; }
|
||||
|
||||
Accessible* OuterDocOfRemoteBrowser() const;
|
||||
|
||||
/**
|
||||
* Get the role of the accessible we're proxying.
|
||||
*/
|
||||
|
||||
@@ -47,6 +47,16 @@ void
|
||||
ProxyEvent(ProxyAccessible*, uint32_t)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProxyStateChangeEvent(ProxyAccessible*, uint64_t, bool)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,3 +33,13 @@ void
|
||||
a11y::ProxyEvent(ProxyAccessible*, uint32_t)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
a11y::ProxyStateChangeEvent(ProxyAccessible*, uint64_t, bool)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
a11y::ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -58,3 +58,13 @@ void
|
||||
a11y::ProxyEvent(ProxyAccessible*, uint32_t)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
a11y::ProxyStateChangeEvent(ProxyAccessible*, uint64_t, bool)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
a11y::ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -9,9 +9,6 @@ fi
|
||||
## SDK redist ##
|
||||
export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x86/Microsoft.VC100.CRT
|
||||
|
||||
## moz tools location for 64-bit builders ##
|
||||
export MOZ_TOOLS=C:/mozilla-build/moztools
|
||||
|
||||
## includes: win8 sdk includes, msvc 10 std library, directx sdk for d3d9 ##
|
||||
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
|
||||
|
||||
@@ -32,5 +29,3 @@ mk_export_correct_style LIBPATH
|
||||
mk_export_correct_style PATH
|
||||
mk_export_correct_style INCLUDE
|
||||
mk_export_correct_style WIN32_REDIST_DIR
|
||||
|
||||
mk_add_options "export MOZ_TOOLS=$MOZ_TOOLS"
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
_VSPATH="/c/tools/vs2013"
|
||||
export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x86/Microsoft.VC120.CRT
|
||||
|
||||
## moz tools location for 64-bit builders ##
|
||||
export MOZ_TOOLS=C:/mozilla-build/moztools
|
||||
|
||||
## includes: win8.1 sdk includes, msvc std library, directx sdk for d3d9 ##
|
||||
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/um:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
|
||||
|
||||
@@ -24,5 +21,3 @@ mk_export_correct_style LIBPATH
|
||||
mk_export_correct_style PATH
|
||||
mk_export_correct_style INCLUDE
|
||||
mk_export_correct_style WIN32_REDIST_DIR
|
||||
|
||||
mk_add_options "export MOZ_TOOLS=$MOZ_TOOLS"
|
||||
|
||||
@@ -2330,22 +2330,6 @@ ia64*-hpux*)
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$host" in
|
||||
*-mingw*)
|
||||
if test -z "$MOZ_TOOLS"; then
|
||||
AC_MSG_ERROR([MOZ_TOOLS is not set])
|
||||
fi
|
||||
MOZ_TOOLS_DIR=`cd $MOZ_TOOLS && pwd -W`
|
||||
if test "$?" != "0" -o -z "$MOZ_TOOLS_DIR"; then
|
||||
AC_MSG_ERROR([cd \$MOZ_TOOLS failed. MOZ_TOOLS ==? $MOZ_TOOLS])
|
||||
fi
|
||||
MOZ_TOOLS_BIN_DIR="$(cd "$MOZ_TOOLS_DIR/bin" && pwd)"
|
||||
if test `echo ${PATH}: | grep -ic "$MOZ_TOOLS_BINDIR:"` = 0; then
|
||||
AC_MSG_ERROR([\$MOZ_TOOLS\\bin must be in your path.])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$host_os" in
|
||||
cygwin*|msvc*|mks*)
|
||||
AC_MSG_ERROR([Using a Cygwin build environment is unsupported. Configure cannot check for presence of necessary headers. Please upgrade to MozillaBuild; see https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
|
||||
@@ -8371,7 +8355,6 @@ fi
|
||||
|
||||
dnl win32 options
|
||||
AC_SUBST(MOZ_BROWSE_INFO)
|
||||
AC_SUBST(MOZ_TOOLS_DIR)
|
||||
AC_SUBST(WIN32_REDIST_DIR)
|
||||
AC_SUBST(MAKENSISU)
|
||||
|
||||
|
||||
@@ -129,6 +129,14 @@ GetBuildConfiguration(JSContext* cx, unsigned argc, Value* vp)
|
||||
if (!JS_SetProperty(cx, info, "asan", value))
|
||||
return false;
|
||||
|
||||
#ifdef MOZ_TSAN
|
||||
value = BooleanValue(true);
|
||||
#else
|
||||
value = BooleanValue(false);
|
||||
#endif
|
||||
if (!JS_SetProperty(cx, info, "tsan", value))
|
||||
return false;
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
value = BooleanValue(true);
|
||||
#else
|
||||
|
||||
@@ -1860,22 +1860,6 @@ ia64*-hpux*)
|
||||
no_x=yes
|
||||
AC_DEFINE(NO_X11)
|
||||
|
||||
case "$host" in
|
||||
*-mingw*)
|
||||
if test -z "$MOZ_TOOLS"; then
|
||||
AC_MSG_ERROR([MOZ_TOOLS is not set])
|
||||
fi
|
||||
MOZ_TOOLS_DIR=`cd $MOZ_TOOLS && pwd -W`
|
||||
if test "$?" != "0" -o -z "$MOZ_TOOLS_DIR"; then
|
||||
AC_MSG_ERROR([cd \$MOZ_TOOLS failed. MOZ_TOOLS ==? $MOZ_TOOLS])
|
||||
fi
|
||||
MOZ_TOOLS_BIN_DIR="$(cd "$MOZ_TOOLS_DIR/bin" && pwd)"
|
||||
if test `echo ${PATH}: | grep -ic "$MOZ_TOOLS_BINDIR:"` = 0; then
|
||||
AC_MSG_ERROR([\$MOZ_TOOLS\\bin must be in your path.])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$host_os" in
|
||||
cygwin*|msvc*|mks*)
|
||||
AC_MSG_ERROR([Using a Cygwin build environment is unsupported. Configure cannot check for presence of necessary headers. Please upgrade to MozillaBuild; see https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
|
||||
@@ -3715,7 +3699,6 @@ AC_SUBST(MOZILLA_OFFICIAL)
|
||||
|
||||
dnl win32 options
|
||||
AC_SUBST(MOZ_BROWSE_INFO)
|
||||
AC_SUBST(MOZ_TOOLS_DIR)
|
||||
|
||||
dnl Echo the CFLAGS to remove extra whitespace.
|
||||
CFLAGS=`echo \
|
||||
|
||||
Reference in New Issue
Block a user