Bug 1384606 - part 3: Make `nsPeekOffsetStruct` and its handlers treat `bool` options with an `EnumSet` r=emilio

The constructor of `nsPeekOffsetStruct` and `nsIFrame::GetFrameFromDirection`
take too many `bool` arguments.  Therefore, adding new `bool` arguments does
not make sense.  Now, we have a useful `mozilla:EnumSet` class to treat them
with an `enum class`. Therefore, let's change `nsPeekOffsetStruct` with it.

Differential Revision: https://phabricator.services.mozilla.com/D172758
This commit is contained in:
Masayuki Nakano 2023-03-17 04:22:05 +00:00
Родитель 3f04e976fa
Коммит 1387f2e7bc
10 изменённых файлов: 188 добавлений и 166 удалений

Просмотреть файл

@ -531,14 +531,11 @@ uint32_t HyperTextAccessible::FindOffset(uint32_t aOffset,
childFrame->GetChildFrameContainingOffset(
innerContentOffset, true, &unusedOffsetInFrame, &frameAtOffset);
const bool kIsJumpLinesOk = true; // okay to jump lines
const bool kIsScrollViewAStop = false; // do not stop at scroll views
const bool kIsKeyboardSelect = true; // is keyboard selection
const bool kIsVisualBidi = false; // use visual order for bidi text
nsPeekOffsetStruct pos(
aAmount, aDirection, innerContentOffset, nsPoint(0, 0), kIsJumpLinesOk,
kIsScrollViewAStop, kIsKeyboardSelect, kIsVisualBidi, false,
nsPeekOffsetStruct::ForceEditableRegion::No, aWordMovementType, false);
PeekOffsetStruct pos(
aAmount, aDirection, innerContentOffset, nsPoint(0, 0),
{PeekOffsetOption::JumpLines, PeekOffsetOption::IsKeyboardSelect,
PeekOffsetOption::PreserveSpaces},
aWordMovementType);
nsresult rv = frameAtOffset->PeekOffset(&pos);
// PeekOffset fails on last/first lines of the text in certain cases.

Просмотреть файл

@ -727,14 +727,11 @@ TextPoint HyperTextAccessibleWrap::FindTextPoint(
}
}
const bool kIsJumpLinesOk = true; // okay to jump lines
const bool kIsScrollViewAStop = false; // do not stop at scroll views
const bool kIsKeyboardSelect = true; // is keyboard selection
const bool kIsVisualBidi = false; // use visual order for bidi text
nsPeekOffsetStruct pos(
aAmount, aDirection, innerContentOffset, nsPoint(0, 0), kIsJumpLinesOk,
kIsScrollViewAStop, kIsKeyboardSelect, kIsVisualBidi, false,
nsPeekOffsetStruct::ForceEditableRegion::No, aWordMovementType, false);
PeekOffsetStruct pos(
aAmount, aDirection, innerContentOffset, nsPoint(0, 0),
{PeekOffsetOption::JumpLines, PeekOffsetOption::IsKeyboardSelect,
PeekOffsetOption::PreserveSpaces},
aWordMovementType);
nsresult rv = frameAtOffset->PeekOffset(&pos);
// PeekOffset fails on last/first lines of the text in certain cases.

Просмотреть файл

@ -1160,8 +1160,9 @@ bool AccessibleCaretManager::RestrictCaretDraggingOffsets(
// Move one character (in the direction of dir) from the inactive caret's
// position. This is the limit for the active caret's new position.
nsPeekOffsetStruct limit(eSelectCluster, dir, offset, nsPoint(0, 0), true,
true, false, false, false);
PeekOffsetStruct limit(
eSelectCluster, dir, offset, nsPoint(0, 0),
{PeekOffsetOption::JumpLines, PeekOffsetOption::ScrollViewStop});
nsresult rv = frame->PeekOffset(&limit);
if (NS_FAILED(rv)) {
limit.mResultContent = content;

Просмотреть файл

@ -750,9 +750,10 @@ nsIFrame* nsCaret::GetCaretFrameForNodeOffset(nsFrameSelection* aFrameSelection,
// be in. We have to find the visually first frame on the line.
BidiEmbeddingLevel baseLevel = frameAfter->GetBaseLevel();
if (baseLevel != levelAfter) {
nsPeekOffsetStruct pos(eSelectBeginLine, eDirPrevious, 0,
nsPoint(0, 0), false, true, false,
true, false);
PeekOffsetStruct pos(eSelectBeginLine, eDirPrevious, 0,
nsPoint(0, 0),
{PeekOffsetOption::ScrollViewStop,
PeekOffsetOption::Visual});
if (NS_SUCCEEDED(frameAfter->PeekOffset(&pos))) {
theFrame = pos.mResultFrame;
theFrameOffset = pos.mContentOffset;
@ -781,9 +782,10 @@ nsIFrame* nsCaret::GetCaretFrameForNodeOffset(nsFrameSelection* aFrameSelection,
// frame on the line.
BidiEmbeddingLevel baseLevel = frameBefore->GetBaseLevel();
if (baseLevel != levelBefore) {
nsPeekOffsetStruct pos(eSelectEndLine, eDirNext, 0,
nsPoint(0, 0), false, true, false,
true, false);
PeekOffsetStruct pos(eSelectEndLine, eDirNext, 0,
nsPoint(0, 0),
{PeekOffsetOption::ScrollViewStop,
PeekOffsetOption::Visual});
if (NS_SUCCEEDED(frameBefore->PeekOffset(&pos))) {
theFrame = pos.mResultFrame;
theFrameOffset = pos.mContentOffset;

Просмотреть файл

@ -1312,7 +1312,7 @@ nsTextControlFrame::RestoreState(PresState* aState) {
return NS_OK;
}
nsresult nsTextControlFrame::PeekOffset(nsPeekOffsetStruct* aPos) {
nsresult nsTextControlFrame::PeekOffset(PeekOffsetStruct* aPos) {
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -187,7 +187,7 @@ class nsTextControlFrame : public nsContainerFrame,
*/
bool TextEquals(const nsAString& aText) const;
nsresult PeekOffset(nsPeekOffsetStruct* aPos) override;
nsresult PeekOffset(mozilla::PeekOffsetStruct* aPos) override;
NS_DECL_QUERYFRAME

Просмотреть файл

@ -129,7 +129,7 @@ static void printRange(nsRange* aDomRange);
#endif // PRINT_RANGE
/******************************************************************************
* nsPeekOffsetStruct
* mozilla::PeekOffsetStruct
******************************************************************************/
// #define DEBUG_SELECTION // uncomment for printf describing every collapse and
@ -137,29 +137,26 @@ static void printRange(nsRange* aDomRange);
// #define DEBUG_TABLE_SELECTION 1
nsPeekOffsetStruct::nsPeekOffsetStruct(
nsSelectionAmount aAmount, nsDirection aDirection, int32_t aStartOffset,
nsPoint aDesiredCaretPos, bool aJumpLines, bool aScrollViewStop,
bool aIsKeyboardSelect, bool aVisual, bool aExtend,
ForceEditableRegion aForceEditableRegion,
EWordMovementType aWordMovementType, bool aTrimSpaces)
namespace mozilla {
PeekOffsetStruct::PeekOffsetStruct(nsSelectionAmount aAmount,
nsDirection aDirection, int32_t aStartOffset,
nsPoint aDesiredCaretPos,
const PeekOffsetOptions aOptions,
EWordMovementType aWordMovementType)
: mAmount(aAmount),
mDirection(aDirection),
mStartOffset(aStartOffset),
mDesiredCaretPos(aDesiredCaretPos),
mWordMovementType(aWordMovementType),
mJumpLines(aJumpLines),
mTrimSpaces(aTrimSpaces),
mScrollViewStop(aScrollViewStop),
mIsKeyboardSelect(aIsKeyboardSelect),
mVisual(aVisual),
mExtend(aExtend),
mForceEditableRegion(aForceEditableRegion == ForceEditableRegion::Yes),
mOptions(aOptions),
mResultContent(),
mResultFrame(nullptr),
mContentOffset(0),
mAttach(CARET_ASSOCIATE_BEFORE) {}
} // namespace mozilla
// Array which contains index of each SelecionType in Selection::mDOMSelections.
// For avoiding using if nor switch to retrieve the index, this needs to have
// -1 for SelectionTypes which won't be created its Selection instance.
@ -800,11 +797,11 @@ nsresult nsFrameSelection::MoveCaret(nsDirection aDirection,
CaretAssociateHint tHint(mCaret.mHint); // temporary variable so we dont set
// mCaret.mHint until it is necessary
Result<nsPeekOffsetStruct, nsresult> result = PeekOffsetForCaretMove(
Result<PeekOffsetStruct, nsresult> result = PeekOffsetForCaretMove(
direction, aContinueSelection, aAmount, aMovementStyle, desiredPos);
nsresult rv;
if (result.isOk() && result.inspect().mResultContent) {
const nsPeekOffsetStruct& pos = result.inspect();
const PeekOffsetStruct& pos = result.inspect();
nsIFrame* theFrame;
int32_t currentOffset, frameStart, frameEnd;
@ -893,7 +890,7 @@ nsresult nsFrameSelection::MoveCaret(nsDirection aDirection,
return rv;
}
Result<nsPeekOffsetStruct, nsresult> nsFrameSelection::PeekOffsetForCaretMove(
Result<PeekOffsetStruct, nsresult> nsFrameSelection::PeekOffsetForCaretMove(
nsDirection aDirection, bool aContinueSelection,
const nsSelectionAmount aAmount, CaretMovementStyle aMovementStyle,
const nsPoint& aDesiredCaretPos) const {
@ -913,17 +910,25 @@ Result<nsPeekOffsetStruct, nsresult> nsFrameSelection::PeekOffsetForCaretMove(
return Err(NS_ERROR_FAILURE);
}
const auto kForceEditableRegion =
selection->IsEditorSelection()
? nsPeekOffsetStruct::ForceEditableRegion::Yes
: nsPeekOffsetStruct::ForceEditableRegion::No;
// set data using mLimiters.mLimiter to stop on scroll views. If we have a
// limiter then we stop peeking when we hit scrollable views. If no limiter
// then just let it go ahead
nsPeekOffsetStruct pos(aAmount, aDirection, offsetused, aDesiredCaretPos,
true, !!mLimiters.mLimiter, true, visualMovement,
aContinueSelection, kForceEditableRegion);
PeekOffsetOptions options{PeekOffsetOption::JumpLines,
PeekOffsetOption::IsKeyboardSelect};
if (mLimiters.mLimiter) {
options += PeekOffsetOption::ScrollViewStop;
}
if (visualMovement) {
options += PeekOffsetOption::Visual;
}
if (aContinueSelection) {
options += PeekOffsetOption::Extend;
}
if (selection->IsEditorSelection()) {
options += PeekOffsetOption::ForceEditableRegion;
}
PeekOffsetStruct pos(aAmount, aDirection, offsetused, aDesiredCaretPos,
options);
nsresult rv = frame->PeekOffset(&pos);
if (NS_FAILED(rv)) {
return Err(rv);
@ -1173,21 +1178,23 @@ void nsFrameSelection::MaintainedRange::AdjustContentOffsets(
nsIFrame* frame = GetFrameForNodeOffset(aOffsets.content, aOffsets.offset,
CARET_ASSOCIATE_AFTER, &offset);
PeekOffsetOptions peekOffsetOptions{};
if (aScrollViewStop) {
peekOffsetOptions += PeekOffsetOption::ScrollViewStop;
}
if (frame && amount == eSelectWord && direction == eDirPrevious) {
// To avoid selecting the previous word when at start of word,
// first move one character forward.
nsPeekOffsetStruct charPos(eSelectCharacter, eDirNext, offset,
nsPoint(0, 0), false, aScrollViewStop, false,
false, false);
PeekOffsetStruct charPos(eSelectCharacter, eDirNext, offset,
nsPoint(0, 0), peekOffsetOptions);
if (NS_SUCCEEDED(frame->PeekOffset(&charPos))) {
frame = charPos.mResultFrame;
offset = charPos.mContentOffset;
}
}
nsPeekOffsetStruct pos(amount, direction, offset, nsPoint(0, 0), false,
aScrollViewStop, false, false, false);
PeekOffsetStruct pos(amount, direction, offset, nsPoint(0, 0),
peekOffsetOptions);
if (frame && NS_SUCCEEDED(frame->PeekOffset(&pos)) && pos.mResultContent) {
aOffsets.content = pos.mResultContent;
aOffsets.offset = pos.mContentOffset;
@ -2196,12 +2203,12 @@ nsFrameSelection::CreateRangeExtendedToSomewhere(
if (!firstRange || !firstRange->IsPositioned()) {
return Err(NS_ERROR_FAILURE);
}
Result<nsPeekOffsetStruct, nsresult> result = PeekOffsetForCaretMove(
Result<PeekOffsetStruct, nsresult> result = PeekOffsetForCaretMove(
aDirection, true, aAmount, aMovementStyle, nsPoint(0, 0));
if (result.isErr()) {
return Err(NS_ERROR_FAILURE);
}
const nsPeekOffsetStruct& pos = result.inspect();
const PeekOffsetStruct& pos = result.inspect();
RefPtr<RangeType> range;
if (NS_WARN_IF(!pos.mResultContent)) {
return range;

Просмотреть файл

@ -7,9 +7,11 @@
#ifndef nsFrameSelection_h___
#define nsFrameSelection_h___
#include <stdint.h>
#include "mozilla/intl/BidiEmbeddingLevel.h"
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/EnumSet.h"
#include "mozilla/EventForwards.h"
#include "mozilla/dom/Selection.h"
#include "mozilla/Result.h"
@ -66,19 +68,50 @@ class PresShell;
* that are passed to nsIFrame::PeekOffset(). See below for the description of
* individual arguments.
*/
struct MOZ_STACK_CLASS nsPeekOffsetStruct {
enum class ForceEditableRegion {
No,
Yes,
};
nsPeekOffsetStruct(
nsSelectionAmount aAmount, nsDirection aDirection, int32_t aStartOffset,
nsPoint aDesiredCaretPos, bool aJumpLines, bool aScrollViewStop,
bool aIsKeyboardSelect, bool aVisual, bool aExtend,
ForceEditableRegion = ForceEditableRegion::No,
mozilla::EWordMovementType aWordMovementType = mozilla::eDefaultBehavior,
bool aTrimSpaces = true);
namespace mozilla {
enum class PeekOffsetOption : uint8_t {
// Whether to allow jumping across line boundaries.
//
// Used with: eSelectCharacter, eSelectWord.
JumpLines,
// Whether we should preserve or trim spaces at begin/end of content
PreserveSpaces,
// Whether to stop when reaching a scroll view boundary.
//
// Used with: eSelectCharacter, eSelectWord, eSelectLine.
ScrollViewStop,
// Whether the peeking is done in response to a keyboard action.
//
// Used with: eSelectWord.
IsKeyboardSelect,
// Whether bidi caret behavior is visual (set) or logical (unset).
//
// Used with: eSelectCharacter, eSelectWord, eSelectBeginLine, eSelectEndLine.
Visual,
// Whether the selection is being extended or moved.
Extend,
// If true, the offset has to end up in an editable node, otherwise we'll keep
// searching.
ForceEditableRegion,
};
using PeekOffsetOptions = EnumSet<PeekOffsetOption>;
struct MOZ_STACK_CLASS PeekOffsetStruct {
PeekOffsetStruct(nsSelectionAmount aAmount, nsDirection aDirection,
int32_t aStartOffset, nsPoint aDesiredCaretPos,
// Passing by value here is intentional because EnumSet
// is optimized as uint*_t in opt builds.
const PeekOffsetOptions aOptions,
EWordMovementType aWordMovementType = eDefaultBehavior);
// Note: Most arguments (input and output) are only used with certain values
// of mAmount. These values are indicated for each argument below.
@ -116,39 +149,11 @@ struct MOZ_STACK_CLASS nsPeekOffsetStruct {
const nsPoint mDesiredCaretPos;
// An enum that determines whether to prefer the start or end of a word or to
// use the default beahvior, which is a combination of direction and the
// use the default behavior, which is a combination of direction and the
// platform-based pref "layout.word_select.eat_space_to_next_word"
mozilla::EWordMovementType mWordMovementType;
EWordMovementType mWordMovementType;
// Whether to allow jumping across line boundaries.
//
// Used with: eSelectCharacter, eSelectWord.
const bool mJumpLines;
// mTrimSpaces: Whether we should trim spaces at begin/end of content
const bool mTrimSpaces;
// Whether to stop when reaching a scroll view boundary.
//
// Used with: eSelectCharacter, eSelectWord, eSelectLine.
const bool mScrollViewStop;
// Whether the peeking is done in response to a keyboard action.
//
// Used with: eSelectWord.
const bool mIsKeyboardSelect;
// Whether bidi caret behavior is visual (true) or logical (false).
//
// Used with: eSelectCharacter, eSelectWord, eSelectBeginLine, eSelectEndLine.
const bool mVisual;
// Whether the selection is being extended or moved.
const bool mExtend;
// If true, the offset has to end up in an editable node, otherwise we'll keep
// searching.
const bool mForceEditableRegion;
PeekOffsetOptions mOptions;
/*** Output arguments ***/
@ -169,9 +174,11 @@ struct MOZ_STACK_CLASS nsPeekOffsetStruct {
// logically after the caret".
//
// Used with: eSelectLine, eSelectBeginLine, eSelectEndLine.
mozilla::CaretAssociationHint mAttach;
CaretAssociationHint mAttach;
};
} // namespace mozilla
struct nsPrevNextBidiLevels {
void SetData(nsIFrame* aFrameBefore, nsIFrame* aFrameAfter,
mozilla::intl::BidiEmbeddingLevel aLevelBefore,
@ -906,7 +913,7 @@ class nsFrameSelection final {
* PeekOffsetForCaretMove() only peek offset for caret move. I.e., won't
* change selection ranges nor bidi information.
*/
mozilla::Result<nsPeekOffsetStruct, nsresult> PeekOffsetForCaretMove(
mozilla::Result<mozilla::PeekOffsetStruct, nsresult> PeekOffsetForCaretMove(
nsDirection aDirection, bool aContinueSelection,
const nsSelectionAmount aAmount, CaretMovementStyle aMovementStyle,
const nsPoint& aDesiredCaretPos) const;
@ -1064,7 +1071,7 @@ class nsFrameSelection final {
mozilla::dom::Selection& aNormalSelection) const;
/**
* @param aScrollViewStop see `nsPeekOffsetStruct::mScrollViewStop`.
* @param aScrollViewStop see `PeekOffsetOption::ScrollViewStop`.
*/
void AdjustContentOffsets(nsIFrame::ContentOffsets& aOffsets,
bool aScrollViewStop) const;

Просмотреть файл

@ -5025,13 +5025,16 @@ nsresult nsIFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
int32_t baseOffset = aStartPos;
nsresult rv;
PeekOffsetOptions peekOffsetOptions{PeekOffsetOption::ScrollViewStop};
if (aJumpLines) {
peekOffsetOptions += PeekOffsetOption::JumpLines;
}
if (aAmountBack == eSelectWord) {
// To avoid selecting the previous word when at start of word,
// first move one character forward.
nsPeekOffsetStruct pos(eSelectCharacter, eDirNext, aStartPos, nsPoint(0, 0),
aJumpLines,
true, // limit on scrolled views
false, false, false);
PeekOffsetStruct pos(eSelectCharacter, eDirNext, aStartPos, nsPoint(0, 0),
peekOffsetOptions);
rv = PeekOffset(&pos);
if (NS_SUCCEEDED(rv)) {
baseFrame = pos.mResultFrame;
@ -5040,10 +5043,8 @@ nsresult nsIFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
}
// Search backward for a boundary.
nsPeekOffsetStruct startpos(aAmountBack, eDirPrevious, baseOffset,
nsPoint(0, 0), aJumpLines,
true, // limit on scrolled views
false, false, false);
PeekOffsetStruct startpos(aAmountBack, eDirPrevious, baseOffset,
nsPoint(0, 0), peekOffsetOptions);
rv = baseFrame->PeekOffset(&startpos);
if (NS_FAILED(rv)) {
return rv;
@ -5059,10 +5060,8 @@ nsresult nsIFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
baseOffset = aStartPos;
}
nsPeekOffsetStruct endpos(aAmountForward, eDirNext, baseOffset, nsPoint(0, 0),
aJumpLines,
true, // limit on scrolled views
false, false, false);
PeekOffsetStruct endpos(aAmountForward, eDirNext, baseOffset, nsPoint(0, 0),
peekOffsetOptions);
rv = baseFrame->PeekOffset(&endpos);
if (NS_FAILED(rv)) {
return rv;
@ -8540,7 +8539,7 @@ nsresult nsIFrame::GetChildFrameContainingOffset(int32_t inContentOffset,
// aOutSideLimit != 0 means ignore aLineStart, instead work from
// the end (if > 0) or beginning (if < 0).
//
static nsresult GetNextPrevLineFromBlockFrame(nsPeekOffsetStruct* aPos,
static nsresult GetNextPrevLineFromBlockFrame(PeekOffsetStruct* aPos,
nsIFrame* aBlockFrame,
int32_t aLineStart,
int8_t aOutSideLimit) {
@ -8640,12 +8639,12 @@ static nsresult GetNextPrevLineFromBlockFrame(nsPeekOffsetStruct* aPos,
result = NS_ERROR_FAILURE;
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal), pc,
resultFrame, ePostOrder,
false, // aVisual
aPos->mScrollViewStop,
false, // aFollowOOFs
false // aSkipPopupChecks
result = NS_NewFrameTraversal(
getter_AddRefs(frameTraversal), pc, resultFrame, ePostOrder,
false, // aVisual
aPos->mOptions.contains(PeekOffsetOption::ScrollViewStop),
false, // aFollowOOFs
false // aSkipPopupChecks
);
if (NS_FAILED(result)) {
return result;
@ -8659,7 +8658,8 @@ static nsresult GetNextPrevLineFromBlockFrame(nsPeekOffsetStruct* aPos,
if (!aFrame->IsSelectable(nullptr)) {
return false;
}
if (aPos->mForceEditableRegion && !aOffsets.content->IsEditable()) {
if (aPos->mOptions.contains(PeekOffsetOption::ForceEditableRegion) &&
!aOffsets.content->IsEditable()) {
return false;
}
return true;
@ -8715,12 +8715,12 @@ static nsresult GetNextPrevLineFromBlockFrame(nsPeekOffsetStruct* aPos,
if (!found) {
resultFrame = storeOldResultFrame;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal), pc,
resultFrame, eLeaf,
false, // aVisual
aPos->mScrollViewStop,
false, // aFollowOOFs
false // aSkipPopupChecks
result = NS_NewFrameTraversal(
getter_AddRefs(frameTraversal), pc, resultFrame, eLeaf,
false, // aVisual
aPos->mOptions.contains(PeekOffsetOption::ScrollViewStop),
false, // aFollowOOFs
false // aSkipPopupChecks
);
}
while (!found) {
@ -8852,7 +8852,7 @@ static nsContentAndOffset FindLineBreakingFrame(nsIFrame* aFrame,
return result;
}
nsresult nsIFrame::PeekOffsetForParagraph(nsPeekOffsetStruct* aPos) {
nsresult nsIFrame::PeekOffsetForParagraph(PeekOffsetStruct* aPos) {
nsIFrame* frame = this;
nsContentAndOffset blockFrameOrBR;
blockFrameOrBR.mContent = nullptr;
@ -8918,7 +8918,7 @@ static bool IsMovingInFrameDirection(const nsIFrame* frame,
// non-whitespace (in the direction we're moving in)". It is true when moving
// forward and looking for a beginning of a word, or when moving backwards and
// looking for an end of a word.
static bool ShouldWordSelectionEatSpace(const nsPeekOffsetStruct& aPos) {
static bool ShouldWordSelectionEatSpace(const PeekOffsetStruct& aPos) {
if (aPos.mWordMovementType != eDefaultBehavior) {
// aPos->mWordMovementType possible values:
// eEndWord: eat the space if we're moving backwards
@ -8937,7 +8937,7 @@ static bool ShouldWordSelectionEatSpace(const nsPeekOffsetStruct& aPos) {
enum class OffsetIsAtLineEdge : bool { No, Yes };
static void SetPeekResultFromFrame(nsPeekOffsetStruct& aPos, nsIFrame* aFrame,
static void SetPeekResultFromFrame(PeekOffsetStruct& aPos, nsIFrame* aFrame,
int32_t aOffset,
OffsetIsAtLineEdge aAtLineEdge) {
FrameContentRange range = GetRangeForFrame(aFrame);
@ -8952,8 +8952,7 @@ static void SetPeekResultFromFrame(nsPeekOffsetStruct& aPos, nsIFrame* aFrame,
}
}
void nsIFrame::SelectablePeekReport::TransferTo(
nsPeekOffsetStruct& aPos) const {
void nsIFrame::SelectablePeekReport::TransferTo(PeekOffsetStruct& aPos) const {
return SetPeekResultFromFrame(aPos, mFrame, mOffset, OffsetIsAtLineEdge::No);
}
@ -8963,15 +8962,16 @@ nsIFrame::SelectablePeekReport::SelectablePeekReport(
// Return an empty report
}
nsresult nsIFrame::PeekOffsetForCharacter(nsPeekOffsetStruct* aPos,
nsresult nsIFrame::PeekOffsetForCharacter(PeekOffsetStruct* aPos,
int32_t aOffset) {
SelectablePeekReport current{this, aOffset};
nsIFrame::FrameSearchResult peekSearchState = CONTINUE;
while (peekSearchState != FOUND) {
bool movingInFrameDirection = IsMovingInFrameDirection(
current.mFrame, aPos->mDirection, aPos->mVisual);
const bool movingInFrameDirection = IsMovingInFrameDirection(
current.mFrame, aPos->mDirection,
aPos->mOptions.contains(PeekOffsetOption::Visual));
if (current.mJumpedLine) {
// If we jumped lines, it's as if we found a character, but we still need
@ -9002,7 +9002,8 @@ nsresult nsIFrame::PeekOffsetForCharacter(nsPeekOffsetStruct* aPos,
// the offset to be at the frame edge. Note that if we are extending the
// selection, this doesn't matter.
if (peekSearchState == FOUND && current.mMovedOverNonSelectableText &&
(!aPos->mExtend || current.mHasSelectableFrame)) {
(!aPos->mOptions.contains(PeekOffsetOption::Extend) ||
current.mHasSelectableFrame)) {
auto [start, end] = current.mFrame->GetOffsets();
current.mOffset = aPos->mDirection == eDirNext ? 0 : end - start;
}
@ -9022,8 +9023,7 @@ nsresult nsIFrame::PeekOffsetForCharacter(nsPeekOffsetStruct* aPos,
return NS_OK;
}
nsresult nsIFrame::PeekOffsetForWord(nsPeekOffsetStruct* aPos,
int32_t aOffset) {
nsresult nsIFrame::PeekOffsetForWord(PeekOffsetStruct* aPos, int32_t aOffset) {
SelectablePeekReport current{this, aOffset};
bool shouldStopAtHardBreak =
aPos->mWordMovementType == eDefaultBehavior &&
@ -9033,11 +9033,14 @@ nsresult nsIFrame::PeekOffsetForWord(nsPeekOffsetStruct* aPos,
PeekWordState state;
while (true) {
bool movingInFrameDirection = IsMovingInFrameDirection(
current.mFrame, aPos->mDirection, aPos->mVisual);
current.mFrame, aPos->mDirection,
aPos->mOptions.contains(PeekOffsetOption::Visual));
FrameSearchResult searchResult = current.mFrame->PeekOffsetWord(
movingInFrameDirection, wordSelectEatSpace, aPos->mIsKeyboardSelect,
&current.mOffset, &state, aPos->mTrimSpaces);
movingInFrameDirection, wordSelectEatSpace,
aPos->mOptions.contains(PeekOffsetOption::IsKeyboardSelect),
&current.mOffset, &state,
!aPos->mOptions.contains(PeekOffsetOption::PreserveSpaces));
if (searchResult == FOUND) {
break;
}
@ -9128,7 +9131,7 @@ static nsIFrame* GetFirstSelectableDescendantWithLineIterator(
return nullptr;
}
nsresult nsIFrame::PeekOffsetForLine(nsPeekOffsetStruct* aPos) {
nsresult nsIFrame::PeekOffsetForLine(PeekOffsetStruct* aPos) {
nsIFrame* blockFrame = this;
nsresult result = NS_ERROR_FAILURE;
@ -9136,8 +9139,8 @@ nsresult nsIFrame::PeekOffsetForLine(nsPeekOffsetStruct* aPos) {
// moving to a next block when no more blocks are available in a subtree
AutoAssertNoDomMutations guard;
while (NS_FAILED(result)) {
auto [newBlock, lineFrame] =
blockFrame->GetContainingBlockForLine(aPos->mScrollViewStop);
auto [newBlock, lineFrame] = blockFrame->GetContainingBlockForLine(
aPos->mOptions.contains(PeekOffsetOption::ScrollViewStop));
if (!newBlock) {
return NS_ERROR_FAILURE;
}
@ -9194,7 +9197,8 @@ nsresult nsIFrame::PeekOffsetForLine(nsPeekOffsetStruct* aPos) {
if (shouldDrillIntoChildren) {
nsIFrame* child = GetFirstSelectableDescendantWithLineIterator(
aPos->mResultFrame, aPos->mForceEditableRegion);
aPos->mResultFrame,
aPos->mOptions.contains(PeekOffsetOption::ForceEditableRegion));
if (child) {
aPos->mResultFrame = child;
}
@ -9225,13 +9229,13 @@ nsresult nsIFrame::PeekOffsetForLine(nsPeekOffsetStruct* aPos) {
return result;
}
nsresult nsIFrame::PeekOffsetForLineEdge(nsPeekOffsetStruct* aPos) {
nsresult nsIFrame::PeekOffsetForLineEdge(PeekOffsetStruct* aPos) {
// Adjusted so that the caret can't get confused when content changes
nsIFrame* frame = AdjustFrameForSelectionStyles(this);
Element* editingHost = frame->GetContent()->GetEditingHost();
auto [blockFrame, lineFrame] =
frame->GetContainingBlockForLine(aPos->mScrollViewStop);
auto [blockFrame, lineFrame] = frame->GetContainingBlockForLine(
aPos->mOptions.contains(PeekOffsetOption::ScrollViewStop));
if (!blockFrame) {
return NS_ERROR_FAILURE;
}
@ -9245,7 +9249,8 @@ nsresult nsIFrame::PeekOffsetForLineEdge(nsPeekOffsetStruct* aPos) {
nsIFrame* baseFrame = nullptr;
bool endOfLine = eSelectEndLine == aPos->mAmount;
if (aPos->mVisual && PresContext()->BidiEnabled()) {
if (aPos->mOptions.contains(PeekOffsetOption::Visual) &&
PresContext()->BidiEnabled()) {
nsIFrame* firstFrame;
bool isReordered;
nsIFrame* lastFrame;
@ -9305,7 +9310,7 @@ nsresult nsIFrame::PeekOffsetForLineEdge(nsPeekOffsetStruct* aPos) {
return NS_OK;
}
nsresult nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos) {
nsresult nsIFrame::PeekOffset(PeekOffsetStruct* aPos) {
MOZ_ASSERT(aPos);
if (NS_WARN_IF(HasAnyStateBits(NS_FRAME_IS_DIRTY))) {
@ -9627,9 +9632,12 @@ nsIFrame::SelectablePeekReport nsIFrame::GetFrameFromDirection(
}
nsIFrame::SelectablePeekReport nsIFrame::GetFrameFromDirection(
const nsPeekOffsetStruct& aPos) {
return GetFrameFromDirection(aPos.mDirection, aPos.mVisual, aPos.mJumpLines,
aPos.mScrollViewStop, aPos.mForceEditableRegion);
const PeekOffsetStruct& aPos) {
return GetFrameFromDirection(
aPos.mDirection, aPos.mOptions.contains(PeekOffsetOption::Visual),
aPos.mOptions.contains(PeekOffsetOption::JumpLines),
aPos.mOptions.contains(PeekOffsetOption::ScrollViewStop),
aPos.mOptions.contains(PeekOffsetOption::ForceEditableRegion));
}
nsView* nsIFrame::GetClosestView(nsPoint* aOffset) const {

Просмотреть файл

@ -125,7 +125,6 @@ class nsViewManager;
class nsWindowSizes;
struct nsBoxLayoutMetrics;
struct nsPeekOffsetStruct;
struct CharacterDataChangeInfo;
namespace mozilla {
@ -145,6 +144,8 @@ class PresShell;
class WidgetGUIEvent;
class WidgetMouseEvent;
struct PeekOffsetStruct;
namespace layers {
class Layer;
class LayerManager;
@ -3809,13 +3810,14 @@ class nsIFrame : public nsQueryFrame {
*
* @param aPos is defined in nsFrameSelection
*/
virtual nsresult PeekOffset(nsPeekOffsetStruct* aPos);
virtual nsresult PeekOffset(mozilla::PeekOffsetStruct* aPos);
private:
nsresult PeekOffsetForCharacter(nsPeekOffsetStruct* aPos, int32_t aOffset);
nsresult PeekOffsetForWord(nsPeekOffsetStruct* aPos, int32_t aOffset);
nsresult PeekOffsetForLine(nsPeekOffsetStruct* aPos);
nsresult PeekOffsetForLineEdge(nsPeekOffsetStruct* aPos);
nsresult PeekOffsetForCharacter(mozilla::PeekOffsetStruct* aPos,
int32_t aOffset);
nsresult PeekOffsetForWord(mozilla::PeekOffsetStruct* aPos, int32_t aOffset);
nsresult PeekOffsetForLine(mozilla::PeekOffsetStruct* aPos);
nsresult PeekOffsetForLineEdge(mozilla::PeekOffsetStruct* aPos);
/**
* Search for the first paragraph boundary before or after the given position
@ -3824,7 +3826,7 @@ class nsIFrame : public nsQueryFrame {
* Input: mDirection
* Output: mResultContent, mContentOffset
*/
nsresult PeekOffsetForParagraph(nsPeekOffsetStruct* aPos);
nsresult PeekOffsetForParagraph(mozilla::PeekOffsetStruct* aPos);
public:
// given a frame five me the first/last leaf available
@ -3861,7 +3863,7 @@ class nsIFrame : public nsQueryFrame {
};
/** Transfers frame and offset info for PeekOffset() result */
void TransferTo(nsPeekOffsetStruct& aPos) const;
void TransferTo(mozilla::PeekOffsetStruct& aPos) const;
bool Failed() { return !mFrame; }
explicit SelectablePeekReport(nsIFrame* aFrame = nullptr,
@ -3886,7 +3888,8 @@ class nsIFrame : public nsQueryFrame {
bool aScrollViewStop,
bool aForceEditableRegion);
SelectablePeekReport GetFrameFromDirection(const nsPeekOffsetStruct& aPos);
SelectablePeekReport GetFrameFromDirection(
const mozilla::PeekOffsetStruct& aPos);
/**
* Return: