зеркало из 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();
|
||||
}
|
||||
|
||||
#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
|
||||
DocAccessibleParent::RecvSelectionEvent(const uint64_t& aID,
|
||||
const uint64_t& aWidgetID,
|
||||
|
|
|
@ -88,6 +88,13 @@ public:
|
|||
const bool& aIsInsert,
|
||||
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,
|
||||
const uint64_t& aWidgetID,
|
||||
const uint32_t& aType) override;
|
||||
|
|
|
@ -190,6 +190,13 @@ DocAccessibleChild::SendTextChangeEvent(const uint64_t& aID,
|
|||
const bool& aFromUser)
|
||||
{
|
||||
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,
|
||||
aLen, aIsInsert, aFromUser);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsArrayUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
#include "mozilla/mscom/AsyncInvoker.h"
|
||||
|
||||
#include "oleacc.h"
|
||||
|
||||
|
@ -1627,3 +1628,60 @@ AccessibleWrap::SetHandlerControl(DWORD aPid, RefPtr<IHandlerControl> aCtrl)
|
|||
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);
|
||||
|
||||
bool DispatchTextChangeToHandler(bool aIsInsert, const nsString& aText,
|
||||
int32_t aStart, uint32_t aLen);
|
||||
protected:
|
||||
virtual ~AccessibleWrap();
|
||||
|
||||
|
|
|
@ -132,6 +132,14 @@ a11y::ProxyTextChangeEvent(ProxyAccessible* aText, const nsString& aStr,
|
|||
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());
|
||||
if (text) {
|
||||
ia2AccessibleText::UpdateTextChangeData(text, aInsert, aStr, aStart, aLen);
|
||||
|
|
Загрузка…
Ссылка в новой задаче