Bug 1949920: Expose the UIA Text pattern on text leaves. Don't expose it on the root. r=nlapre
We need to support the Text pattern on text leaves to fix issues with Narrator. Removing support on the root isn't strictly necessary, but the Text pattern isn't normally supported on a UIA Window and Chromium doesn't do this, so I think it's best to follow. This change necessitated moving UiaText so that it is no longer inherited by ia2AccessibleHypertext. I initially tried to inherit UiaText into uiaRawElmProvider, but that doesn't work because ITextProvider and ISelectionProvider both have a GetSelection method with the same signature. This meant that the ISelectionProvider implementation of GetSelection in uiaRawElmProvider was overriding the implementation in UiaText. Instead, UiaText has now been split into a separate object. Differential Revision: https://phabricator.services.mozilla.com/D239811
This commit is contained in:
@@ -41,8 +41,6 @@ ia2AccessibleHypertext::QueryInterface(REFIID aIID, void** aInstancePtr) {
|
||||
*aInstancePtr = static_cast<IAccessibleEditableText*>(this);
|
||||
} else if (aIID == IID_IAccessibleTextSelectionContainer) {
|
||||
*aInstancePtr = static_cast<IAccessibleTextSelectionContainer*>(this);
|
||||
} else if (aIID == IID_ITextProvider) {
|
||||
*aInstancePtr = static_cast<ITextProvider*>(this);
|
||||
}
|
||||
|
||||
if (*aInstancePtr) {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "AccessibleHypertext2.h"
|
||||
#include "IUnknownImpl.h"
|
||||
#include "MsaaAccessible.h"
|
||||
#include "UiaText.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
@@ -26,13 +25,8 @@ class ia2AccessibleHypertext : public ia2AccessibleText,
|
||||
public IAccessibleHypertext2,
|
||||
public ia2AccessibleEditableText,
|
||||
public ia2AccessibleTextSelectionContainer,
|
||||
public UiaText,
|
||||
public MsaaAccessible {
|
||||
public:
|
||||
// UiaText has a private Acc() method. Explicitly specify what
|
||||
// ia2AccessibleHypertext::Acc should use.
|
||||
using MsaaAccessible::Acc;
|
||||
|
||||
// IUnknown
|
||||
DECL_IUNKNOWN_INHERITED
|
||||
IMPL_IUNKNOWN_REFCOUNTING_INHERITED(MsaaAccessible)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "UiaText.h"
|
||||
|
||||
#include "ia2AccessibleHypertext.h"
|
||||
#include "MsaaAccessible.h"
|
||||
#include "mozilla/a11y/States.h"
|
||||
#include "TextLeafRange.h"
|
||||
#include "UiaTextRange.h"
|
||||
@@ -34,12 +34,14 @@ static SAFEARRAY* TextLeafRangesToUiaRanges(
|
||||
return uiaRanges;
|
||||
}
|
||||
|
||||
// IUnknown
|
||||
IMPL_IUNKNOWN1(UiaText, ITextProvider)
|
||||
|
||||
// UiaText
|
||||
|
||||
Accessible* UiaText::Acc() const {
|
||||
auto* hyp = static_cast<const ia2AccessibleHypertext*>(this);
|
||||
return hyp->Acc();
|
||||
}
|
||||
UiaText::UiaText(MsaaAccessible* aMsaa) : mMsaa(aMsaa) {}
|
||||
|
||||
Accessible* UiaText::Acc() const { return mMsaa->Acc(); }
|
||||
|
||||
// ITextProvider methods
|
||||
|
||||
|
||||
@@ -10,13 +10,24 @@
|
||||
#include "objbase.h"
|
||||
#include "uiautomation.h"
|
||||
|
||||
#include "IUnknownImpl.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla::a11y {
|
||||
class Accessible;
|
||||
class MsaaAccessible;
|
||||
|
||||
/**
|
||||
* ITextProvider implementation.
|
||||
*/
|
||||
class UiaText : public ITextProvider {
|
||||
public:
|
||||
explicit UiaText(MsaaAccessible* aMsaa);
|
||||
|
||||
// IUnknown
|
||||
DECL_IUNKNOWN
|
||||
|
||||
// ITextProvider
|
||||
virtual HRESULT STDMETHODCALLTYPE GetSelection(
|
||||
/* [retval][out] */ __RPC__deref_out_opt SAFEARRAY** aRetVal);
|
||||
@@ -39,7 +50,10 @@ class UiaText : public ITextProvider {
|
||||
/* [retval][out] */ __RPC__out enum SupportedTextSelection* aRetVal);
|
||||
|
||||
private:
|
||||
virtual ~UiaText() = default;
|
||||
Accessible* Acc() const;
|
||||
|
||||
RefPtr<MsaaAccessible> mMsaa;
|
||||
};
|
||||
|
||||
} // namespace mozilla::a11y
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "Relation.h"
|
||||
#include "RootAccessible.h"
|
||||
#include "TextLeafRange.h"
|
||||
#include "UiaText.h"
|
||||
#include "UiaTextRange.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@@ -100,10 +101,17 @@ static void MaybeRaiseUiaLiveRegionEvent(Accessible* aAcc,
|
||||
}
|
||||
|
||||
static bool HasTextPattern(Accessible* aAcc) {
|
||||
// Only documents and editable text controls should have the Text pattern.
|
||||
// The Text pattern must be supported for documents and editable text controls
|
||||
// on the web:
|
||||
// https://learn.microsoft.com/en-us/windows/win32/winauto/uiauto-textpattern-and-embedded-objects-overview#webpage-and-text-input-controls-in-edge
|
||||
// It is also recommended that the Text pattern be supported for the Text
|
||||
// control type:
|
||||
// https://learn.microsoft.com/en-us/windows/win32/winauto/uiauto-about-text-and-textrange-patterns#control-types
|
||||
// If we don't support this for the Text control type, when Narrator is
|
||||
// continuously reading a document, it doesn't respect the starting position
|
||||
// of the cursor and doesn't move the cursor as it reads. See bug 1949920.
|
||||
constexpr uint64_t editableRootStates = states::EDITABLE | states::FOCUSABLE;
|
||||
return aAcc->IsDoc() ||
|
||||
return aAcc->IsText() || (aAcc->IsDoc() && !aAcc->IsRoot()) ||
|
||||
(aAcc->IsHyperText() &&
|
||||
(aAcc->State() & editableRootStates) == editableRootStates);
|
||||
}
|
||||
@@ -463,8 +471,8 @@ uiaRawElmProvider::GetPatternProvider(
|
||||
return S_OK;
|
||||
case UIA_TextPatternId:
|
||||
if (HasTextPattern(acc)) {
|
||||
auto text =
|
||||
GetPatternFromDerived<ia2AccessibleHypertext, ITextProvider>();
|
||||
RefPtr<ITextProvider> text =
|
||||
new UiaText(static_cast<MsaaAccessible*>(this));
|
||||
text.forget(aPatternProvider);
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
Reference in New Issue
Block a user