зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1322532: Platform a11y changes to enable handler-based live regions; r=tbsaunde
MozReview-Commit-ID: nNPvBy3ZGO --HG-- extra : rebase_source : d8a797c9ddfb3d8ab4f13c9f2f261fba04320beb extra : histedit_source : cc4f0bd8ba26cc88bcf9907f684e5d6c240d354f
This commit is contained in:
Родитель
1de2299a3a
Коммит
0ee7073299
|
@ -338,6 +338,21 @@ DocAccessibleParent::RecvTextChangeEvent(const uint64_t& aID,
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
|
||||||
|
mozilla::ipc::IPCResult
|
||||||
|
DocAccessibleParent::RecvSyncTextChangeEvent(const uint64_t& aID,
|
||||||
|
const nsString& aStr,
|
||||||
|
const int32_t& aStart,
|
||||||
|
const uint32_t& aLen,
|
||||||
|
const bool& aIsInsert,
|
||||||
|
const bool& aFromUser)
|
||||||
|
{
|
||||||
|
return RecvTextChangeEvent(aID, aStr, aStart, aLen, aIsInsert, aFromUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
mozilla::ipc::IPCResult
|
mozilla::ipc::IPCResult
|
||||||
DocAccessibleParent::RecvSelectionEvent(const uint64_t& aID,
|
DocAccessibleParent::RecvSelectionEvent(const uint64_t& aID,
|
||||||
const uint64_t& aWidgetID,
|
const uint64_t& aWidgetID,
|
||||||
|
|
|
@ -88,6 +88,13 @@ public:
|
||||||
const bool& aIsInsert,
|
const bool& aIsInsert,
|
||||||
const bool& aFromUser) override;
|
const bool& aFromUser) override;
|
||||||
|
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
virtual mozilla::ipc::IPCResult RecvSyncTextChangeEvent(const uint64_t& aID, const nsString& aStr,
|
||||||
|
const int32_t& aStart, const uint32_t& aLen,
|
||||||
|
const bool& aIsInsert,
|
||||||
|
const bool& aFromUser) override;
|
||||||
|
#endif // defined(XP_WIN)
|
||||||
|
|
||||||
virtual mozilla::ipc::IPCResult RecvSelectionEvent(const uint64_t& aID,
|
virtual mozilla::ipc::IPCResult RecvSelectionEvent(const uint64_t& aID,
|
||||||
const uint64_t& aWidgetID,
|
const uint64_t& aWidgetID,
|
||||||
const uint32_t& aType) override;
|
const uint32_t& aType) override;
|
||||||
|
|
|
@ -190,6 +190,13 @@ DocAccessibleChild::SendTextChangeEvent(const uint64_t& aID,
|
||||||
const bool& aFromUser)
|
const bool& aFromUser)
|
||||||
{
|
{
|
||||||
if (IsConstructedInParentProcess()) {
|
if (IsConstructedInParentProcess()) {
|
||||||
|
if (aStr.Contains(L'\xfffc')) {
|
||||||
|
// The AT is going to need to reenter content while the event is being
|
||||||
|
// dispatched synchronously.
|
||||||
|
return PDocAccessibleChild::SendSyncTextChangeEvent(aID, aStr, aStart,
|
||||||
|
aLen, aIsInsert,
|
||||||
|
aFromUser);
|
||||||
|
}
|
||||||
return PDocAccessibleChild::SendTextChangeEvent(aID, aStr, aStart,
|
return PDocAccessibleChild::SendTextChangeEvent(aID, aStr, aStart,
|
||||||
aLen, aIsInsert, aFromUser);
|
aLen, aIsInsert, aFromUser);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "nsArrayUtils.h"
|
#include "nsArrayUtils.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "nsIXULRuntime.h"
|
#include "nsIXULRuntime.h"
|
||||||
|
#include "mozilla/mscom/AsyncInvoker.h"
|
||||||
|
|
||||||
#include "oleacc.h"
|
#include "oleacc.h"
|
||||||
|
|
||||||
|
@ -1627,3 +1628,60 @@ AccessibleWrap::SetHandlerControl(DWORD aPid, RefPtr<IHandlerControl> aCtrl)
|
||||||
sHandlerControllers->AppendElement(Move(ctrlData));
|
sHandlerControllers->AppendElement(Move(ctrlData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AccessibleWrap::DispatchTextChangeToHandler(bool aIsInsert,
|
||||||
|
const nsString& aText,
|
||||||
|
int32_t aStart, uint32_t aLen)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(XRE_IsParentProcess());
|
||||||
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (!sHandlerControllers || sHandlerControllers->IsEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND hwnd = GetHWNDFor(this);
|
||||||
|
MOZ_ASSERT(hwnd);
|
||||||
|
if (!hwnd) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
long msaaId = GetChildIDFor(this);
|
||||||
|
|
||||||
|
DWORD ourPid = ::GetCurrentProcessId();
|
||||||
|
|
||||||
|
// The handler ends up calling NotifyWinEvent, which should only be done once
|
||||||
|
// since it broadcasts the same event to every process who is subscribed.
|
||||||
|
// OTOH, if our chrome process contains a handler, we should prefer to
|
||||||
|
// broadcast the event from that process, as we want any DLLs injected by ATs
|
||||||
|
// to receive the event synchronously. Otherwise we simply choose the first
|
||||||
|
// handler in the list, for the lack of a better heuristic.
|
||||||
|
|
||||||
|
nsTArray<HandlerControllerData>::index_type ctrlIndex =
|
||||||
|
sHandlerControllers->IndexOf(ourPid);
|
||||||
|
|
||||||
|
if (ctrlIndex == nsTArray<HandlerControllerData>::NoIndex) {
|
||||||
|
ctrlIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandlerControllerData& controller = sHandlerControllers->ElementAt(ctrlIndex);
|
||||||
|
MOZ_ASSERT(controller.mPid);
|
||||||
|
MOZ_ASSERT(controller.mCtrl);
|
||||||
|
|
||||||
|
VARIANT_BOOL isInsert = aIsInsert ? VARIANT_TRUE : VARIANT_FALSE;
|
||||||
|
|
||||||
|
IA2TextSegment textSegment{::SysAllocStringLen(aText.get(), aText.Length()),
|
||||||
|
aStart, static_cast<long>(aLen)};
|
||||||
|
|
||||||
|
ASYNC_INVOKER_FOR(IHandlerControl) invoker(controller.mCtrl,
|
||||||
|
Some(controller.mIsProxy));
|
||||||
|
|
||||||
|
HRESULT hr = ASYNC_INVOKE(invoker, OnTextChange, PtrToLong(hwnd), msaaId,
|
||||||
|
isInsert, &textSegment);
|
||||||
|
|
||||||
|
::SysFreeString(textSegment.text);
|
||||||
|
|
||||||
|
return SUCCEEDED(hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -192,6 +192,8 @@ public: // construction, destruction
|
||||||
|
|
||||||
static void SetHandlerControl(DWORD aPid, RefPtr<IHandlerControl> aCtrl);
|
static void SetHandlerControl(DWORD aPid, RefPtr<IHandlerControl> aCtrl);
|
||||||
|
|
||||||
|
bool DispatchTextChangeToHandler(bool aIsInsert, const nsString& aText,
|
||||||
|
int32_t aStart, uint32_t aLen);
|
||||||
protected:
|
protected:
|
||||||
virtual ~AccessibleWrap();
|
virtual ~AccessibleWrap();
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,14 @@ a11y::ProxyTextChangeEvent(ProxyAccessible* aText, const nsString& aStr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const bool useHandler =
|
||||||
|
Preferences::GetBool("accessibility.handler.enabled", false);
|
||||||
|
|
||||||
|
if (useHandler) {
|
||||||
|
wrapper->DispatchTextChangeToHandler(aInsert, aStr, aStart, aLen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto text = static_cast<HyperTextAccessibleWrap*>(wrapper->AsHyperText());
|
auto text = static_cast<HyperTextAccessibleWrap*>(wrapper->AsHyperText());
|
||||||
if (text) {
|
if (text) {
|
||||||
ia2AccessibleText::UpdateTextChangeData(text, aInsert, aStr, aStart, aLen);
|
ia2AccessibleText::UpdateTextChangeData(text, aInsert, aStr, aStart, aLen);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче