Bug 1926483 - part 1: Make WSRunScanner instance free from editing host r=m_kato

If it scans starting from a editable point, it does not require the editing
host as an ancestor limiter.  Therefore, some users can be free from editing
host.

Differential Revision: https://phabricator.services.mozilla.com/D233791
This commit is contained in:
Masayuki Nakano
2025-01-24 05:00:47 +00:00
parent 94cf6b7230
commit 395226db0c
8 changed files with 122 additions and 123 deletions

View File

@@ -2323,8 +2323,9 @@ Result<CreateElementResult, nsresult> HTMLEditor::HandleInsertBRElement(
const bool editingHostIsEmpty = HTMLEditUtils::IsEmptyNode(
aEditingHost, {EmptyCheckOption::TreatNonEditableContentAsInvisible});
WSRunScanner wsRunScanner(&aEditingHost, aPointToBreak,
BlockInlineCheck::UseComputedDisplayStyle);
const WSRunScanner wsRunScanner(WSRunScanner::Scan::EditableNodes,
aPointToBreak,
BlockInlineCheck::UseComputedDisplayStyle);
const WSScanResult backwardScanResult =
wsRunScanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(aPointToBreak);
if (MOZ_UNLIKELY(backwardScanResult.Failed())) {
@@ -2619,8 +2620,9 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::HandleInsertLinefeed(
// boundary. Note that it should always be <br> for avoiding padding line
// breaks appear in `.textContent` value.
if (pointToPutCaret.IsInContentNode() && pointToPutCaret.IsEndOfContainer()) {
WSRunScanner wsScannerAtCaret(&aEditingHost, pointToPutCaret,
BlockInlineCheck::UseComputedDisplayStyle);
const WSRunScanner wsScannerAtCaret(
WSRunScanner::Scan::EditableNodes, pointToPutCaret,
BlockInlineCheck::UseComputedDisplayStyle);
if (wsScannerAtCaret.StartsFromPreformattedLineBreak() &&
(wsScannerAtCaret.EndsByBlockBoundary() ||
wsScannerAtCaret.EndsByInlineEditingHostBoundary()) &&
@@ -7821,8 +7823,8 @@ HTMLEditor::GetRangeExtendedToHardLineEdgesForBlockEditAction(
// Is there any intervening visible white-space? If so we can't push
// selection past that, it would visibly change meaning of users selection.
WSRunScanner wsScannerAtEnd(
&aEditingHost, endPoint,
const WSRunScanner wsScannerAtEnd(
WSRunScanner::Scan::EditableNodes, endPoint,
// We should refer only the default style of HTML because we need to wrap
// any elements with a specific HTML element. So we should not refer
// actual style. For example, we want to reformat parent HTML block
@@ -7866,8 +7868,9 @@ HTMLEditor::GetRangeExtendedToHardLineEdgesForBlockEditAction(
// Is there any intervening visible white-space? If so we can't push
// selection past that, it would visibly change meaning of users selection.
WSRunScanner wsScannerAtStart(&aEditingHost, startPoint,
BlockInlineCheck::UseHTMLDefaultStyle);
const WSRunScanner wsScannerAtStart(WSRunScanner::Scan::EditableNodes,
startPoint,
BlockInlineCheck::UseHTMLDefaultStyle);
const WSScanResult scanResultAtStart =
wsScannerAtStart.ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
startPoint);

View File

@@ -114,17 +114,15 @@ template nsIContent* HTMLEditUtils::GetContentToPreserveInlineStyles(
const EditorRawDOMPoint& aPoint, const Element& aEditingHost);
template EditorDOMPoint HTMLEditUtils::GetBetterInsertionPointFor(
const nsIContent& aContentToInsert, const EditorDOMPoint& aPointToInsert,
const Element& aEditingHost);
const nsIContent& aContentToInsert, const EditorDOMPoint& aPointToInsert);
template EditorRawDOMPoint HTMLEditUtils::GetBetterInsertionPointFor(
const nsIContent& aContentToInsert, const EditorRawDOMPoint& aPointToInsert,
const Element& aEditingHost);
const nsIContent& aContentToInsert,
const EditorRawDOMPoint& aPointToInsert);
template EditorDOMPoint HTMLEditUtils::GetBetterInsertionPointFor(
const nsIContent& aContentToInsert, const EditorRawDOMPoint& aPointToInsert,
const Element& aEditingHost);
const nsIContent& aContentToInsert,
const EditorRawDOMPoint& aPointToInsert);
template EditorRawDOMPoint HTMLEditUtils::GetBetterInsertionPointFor(
const nsIContent& aContentToInsert, const EditorDOMPoint& aPointToInsert,
const Element& aEditingHost);
const nsIContent& aContentToInsert, const EditorDOMPoint& aPointToInsert);
template EditorDOMPoint HTMLEditUtils::GetBetterCaretPositionToInsertText(
const EditorDOMPoint& aPoint, const Element& aEditingHost);
@@ -2546,6 +2544,9 @@ nsIContent* HTMLEditUtils::GetContentToPreserveInlineStyles(
if (nextVisibleThing.InVisibleOrCollapsibleCharacters()) {
return nextVisibleThing.TextPtr();
}
if (nextVisibleThing.GetContent() == &aEditingHost) {
break;
}
// Ignore empty inline container elements because it's not visible for
// users so that using the style will appear suddenly from point of
// view of users.
@@ -2566,18 +2567,16 @@ nsIContent* HTMLEditUtils::GetContentToPreserveInlineStyles(
template <typename EditorDOMPointType, typename EditorDOMPointTypeInput>
EditorDOMPointType HTMLEditUtils::GetBetterInsertionPointFor(
const nsIContent& aContentToInsert,
const EditorDOMPointTypeInput& aPointToInsert,
const Element& aEditingHost) {
const EditorDOMPointTypeInput& aPointToInsert) {
if (NS_WARN_IF(!aPointToInsert.IsSet())) {
return EditorDOMPointType();
}
auto pointToInsert =
aPointToInsert.template GetNonAnonymousSubtreePoint<EditorDOMPointType>();
if (MOZ_UNLIKELY(
NS_WARN_IF(!pointToInsert.IsSet()) ||
NS_WARN_IF(!pointToInsert.GetContainer()->IsInclusiveDescendantOf(
&aEditingHost)))) {
if (NS_WARN_IF(!pointToInsert.IsSet()) ||
NS_WARN_IF(!HTMLEditUtils::IsSimplyEditableNode(
*pointToInsert.GetContainer()))) {
// Cannot insert aContentToInsert into this DOM tree.
return EditorDOMPointType();
}
@@ -2589,8 +2588,8 @@ EditorDOMPointType HTMLEditUtils::GetBetterInsertionPointFor(
return pointToInsert;
}
WSRunScanner wsScannerForPointToInsert(
const_cast<Element*>(&aEditingHost), pointToInsert,
const WSRunScanner wsScannerForPointToInsert(
WSRunScanner::Scan::EditableNodes, pointToInsert,
BlockInlineCheck::UseComputedDisplayStyle);
// If the insertion position is after the last visible item in a line,
@@ -2644,10 +2643,9 @@ EditorDOMPointType HTMLEditUtils::GetBetterCaretPositionToInsertText(
return EditorDOMPointType(aPoint.GetChild(), 0u);
}
if (aPoint.IsEndOfContainer()) {
WSRunScanner scanner(&aEditingHost, aPoint,
BlockInlineCheck::UseComputedDisplayStyle);
const WSScanResult previousThing =
scanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(aPoint);
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
&aEditingHost, aPoint, BlockInlineCheck::UseComputedDisplayStyle);
if (previousThing.InVisibleOrCollapsibleCharacters()) {
return EditorDOMPointType::AtEndOf(*previousThing.TextPtr());
}

View File

@@ -2364,7 +2364,6 @@ class HTMLEditUtils final {
*
* @param aContentToInsert The content to insert.
* @param aPointToInsert A candidate point to insert the node.
* @param aEditingHost The editing host containing aPointToInsert.
* @return Better insertion point if next visible node
* is a <br> element and previous visible node
* is neither none, another <br> element nor
@@ -2373,8 +2372,7 @@ class HTMLEditUtils final {
template <typename EditorDOMPointType, typename EditorDOMPointTypeInput>
static EditorDOMPointType GetBetterInsertionPointFor(
const nsIContent& aContentToInsert,
const EditorDOMPointTypeInput& aPointToInsert,
const Element& aEditingHost);
const EditorDOMPointTypeInput& aPointToInsert);
/**
* GetBetterCaretPositionToInsertText() returns better point to put caret

View File

@@ -2244,12 +2244,16 @@ nsresult HTMLEditor::InsertElementAtSelectionAsAction(
if (!SelectionRef().GetAnchorNode()) {
return NS_OK;
}
if (NS_WARN_IF(!SelectionRef().GetAnchorNode()->IsInclusiveDescendantOf(
editingHost))) {
return NS_ERROR_FAILURE;
}
EditorRawDOMPoint atAnchor(SelectionRef().AnchorRef());
// Adjust position based on the node we are going to insert.
EditorDOMPoint pointToInsert =
HTMLEditUtils::GetBetterInsertionPointFor<EditorDOMPoint>(
*aElement, atAnchor, *editingHost);
HTMLEditUtils::GetBetterInsertionPointFor<EditorDOMPoint>(*aElement,
atAnchor);
if (!pointToInsert.IsSet()) {
NS_WARNING("HTMLEditUtils::GetBetterInsertionPointFor() failed");
return NS_ERROR_FAILURE;

View File

@@ -501,8 +501,8 @@ HTMLEditor::HTMLWithContextInserter::FragmentFromPasteCreator final {
HTMLBRElement*
HTMLEditor::HTMLWithContextInserter::GetInvisibleBRElementAtPoint(
const EditorDOMPoint& aPointToInsert) const {
WSRunScanner wsRunScannerAtInsertionPoint(
mHTMLEditor.ComputeEditingHost(), aPointToInsert,
const WSRunScanner wsRunScannerAtInsertionPoint(
WSRunScanner::Scan::EditableNodes, aPointToInsert,
BlockInlineCheck::UseComputedDisplayStyle);
if (wsRunScannerAtInsertionPoint.EndsByInvisibleBRElement()) {
return wsRunScannerAtInsertionPoint.EndReasonBRElementPtr();
@@ -563,14 +563,14 @@ HTMLEditor::HTMLWithContextInserter::GetNewCaretPointAfterInsertingHTML(
// Make sure we don't end up with selection collapsed after an invisible
// `<br>` element.
Element* editingHost = mHTMLEditor.ComputeEditingHost();
WSRunScanner wsRunScannerAtCaret(editingHost, pointToPutCaret,
BlockInlineCheck::UseComputedDisplayStyle);
const WSRunScanner wsRunScannerAtCaret(
WSRunScanner::Scan::EditableNodes, pointToPutCaret,
BlockInlineCheck::UseComputedDisplayStyle);
if (wsRunScannerAtCaret
.ScanPreviousVisibleNodeOrBlockBoundaryFrom(pointToPutCaret)
.ReachedInvisibleBRElement()) {
WSRunScanner wsRunScannerAtStartReason(
editingHost,
const WSRunScanner wsRunScannerAtStartReason(
WSRunScanner::Scan::EditableNodes,
EditorDOMPoint(wsRunScannerAtCaret.GetStartReasonContent()),
BlockInlineCheck::UseComputedDisplayStyle);
const WSScanResult backwardScanFromPointToCaretResult =
@@ -830,11 +830,18 @@ Result<EditActionResult, nsresult> HTMLEditor::HTMLWithContextInserter::Run(
}
// Adjust position based on the first node we are going to insert.
const auto candidatePointToInsert =
mHTMLEditor.GetFirstSelectionStartPoint<EditorRawDOMPoint>();
if (NS_WARN_IF(!candidatePointToInsert.IsSet()) ||
NS_WARN_IF(
!candidatePointToInsert.GetContainer()->IsInclusiveDescendantOf(
&mEditingHost))) {
return Err(NS_ERROR_FAILURE);
}
EditorDOMPoint pointToInsert =
HTMLEditUtils::GetBetterInsertionPointFor<EditorDOMPoint>(
arrayOfTopMostChildContents[0],
mHTMLEditor.GetFirstSelectionStartPoint<EditorRawDOMPoint>(),
mEditingHost);
mHTMLEditor.GetFirstSelectionStartPoint<EditorRawDOMPoint>());
if (!pointToInsert.IsSet()) {
NS_WARNING("HTMLEditor::GetBetterInsertionPointFor() failed");
return Err(NS_ERROR_FAILURE);

View File

@@ -1517,8 +1517,8 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDelete(
EditorType::HTML)) {
return NS_SUCCESS_DOM_NO_OPERATION;
}
WSRunScanner wsRunScannerAtCaret(
&aEditingHost, caretPoint,
const WSRunScanner wsRunScannerAtCaret(
WSRunScanner::Scan::EditableNodes, caretPoint,
BlockInlineCheck::UseComputedDisplayOutsideStyle);
const WSScanResult scanFromCaretPointResult =
aDirectionAndAmount == nsIEditor::eNext
@@ -1535,8 +1535,7 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDelete(
MOZ_ASSERT(scanFromCaretPointResult.GetContent());
if (scanFromCaretPointResult.ReachedBRElement()) {
if (scanFromCaretPointResult.BRElementPtr() ==
wsRunScannerAtCaret.GetEditingHost()) {
if (scanFromCaretPointResult.BRElementPtr() == &aEditingHost) {
return NS_OK;
}
if (!scanFromCaretPointResult.IsContentEditable()) {
@@ -1812,8 +1811,8 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::Run(
*caretPoint.ref().ContainerAs<nsIContent>(), EditorType::HTML)) {
return EditActionResult::CanceledResult();
}
WSRunScanner wsRunScannerAtCaret(
&aEditingHost, caretPoint.ref(),
const WSRunScanner wsRunScannerAtCaret(
WSRunScanner::Scan::EditableNodes, caretPoint.ref(),
BlockInlineCheck::UseComputedDisplayOutsideStyle);
const WSScanResult scanFromCaretPointResult =
aDirectionAndAmount == nsIEditor::eNext
@@ -1872,8 +1871,8 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::Run(
NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT)) {
// Let's check whether there is new invisible `<br>` element
// for avoiding infinite recursive calls.
WSRunScanner wsRunScannerAtCaret(
&aEditingHost, caretPoint.ref(),
const WSRunScanner wsRunScannerAtCaret(
WSRunScanner::Scan::EditableNodes, caretPoint.ref(),
BlockInlineCheck::UseComputedDisplayOutsideStyle);
const WSScanResult scanFromCaretPointResult =
aDirectionAndAmount == nsIEditor::eNext
@@ -1956,8 +1955,7 @@ HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteAroundCollapsedRanges(
aScanFromCaretPointResult.ReachedBRElement() ||
aScanFromCaretPointResult.ReachedHRElement() ||
aScanFromCaretPointResult.ReachedNonEditableOtherBlockElement()) {
if (aScanFromCaretPointResult.GetContent() ==
aWSRunScannerAtCaret.GetEditingHost()) {
if (aScanFromCaretPointResult.GetContent() == &aEditingHost) {
return NS_OK;
}
nsIContent* atomicContent = GetAtomicContentToDelete(
@@ -2727,7 +2725,7 @@ HTMLEditor::AutoDeleteRangesHandler::HandleDeleteAtomicContent(
const Element& aEditingHost) {
MOZ_ASSERT(aHTMLEditor.IsEditActionDataAvailable());
MOZ_ASSERT(!HTMLEditUtils::IsInvisibleBRElement(aAtomicContent));
MOZ_ASSERT(&aAtomicContent != aWSRunScannerAtCaret.GetEditingHost());
MOZ_ASSERT(!aAtomicContent.IsEditingHost());
EditorDOMPoint pointToPutCaret = aCaretPoint;
{
@@ -3084,8 +3082,9 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
aHTMLEditor.GetEditAction())) {
return EditorDOMPoint();
}
WSRunScanner scanner(&aEditingHost, EditorRawDOMPoint(mBRElement),
BlockInlineCheck::UseComputedDisplayOutsideStyle);
const WSRunScanner scanner(
WSRunScanner::Scan::EditableNodes, EditorRawDOMPoint(mBRElement),
BlockInlineCheck::UseComputedDisplayOutsideStyle);
const WSScanResult maybePreviousText =
scanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(
EditorRawDOMPoint(mBRElement));
@@ -4554,8 +4553,9 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
// node because the other browsers insert following inputs into there.
if (MayEditActionDeleteAroundCollapsedSelection(
aHTMLEditor.GetEditAction())) {
WSRunScanner scanner(&aEditingHost, startOfRightContent,
BlockInlineCheck::UseComputedDisplayOutsideStyle);
const WSRunScanner scanner(
WSRunScanner::Scan::EditableNodes, startOfRightContent,
BlockInlineCheck::UseComputedDisplayOutsideStyle);
const WSScanResult maybePreviousText =
scanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(startOfRightContent);
if (maybePreviousText.IsContentEditable() &&
@@ -5684,8 +5684,9 @@ HTMLEditor::AutoDeleteRangesHandler::DeleteParentBlocksWithTransactionIfEmpty(
// First, check there is visible contents before the point in current block.
RefPtr<Element> editingHost = aHTMLEditor.ComputeEditingHost();
WSRunScanner wsScannerForPoint(
editingHost, aPoint, BlockInlineCheck::UseComputedDisplayOutsideStyle);
const WSRunScanner wsScannerForPoint(
WSRunScanner::Scan::EditableNodes, aPoint,
BlockInlineCheck::UseComputedDisplayOutsideStyle);
if (!wsScannerForPoint.StartsFromCurrentBlockBoundary() &&
!wsScannerForPoint.StartsFromInlineEditingHostBoundary()) {
// If there is visible node before the point, we shouldn't remove the
@@ -6477,8 +6478,9 @@ Result<DeleteRangeResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
// We should put caret to end of preceding text node if there is.
// Then, users can type text into it like the other browsers.
auto pointToPutCaret = [&]() -> EditorDOMPoint {
WSRunScanner scanner(&aEditingHost, maybeDeepStartOfRightContent,
BlockInlineCheck::UseComputedDisplayStyle);
const WSRunScanner scanner(WSRunScanner::Scan::EditableNodes,
maybeDeepStartOfRightContent,
BlockInlineCheck::UseComputedDisplayStyle);
const WSScanResult maybePreviousText =
scanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(
maybeDeepStartOfRightContent);
@@ -8350,7 +8352,8 @@ HTMLEditor::AutoDeleteRangesHandler::ExtendOrShrinkRangeToDelete(
break;
}
MOZ_ASSERT(backwardScanFromStartResult.GetContent() ==
WSRunScanner(closestEditingHost, rangeToDelete.StartRef(),
WSRunScanner(WSRunScanner::Scan::EditableNodes,
rangeToDelete.StartRef(),
BlockInlineCheck::UseComputedDisplayOutsideStyle)
.GetStartReasonContent());
// We want to keep looking up. But stop if we are crossing table
@@ -8396,8 +8399,8 @@ HTMLEditor::AutoDeleteRangesHandler::ExtendOrShrinkRangeToDelete(
if (rangeToDelete.EndRef().GetContainer() !=
closestBlockAncestorOrInlineEditingHost) {
for (;;) {
WSRunScanner wsScannerAtEnd(
closestEditingHost, rangeToDelete.EndRef(),
const WSRunScanner wsScannerAtEnd(
WSRunScanner::Scan::EditableNodes, rangeToDelete.EndRef(),
BlockInlineCheck::UseComputedDisplayOutsideStyle);
const WSScanResult forwardScanFromEndResult =
wsScannerAtEnd.ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(

View File

@@ -83,13 +83,14 @@ WSScanResult WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundaryFrom(
// If the visible things are not editable, we shouldn't scan "editable"
// things now. Whether keep scanning editable things or not should be
// considered by the caller.
if (aPoint.GetChild() && !aPoint.GetChild()->IsEditable()) {
if (mScanMode == Scan::EditableNodes && aPoint.GetChild() &&
!HTMLEditUtils::IsSimplyEditableNode((*aPoint.GetChild()))) {
return WSScanResult(WSScanResult::ScanDirection::Backward,
*aPoint.GetChild(), WSType::SpecialContent,
mBlockInlineCheck);
}
const auto atPreviousChar =
GetPreviousEditableCharPoint<EditorRawDOMPointInText>(aPoint);
GetPreviousCharPoint<EditorRawDOMPointInText>(aPoint);
// When it's a non-empty text node, return it.
if (atPreviousChar.IsSet() && !atPreviousChar.IsContainerEmpty()) {
MOZ_ASSERT(!atPreviousChar.IsEndOfContainer());
@@ -180,13 +181,13 @@ WSScanResult WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
// If the visible things are not editable, we shouldn't scan "editable"
// things now. Whether keep scanning editable things or not should be
// considered by the caller.
if (aPoint.GetChild() && !aPoint.GetChild()->IsEditable()) {
if (mScanMode == Scan::EditableNodes && aPoint.GetChild() &&
!HTMLEditUtils::IsSimplyEditableNode(*aPoint.GetChild())) {
return WSScanResult(WSScanResult::ScanDirection::Forward,
*aPoint.GetChild(), WSType::SpecialContent,
mBlockInlineCheck);
}
const auto atNextChar =
GetInclusiveNextEditableCharPoint<EditorDOMPoint>(aPoint);
const auto atNextChar = GetInclusiveNextCharPoint<EditorDOMPoint>(aPoint);
// When it's a non-empty text node, return it.
if (atNextChar.IsSet() && !atNextChar.IsContainerEmpty()) {
return WSScanResult(WSScanResult::ScanDirection::Forward, atNextChar,
@@ -293,15 +294,6 @@ EditorDOMPointType WSRunScanner::GetFirstVisiblePoint(Text& aTextNode) {
return invisibleWhiteSpaceRange.EndRef().To<EditorDOMPointType>();
}
char16_t WSRunScanner::GetCharAt(Text* aTextNode, uint32_t aOffset) const {
// return 0 if we can't get a char, for whatever reason
if (NS_WARN_IF(!aTextNode) ||
NS_WARN_IF(aOffset >= aTextNode->TextDataLength())) {
return 0;
}
return aTextNode->TextFragment().CharAt(aOffset);
}
/*****************************************************************************
* Implementation for new white-space normalizer
*****************************************************************************/

View File

@@ -435,14 +435,14 @@ class MOZ_STACK_CLASS WSRunScanner final {
}
template <typename EditorDOMPointType>
WSRunScanner(const Element* aEditingHost,
const EditorDOMPointType& aScanStartPoint,
BlockInlineCheck aBlockInlineCheck)
WSRunScanner(Scan aScanMode, const EditorDOMPointType& aScanStartPoint,
BlockInlineCheck aBlockInlineCheck,
const Element* aAncestorLimiter = nullptr)
: mScanStartPoint(aScanStartPoint.template To<EditorDOMPoint>()),
mEditingHost(const_cast<Element*>(aEditingHost)),
mTextFragmentDataAtStart(Scan::EditableNodes, mScanStartPoint,
aBlockInlineCheck),
mBlockInlineCheck(aBlockInlineCheck) {}
mTextFragmentDataAtStart(aScanMode, mScanStartPoint, aBlockInlineCheck,
aAncestorLimiter),
mBlockInlineCheck(aBlockInlineCheck),
mScanMode(aScanMode) {}
// ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom() returns the first visible
// node at or after aPoint. If there is no visible nodes after aPoint,
@@ -457,7 +457,8 @@ class MOZ_STACK_CLASS WSRunScanner final {
static WSScanResult ScanInclusiveNextVisibleNodeOrBlockBoundary(
const Element* aEditingHost, const EditorDOMPointBase<PT, CT>& aPoint,
BlockInlineCheck aBlockInlineCheck) {
return WSRunScanner(aEditingHost, aPoint, aBlockInlineCheck)
return WSRunScanner(Scan::EditableNodes, aPoint, aBlockInlineCheck,
aEditingHost)
.ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(aPoint);
}
@@ -474,7 +475,8 @@ class MOZ_STACK_CLASS WSRunScanner final {
static WSScanResult ScanPreviousVisibleNodeOrBlockBoundary(
const Element* aEditingHost, const EditorDOMPointBase<PT, CT>& aPoint,
BlockInlineCheck aBlockInlineCheck) {
return WSRunScanner(aEditingHost, aPoint, aBlockInlineCheck)
return WSRunScanner(Scan::EditableNodes, aPoint, aBlockInlineCheck,
aEditingHost)
.ScanPreviousVisibleNodeOrBlockBoundaryFrom(aPoint);
}
@@ -494,8 +496,9 @@ class MOZ_STACK_CLASS WSRunScanner final {
return EditorDOMPointType(aPoint.template ContainerAs<Text>(),
aPoint.Offset());
}
return WSRunScanner(aEditingHost, aPoint, aBlockInlineCheck)
.GetInclusiveNextEditableCharPoint<EditorDOMPointType>(aPoint);
return WSRunScanner(Scan::EditableNodes, aPoint, aBlockInlineCheck,
aEditingHost)
.GetInclusiveNextCharPoint<EditorDOMPointType>(aPoint);
}
/**
@@ -513,8 +516,9 @@ class MOZ_STACK_CLASS WSRunScanner final {
return EditorDOMPointType(aPoint.template ContainerAs<Text>(),
aPoint.Offset() - 1);
}
return WSRunScanner(aEditingHost, aPoint, aBlockInlineCheck)
.GetPreviousEditableCharPoint<EditorDOMPointType>(aPoint);
return WSRunScanner(Scan::EditableNodes, aPoint, aBlockInlineCheck,
aEditingHost)
.GetPreviousCharPoint<EditorDOMPointType>(aPoint);
}
/**
@@ -719,11 +723,6 @@ class MOZ_STACK_CLASS WSRunScanner final {
return TextFragmentDataAtStartRef().EndReasonBRElementPtr();
}
/**
* Active editing host when this instance is created.
*/
Element* GetEditingHost() const { return mEditingHost; }
protected:
using EditorType = EditorBase::EditorType;
@@ -845,34 +844,36 @@ class MOZ_STACK_CLASS WSRunScanner final {
using PointPosition = VisibleWhiteSpacesData::PointPosition;
/**
* GetInclusiveNextEditableCharPoint() returns aPoint if it points a character
* in an editable text node, or start of next editable text node otherwise.
* FYI: For the performance, this does not check whether given container
* is not after mStart.mReasonContent or not.
* Return aPoint if it points a character in a `Text` node, or start of next
* `Text` node otherwise.
* FYI: For the performance, this does not check whether given container is
* not after mStart.mReasonContent or not.
*/
template <typename EditorDOMPointType = EditorDOMPointInText, typename PT,
typename CT>
EditorDOMPointType GetInclusiveNextEditableCharPoint(
template <typename EditorDOMPointType, typename PT, typename CT>
EditorDOMPointType GetInclusiveNextCharPoint(
const EditorDOMPointBase<PT, CT>& aPoint) const {
return TextFragmentDataAtStartRef()
.GetInclusiveNextCharPoint<EditorDOMPointType>(
aPoint, IgnoreNonEditableNodes::Yes);
aPoint, mScanMode == Scan::EditableNodes
? IgnoreNonEditableNodes::Yes
: IgnoreNonEditableNodes::No);
}
/**
* GetPreviousEditableCharPoint() returns previous editable point in a
* text node. Note that this returns last character point when it meets
* non-empty text node, otherwise, returns a point in an empty text node.
* FYI: For the performance, this does not check whether given container
* is not before mEnd.mReasonContent or not.
* Return the previous editable point in a `Text` node. Note that this
* returns the last character point when it meets non-empty text node,
* otherwise, returns a point in an empty text node.
* FYI: For the performance, this does not check whether given container is
* not before mEnd.mReasonContent or not.
*/
template <typename EditorDOMPointType = EditorDOMPointInText, typename PT,
typename CT>
EditorDOMPointType GetPreviousEditableCharPoint(
template <typename EditorDOMPointType, typename PT, typename CT>
EditorDOMPointType GetPreviousCharPoint(
const EditorDOMPointBase<PT, CT>& aPoint) const {
return TextFragmentDataAtStartRef()
.GetPreviousCharPoint<EditorDOMPointType>(aPoint,
IgnoreNonEditableNodes::Yes);
.GetPreviousCharPoint<EditorDOMPointType>(
aPoint, mScanMode == Scan::EditableNodes
? IgnoreNonEditableNodes::Yes
: IgnoreNonEditableNodes::No);
}
/**
@@ -882,7 +883,7 @@ class MOZ_STACK_CLASS WSRunScanner final {
* Note that this may return different text node from the container of
* aPointAtASCIIWhiteSpace.
*/
template <typename EditorDOMPointType = EditorDOMPointInText>
template <typename EditorDOMPointType>
EditorDOMPointType GetEndOfCollapsibleASCIIWhiteSpaces(
const EditorDOMPointInText& aPointAtASCIIWhiteSpace,
nsIEditor::EDirection aDirectionToDelete) const {
@@ -902,7 +903,7 @@ class MOZ_STACK_CLASS WSRunScanner final {
* Note that this may return different text node from the container of
* aPointAtASCIIWhiteSpace.
*/
template <typename EditorDOMPointType = EditorDOMPointInText>
template <typename EditorDOMPointType>
EditorDOMPointType GetFirstASCIIWhiteSpacePointCollapsedTo(
const EditorDOMPointInText& aPointAtASCIIWhiteSpace,
nsIEditor::EDirection aDirectionToDelete) const {
@@ -914,11 +915,6 @@ class MOZ_STACK_CLASS WSRunScanner final {
aPointAtASCIIWhiteSpace, aDirectionToDelete);
}
EditorDOMPointInText GetPreviousCharPointFromPointInText(
const EditorDOMPointInText& aPoint) const;
char16_t GetCharAt(Text* aTextNode, uint32_t aOffset) const;
/**
* TextFragmentData stores the information of white-space sequence which
* contains `aPoint` of the constructor.
@@ -1524,9 +1520,6 @@ class MOZ_STACK_CLASS WSRunScanner final {
// Together, the above represent the point at which we are building up ws
// info.
// The editing host when the instance is created.
RefPtr<Element> mEditingHost;
private:
/**
* ComputeRangeInTextNodesContainingInvisibleWhiteSpaces() returns range
@@ -1545,6 +1538,7 @@ class MOZ_STACK_CLASS WSRunScanner final {
TextFragmentData mTextFragmentDataAtStart;
const BlockInlineCheck mBlockInlineCheck;
const Scan mScanMode;
friend class WhiteSpaceVisibilityKeeper;
};