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:
@@ -2323,7 +2323,8 @@ Result<CreateElementResult, nsresult> HTMLEditor::HandleInsertBRElement(
|
||||
|
||||
const bool editingHostIsEmpty = HTMLEditUtils::IsEmptyNode(
|
||||
aEditingHost, {EmptyCheckOption::TreatNonEditableContentAsInvisible});
|
||||
WSRunScanner wsRunScanner(&aEditingHost, aPointToBreak,
|
||||
const WSRunScanner wsRunScanner(WSRunScanner::Scan::EditableNodes,
|
||||
aPointToBreak,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
const WSScanResult backwardScanResult =
|
||||
wsRunScanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(aPointToBreak);
|
||||
@@ -2619,7 +2620,8 @@ 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,
|
||||
const WSRunScanner wsScannerAtCaret(
|
||||
WSRunScanner::Scan::EditableNodes, pointToPutCaret,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (wsScannerAtCaret.StartsFromPreformattedLineBreak() &&
|
||||
(wsScannerAtCaret.EndsByBlockBoundary() ||
|
||||
@@ -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,7 +7868,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 wsScannerAtStart(&aEditingHost, startPoint,
|
||||
const WSRunScanner wsScannerAtStart(WSRunScanner::Scan::EditableNodes,
|
||||
startPoint,
|
||||
BlockInlineCheck::UseHTMLDefaultStyle);
|
||||
const WSScanResult scanResultAtStart =
|
||||
wsScannerAtStart.ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
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);
|
||||
|
||||
@@ -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,7 +3082,8 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
aHTMLEditor.GetEditAction())) {
|
||||
return EditorDOMPoint();
|
||||
}
|
||||
WSRunScanner scanner(&aEditingHost, EditorRawDOMPoint(mBRElement),
|
||||
const WSRunScanner scanner(
|
||||
WSRunScanner::Scan::EditableNodes, EditorRawDOMPoint(mBRElement),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
const WSScanResult maybePreviousText =
|
||||
scanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||
@@ -4554,7 +4553,8 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
// node because the other browsers insert following inputs into there.
|
||||
if (MayEditActionDeleteAroundCollapsedSelection(
|
||||
aHTMLEditor.GetEditAction())) {
|
||||
WSRunScanner scanner(&aEditingHost, startOfRightContent,
|
||||
const WSRunScanner scanner(
|
||||
WSRunScanner::Scan::EditableNodes, startOfRightContent,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
const WSScanResult maybePreviousText =
|
||||
scanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(startOfRightContent);
|
||||
@@ -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,7 +6478,8 @@ 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,
|
||||
const WSRunScanner scanner(WSRunScanner::Scan::EditableNodes,
|
||||
maybeDeepStartOfRightContent,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
const WSScanResult maybePreviousText =
|
||||
scanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
*****************************************************************************/
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user