Bug 1730095 - P5: Add GeckoTextMarker proxy class. r=morgan

Abstracting the text marker will allow us to have a drop-in caching version in the next patch.
In this change I moved the (de)serializing code to the proxy class and changed it from being a constructor to a static method. I also added standalone get-range-for methods instead of the enum because the caching version will transition away from it. It was useful in the non-caching version because it allowed us to have one sync message with an enum and a switch statement in the recieving end.

Differential Revision: https://phabricator.services.mozilla.com/D168450
This commit is contained in:
Eitan Isaacson
2023-02-22 04:53:01 +00:00
parent c3e5a29248
commit a01500c390
9 changed files with 440 additions and 203 deletions

View File

@@ -0,0 +1,154 @@
/* clang-format off */
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* clang-format on */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _GeckoTextMarker_H_
#define _GeckoTextMarker_H_
#include <Foundation/Foundation.h>
#import "LegacyTextMarker.h"
namespace mozilla {
namespace a11y {
class Accessible;
class GeckoTextMarkerRange;
class GeckoTextMarker {
public:
GeckoTextMarker();
GeckoTextMarker(const GeckoTextMarker& aOther) {
mLegacyTextMarker = aOther.mLegacyTextMarker;
}
explicit GeckoTextMarker(const LegacyTextMarker& aTextMarker)
: mLegacyTextMarker(aTextMarker) {}
GeckoTextMarker(Accessible* aContainer, int32_t aOffset);
static GeckoTextMarker MarkerFromAXTextMarker(Accessible* aDoc,
AXTextMarkerRef aTextMarker);
static GeckoTextMarker MarkerFromIndex(Accessible* aRoot, int32_t aIndex);
AXTextMarkerRef CreateAXTextMarker();
bool Next() { return mLegacyTextMarker.Next(); }
bool Previous() { return mLegacyTextMarker.Previous(); }
GeckoTextMarkerRange LeftWordRange() const;
GeckoTextMarkerRange RightWordRange() const;
GeckoTextMarkerRange LeftLineRange() const;
GeckoTextMarkerRange RightLineRange() const;
GeckoTextMarkerRange ParagraphRange() const;
GeckoTextMarkerRange StyleRange() const;
Accessible* Leaf() { return mLegacyTextMarker.Leaf(); }
int32_t& Offset() { return mLegacyTextMarker.mOffset; }
Accessible* Acc() const { return mLegacyTextMarker.mContainer; }
bool IsValid() const { return mLegacyTextMarker.IsValid(); }
bool operator<(const GeckoTextMarker& aPoint) const {
return mLegacyTextMarker < aPoint.mLegacyTextMarker;
}
bool operator==(const GeckoTextMarker& aPoint) const {
return mLegacyTextMarker == aPoint.mLegacyTextMarker;
}
private:
LegacyTextMarker mLegacyTextMarker;
friend class GeckoTextMarkerRange;
};
class GeckoTextMarkerRange {
public:
GeckoTextMarkerRange();
GeckoTextMarkerRange(const GeckoTextMarkerRange& aOther) {
mLegacyTextMarkerRange = aOther.mLegacyTextMarkerRange;
}
explicit GeckoTextMarkerRange(const LegacyTextMarkerRange& aTextMarkerRange)
: mLegacyTextMarkerRange(aTextMarkerRange) {}
GeckoTextMarkerRange(const GeckoTextMarker& aStart,
const GeckoTextMarker& aEnd) {
mLegacyTextMarkerRange =
LegacyTextMarkerRange(aStart.mLegacyTextMarker, aEnd.mLegacyTextMarker);
}
explicit GeckoTextMarkerRange(Accessible* aAccessible);
static GeckoTextMarkerRange MarkerRangeFromAXTextMarkerRange(
Accessible* aDoc, AXTextMarkerRangeRef aTextMarkerRange);
AXTextMarkerRangeRef CreateAXTextMarkerRange();
bool IsValid() const { return mLegacyTextMarkerRange.IsValid(); }
GeckoTextMarker Start() {
return GeckoTextMarker(mLegacyTextMarkerRange.mStart);
}
GeckoTextMarker End() { return GeckoTextMarker(mLegacyTextMarkerRange.mEnd); }
/**
* Return text enclosed by the range.
*/
NSString* Text() const { return mLegacyTextMarkerRange.Text(); }
/**
* Return the attributed text enclosed by the range.
*/
NSAttributedString* AttributedText() const {
return mLegacyTextMarkerRange.AttributedText();
}
/**
* Return length of characters enclosed by the range.
*/
int32_t Length() const { return mLegacyTextMarkerRange.Length(); }
/**
* Return screen bounds of range.
*/
NSValue* Bounds() const { return mLegacyTextMarkerRange.Bounds(); }
/**
* Set the current range as the DOM selection.
*/
void Select() const { mLegacyTextMarkerRange.Select(); }
/**
* Crops the range if it overlaps the given accessible element boundaries.
* Return true if successfully cropped. false if the range does not intersect
* with the container.
*/
bool Crop(Accessible* aContainer) {
return mLegacyTextMarkerRange.Crop(aContainer);
}
private:
LegacyTextMarkerRange mLegacyTextMarkerRange;
};
} // namespace a11y
} // namespace mozilla
#endif

View File

@@ -0,0 +1,173 @@
/* clang-format off */
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* clang-format on */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#import "GeckoTextMarker.h"
#import "MacUtils.h"
#include "DocAccessibleParent.h"
namespace mozilla {
namespace a11y {
struct TextMarkerData {
TextMarkerData(uintptr_t aDoc, uintptr_t aID, int32_t aOffset)
: mDoc(aDoc), mID(aID), mOffset(aOffset) {}
TextMarkerData() {}
uintptr_t mDoc;
uintptr_t mID;
int32_t mOffset;
};
// LegacyTextMarker
GeckoTextMarker::GeckoTextMarker() { mLegacyTextMarker = LegacyTextMarker(); }
GeckoTextMarker::GeckoTextMarker(Accessible* aContainer, int32_t aOffset) {
int32_t offset = aOffset;
if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT) {
offset = aContainer->IsRemote() ? aContainer->AsRemote()->CharacterCount()
: aContainer->AsLocal()
->Document()
->AsHyperText()
->CharacterCount();
}
mLegacyTextMarker = LegacyTextMarker(aContainer, offset);
}
GeckoTextMarker GeckoTextMarker::MarkerFromAXTextMarker(
Accessible* aDoc, AXTextMarkerRef aTextMarker) {
MOZ_ASSERT(aDoc);
if (!aTextMarker) {
return GeckoTextMarker();
}
if (AXTextMarkerGetLength(aTextMarker) != sizeof(TextMarkerData)) {
MOZ_ASSERT_UNREACHABLE("Malformed AXTextMarkerRef");
return GeckoTextMarker();
}
TextMarkerData markerData;
memcpy(&markerData, AXTextMarkerGetBytePtr(aTextMarker),
sizeof(TextMarkerData));
if (!utils::DocumentExists(aDoc, markerData.mDoc)) {
return GeckoTextMarker();
}
Accessible* doc = reinterpret_cast<Accessible*>(markerData.mDoc);
MOZ_ASSERT(doc->IsDoc());
int32_t offset = markerData.mOffset;
Accessible* acc = nullptr;
if (doc->IsRemote()) {
acc = doc->AsRemote()->AsDoc()->GetAccessible(markerData.mID);
} else {
acc = doc->AsLocal()->AsDoc()->GetAccessibleByUniqueID(
reinterpret_cast<void*>(markerData.mID));
}
if (!acc) {
return GeckoTextMarker();
}
return GeckoTextMarker(acc, offset);
}
GeckoTextMarker GeckoTextMarker::MarkerFromIndex(Accessible* aRoot,
int32_t aIndex) {
return GeckoTextMarker(LegacyTextMarker::MarkerFromIndex(aRoot, aIndex));
}
AXTextMarkerRef GeckoTextMarker::CreateAXTextMarker() {
if (!IsValid()) {
return nil;
}
Accessible* acc = mLegacyTextMarker.mContainer;
int32_t offset = mLegacyTextMarker.mOffset;
Accessible* doc = nsAccUtils::DocumentFor(acc);
TextMarkerData markerData(reinterpret_cast<uintptr_t>(doc), acc->ID(),
offset);
AXTextMarkerRef cf_text_marker = AXTextMarkerCreate(
kCFAllocatorDefault, reinterpret_cast<const UInt8*>(&markerData),
sizeof(TextMarkerData));
return (__bridge AXTextMarkerRef)[(__bridge id)(cf_text_marker)autorelease];
}
GeckoTextMarkerRange GeckoTextMarker::LeftWordRange() const {
return GeckoTextMarkerRange(mLegacyTextMarker.Range(EWhichRange::eLeftWord));
}
GeckoTextMarkerRange GeckoTextMarker::RightWordRange() const {
return GeckoTextMarkerRange(mLegacyTextMarker.Range(EWhichRange::eRightWord));
}
GeckoTextMarkerRange GeckoTextMarker::LeftLineRange() const {
return GeckoTextMarkerRange(mLegacyTextMarker.Range(EWhichRange::eLeftLine));
}
GeckoTextMarkerRange GeckoTextMarker::RightLineRange() const {
return GeckoTextMarkerRange(mLegacyTextMarker.Range(EWhichRange::eRightLine));
}
GeckoTextMarkerRange GeckoTextMarker::ParagraphRange() const {
return GeckoTextMarkerRange(mLegacyTextMarker.Range(EWhichRange::eParagraph));
}
GeckoTextMarkerRange GeckoTextMarker::StyleRange() const {
return GeckoTextMarkerRange(mLegacyTextMarker.Range(EWhichRange::eStyle));
}
GeckoTextMarkerRange::GeckoTextMarkerRange() {
mLegacyTextMarkerRange = LegacyTextMarkerRange();
}
GeckoTextMarkerRange::GeckoTextMarkerRange(Accessible* aAccessible) {
mLegacyTextMarkerRange = LegacyTextMarkerRange(aAccessible);
}
GeckoTextMarkerRange GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
Accessible* aDoc, AXTextMarkerRangeRef aTextMarkerRange) {
if (!aTextMarkerRange ||
CFGetTypeID(aTextMarkerRange) != AXTextMarkerRangeGetTypeID()) {
return GeckoTextMarkerRange();
}
AXTextMarkerRef start_marker(
AXTextMarkerRangeCopyStartMarker(aTextMarkerRange));
AXTextMarkerRef end_marker(AXTextMarkerRangeCopyEndMarker(aTextMarkerRange));
GeckoTextMarker start =
GeckoTextMarker::MarkerFromAXTextMarker(aDoc, start_marker);
GeckoTextMarker end =
GeckoTextMarker::MarkerFromAXTextMarker(aDoc, end_marker);
CFRelease(start_marker);
CFRelease(end_marker);
return GeckoTextMarkerRange(start, end);
}
AXTextMarkerRangeRef GeckoTextMarkerRange::CreateAXTextMarkerRange() {
if (!IsValid()) {
return nil;
}
GeckoTextMarker start, end;
start = GeckoTextMarker(mLegacyTextMarkerRange.mStart);
end = GeckoTextMarker(mLegacyTextMarkerRange.mEnd);
AXTextMarkerRangeRef cf_text_marker_range =
AXTextMarkerRangeCreate(kCFAllocatorDefault, start.CreateAXTextMarker(),
end.CreateAXTextMarker());
return (__bridge AXTextMarkerRangeRef)[(__bridge id)(
cf_text_marker_range)autorelease];
}
} // namespace a11y
} // namespace mozilla

View File

@@ -30,20 +30,16 @@ class LegacyTextMarker final {
LegacyTextMarker(const LegacyTextMarker& aPoint)
: mContainer(aPoint.mContainer), mOffset(aPoint.mOffset) {}
LegacyTextMarker(Accessible* aDoc, AXTextMarkerRef aTextMarker);
LegacyTextMarker() : mContainer(nullptr), mOffset(0) {}
static LegacyTextMarker MarkerFromIndex(Accessible* aRoot, int32_t aIndex);
AXTextMarkerRef CreateAXTextMarker();
bool Next();
bool Previous();
// Return a range with the given type relative to this marker.
LegacyTextMarkerRange Range(EWhichRange aRangeType);
LegacyTextMarkerRange Range(EWhichRange aRangeType) const;
Accessible* Leaf();
@@ -77,13 +73,8 @@ class LegacyTextMarkerRange final {
LegacyTextMarkerRange() {}
LegacyTextMarkerRange(Accessible* aDoc,
AXTextMarkerRangeRef aTextMarkerRange);
explicit LegacyTextMarkerRange(Accessible* aAccessible);
AXTextMarkerRangeRef CreateAXTextMarkerRange();
bool IsValid() const { return !!mStart.mContainer && !!mEnd.mContainer; };
/**
@@ -122,10 +113,6 @@ class LegacyTextMarkerRange final {
LegacyTextMarker mEnd;
};
// XXX: Temporary for next patch so we don't have to do a massive rename.
typedef LegacyTextMarker GeckoTextMarker;
typedef LegacyTextMarkerRange GeckoTextMarkerRange;
} // namespace a11y
} // namespace mozilla

View File

@@ -7,8 +7,6 @@
#import "LegacyTextMarker.h"
#import "MacUtils.h"
#include "DocAccessible.h"
#include "DocAccessibleParent.h"
#include "AccAttributes.h"
@@ -21,42 +19,6 @@
namespace mozilla {
namespace a11y {
struct OpaqueLegacyTextMarker {
OpaqueLegacyTextMarker(uintptr_t aDoc, uintptr_t aID, int32_t aOffset)
: mDoc(aDoc), mID(aID), mOffset(aOffset) {}
OpaqueLegacyTextMarker() {}
uintptr_t mDoc;
uintptr_t mID;
int32_t mOffset;
};
// LegacyTextMarker
LegacyTextMarker::LegacyTextMarker(Accessible* aDoc,
AXTextMarkerRef aTextMarker) {
MOZ_ASSERT(aDoc);
OpaqueLegacyTextMarker opaqueMarker;
if (aTextMarker &&
AXTextMarkerGetLength(aTextMarker) == sizeof(OpaqueLegacyTextMarker)) {
memcpy(&opaqueMarker, AXTextMarkerGetBytePtr(aTextMarker),
sizeof(OpaqueLegacyTextMarker));
if (utils::DocumentExists(aDoc, opaqueMarker.mDoc)) {
Accessible* doc = reinterpret_cast<Accessible*>(opaqueMarker.mDoc);
if (doc->IsRemote()) {
mContainer = doc->AsRemote()->AsDoc()->GetAccessible(opaqueMarker.mID);
} else {
mContainer = doc->AsLocal()->AsDoc()->GetAccessibleByUniqueID(
reinterpret_cast<void*>(opaqueMarker.mID));
}
}
mOffset = opaqueMarker.mOffset;
} else {
mContainer = nullptr;
mOffset = 0;
}
}
LegacyTextMarker LegacyTextMarker::MarkerFromIndex(Accessible* aRoot,
int32_t aIndex) {
if (aRoot->IsRemote()) {
@@ -78,32 +40,6 @@ LegacyTextMarker LegacyTextMarker::MarkerFromIndex(Accessible* aRoot,
return LegacyTextMarker();
}
AXTextMarkerRef LegacyTextMarker::CreateAXTextMarker() {
if (!IsValid()) {
return nil;
}
Accessible* doc;
if (mContainer->IsRemote()) {
doc = mContainer->AsRemote()->Document();
} else {
doc = mContainer->AsLocal()->Document();
}
uintptr_t identifier =
mContainer->IsRemote()
? mContainer->AsRemote()->ID()
: reinterpret_cast<uintptr_t>(mContainer->AsLocal()->UniqueID());
OpaqueLegacyTextMarker opaqueMarker(reinterpret_cast<uintptr_t>(doc),
identifier, mOffset);
AXTextMarkerRef cf_text_marker = AXTextMarkerCreate(
kCFAllocatorDefault, reinterpret_cast<const UInt8*>(&opaqueMarker),
sizeof(OpaqueLegacyTextMarker));
return (__bridge AXTextMarkerRef)[(__bridge id)(cf_text_marker)autorelease];
}
bool LegacyTextMarker::operator<(const LegacyTextMarker& aPoint) const {
if (mContainer == aPoint.mContainer) return mOffset < aPoint.mOffset;
@@ -245,7 +181,7 @@ static uint32_t CharacterCount(Accessible* aContainer) {
return 0;
}
LegacyTextMarkerRange LegacyTextMarker::Range(EWhichRange aRangeType) {
LegacyTextMarkerRange LegacyTextMarker::Range(EWhichRange aRangeType) const {
MOZ_ASSERT(mContainer);
if (mContainer->IsRemote()) {
int32_t startOffset = 0, endOffset = 0;
@@ -290,24 +226,6 @@ Accessible* LegacyTextMarker::Leaf() {
// LegacyTextMarkerRange
LegacyTextMarkerRange::LegacyTextMarkerRange(
Accessible* aDoc, AXTextMarkerRangeRef aTextMarkerRange) {
if (!aTextMarkerRange ||
CFGetTypeID(aTextMarkerRange) != AXTextMarkerRangeGetTypeID()) {
return;
}
AXTextMarkerRef start_marker(
AXTextMarkerRangeCopyStartMarker(aTextMarkerRange));
AXTextMarkerRef end_marker(AXTextMarkerRangeCopyEndMarker(aTextMarkerRange));
mStart = LegacyTextMarker(aDoc, start_marker);
mEnd = LegacyTextMarker(aDoc, end_marker);
CFRelease(start_marker);
CFRelease(end_marker);
}
LegacyTextMarkerRange::LegacyTextMarkerRange(Accessible* aAccessible) {
if (aAccessible->IsHyperText()) {
// The accessible is a hypertext. Initialize range to its inner text range.
@@ -330,19 +248,6 @@ LegacyTextMarkerRange::LegacyTextMarkerRange(Accessible* aAccessible) {
}
}
AXTextMarkerRangeRef LegacyTextMarkerRange::CreateAXTextMarkerRange() {
if (!IsValid()) {
return nil;
}
AXTextMarkerRangeRef cf_text_marker_range =
AXTextMarkerRangeCreate(kCFAllocatorDefault, mStart.CreateAXTextMarker(),
mEnd.CreateAXTextMarker());
return (__bridge AXTextMarkerRangeRef)[(__bridge id)(
cf_text_marker_range)autorelease];
}
NSString* LegacyTextMarkerRange::Text() const {
nsAutoString text;
if (mStart.mContainer->IsRemote() && mEnd.mContainer->IsRemote()) {

View File

@@ -8,7 +8,7 @@
#import <Cocoa/Cocoa.h>
#import "MOXAccessibleProtocol.h"
#import "LegacyTextMarker.h"
#import "GeckoTextMarker.h"
@interface MOXTextMarkerDelegate : NSObject <MOXTextMarkerSupport> {
mozilla::a11y::Accessible* mGeckoDocAccessible;

View File

@@ -95,11 +95,13 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
// regarding which attributes to add to the info object.
- (NSDictionary*)selectionChangeInfo {
GeckoTextMarkerRange selectedGeckoRange =
GeckoTextMarkerRange(mGeckoDocAccessible, mSelection);
GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
mGeckoDocAccessible, mSelection);
int32_t stateChangeType = selectedGeckoRange.mStart == selectedGeckoRange.mEnd
? AXTextStateChangeTypeSelectionMove
: AXTextStateChangeTypeSelectionExtend;
int32_t stateChangeType =
selectedGeckoRange.Start() == selectedGeckoRange.End()
? AXTextStateChangeTypeSelectionMove
: AXTextStateChangeTypeSelectionExtend;
// This is the base info object, includes the selected marker range and
// the change type depending on the collapsed state of the selection.
@@ -110,8 +112,10 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
@"AXTextStateChangeType" : @(stateChangeType),
} mutableCopy] autorelease];
GeckoTextMarker caretMarker(mGeckoDocAccessible, mCaret);
GeckoTextMarker prevCaretMarker(mGeckoDocAccessible, mPrevCaret);
GeckoTextMarker caretMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, mCaret);
GeckoTextMarker prevCaretMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, mPrevCaret);
if (!caretMarker.IsValid()) {
// If the current caret is invalid, stop here and return base info.
@@ -119,8 +123,7 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
}
mozAccessible* caretEditable =
[GetNativeFromGeckoAccessible(caretMarker.mContainer)
moxEditableAncestor];
[GetNativeFromGeckoAccessible(caretMarker.Acc()) moxEditableAncestor];
if (!caretEditable && stateChangeType == AXTextStateChangeTypeSelectionMove) {
// If we are not in an editable, VO expects AXTextStateSync to be present
@@ -134,8 +137,7 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
}
mozAccessible* prevCaretEditable =
[GetNativeFromGeckoAccessible(prevCaretMarker.mContainer)
moxEditableAncestor];
[GetNativeFromGeckoAccessible(prevCaretMarker.Acc()) moxEditableAncestor];
if (prevCaretEditable != caretEditable) {
// If the caret goes in or out of an editable, consider the
@@ -202,7 +204,8 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
}
- (mozilla::a11y::GeckoTextMarkerRange)selection {
return mozilla::a11y::GeckoTextMarkerRange(mGeckoDocAccessible, mSelection);
return mozilla::a11y::GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
mGeckoDocAccessible, mSelection);
}
- (AXTextMarkerRef)moxStartTextMarker {
@@ -211,27 +214,23 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
}
- (AXTextMarkerRef)moxEndTextMarker {
uint32_t characterCount =
mGeckoDocAccessible->IsRemote()
? mGeckoDocAccessible->AsRemote()->CharacterCount()
: mGeckoDocAccessible->AsLocal()
->Document()
->AsHyperText()
->CharacterCount();
GeckoTextMarker geckoTextPoint(mGeckoDocAccessible, characterCount);
GeckoTextMarker geckoTextPoint(mGeckoDocAccessible,
nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT);
return geckoTextPoint.CreateAXTextMarker();
}
- (AXTextMarkerRangeRef)moxSelectedTextMarkerRange {
return mSelection &&
GeckoTextMarkerRange(mGeckoDocAccessible, mSelection).IsValid()
return mSelection && GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
mGeckoDocAccessible, mSelection)
.IsValid()
? mSelection
: nil;
}
- (NSString*)moxStringForTextMarkerRange:(AXTextMarkerRangeRef)textMarkerRange {
mozilla::a11y::GeckoTextMarkerRange range(mGeckoDocAccessible,
textMarkerRange);
mozilla::a11y::GeckoTextMarkerRange range =
GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
mGeckoDocAccessible, textMarkerRange);
if (!range.IsValid()) {
return @"";
}
@@ -240,7 +239,10 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
}
- (NSNumber*)moxLengthForTextMarkerRange:(AXTextMarkerRangeRef)textMarkerRange {
return @([[self moxStringForTextMarkerRange:textMarkerRange] length]);
mozilla::a11y::GeckoTextMarkerRange range =
GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
mGeckoDocAccessible, textMarkerRange);
return @(range.Length());
}
- (AXTextMarkerRangeRef)moxTextMarkerRangeForUnorderedTextMarkers:
@@ -250,10 +252,10 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
return nil;
}
GeckoTextMarker p1(mGeckoDocAccessible,
(__bridge AXTextMarkerRef)textMarkers[0]);
GeckoTextMarker p2(mGeckoDocAccessible,
(__bridge AXTextMarkerRef)textMarkers[1]);
GeckoTextMarker p1 = GeckoTextMarker::MarkerFromAXTextMarker(
mGeckoDocAccessible, (__bridge AXTextMarkerRef)textMarkers[0]);
GeckoTextMarker p2 = GeckoTextMarker::MarkerFromAXTextMarker(
mGeckoDocAccessible, (__bridge AXTextMarkerRef)textMarkers[1]);
if (!p1.IsValid() || !p2.IsValid()) {
// If either marker is invalid, return nil.
@@ -268,98 +270,103 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
- (AXTextMarkerRef)moxStartTextMarkerForTextMarkerRange:
(AXTextMarkerRangeRef)textMarkerRange {
mozilla::a11y::GeckoTextMarkerRange range(mGeckoDocAccessible,
textMarkerRange);
mozilla::a11y::GeckoTextMarkerRange range =
GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
mGeckoDocAccessible, textMarkerRange);
return range.IsValid() ? range.mStart.CreateAXTextMarker() : nil;
return range.IsValid() ? range.Start().CreateAXTextMarker() : nil;
}
- (AXTextMarkerRef)moxEndTextMarkerForTextMarkerRange:
(AXTextMarkerRangeRef)textMarkerRange {
mozilla::a11y::GeckoTextMarkerRange range(mGeckoDocAccessible,
textMarkerRange);
mozilla::a11y::GeckoTextMarkerRange range =
GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
mGeckoDocAccessible, textMarkerRange);
return range.IsValid() ? range.mEnd.CreateAXTextMarker() : nil;
return range.IsValid() ? range.End().CreateAXTextMarker() : nil;
}
- (AXTextMarkerRangeRef)moxLeftWordTextMarkerRangeForTextMarker:
(AXTextMarkerRef)textMarker {
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return nil;
}
return geckoTextMarker.Range(EWhichRange::eLeftWord)
.CreateAXTextMarkerRange();
return geckoTextMarker.LeftWordRange().CreateAXTextMarkerRange();
}
- (AXTextMarkerRangeRef)moxRightWordTextMarkerRangeForTextMarker:
(AXTextMarkerRef)textMarker {
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return nil;
}
return geckoTextMarker.Range(EWhichRange::eRightWord)
.CreateAXTextMarkerRange();
return geckoTextMarker.RightWordRange().CreateAXTextMarkerRange();
}
- (AXTextMarkerRangeRef)moxLineTextMarkerRangeForTextMarker:
(AXTextMarkerRef)textMarker {
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return nil;
}
return geckoTextMarker.Range(EWhichRange::eLine).CreateAXTextMarkerRange();
return geckoTextMarker.LeftLineRange().CreateAXTextMarkerRange();
}
- (AXTextMarkerRangeRef)moxLeftLineTextMarkerRangeForTextMarker:
(AXTextMarkerRef)textMarker {
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return nil;
}
return geckoTextMarker.Range(EWhichRange::eLeftLine)
.CreateAXTextMarkerRange();
return geckoTextMarker.LeftLineRange().CreateAXTextMarkerRange();
}
- (AXTextMarkerRangeRef)moxRightLineTextMarkerRangeForTextMarker:
(AXTextMarkerRef)textMarker {
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return nil;
}
return geckoTextMarker.Range(EWhichRange::eRightLine)
.CreateAXTextMarkerRange();
return geckoTextMarker.RightLineRange().CreateAXTextMarkerRange();
}
- (AXTextMarkerRangeRef)moxParagraphTextMarkerRangeForTextMarker:
(AXTextMarkerRef)textMarker {
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return nil;
}
return geckoTextMarker.Range(EWhichRange::eParagraph)
.CreateAXTextMarkerRange();
return geckoTextMarker.ParagraphRange().CreateAXTextMarkerRange();
}
// override
- (AXTextMarkerRangeRef)moxStyleTextMarkerRangeForTextMarker:
(AXTextMarkerRef)textMarker {
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return nil;
}
return geckoTextMarker.Range(EWhichRange::eStyle).CreateAXTextMarkerRange();
return geckoTextMarker.StyleRange().CreateAXTextMarkerRange();
}
- (AXTextMarkerRef)moxNextTextMarkerForTextMarker:(AXTextMarkerRef)textMarker {
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return nil;
}
@@ -373,7 +380,8 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
- (AXTextMarkerRef)moxPreviousTextMarkerForTextMarker:
(AXTextMarkerRef)textMarker {
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return nil;
}
@@ -387,8 +395,9 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
- (NSAttributedString*)moxAttributedStringForTextMarkerRange:
(AXTextMarkerRangeRef)textMarkerRange {
mozilla::a11y::GeckoTextMarkerRange range(mGeckoDocAccessible,
textMarkerRange);
mozilla::a11y::GeckoTextMarkerRange range =
GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
mGeckoDocAccessible, textMarkerRange);
if (!range.IsValid()) {
return nil;
}
@@ -397,8 +406,9 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
}
- (NSValue*)moxBoundsForTextMarkerRange:(AXTextMarkerRangeRef)textMarkerRange {
mozilla::a11y::GeckoTextMarkerRange range(mGeckoDocAccessible,
textMarkerRange);
mozilla::a11y::GeckoTextMarkerRange range =
GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
mGeckoDocAccessible, textMarkerRange);
if (!range.IsValid()) {
return nil;
}
@@ -407,7 +417,8 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
}
- (NSNumber*)moxIndexForTextMarker:(AXTextMarkerRef)textMarker {
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return nil;
}
@@ -429,7 +440,8 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
}
- (id)moxUIElementForTextMarker:(AXTextMarkerRef)textMarker {
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return nil;
}
@@ -456,14 +468,15 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
return nil;
}
GeckoTextMarker geckoTextMarker(mGeckoDocAccessible, textMarker);
GeckoTextMarker geckoTextMarker =
GeckoTextMarker::MarkerFromAXTextMarker(mGeckoDocAccessible, textMarker);
if (!geckoTextMarker.IsValid()) {
return @"<GeckoTextMarker 0x0 [0]>";
}
return [NSString stringWithFormat:@"<GeckoTextMarker %p [%d]>",
geckoTextMarker.mContainer,
geckoTextMarker.mOffset];
geckoTextMarker.Acc(),
geckoTextMarker.Offset()];
}
- (NSString*)moxMozDebugDescriptionForTextMarkerRange:
@@ -472,21 +485,22 @@ static nsTHashMap<nsPtrHashKey<mozilla::a11y::Accessible>,
return nil;
}
mozilla::a11y::GeckoTextMarkerRange range(mGeckoDocAccessible,
textMarkerRange);
mozilla::a11y::GeckoTextMarkerRange range =
GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
mGeckoDocAccessible, textMarkerRange);
if (!range.IsValid()) {
return @"<GeckoTextMarkerRange 0x0 [0] - 0x0 [0]>";
}
return
[NSString stringWithFormat:@"<GeckoTextMarkerRange %p [%d] - %p [%d]>",
range.mStart.mContainer, range.mStart.mOffset,
range.mEnd.mContainer, range.mEnd.mOffset];
return [NSString stringWithFormat:@"<GeckoTextMarkerRange %p [%d] - %p [%d]>",
range.Start().Acc(), range.Start().Offset(),
range.End().Acc(), range.End().Offset()];
}
- (void)moxSetSelectedTextMarkerRange:(AXTextMarkerRangeRef)textMarkerRange {
mozilla::a11y::GeckoTextMarkerRange range(mGeckoDocAccessible,
textMarkerRange);
mozilla::a11y::GeckoTextMarkerRange range =
GeckoTextMarkerRange::MarkerRangeFromAXTextMarkerRange(
mGeckoDocAccessible, textMarkerRange);
if (range.IsValid()) {
range.Select();
}

View File

@@ -17,6 +17,7 @@ EXPORTS.mozilla.a11y += [
UNIFIED_SOURCES += [
"AccessibleWrap.mm",
"DocAccessibleWrap.mm",
"GeckoTextMarker.mm",
"HyperTextAccessibleWrap.mm",
"LegacyTextMarker.mm",
"MacUtils.mm",

View File

@@ -11,6 +11,7 @@
#import "MacUtils.h"
#import "mozView.h"
#import "MOXSearchInfo.h"
#import "MOXTextMarkerDelegate.h"
#import "MOXWebAreaAccessible.h"
#import "mozTextAccessible.h"
#import "mozRootAccessible.h"
@@ -26,6 +27,7 @@
#include "mozilla/dom/BrowserParent.h"
#include "OuterDocAccessible.h"
#include "nsChildView.h"
#include "xpcAccessibleMacInterface.h"
#include "nsRect.h"
#include "nsCocoaUtils.h"

View File

@@ -14,7 +14,7 @@
#include "TextLeafAccessible.h"
#import "mozTextAccessible.h"
#import "LegacyTextMarker.h"
#import "GeckoTextMarker.h"
#import "MOXTextMarkerDelegate.h"
using namespace mozilla;
@@ -156,7 +156,7 @@ inline NSString* ToNSString(id aValue) {
}
GeckoTextMarkerRange fromStartToSelection(
GeckoTextMarker(mGeckoAccessible, 0), selection.mStart);
GeckoTextMarker(mGeckoAccessible, 0), selection.Start());
return [NSValue valueWithRange:NSMakeRange(fromStartToSelection.Length(),
selection.Length())];
@@ -407,38 +407,39 @@ inline NSString* ToNSString(id aValue) {
return [self moxValue] == nil || [super moxIgnoreWithParent:parent];
}
static GeckoTextMarkerRange TextMarkerSubrange(Accessible* aAccessible,
NSValue* aRange) {
GeckoTextMarkerRange textMarkerRange(aAccessible);
GeckoTextMarker start = textMarkerRange.Start();
GeckoTextMarker end = textMarkerRange.End();
NSRange r = [aRange rangeValue];
start.Offset() += r.location;
end.Offset() = start.Offset() + r.location + r.length;
return GeckoTextMarkerRange(start, end);
}
- (NSString*)moxStringForRange:(NSValue*)range {
MOZ_ASSERT(mGeckoAccessible);
NSRange r = [range rangeValue];
GeckoTextMarkerRange textMarkerRange(mGeckoAccessible);
textMarkerRange.mStart.mOffset += r.location;
textMarkerRange.mEnd.mOffset =
textMarkerRange.mStart.mOffset + r.location + r.length;
GeckoTextMarkerRange textMarkerRange =
TextMarkerSubrange(mGeckoAccessible, range);
return textMarkerRange.Text();
}
- (NSAttributedString*)moxAttributedStringForRange:(NSValue*)range {
MOZ_ASSERT(mGeckoAccessible);
NSRange r = [range rangeValue];
GeckoTextMarkerRange textMarkerRange(mGeckoAccessible);
textMarkerRange.mStart.mOffset += r.location;
textMarkerRange.mEnd.mOffset =
textMarkerRange.mStart.mOffset + r.location + r.length;
GeckoTextMarkerRange textMarkerRange =
TextMarkerSubrange(mGeckoAccessible, range);
return textMarkerRange.AttributedText();
}
- (NSValue*)moxBoundsForRange:(NSValue*)range {
MOZ_ASSERT(mGeckoAccessible);
NSRange r = [range rangeValue];
GeckoTextMarkerRange textMarkerRange(mGeckoAccessible);
textMarkerRange.mStart.mOffset += r.location;
textMarkerRange.mEnd.mOffset = textMarkerRange.mStart.mOffset + r.length;
GeckoTextMarkerRange textMarkerRange =
TextMarkerSubrange(mGeckoAccessible, range);
return textMarkerRange.Bounds();
}