forked from mirrors/gecko-dev
Bug 1785930 - Introduce aStopInEditable argument in TextLeafPoint::FindBoundary. r=Jamie
Differential Revision: https://phabricator.services.mozilla.com/D155030
This commit is contained in:
parent
f6705eb81f
commit
c039e2a85b
2 changed files with 56 additions and 28 deletions
|
|
@ -123,20 +123,32 @@ static HyperTextAccessible* HyperTextFor(LocalAccessible* aAcc) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Accessible* NextLeaf(Accessible* aOrigin) {
|
static Accessible* NextLeaf(Accessible* aOrigin, bool aIsEditable = false) {
|
||||||
MOZ_ASSERT(aOrigin);
|
MOZ_ASSERT(aOrigin);
|
||||||
Accessible* doc = nsAccUtils::DocumentFor(aOrigin);
|
Accessible* doc = nsAccUtils::DocumentFor(aOrigin);
|
||||||
Pivot pivot(doc);
|
Pivot pivot(doc);
|
||||||
auto rule = LeafRule();
|
auto rule = LeafRule();
|
||||||
return pivot.Next(aOrigin, rule);
|
Accessible* leaf = pivot.Next(aOrigin, rule);
|
||||||
|
if (aIsEditable && leaf) {
|
||||||
|
return leaf->Parent() && (leaf->Parent()->State() & states::EDITABLE)
|
||||||
|
? leaf
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
|
return leaf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Accessible* PrevLeaf(Accessible* aOrigin) {
|
static Accessible* PrevLeaf(Accessible* aOrigin, bool aIsEditable = false) {
|
||||||
MOZ_ASSERT(aOrigin);
|
MOZ_ASSERT(aOrigin);
|
||||||
Accessible* doc = nsAccUtils::DocumentFor(aOrigin);
|
Accessible* doc = nsAccUtils::DocumentFor(aOrigin);
|
||||||
Pivot pivot(doc);
|
Pivot pivot(doc);
|
||||||
auto rule = LeafRule();
|
auto rule = LeafRule();
|
||||||
return pivot.Prev(aOrigin, rule);
|
Accessible* leaf = pivot.Prev(aOrigin, rule);
|
||||||
|
if (aIsEditable && leaf) {
|
||||||
|
return leaf->Parent() && (leaf->Parent()->State() & states::EDITABLE)
|
||||||
|
? leaf
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
|
return leaf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsIFrame* GetFrameInBlock(const LocalAccessible* aAcc) {
|
static nsIFrame* GetFrameInBlock(const LocalAccessible* aAcc) {
|
||||||
|
|
@ -820,7 +832,8 @@ TextLeafPoint TextLeafPoint::ActualizeCaret(bool aAdjustAtEndOfLine) const {
|
||||||
|
|
||||||
TextLeafPoint TextLeafPoint::FindBoundary(AccessibleTextBoundary aBoundaryType,
|
TextLeafPoint TextLeafPoint::FindBoundary(AccessibleTextBoundary aBoundaryType,
|
||||||
nsDirection aDirection,
|
nsDirection aDirection,
|
||||||
bool aIncludeOrigin) const {
|
bool aIncludeOrigin,
|
||||||
|
bool aStopInEditable) const {
|
||||||
if (IsCaret()) {
|
if (IsCaret()) {
|
||||||
if (aBoundaryType == nsIAccessibleText::BOUNDARY_CHAR) {
|
if (aBoundaryType == nsIAccessibleText::BOUNDARY_CHAR) {
|
||||||
if (IsCaretAtEndOfLine()) {
|
if (IsCaretAtEndOfLine()) {
|
||||||
|
|
@ -831,11 +844,14 @@ TextLeafPoint TextLeafPoint::FindBoundary(AccessibleTextBoundary aBoundaryType,
|
||||||
return ActualizeCaret().FindBoundary(aBoundaryType, aDirection,
|
return ActualizeCaret().FindBoundary(aBoundaryType, aDirection,
|
||||||
aIncludeOrigin);
|
aIncludeOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool inEditableAndStopInIt = aStopInEditable && mAcc->Parent() &&
|
||||||
|
(mAcc->Parent()->State() & states::EDITABLE);
|
||||||
if (aBoundaryType == nsIAccessibleText::BOUNDARY_LINE_END) {
|
if (aBoundaryType == nsIAccessibleText::BOUNDARY_LINE_END) {
|
||||||
return FindLineEnd(aDirection, aIncludeOrigin);
|
return FindLineEnd(aDirection, aIncludeOrigin, inEditableAndStopInIt);
|
||||||
}
|
}
|
||||||
if (aBoundaryType == nsIAccessibleText::BOUNDARY_WORD_END) {
|
if (aBoundaryType == nsIAccessibleText::BOUNDARY_WORD_END) {
|
||||||
return FindWordEnd(aDirection, aIncludeOrigin);
|
return FindWordEnd(aDirection, aIncludeOrigin, inEditableAndStopInIt);
|
||||||
}
|
}
|
||||||
if ((aBoundaryType == nsIAccessibleText::BOUNDARY_LINE_START ||
|
if ((aBoundaryType == nsIAccessibleText::BOUNDARY_LINE_START ||
|
||||||
aBoundaryType == nsIAccessibleText::BOUNDARY_PARAGRAPH) &&
|
aBoundaryType == nsIAccessibleText::BOUNDARY_PARAGRAPH) &&
|
||||||
|
|
@ -892,8 +908,9 @@ TextLeafPoint TextLeafPoint::FindBoundary(AccessibleTextBoundary aBoundaryType,
|
||||||
return boundary;
|
return boundary;
|
||||||
}
|
}
|
||||||
// We didn't find it in this Accessible, so try the previous/next leaf.
|
// We didn't find it in this Accessible, so try the previous/next leaf.
|
||||||
Accessible* acc = aDirection == eDirPrevious ? PrevLeaf(searchFrom.mAcc)
|
Accessible* acc = aDirection == eDirPrevious
|
||||||
: NextLeaf(searchFrom.mAcc);
|
? PrevLeaf(searchFrom.mAcc, inEditableAndStopInIt)
|
||||||
|
: NextLeaf(searchFrom.mAcc, inEditableAndStopInIt);
|
||||||
if (!acc) {
|
if (!acc) {
|
||||||
// No further leaf was found. Use the start/end of the first/last leaf.
|
// No further leaf was found. Use the start/end of the first/last leaf.
|
||||||
return TextLeafPoint(
|
return TextLeafPoint(
|
||||||
|
|
@ -917,22 +934,24 @@ TextLeafPoint TextLeafPoint::FindBoundary(AccessibleTextBoundary aBoundaryType,
|
||||||
}
|
}
|
||||||
|
|
||||||
TextLeafPoint TextLeafPoint::FindLineEnd(nsDirection aDirection,
|
TextLeafPoint TextLeafPoint::FindLineEnd(nsDirection aDirection,
|
||||||
bool aIncludeOrigin) const {
|
bool aIncludeOrigin,
|
||||||
|
bool aStopInEditable) const {
|
||||||
if (aDirection == eDirPrevious && IsEmptyLastLine()) {
|
if (aDirection == eDirPrevious && IsEmptyLastLine()) {
|
||||||
// If we're at an empty line at the end of an Accessible, we don't want to
|
// If we're at an empty line at the end of an Accessible, we don't want to
|
||||||
// walk into the previous line. For example, this can happen if the caret
|
// walk into the previous line. For example, this can happen if the caret
|
||||||
// is positioned on an empty line at the end of a textarea.
|
// is positioned on an empty line at the end of a textarea.
|
||||||
// Because we want the line end, we must walk back to the line feed
|
// Because we want the line end, we must walk back to the line feed
|
||||||
// character.
|
// character.
|
||||||
return FindBoundary(nsIAccessibleText::BOUNDARY_CHAR, eDirPrevious);
|
return FindBoundary(nsIAccessibleText::BOUNDARY_CHAR, eDirPrevious, false,
|
||||||
|
aStopInEditable);
|
||||||
}
|
}
|
||||||
if (aIncludeOrigin && IsLineFeedChar()) {
|
if (aIncludeOrigin && IsLineFeedChar()) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
if (aDirection == eDirPrevious && !aIncludeOrigin) {
|
if (aDirection == eDirPrevious && !aIncludeOrigin) {
|
||||||
// If there is a line feed immediately before us, return that.
|
// If there is a line feed immediately before us, return that.
|
||||||
TextLeafPoint prevChar =
|
TextLeafPoint prevChar = FindBoundary(nsIAccessibleText::BOUNDARY_CHAR,
|
||||||
FindBoundary(nsIAccessibleText::BOUNDARY_CHAR, eDirPrevious);
|
eDirPrevious, false, aStopInEditable);
|
||||||
if (prevChar.IsLineFeedChar()) {
|
if (prevChar.IsLineFeedChar()) {
|
||||||
return prevChar;
|
return prevChar;
|
||||||
}
|
}
|
||||||
|
|
@ -942,14 +961,16 @@ TextLeafPoint TextLeafPoint::FindLineEnd(nsDirection aDirection,
|
||||||
// If we search for the next line start from a line feed, we'll get the
|
// If we search for the next line start from a line feed, we'll get the
|
||||||
// character immediately following the line feed. We actually want the
|
// character immediately following the line feed. We actually want the
|
||||||
// next line start after that. Skip the line feed.
|
// next line start after that. Skip the line feed.
|
||||||
searchFrom = FindBoundary(nsIAccessibleText::BOUNDARY_CHAR, eDirNext);
|
searchFrom = FindBoundary(nsIAccessibleText::BOUNDARY_CHAR, eDirNext, false,
|
||||||
|
aStopInEditable);
|
||||||
}
|
}
|
||||||
TextLeafPoint lineStart = searchFrom.FindBoundary(
|
TextLeafPoint lineStart =
|
||||||
nsIAccessibleText::BOUNDARY_LINE_START, aDirection, aIncludeOrigin);
|
searchFrom.FindBoundary(nsIAccessibleText::BOUNDARY_LINE_START,
|
||||||
|
aDirection, aIncludeOrigin, aStopInEditable);
|
||||||
// If there is a line feed before this line start (at the end of the previous
|
// If there is a line feed before this line start (at the end of the previous
|
||||||
// line), we must return that.
|
// line), we must return that.
|
||||||
TextLeafPoint prevChar = lineStart.FindBoundary(
|
TextLeafPoint prevChar = lineStart.FindBoundary(
|
||||||
nsIAccessibleText::BOUNDARY_CHAR, eDirPrevious, false);
|
nsIAccessibleText::BOUNDARY_CHAR, eDirPrevious, false, aStopInEditable);
|
||||||
if (prevChar && prevChar.IsLineFeedChar()) {
|
if (prevChar && prevChar.IsLineFeedChar()) {
|
||||||
return prevChar;
|
return prevChar;
|
||||||
}
|
}
|
||||||
|
|
@ -961,14 +982,15 @@ bool TextLeafPoint::IsSpace() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextLeafPoint TextLeafPoint::FindWordEnd(nsDirection aDirection,
|
TextLeafPoint TextLeafPoint::FindWordEnd(nsDirection aDirection,
|
||||||
bool aIncludeOrigin) const {
|
bool aIncludeOrigin,
|
||||||
|
bool aStopInEditable) const {
|
||||||
char16_t origChar = GetChar();
|
char16_t origChar = GetChar();
|
||||||
const bool origIsSpace = GetWordBreakClass(origChar) == eWbcSpace;
|
const bool origIsSpace = GetWordBreakClass(origChar) == eWbcSpace;
|
||||||
bool prevIsSpace = false;
|
bool prevIsSpace = false;
|
||||||
if (aDirection == eDirPrevious || (aIncludeOrigin && origIsSpace) ||
|
if (aDirection == eDirPrevious || (aIncludeOrigin && origIsSpace) ||
|
||||||
!origChar) {
|
!origChar) {
|
||||||
TextLeafPoint prev =
|
TextLeafPoint prev = FindBoundary(nsIAccessibleText::BOUNDARY_CHAR,
|
||||||
FindBoundary(nsIAccessibleText::BOUNDARY_CHAR, eDirPrevious, false);
|
eDirPrevious, false, aStopInEditable);
|
||||||
if (aDirection == eDirPrevious && prev == *this) {
|
if (aDirection == eDirPrevious && prev == *this) {
|
||||||
return *this; // Can't go any further.
|
return *this; // Can't go any further.
|
||||||
}
|
}
|
||||||
|
|
@ -984,13 +1006,13 @@ TextLeafPoint TextLeafPoint::FindWordEnd(nsDirection aDirection,
|
||||||
// If there isn't space immediately before us, first find the start of the
|
// If there isn't space immediately before us, first find the start of the
|
||||||
// previous word.
|
// previous word.
|
||||||
boundary = FindBoundary(nsIAccessibleText::BOUNDARY_WORD_START,
|
boundary = FindBoundary(nsIAccessibleText::BOUNDARY_WORD_START,
|
||||||
eDirPrevious, aIncludeOrigin);
|
eDirPrevious, aIncludeOrigin, aStopInEditable);
|
||||||
} else if (aDirection == eDirNext &&
|
} else if (aDirection == eDirNext &&
|
||||||
(origIsSpace || (!origChar && prevIsSpace))) {
|
(origIsSpace || (!origChar && prevIsSpace))) {
|
||||||
// We're within the space at the end of the word. Skip over the space. We
|
// We're within the space at the end of the word. Skip over the space. We
|
||||||
// can do that by searching for the next word start.
|
// can do that by searching for the next word start.
|
||||||
boundary =
|
boundary = FindBoundary(nsIAccessibleText::BOUNDARY_WORD_START, eDirNext,
|
||||||
FindBoundary(nsIAccessibleText::BOUNDARY_WORD_START, eDirNext, false);
|
false, aStopInEditable);
|
||||||
if (boundary.IsSpace()) {
|
if (boundary.IsSpace()) {
|
||||||
// The next word starts with a space. This can happen if there is a space
|
// The next word starts with a space. This can happen if there is a space
|
||||||
// after or at the start of a block element.
|
// after or at the start of a block element.
|
||||||
|
|
@ -999,14 +1021,15 @@ TextLeafPoint TextLeafPoint::FindWordEnd(nsDirection aDirection,
|
||||||
}
|
}
|
||||||
if (aDirection == eDirNext) {
|
if (aDirection == eDirNext) {
|
||||||
boundary = boundary.FindBoundary(nsIAccessibleText::BOUNDARY_WORD_START,
|
boundary = boundary.FindBoundary(nsIAccessibleText::BOUNDARY_WORD_START,
|
||||||
eDirNext, aIncludeOrigin);
|
eDirNext, aIncludeOrigin, aStopInEditable);
|
||||||
}
|
}
|
||||||
// At this point, boundary is either the start of a word or at a space. A
|
// At this point, boundary is either the start of a word or at a space. A
|
||||||
// word ends at the beginning of consecutive space. Therefore, skip back to
|
// word ends at the beginning of consecutive space. Therefore, skip back to
|
||||||
// the start of any space before us.
|
// the start of any space before us.
|
||||||
TextLeafPoint prev = boundary;
|
TextLeafPoint prev = boundary;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
prev = prev.FindBoundary(nsIAccessibleText::BOUNDARY_CHAR, eDirPrevious);
|
prev = prev.FindBoundary(nsIAccessibleText::BOUNDARY_CHAR, eDirPrevious,
|
||||||
|
false, aStopInEditable);
|
||||||
if (prev == boundary) {
|
if (prev == boundary) {
|
||||||
break; // Can't go any further.
|
break; // Can't go any further.
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,13 @@ class TextLeafPoint final {
|
||||||
* (depending on the direction).
|
* (depending on the direction).
|
||||||
* If aIncludeorigin is true and this is at a boundary, this will be
|
* If aIncludeorigin is true and this is at a boundary, this will be
|
||||||
* returned unchanged.
|
* returned unchanged.
|
||||||
|
* If aStopInEditable is true the boundary returned will be within the
|
||||||
|
* current editable (if this point is in an editable).
|
||||||
*/
|
*/
|
||||||
TextLeafPoint FindBoundary(AccessibleTextBoundary aBoundaryType,
|
TextLeafPoint FindBoundary(AccessibleTextBoundary aBoundaryType,
|
||||||
nsDirection aDirection,
|
nsDirection aDirection,
|
||||||
bool aIncludeOrigin = false) const;
|
bool aIncludeOrigin = false,
|
||||||
|
bool aStopInEditable = false) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These two functions find a line start boundary within the same
|
* These two functions find a line start boundary within the same
|
||||||
|
|
@ -196,8 +199,10 @@ class TextLeafPoint final {
|
||||||
TextLeafPoint FindLineStartSameAcc(nsDirection aDirection,
|
TextLeafPoint FindLineStartSameAcc(nsDirection aDirection,
|
||||||
bool aIncludeOrigin) const;
|
bool aIncludeOrigin) const;
|
||||||
|
|
||||||
TextLeafPoint FindLineEnd(nsDirection aDirection, bool aIncludeOrigin) const;
|
TextLeafPoint FindLineEnd(nsDirection aDirection, bool aIncludeOrigin,
|
||||||
TextLeafPoint FindWordEnd(nsDirection aDirection, bool aIncludeOrigin) const;
|
bool aStopInEditable) const;
|
||||||
|
TextLeafPoint FindWordEnd(nsDirection aDirection, bool aIncludeOrigin,
|
||||||
|
bool aStopInEditable) const;
|
||||||
|
|
||||||
TextLeafPoint FindParagraphSameAcc(nsDirection aDirection,
|
TextLeafPoint FindParagraphSameAcc(nsDirection aDirection,
|
||||||
bool aIncludeOrigin) const;
|
bool aIncludeOrigin) const;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue