diff --git a/accessible/ipc/extension/mac/DocAccessiblePlatformExtChild.cpp b/accessible/ipc/extension/mac/DocAccessiblePlatformExtChild.cpp index 8094eef03623..7e526b5bb2c4 100644 --- a/accessible/ipc/extension/mac/DocAccessiblePlatformExtChild.cpp +++ b/accessible/ipc/extension/mac/DocAccessiblePlatformExtChild.cpp @@ -169,6 +169,14 @@ mozilla::ipc::IPCResult DocAccessiblePlatformExtChild::RecvOffsetAtIndex( mozilla::ipc::IPCResult DocAccessiblePlatformExtChild::RecvRangeOfChild( const uint64_t& aID, const uint64_t& aChild, int32_t* aStartOffset, int32_t* aEndOffset) { + HyperTextAccessibleWrap* acc = IdToHyperTextAccessibleWrap(aID); + Accessible* child = + static_cast(Manager())->IdToAccessible(aChild); + if (!acc || !child) { + return IPC_OK(); + } + + acc->RangeOfChild(child, aStartOffset, aEndOffset); return IPC_OK(); } diff --git a/accessible/mac/GeckoTextMarker.h b/accessible/mac/GeckoTextMarker.h index 46b613b02d39..bd0cd58ef1f5 100644 --- a/accessible/mac/GeckoTextMarker.h +++ b/accessible/mac/GeckoTextMarker.h @@ -74,6 +74,8 @@ class GeckoTextMarkerRange final { GeckoTextMarkerRange(AccessibleOrProxy aDoc, AXTextMarkerRangeRef aTextMarkerRange); + explicit GeckoTextMarkerRange(const AccessibleOrProxy& aAccessible); + id CreateAXTextMarkerRange(); bool IsValid() const { diff --git a/accessible/mac/GeckoTextMarker.mm b/accessible/mac/GeckoTextMarker.mm index 7b410c0c574b..deb0c440cbbc 100644 --- a/accessible/mac/GeckoTextMarker.mm +++ b/accessible/mac/GeckoTextMarker.mm @@ -288,6 +288,21 @@ GeckoTextMarkerRange::GeckoTextMarkerRange( CFRelease(end_marker); } +GeckoTextMarkerRange::GeckoTextMarkerRange( + const AccessibleOrProxy& aAccessible) { + mStart = GeckoTextMarker(aAccessible.Parent(), 0); + mEnd = GeckoTextMarker(aAccessible.Parent(), 0); + if (mStart.mContainer.IsProxy()) { + DocAccessibleParent* ipcDoc = mStart.mContainer.AsProxy()->Document(); + Unused << ipcDoc->GetPlatformExtension()->SendRangeOfChild( + mStart.mContainer.AsProxy()->ID(), aAccessible.AsProxy()->ID(), + &mStart.mOffset, &mEnd.mOffset); + } else if (auto htWrap = mStart.ContainerAsHyperTextWrap()) { + htWrap->RangeOfChild(aAccessible.AsAccessible(), &mStart.mOffset, + &mEnd.mOffset); + } +} + id GeckoTextMarkerRange::CreateAXTextMarkerRange() { AXTextMarkerRangeRef cf_text_marker_range = AXTextMarkerRangeCreate(kCFAllocatorDefault, mStart.CreateAXTextMarker(), diff --git a/accessible/mac/HyperTextAccessibleWrap.h b/accessible/mac/HyperTextAccessibleWrap.h index dccd735bab02..527523f9b407 100644 --- a/accessible/mac/HyperTextAccessibleWrap.h +++ b/accessible/mac/HyperTextAccessibleWrap.h @@ -46,6 +46,9 @@ class HyperTextAccessibleWrap : public HyperTextAccessible { void PreviousClusterAt(int32_t aOffset, HyperTextAccessible** aPrevContainer, int32_t* aPrevOffset); + void RangeOfChild(Accessible* aChild, int32_t* aStartOffset, + int32_t* aEndOffset); + protected: ~HyperTextAccessibleWrap() {} diff --git a/accessible/mac/HyperTextAccessibleWrap.mm b/accessible/mac/HyperTextAccessibleWrap.mm index f98e10a4c382..8dee6f1989c9 100644 --- a/accessible/mac/HyperTextAccessibleWrap.mm +++ b/accessible/mac/HyperTextAccessibleWrap.mm @@ -351,6 +351,20 @@ void HyperTextAccessibleWrap::PreviousClusterAt( *aPrevOffset = prev.mOffset; } +void HyperTextAccessibleWrap::RangeOfChild(Accessible* aChild, + int32_t* aStartOffset, + int32_t* aEndOffset) { + MOZ_ASSERT(aChild->Parent() == this); + *aStartOffset = *aEndOffset = -1; + int32_t index = GetIndexOf(aChild); + if (index != -1) { + *aStartOffset = GetChildOffset(index); + // If this is the last child index + 1 will return the total + // chracter count. + *aEndOffset = GetChildOffset(index + 1); + } +} + 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 ad68d0d6f2f8..6c6e9cd9c958 100644 --- a/accessible/mac/MOXAccessibleProtocol.h +++ b/accessible/mac/MOXAccessibleProtocol.h @@ -398,4 +398,7 @@ // AXTextMarkerForIndex - (id _Nullable)moxTextMarkerForIndex:(NSNumber* _Nonnull)index; +// AXTextMarkerRangeForUIElement +- (id _Nullable)moxTextMarkerRangeForUIElement:(id _Nonnull)element; + @end diff --git a/accessible/mac/MOXTextMarkerDelegate.h b/accessible/mac/MOXTextMarkerDelegate.h index 63ee5b83f879..fdb534c0c743 100644 --- a/accessible/mac/MOXTextMarkerDelegate.h +++ b/accessible/mac/MOXTextMarkerDelegate.h @@ -74,4 +74,7 @@ // override - (NSValue*)moxBoundsForTextMarkerRange:(id)textMarkerRange; +// override +- (id)moxTextMarkerRangeForUIElement:(id)element; + @end diff --git a/accessible/mac/MOXTextMarkerDelegate.mm b/accessible/mac/MOXTextMarkerDelegate.mm index 0aea2a95c75e..c0813be83812 100644 --- a/accessible/mac/MOXTextMarkerDelegate.mm +++ b/accessible/mac/MOXTextMarkerDelegate.mm @@ -243,4 +243,13 @@ static nsDataHashtable sDelegates; return geckoTextMarker.CreateAXTextMarker(); } +- (id)moxTextMarkerRangeForUIElement:(id)element { + if (![element isKindOfClass:[mozAccessible class]]) { + return nil; + } + + GeckoTextMarkerRange range([element geckoAccessible]); + return range.CreateAXTextMarkerRange(); +} + @end