From debfb84ee98d246bca234fcf38250104384da597 Mon Sep 17 00:00:00 2001 From: Eitan Isaacson Date: Thu, 10 Sep 2020 21:52:35 +0000 Subject: [PATCH] Bug 1661758 - Part 4: Implement AXUIElementForTextMarker. r=morgan Differential Revision: https://phabricator.services.mozilla.com/D89066 --- .../mac/DocAccessiblePlatformExtChild.cpp | 11 +++++++++ accessible/mac/GeckoTextMarker.h | 2 ++ accessible/mac/GeckoTextMarker.mm | 15 ++++++++++++ accessible/mac/HyperTextAccessibleWrap.h | 2 ++ accessible/mac/HyperTextAccessibleWrap.mm | 23 +++++++++++++++++++ accessible/mac/MOXAccessibleProtocol.h | 3 +++ accessible/mac/MOXTextMarkerDelegate.h | 3 +++ accessible/mac/MOXTextMarkerDelegate.mm | 9 ++++++++ 8 files changed, 68 insertions(+) diff --git a/accessible/ipc/extension/mac/DocAccessiblePlatformExtChild.cpp b/accessible/ipc/extension/mac/DocAccessiblePlatformExtChild.cpp index 7e526b5bb2c4..989f929de2e3 100644 --- a/accessible/ipc/extension/mac/DocAccessiblePlatformExtChild.cpp +++ b/accessible/ipc/extension/mac/DocAccessiblePlatformExtChild.cpp @@ -182,6 +182,17 @@ mozilla::ipc::IPCResult DocAccessiblePlatformExtChild::RecvRangeOfChild( mozilla::ipc::IPCResult DocAccessiblePlatformExtChild::RecvLeafAtOffset( const uint64_t& aID, const int32_t& aOffset, uint64_t* aLeaf) { + HyperTextAccessibleWrap* acc = IdToHyperTextAccessibleWrap(aID); + if (!acc) { + return IPC_OK(); + } + + Accessible* leaf = acc->LeafAtOffset(aOffset); + + MOZ_ASSERT(!leaf || leaf->Document() == acc->Document()); + + *aLeaf = UNIQUE_ID(leaf); + return IPC_OK(); } diff --git a/accessible/mac/GeckoTextMarker.h b/accessible/mac/GeckoTextMarker.h index f760e1d51a0a..0be436e1f005 100644 --- a/accessible/mac/GeckoTextMarker.h +++ b/accessible/mac/GeckoTextMarker.h @@ -45,6 +45,8 @@ class GeckoTextMarker final { // Return a word range right of the given offset. GeckoTextMarkerRange RightWordRange(); + AccessibleOrProxy Leaf(); + bool IsValid() const { return !mContainer.IsNull(); }; bool operator<(const GeckoTextMarker& aPoint) const; diff --git a/accessible/mac/GeckoTextMarker.mm b/accessible/mac/GeckoTextMarker.mm index deb0c440cbbc..0da208adb2a2 100644 --- a/accessible/mac/GeckoTextMarker.mm +++ b/accessible/mac/GeckoTextMarker.mm @@ -269,6 +269,21 @@ GeckoTextMarkerRange GeckoTextMarker::RightWordRange() { return GeckoTextMarkerRange(GeckoTextMarker(), GeckoTextMarker()); } +AccessibleOrProxy GeckoTextMarker::Leaf() { + MOZ_ASSERT(!mContainer.IsNull()); + if (mContainer.IsProxy()) { + uint64_t leafID = 0; + DocAccessibleParent* ipcDoc = mContainer.AsProxy()->Document(); + Unused << ipcDoc->GetPlatformExtension()->SendLeafAtOffset( + mContainer.AsProxy()->ID(), mOffset, &leafID); + return ipcDoc->GetAccessible(leafID); + } else if (auto htWrap = ContainerAsHyperTextWrap()) { + return htWrap->LeafAtOffset(mOffset); + } + + return mContainer; +} + // GeckoTextMarkerRange GeckoTextMarkerRange::GeckoTextMarkerRange( diff --git a/accessible/mac/HyperTextAccessibleWrap.h b/accessible/mac/HyperTextAccessibleWrap.h index 527523f9b407..4399713c3ef3 100644 --- a/accessible/mac/HyperTextAccessibleWrap.h +++ b/accessible/mac/HyperTextAccessibleWrap.h @@ -49,6 +49,8 @@ class HyperTextAccessibleWrap : public HyperTextAccessible { void RangeOfChild(Accessible* aChild, int32_t* aStartOffset, int32_t* aEndOffset); + Accessible* LeafAtOffset(int32_t aOffset); + protected: ~HyperTextAccessibleWrap() {} diff --git a/accessible/mac/HyperTextAccessibleWrap.mm b/accessible/mac/HyperTextAccessibleWrap.mm index 8dee6f1989c9..044e313382b4 100644 --- a/accessible/mac/HyperTextAccessibleWrap.mm +++ b/accessible/mac/HyperTextAccessibleWrap.mm @@ -365,6 +365,29 @@ void HyperTextAccessibleWrap::RangeOfChild(Accessible* aChild, } } +Accessible* HyperTextAccessibleWrap::LeafAtOffset(int32_t aOffset) { + HyperTextAccessible* text = this; + Accessible* child = nullptr; + int32_t innerOffset = aOffset; + do { + int32_t childIdx = text->GetChildIndexAtOffset(innerOffset); + if (childIdx == -1) { + return text; + } + + child = text->GetChildAt(childIdx); + if (!child || nsAccUtils::MustPrune(child)) { + return text; + } + + innerOffset -= text->GetChildOffset(childIdx); + + text = child->AsHyperText(); + } while (text); + + return child; +} + TextPoint HyperTextAccessibleWrap::FindTextPoint( int32_t aOffset, nsDirection aDirection, nsSelectionAmount aAmount, EWordMovementType aWordMovementType) { diff --git a/accessible/mac/MOXAccessibleProtocol.h b/accessible/mac/MOXAccessibleProtocol.h index 6c6e9cd9c958..b5b55de8b53d 100644 --- a/accessible/mac/MOXAccessibleProtocol.h +++ b/accessible/mac/MOXAccessibleProtocol.h @@ -398,6 +398,9 @@ // AXTextMarkerForIndex - (id _Nullable)moxTextMarkerForIndex:(NSNumber* _Nonnull)index; +// AXUIElementForTextMarker +- (id _Nullable)moxUIElementForTextMarker:(id _Nonnull)textMarker; + // AXTextMarkerRangeForUIElement - (id _Nullable)moxTextMarkerRangeForUIElement:(id _Nonnull)element; diff --git a/accessible/mac/MOXTextMarkerDelegate.h b/accessible/mac/MOXTextMarkerDelegate.h index fdb534c0c743..2f12391ae974 100644 --- a/accessible/mac/MOXTextMarkerDelegate.h +++ b/accessible/mac/MOXTextMarkerDelegate.h @@ -74,6 +74,9 @@ // override - (NSValue*)moxBoundsForTextMarkerRange:(id)textMarkerRange; +// override +- (id)moxUIElementForTextMarker:(id)textMarker; + // override - (id)moxTextMarkerRangeForUIElement:(id)element; diff --git a/accessible/mac/MOXTextMarkerDelegate.mm b/accessible/mac/MOXTextMarkerDelegate.mm index c0813be83812..7959f3ad3955 100644 --- a/accessible/mac/MOXTextMarkerDelegate.mm +++ b/accessible/mac/MOXTextMarkerDelegate.mm @@ -243,6 +243,15 @@ static nsDataHashtable sDelegates; return geckoTextMarker.CreateAXTextMarker(); } +- (id)moxUIElementForTextMarker:(id)textMarker { + GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker); + if (!geckoTextMarker.IsValid()) { + return nil; + } + + return GetNativeFromGeckoAccessible(geckoTextMarker.Leaf()); +} + - (id)moxTextMarkerRangeForUIElement:(id)element { if (![element isKindOfClass:[mozAccessible class]]) { return nil;