зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
3f04e976fa
Коммит
1387f2e7bc
|
@ -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,
|
||||
¤t.mOffset, &state, aPos->mTrimSpaces);
|
||||
movingInFrameDirection, wordSelectEatSpace,
|
||||
aPos->mOptions.contains(PeekOffsetOption::IsKeyboardSelect),
|
||||
¤t.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:
|
||||
|
|
Загрузка…
Ссылка в новой задаче