Bug 1939220 - part 6: Make TextFragmentData free from the editing host r=m_kato

It stores the editing host. However, its role is scan the DOM from a point in
a block containing the point.  Therefore, it can know which node is editing
host when it scans without computing the editing host.  So, it does not need
to be specified the editing host.

Then, it can scan non-editable DOM too.  Therefore, this extends some utility
methods of `HTMLEditUtils` which are used by `TextFragmentData` and
`BoundaryData`.

Differential Revision: https://phabricator.services.mozilla.com/D232937
This commit is contained in:
Masayuki Nakano
2025-01-20 08:03:59 +00:00
parent 0e10d664fc
commit c6b4e944ef
11 changed files with 233 additions and 209 deletions

View File

@@ -224,8 +224,7 @@ void AutoClonedRangeArray::EnsureRangesInTextNode(const Text& aTextNode) {
Result<bool, nsresult> Result<bool, nsresult>
AutoClonedRangeArray::ShrinkRangesIfStartFromOrEndAfterAtomicContent( AutoClonedRangeArray::ShrinkRangesIfStartFromOrEndAfterAtomicContent(
const HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount, const HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount,
IfSelectingOnlyOneAtomicContent aIfSelectingOnlyOneAtomicContent, IfSelectingOnlyOneAtomicContent aIfSelectingOnlyOneAtomicContent) {
const Element* aEditingHost) {
if (IsCollapsed()) { if (IsCollapsed()) {
return false; return false;
} }
@@ -246,7 +245,7 @@ AutoClonedRangeArray::ShrinkRangesIfStartFromOrEndAfterAtomicContent(
"Changing range in selection may cause running script"); "Changing range in selection may cause running script");
Result<bool, nsresult> result = Result<bool, nsresult> result =
WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent( WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent(
aHTMLEditor, range, aEditingHost); aHTMLEditor, range);
if (result.isErr()) { if (result.isErr()) {
NS_WARNING( NS_WARNING(
"WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent() " "WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent() "

View File

@@ -197,8 +197,7 @@ class MOZ_STACK_CLASS AutoClonedRangeArray {
}; };
Result<bool, nsresult> ShrinkRangesIfStartFromOrEndAfterAtomicContent( Result<bool, nsresult> ShrinkRangesIfStartFromOrEndAfterAtomicContent(
const HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount, const HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount,
IfSelectingOnlyOneAtomicContent aIfSelectingOnlyOneAtomicContent, IfSelectingOnlyOneAtomicContent aIfSelectingOnlyOneAtomicContent);
const dom::Element* aEditingHost);
/** /**
* The following methods are same as `Selection`'s methods. * The following methods are same as `Selection`'s methods.

View File

@@ -1250,7 +1250,7 @@ Result<EditActionResult, nsresult> HTMLEditor::HandleInsertText(
WhiteSpaceVisibilityKeeper::ReplaceText( WhiteSpaceVisibilityKeeper::ReplaceText(
*this, aInsertionString, *this, aInsertionString,
EditorDOMRange(pointToInsert, compositionEndPoint), EditorDOMRange(pointToInsert, compositionEndPoint),
InsertTextTo::ExistingTextNodeIfAvailable, *editingHost); InsertTextTo::ExistingTextNodeIfAvailable);
if (MOZ_UNLIKELY(replaceTextResult.isErr())) { if (MOZ_UNLIKELY(replaceTextResult.isErr())) {
NS_WARNING("WhiteSpaceVisibilityKeeper::ReplaceText() failed"); NS_WARNING("WhiteSpaceVisibilityKeeper::ReplaceText() failed");
return replaceTextResult.propagateErr(); return replaceTextResult.propagateErr();
@@ -1452,15 +1452,14 @@ Result<EditActionResult, nsresult> HTMLEditor::HandleInsertText(
if (!lineText.Contains(u'\t')) { if (!lineText.Contains(u'\t')) {
return WhiteSpaceVisibilityKeeper::InsertText( return WhiteSpaceVisibilityKeeper::InsertText(
*this, lineText, currentPoint, *this, lineText, currentPoint,
GetInsertTextTo(inclusiveNextLinefeedOffset, lineStartOffset), GetInsertTextTo(inclusiveNextLinefeedOffset,
*editingHost); lineStartOffset));
} }
nsAutoString formattedLineText(lineText); nsAutoString formattedLineText(lineText);
formattedLineText.ReplaceSubstring(u"\t"_ns, u" "_ns); formattedLineText.ReplaceSubstring(u"\t"_ns, u" "_ns);
return WhiteSpaceVisibilityKeeper::InsertText( return WhiteSpaceVisibilityKeeper::InsertText(
*this, formattedLineText, currentPoint, *this, formattedLineText, currentPoint,
GetInsertTextTo(inclusiveNextLinefeedOffset, lineStartOffset), GetInsertTextTo(inclusiveNextLinefeedOffset, lineStartOffset));
*editingHost);
}(); }();
if (MOZ_UNLIKELY(insertTextResult.isErr())) { if (MOZ_UNLIKELY(insertTextResult.isErr())) {
NS_WARNING("WhiteSpaceVisibilityKeeper::InsertText() failed"); NS_WARNING("WhiteSpaceVisibilityKeeper::InsertText() failed");
@@ -1481,8 +1480,8 @@ Result<EditActionResult, nsresult> HTMLEditor::HandleInsertText(
} }
Result<CreateLineBreakResult, nsresult> insertLineBreakResultOrError = Result<CreateLineBreakResult, nsresult> insertLineBreakResultOrError =
WhiteSpaceVisibilityKeeper::InsertLineBreak( WhiteSpaceVisibilityKeeper::InsertLineBreak(*lineBreakType, *this,
*lineBreakType, *this, currentPoint, *editingHost); currentPoint);
if (MOZ_UNLIKELY(insertLineBreakResultOrError.isErr())) { if (MOZ_UNLIKELY(insertLineBreakResultOrError.isErr())) {
NS_WARNING( NS_WARNING(
nsPrintfCString( nsPrintfCString(
@@ -1701,8 +1700,7 @@ nsresult HTMLEditor::InsertLineBreakAsSubAction() {
Result<CreateLineBreakResult, nsresult> Result<CreateLineBreakResult, nsresult>
insertPaddingBRElementResultOrError = insertPaddingBRElementResultOrError =
WhiteSpaceVisibilityKeeper::InsertLineBreak( WhiteSpaceVisibilityKeeper::InsertLineBreak(
LineBreakType::BRElement, *this, pointToPutCaret, LineBreakType::BRElement, *this, pointToPutCaret);
*editingHost);
if (MOZ_UNLIKELY(insertPaddingBRElementResultOrError.isErr())) { if (MOZ_UNLIKELY(insertPaddingBRElementResultOrError.isErr())) {
NS_WARNING( NS_WARNING(
"WhiteSpaceVisibilityKeeper::InsertLineBreak(LineBreakType::" "WhiteSpaceVisibilityKeeper::InsertLineBreak(LineBreakType::"
@@ -2404,8 +2402,8 @@ Result<CreateElementResult, nsresult> HTMLEditor::HandleInsertBRElement(
splitLinkNodeResult.inspect().AtSplitPoint<EditorDOMPoint>(); splitLinkNodeResult.inspect().AtSplitPoint<EditorDOMPoint>();
} }
Result<CreateLineBreakResult, nsresult> insertBRElementResultOrError = Result<CreateLineBreakResult, nsresult> insertBRElementResultOrError =
WhiteSpaceVisibilityKeeper::InsertLineBreak( WhiteSpaceVisibilityKeeper::InsertLineBreak(LineBreakType::BRElement,
LineBreakType::BRElement, *this, pointToBreak, aEditingHost); *this, pointToBreak);
if (MOZ_UNLIKELY(insertBRElementResultOrError.isErr())) { if (MOZ_UNLIKELY(insertBRElementResultOrError.isErr())) {
NS_WARNING( NS_WARNING(
"WhiteSpaceVisibilityKeeper::InsertLineBreak(LineBreakType::" "WhiteSpaceVisibilityKeeper::InsertLineBreak(LineBreakType::"
@@ -2434,7 +2432,7 @@ Result<CreateElementResult, nsresult> HTMLEditor::HandleInsertBRElement(
Result<CreateLineBreakResult, nsresult> Result<CreateLineBreakResult, nsresult>
insertPaddingBRElementResultOrError = insertPaddingBRElementResultOrError =
WhiteSpaceVisibilityKeeper::InsertLineBreak( WhiteSpaceVisibilityKeeper::InsertLineBreak(
LineBreakType::BRElement, *this, afterBRElement, aEditingHost); LineBreakType::BRElement, *this, afterBRElement);
NS_WARNING_ASSERTION(insertPaddingBRElementResultOrError.isOk(), NS_WARNING_ASSERTION(insertPaddingBRElementResultOrError.isOk(),
"WhiteSpaceVisibilityKeeper::InsertLineBreak(" "WhiteSpaceVisibilityKeeper::InsertLineBreak("
"LineBreakType::BRElement) failed"); "LineBreakType::BRElement) failed");

View File

@@ -2093,7 +2093,7 @@ EditorDOMPointType HTMLEditUtils::GetPreviousEditablePoint(
// There may be invisible trailing white-spaces which should be // There may be invisible trailing white-spaces which should be
// ignored. Let's scan its start. // ignored. Let's scan its start.
return WSRunScanner::GetAfterLastVisiblePoint<EditorDOMPointType>( return WSRunScanner::GetAfterLastVisiblePoint<EditorDOMPointType>(
*textNode, aAncestorLimiter); *textNode);
} }
// If it's a container element, return end of it. Otherwise, return // If it's a container element, return end of it. Otherwise, return
@@ -2204,8 +2204,7 @@ EditorDOMPointType HTMLEditUtils::GetNextEditablePoint(
} }
// There may be invisible leading white-spaces which should be // There may be invisible leading white-spaces which should be
// ignored. Let's scan its start. // ignored. Let's scan its start.
return WSRunScanner::GetFirstVisiblePoint<EditorDOMPointType>( return WSRunScanner::GetFirstVisiblePoint<EditorDOMPointType>(*textNode);
*textNode, aAncestorLimiter);
} }
// If it's a container element, return start of it. Otherwise, return // If it's a container element, return start of it. Otherwise, return

View File

@@ -1235,7 +1235,7 @@ class HTMLEditUtils final {
return content; return content;
} }
if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) &&
aNode.IsEditable() && !content->IsEditable()) { !HTMLEditUtils::IsSimplyEditableNode(*content)) {
return content; return content;
} }
content = content->GetLastChild(); content = content->GetLastChild();
@@ -1283,7 +1283,7 @@ class HTMLEditUtils final {
return content; return content;
} }
if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) &&
aNode.IsEditable() && !content->IsEditable()) { !HTMLEditUtils::IsSimplyEditableNode(*content)) {
return content; return content;
} }
content = content->GetFirstChild(); content = content->GetFirstChild();
@@ -1323,6 +1323,10 @@ class HTMLEditUtils final {
HTMLEditUtils::IsBlockElement(*parentElement, aBlockInlineCheck)) { HTMLEditUtils::IsBlockElement(*parentElement, aBlockInlineCheck)) {
return nullptr; return nullptr;
} }
if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) &&
!parentElement->IsEditable()) {
return nullptr;
}
nextContent = parentElement->GetNextSibling(); nextContent = parentElement->GetNextSibling();
if (nextContent) { if (nextContent) {
break; break;
@@ -1341,7 +1345,7 @@ class HTMLEditUtils final {
return nextContent; return nextContent;
} }
if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) &&
aStartContent.IsEditable() && !nextContent->IsEditable()) { !nextContent->IsEditable()) {
return nextContent; return nextContent;
} }
if (HTMLEditUtils::IsContainerNode(*nextContent)) { if (HTMLEditUtils::IsContainerNode(*nextContent)) {
@@ -1407,8 +1411,7 @@ class HTMLEditUtils final {
return nextContent; return nextContent;
} }
if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) &&
aStartPoint.GetContainer()->IsEditable() && !HTMLEditUtils::IsSimplyEditableNode(*nextContent)) {
!nextContent->IsEditable()) {
return nextContent; return nextContent;
} }
if (HTMLEditUtils::IsContainerNode(*nextContent)) { if (HTMLEditUtils::IsContainerNode(*nextContent)) {
@@ -1458,6 +1461,10 @@ class HTMLEditUtils final {
HTMLEditUtils::IsBlockElement(*parentElement, aBlockInlineCheck)) { HTMLEditUtils::IsBlockElement(*parentElement, aBlockInlineCheck)) {
return nullptr; return nullptr;
} }
if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) &&
!parentElement->IsEditable()) {
return nullptr;
}
previousContent = parentElement->GetPreviousSibling(); previousContent = parentElement->GetPreviousSibling();
if (previousContent) { if (previousContent) {
break; break;
@@ -1476,7 +1483,7 @@ class HTMLEditUtils final {
return previousContent; return previousContent;
} }
if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) &&
aStartContent.IsEditable() && !previousContent->IsEditable()) { !HTMLEditUtils::IsSimplyEditableNode(*previousContent)) {
return previousContent; return previousContent;
} }
if (HTMLEditUtils::IsContainerNode(*previousContent)) { if (HTMLEditUtils::IsContainerNode(*previousContent)) {
@@ -1547,8 +1554,7 @@ class HTMLEditUtils final {
return previousContent; return previousContent;
} }
if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) && if (aLeafNodeTypes.contains(LeafNodeType::LeafNodeOrNonEditableNode) &&
aStartPoint.GetContainer()->IsEditable() && !HTMLEditUtils::IsSimplyEditableNode(*previousContent)) {
!previousContent->IsEditable()) {
return previousContent; return previousContent;
} }
if (HTMLEditUtils::IsContainerNode(*previousContent)) { if (HTMLEditUtils::IsContainerNode(*previousContent)) {

View File

@@ -205,8 +205,7 @@ class MOZ_STACK_CLASS HTMLEditor::AutoDeleteRangesHandler final {
const Element& aEditingHost); const Element& aEditingHost);
nsresult ComputeRangesToDeleteTextAroundCollapsedRanges( nsresult ComputeRangesToDeleteTextAroundCollapsedRanges(
nsIEditor::EDirection aDirectionAndAmount, nsIEditor::EDirection aDirectionAndAmount,
AutoClonedSelectionRangeArray& aRangesToDelete, AutoClonedSelectionRangeArray& aRangesToDelete) const;
const Element& aEditingHost) const;
/** /**
* Handles deletion of collapsed selection at white-spaces in a text node. * Handles deletion of collapsed selection at white-spaces in a text node.
@@ -254,7 +253,7 @@ class MOZ_STACK_CLASS HTMLEditor::AutoDeleteRangesHandler final {
const WSRunScanner& aWSRunScannerAtCaret, const WSRunScanner& aWSRunScannerAtCaret,
const Element& aEditingHost); const Element& aEditingHost);
nsresult ComputeRangesToDeleteAtomicContent( nsresult ComputeRangesToDeleteAtomicContent(
Element* aEditingHost, const nsIContent& aAtomicContent, const nsIContent& aAtomicContent,
AutoClonedSelectionRangeArray& aRangesToDelete) const; AutoClonedSelectionRangeArray& aRangesToDelete) const;
/** /**
@@ -1439,16 +1438,12 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDelete(
if (NS_WARN_IF(!startPoint.IsSet())) { if (NS_WARN_IF(!startPoint.IsSet())) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
RefPtr<Element> editingHost = aHTMLEditor.ComputeEditingHost();
if (NS_WARN_IF(!editingHost)) {
return NS_ERROR_FAILURE;
}
if (startPoint.IsInContentNode()) { if (startPoint.IsInContentNode()) {
AutoEmptyBlockAncestorDeleter deleter; AutoEmptyBlockAncestorDeleter deleter;
if (deleter.ScanEmptyBlockInclusiveAncestor( if (deleter.ScanEmptyBlockInclusiveAncestor(
aHTMLEditor, *startPoint.ContainerAs<nsIContent>())) { aHTMLEditor, *startPoint.ContainerAs<nsIContent>())) {
nsresult rv = deleter.ComputeTargetRanges( nsresult rv = deleter.ComputeTargetRanges(
aHTMLEditor, aDirectionAndAmount, *editingHost, aRangesToDelete); aHTMLEditor, aDirectionAndAmount, aEditingHost, aRangesToDelete);
NS_WARNING_ASSERTION( NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv), NS_SUCCEEDED(rv),
"AutoEmptyBlockAncestorDeleter::ComputeTargetRanges() failed"); "AutoEmptyBlockAncestorDeleter::ComputeTargetRanges() failed");
@@ -1484,8 +1479,7 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDelete(
Result<bool, nsresult> shrunkenResult = Result<bool, nsresult> shrunkenResult =
aRangesToDelete.ShrinkRangesIfStartFromOrEndAfterAtomicContent( aRangesToDelete.ShrinkRangesIfStartFromOrEndAfterAtomicContent(
aHTMLEditor, aDirectionAndAmount, aHTMLEditor, aDirectionAndAmount,
AutoClonedRangeArray::IfSelectingOnlyOneAtomicContent::Collapse, AutoClonedRangeArray::IfSelectingOnlyOneAtomicContent::Collapse);
editingHost);
if (shrunkenResult.isErr()) { if (shrunkenResult.isErr()) {
NS_WARNING( NS_WARNING(
"AutoClonedRangeArray::" "AutoClonedRangeArray::"
@@ -1505,7 +1499,7 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDelete(
return NS_SUCCESS_DOM_NO_OPERATION; return NS_SUCCESS_DOM_NO_OPERATION;
} }
nsresult rv = FallbackToComputeRangesToDeleteRangesWithTransaction( nsresult rv = FallbackToComputeRangesToDeleteRangesWithTransaction(
aHTMLEditor, aRangesToDelete, *editingHost); aHTMLEditor, aRangesToDelete, aEditingHost);
NS_WARNING_ASSERTION( NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv), NS_SUCCEEDED(rv),
"AutoDeleteRangesHandler::" "AutoDeleteRangesHandler::"
@@ -1524,7 +1518,7 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDelete(
return NS_SUCCESS_DOM_NO_OPERATION; return NS_SUCCESS_DOM_NO_OPERATION;
} }
WSRunScanner wsRunScannerAtCaret( WSRunScanner wsRunScannerAtCaret(
editingHost, caretPoint, &aEditingHost, caretPoint,
BlockInlineCheck::UseComputedDisplayOutsideStyle); BlockInlineCheck::UseComputedDisplayOutsideStyle);
const WSScanResult scanFromCaretPointResult = const WSScanResult scanFromCaretPointResult =
aDirectionAndAmount == nsIEditor::eNext aDirectionAndAmount == nsIEditor::eNext
@@ -1769,8 +1763,7 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::Run(
Result<bool, nsresult> shrunkenResult = Result<bool, nsresult> shrunkenResult =
aRangesToDelete.ShrinkRangesIfStartFromOrEndAfterAtomicContent( aRangesToDelete.ShrinkRangesIfStartFromOrEndAfterAtomicContent(
aHTMLEditor, aDirectionAndAmount, aHTMLEditor, aDirectionAndAmount,
AutoClonedRangeArray::IfSelectingOnlyOneAtomicContent::Collapse, AutoClonedRangeArray::IfSelectingOnlyOneAtomicContent::Collapse);
&aEditingHost);
if (MOZ_UNLIKELY(shrunkenResult.isErr())) { if (MOZ_UNLIKELY(shrunkenResult.isErr())) {
NS_WARNING( NS_WARNING(
"AutoClonedRangeArray::" "AutoClonedRangeArray::"
@@ -1950,8 +1943,8 @@ HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteAroundCollapsedRanges(
NS_WARNING("AutoClonedRangeArray::Collapse() failed"); NS_WARNING("AutoClonedRangeArray::Collapse() failed");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
rv = ComputeRangesToDeleteTextAroundCollapsedRanges( rv = ComputeRangesToDeleteTextAroundCollapsedRanges(aDirectionAndAmount,
aDirectionAndAmount, aRangesToDelete, aEditingHost); aRangesToDelete);
NS_WARNING_ASSERTION( NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv), NS_SUCCEEDED(rv),
"AutoDeleteRangesHandler::" "AutoDeleteRangesHandler::"
@@ -1975,8 +1968,8 @@ HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteAroundCollapsedRanges(
"removable atomic content"); "removable atomic content");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
nsresult rv = ComputeRangesToDeleteAtomicContent( nsresult rv =
aWSRunScannerAtCaret.GetEditingHost(), *atomicContent, aRangesToDelete); ComputeRangesToDeleteAtomicContent(*atomicContent, aRangesToDelete);
NS_WARNING_ASSERTION( NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv), NS_SUCCEEDED(rv),
"AutoDeleteRangesHandler::ComputeRangesToDeleteAtomicContent() failed"); "AutoDeleteRangesHandler::ComputeRangesToDeleteAtomicContent() failed");
@@ -2250,8 +2243,7 @@ HTMLEditor::AutoDeleteRangesHandler::HandleDeleteAroundCollapsedRanges(
nsresult HTMLEditor::AutoDeleteRangesHandler:: nsresult HTMLEditor::AutoDeleteRangesHandler::
ComputeRangesToDeleteTextAroundCollapsedRanges( ComputeRangesToDeleteTextAroundCollapsedRanges(
nsIEditor::EDirection aDirectionAndAmount, nsIEditor::EDirection aDirectionAndAmount,
AutoClonedSelectionRangeArray& aRangesToDelete, AutoClonedSelectionRangeArray& aRangesToDelete) const {
const Element& aEditingHost) const {
MOZ_ASSERT(aDirectionAndAmount == nsIEditor::eNext || MOZ_ASSERT(aDirectionAndAmount == nsIEditor::eNext ||
aDirectionAndAmount == nsIEditor::ePrevious); aDirectionAndAmount == nsIEditor::ePrevious);
@@ -2265,8 +2257,7 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::
EditorDOMRangeInTexts rangeToDelete; EditorDOMRangeInTexts rangeToDelete;
if (aDirectionAndAmount == nsIEditor::eNext) { if (aDirectionAndAmount == nsIEditor::eNext) {
Result<EditorDOMRangeInTexts, nsresult> result = Result<EditorDOMRangeInTexts, nsresult> result =
WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(caretPosition, WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(caretPosition);
aEditingHost);
if (result.isErr()) { if (result.isErr()) {
NS_WARNING( NS_WARNING(
"WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom() failed"); "WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom() failed");
@@ -2278,8 +2269,7 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::
} }
} else { } else {
Result<EditorDOMRangeInTexts, nsresult> result = Result<EditorDOMRangeInTexts, nsresult> result =
WSRunScanner::GetRangeInTextNodesToBackspaceFrom(caretPosition, WSRunScanner::GetRangeInTextNodesToBackspaceFrom(caretPosition);
aEditingHost);
if (result.isErr()) { if (result.isErr()) {
NS_WARNING("WSRunScanner::GetRangeInTextNodesToBackspaceFrom() failed"); NS_WARNING("WSRunScanner::GetRangeInTextNodesToBackspaceFrom() failed");
return result.unwrapErr(); return result.unwrapErr();
@@ -2310,7 +2300,7 @@ HTMLEditor::AutoDeleteRangesHandler::HandleDeleteTextAroundCollapsedRanges(
aDirectionAndAmount == nsIEditor::ePrevious); aDirectionAndAmount == nsIEditor::ePrevious);
nsresult rv = ComputeRangesToDeleteTextAroundCollapsedRanges( nsresult rv = ComputeRangesToDeleteTextAroundCollapsedRanges(
aDirectionAndAmount, aRangesToDelete, aEditingHost); aDirectionAndAmount, aRangesToDelete);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
} }
@@ -2711,11 +2701,10 @@ nsIContent* HTMLEditor::AutoDeleteRangesHandler::GetAtomicContentToDelete(
nsresult nsresult
HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteAtomicContent( HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteAtomicContent(
Element* aEditingHost, const nsIContent& aAtomicContent, const nsIContent& aAtomicContent,
AutoClonedSelectionRangeArray& aRangesToDelete) const { AutoClonedSelectionRangeArray& aRangesToDelete) const {
EditorDOMRange rangeToDelete = EditorDOMRange rangeToDelete =
WSRunScanner::GetRangesForDeletingAtomicContent(aEditingHost, WSRunScanner::GetRangesForDeletingAtomicContent(aAtomicContent);
aAtomicContent);
if (!rangeToDelete.IsPositioned()) { if (!rangeToDelete.IsPositioned()) {
NS_WARNING("WSRunScanner::GetRangeForDeleteAContentNode() failed"); NS_WARNING("WSRunScanner::GetRangeForDeleteAContentNode() failed");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@@ -3907,7 +3896,6 @@ HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteNonCollapsedRanges(
EditorDOMRange firstRange(aRangesToDelete.FirstRangeRef()); EditorDOMRange firstRange(aRangesToDelete.FirstRangeRef());
EditorDOMRange extendedRange = EditorDOMRange extendedRange =
WSRunScanner::GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries( WSRunScanner::GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries(
aHTMLEditor.ComputeEditingHost(),
EditorDOMRange(aRangesToDelete.FirstRangeRef())); EditorDOMRange(aRangesToDelete.FirstRangeRef()));
if (firstRange != extendedRange) { if (firstRange != extendedRange) {
nsresult rv = aRangesToDelete.FirstRangeRef()->SetStartAndEnd( nsresult rv = aRangesToDelete.FirstRangeRef()->SetStartAndEnd(

View File

@@ -44,14 +44,11 @@ WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
template WSScanResult template WSScanResult
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom( WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
const EditorRawDOMPointInText& aPoint) const; const EditorRawDOMPointInText& aPoint) const;
template EditorDOMPoint WSRunScanner::GetAfterLastVisiblePoint( template EditorDOMPoint WSRunScanner::GetAfterLastVisiblePoint(Text& aTextNode);
Text& aTextNode, const Element* aAncestorLimiter);
template EditorRawDOMPoint WSRunScanner::GetAfterLastVisiblePoint( template EditorRawDOMPoint WSRunScanner::GetAfterLastVisiblePoint(
Text& aTextNode, const Element* aAncestorLimiter); Text& aTextNode);
template EditorDOMPoint WSRunScanner::GetFirstVisiblePoint( template EditorDOMPoint WSRunScanner::GetFirstVisiblePoint(Text& aTextNode);
Text& aTextNode, const Element* aAncestorLimiter); template EditorRawDOMPoint WSRunScanner::GetFirstVisiblePoint(Text& aTextNode);
template EditorRawDOMPoint WSRunScanner::GetFirstVisiblePoint(
Text& aTextNode, const Element* aAncestorLimiter);
template <typename PT, typename CT> template <typename PT, typename CT>
WSScanResult WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundaryFrom( WSScanResult WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundaryFrom(
@@ -250,8 +247,7 @@ WSScanResult WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
// static // static
template <typename EditorDOMPointType> template <typename EditorDOMPointType>
EditorDOMPointType WSRunScanner::GetAfterLastVisiblePoint( EditorDOMPointType WSRunScanner::GetAfterLastVisiblePoint(Text& aTextNode) {
Text& aTextNode, const Element* aAncestorLimiter) {
EditorDOMPoint atLastCharOfTextNode( EditorDOMPoint atLastCharOfTextNode(
&aTextNode, AssertedCast<uint32_t>(std::max<int64_t>( &aTextNode, AssertedCast<uint32_t>(std::max<int64_t>(
static_cast<int64_t>(aTextNode.Length()) - 1, 0))); static_cast<int64_t>(aTextNode.Length()) - 1, 0)));
@@ -259,8 +255,9 @@ EditorDOMPointType WSRunScanner::GetAfterLastVisiblePoint(
!atLastCharOfTextNode.IsCharCollapsibleASCIISpace()) { !atLastCharOfTextNode.IsCharCollapsibleASCIISpace()) {
return EditorDOMPointType::AtEndOf(aTextNode); return EditorDOMPointType::AtEndOf(aTextNode);
} }
TextFragmentData textFragmentData(atLastCharOfTextNode, aAncestorLimiter, const TextFragmentData textFragmentData(
BlockInlineCheck::UseComputedDisplayStyle); Scan::EditableNodes, atLastCharOfTextNode,
BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentData.IsInitialized())) { if (NS_WARN_IF(!textFragmentData.IsInitialized())) {
return EditorDOMPointType(); // TODO: Make here return error with Err. return EditorDOMPointType(); // TODO: Make here return error with Err.
} }
@@ -275,15 +272,15 @@ EditorDOMPointType WSRunScanner::GetAfterLastVisiblePoint(
// static // static
template <typename EditorDOMPointType> template <typename EditorDOMPointType>
EditorDOMPointType WSRunScanner::GetFirstVisiblePoint( EditorDOMPointType WSRunScanner::GetFirstVisiblePoint(Text& aTextNode) {
Text& aTextNode, const Element* aAncestorLimiter) {
EditorDOMPoint atStartOfTextNode(&aTextNode, 0); EditorDOMPoint atStartOfTextNode(&aTextNode, 0);
if (!atStartOfTextNode.IsContainerEmpty() && if (!atStartOfTextNode.IsContainerEmpty() &&
atStartOfTextNode.IsCharCollapsibleASCIISpace()) { atStartOfTextNode.IsCharCollapsibleASCIISpace()) {
return atStartOfTextNode.To<EditorDOMPointType>(); return atStartOfTextNode.To<EditorDOMPointType>();
} }
TextFragmentData textFragmentData(atStartOfTextNode, aAncestorLimiter, const TextFragmentData textFragmentData(
BlockInlineCheck::UseComputedDisplayStyle); Scan::EditableNodes, atStartOfTextNode,
BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentData.IsInitialized())) { if (NS_WARN_IF(!textFragmentData.IsInitialized())) {
return EditorDOMPointType(); // TODO: Make here return error with Err. return EditorDOMPointType(); // TODO: Make here return error with Err.
} }
@@ -420,14 +417,13 @@ WSRunScanner::ComputeRangeInTextNodesContainingInvisibleWhiteSpaces(
// static // static
Result<EditorDOMRangeInTexts, nsresult> Result<EditorDOMRangeInTexts, nsresult>
WSRunScanner::GetRangeInTextNodesToBackspaceFrom(const EditorDOMPoint& aPoint, WSRunScanner::GetRangeInTextNodesToBackspaceFrom(const EditorDOMPoint& aPoint) {
const Element& aEditingHost) {
// Corresponding to computing delete range part of // Corresponding to computing delete range part of
// `WhiteSpaceVisibilityKeeper::DeletePreviousWhiteSpace()` // `WhiteSpaceVisibilityKeeper::DeletePreviousWhiteSpace()`
MOZ_ASSERT(aPoint.IsSetAndValid()); MOZ_ASSERT(aPoint.IsSetAndValid());
TextFragmentData textFragmentDataAtCaret( const TextFragmentData textFragmentDataAtCaret(
aPoint, &aEditingHost, BlockInlineCheck::UseComputedDisplayStyle); Scan::EditableNodes, aPoint, BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAtCaret.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtCaret.IsInitialized())) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
} }
@@ -496,14 +492,14 @@ WSRunScanner::GetRangeInTextNodesToBackspaceFrom(const EditorDOMPoint& aPoint,
} }
// And also delete invisible white-spaces if they become visible. // And also delete invisible white-spaces if they become visible.
TextFragmentData textFragmentDataAtStart = const TextFragmentData textFragmentDataAtStart =
rangeToDelete.StartRef() != aPoint rangeToDelete.StartRef() != aPoint
? TextFragmentData(rangeToDelete.StartRef(), &aEditingHost, ? TextFragmentData(Scan::EditableNodes, rangeToDelete.StartRef(),
BlockInlineCheck::UseComputedDisplayStyle) BlockInlineCheck::UseComputedDisplayStyle)
: textFragmentDataAtCaret; : textFragmentDataAtCaret;
TextFragmentData textFragmentDataAtEnd = const TextFragmentData textFragmentDataAtEnd =
rangeToDelete.EndRef() != aPoint rangeToDelete.EndRef() != aPoint
? TextFragmentData(rangeToDelete.EndRef(), &aEditingHost, ? TextFragmentData(Scan::EditableNodes, rangeToDelete.EndRef(),
BlockInlineCheck::UseComputedDisplayStyle) BlockInlineCheck::UseComputedDisplayStyle)
: textFragmentDataAtCaret; : textFragmentDataAtCaret;
if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized()) || if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized()) ||
@@ -521,13 +517,13 @@ WSRunScanner::GetRangeInTextNodesToBackspaceFrom(const EditorDOMPoint& aPoint,
// static // static
Result<EditorDOMRangeInTexts, nsresult> Result<EditorDOMRangeInTexts, nsresult>
WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom( WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(
const EditorDOMPoint& aPoint, const Element& aEditingHost) { const EditorDOMPoint& aPoint) {
// Corresponding to computing delete range part of // Corresponding to computing delete range part of
// `WhiteSpaceVisibilityKeeper::DeleteInclusiveNextWhiteSpace()` // `WhiteSpaceVisibilityKeeper::DeleteInclusiveNextWhiteSpace()`
MOZ_ASSERT(aPoint.IsSetAndValid()); MOZ_ASSERT(aPoint.IsSetAndValid());
TextFragmentData textFragmentDataAtCaret( TextFragmentData textFragmentDataAtCaret(
aPoint, &aEditingHost, BlockInlineCheck::UseComputedDisplayStyle); Scan::EditableNodes, aPoint, BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAtCaret.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtCaret.IsInitialized())) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
} }
@@ -593,14 +589,14 @@ WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(
} }
// And also delete invisible white-spaces if they become visible. // And also delete invisible white-spaces if they become visible.
TextFragmentData textFragmentDataAtStart = const TextFragmentData textFragmentDataAtStart =
rangeToDelete.StartRef() != aPoint rangeToDelete.StartRef() != aPoint
? TextFragmentData(rangeToDelete.StartRef(), &aEditingHost, ? TextFragmentData(Scan::EditableNodes, rangeToDelete.StartRef(),
BlockInlineCheck::UseComputedDisplayStyle) BlockInlineCheck::UseComputedDisplayStyle)
: textFragmentDataAtCaret; : textFragmentDataAtCaret;
TextFragmentData textFragmentDataAtEnd = const TextFragmentData textFragmentDataAtEnd =
rangeToDelete.EndRef() != aPoint rangeToDelete.EndRef() != aPoint
? TextFragmentData(rangeToDelete.EndRef(), &aEditingHost, ? TextFragmentData(Scan::EditableNodes, rangeToDelete.EndRef(),
BlockInlineCheck::UseComputedDisplayStyle) BlockInlineCheck::UseComputedDisplayStyle)
: textFragmentDataAtCaret; : textFragmentDataAtCaret;
if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized()) || if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized()) ||
@@ -617,12 +613,12 @@ WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(
// static // static
EditorDOMRange WSRunScanner::GetRangesForDeletingAtomicContent( EditorDOMRange WSRunScanner::GetRangesForDeletingAtomicContent(
Element* aEditingHost, const nsIContent& aAtomicContent) { const nsIContent& aAtomicContent) {
if (aAtomicContent.IsHTMLElement(nsGkAtoms::br)) { if (aAtomicContent.IsHTMLElement(nsGkAtoms::br)) {
// Preceding white-spaces should be preserved, but the following // Preceding white-spaces should be preserved, but the following
// white-spaces should be invisible around `<br>` element. // white-spaces should be invisible around `<br>` element.
TextFragmentData textFragmentDataAfterBRElement( const TextFragmentData textFragmentDataAfterBRElement(
EditorDOMPoint::After(aAtomicContent), aEditingHost, Scan::EditableNodes, EditorDOMPoint::After(aAtomicContent),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAfterBRElement.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAfterBRElement.IsInitialized())) {
return EditorDOMRange(); // TODO: Make here return error with Err. return EditorDOMRange(); // TODO: Make here return error with Err.
@@ -652,8 +648,9 @@ EditorDOMRange WSRunScanner::GetRangesForDeletingAtomicContent(
// Both preceding and following white-spaces can be invisible around a // Both preceding and following white-spaces can be invisible around a
// block element. // block element.
TextFragmentData textFragmentDataBeforeAtomicContent( const TextFragmentData textFragmentDataBeforeAtomicContent(
EditorDOMPoint(const_cast<nsIContent*>(&aAtomicContent)), aEditingHost, Scan::EditableNodes,
EditorDOMPoint(const_cast<nsIContent*>(&aAtomicContent)),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataBeforeAtomicContent.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataBeforeAtomicContent.IsInitialized())) {
return EditorDOMRange(); // TODO: Make here return error with Err. return EditorDOMRange(); // TODO: Make here return error with Err.
@@ -662,8 +659,8 @@ EditorDOMRange WSRunScanner::GetRangesForDeletingAtomicContent(
textFragmentDataBeforeAtomicContent.GetNonCollapsedRangeInTexts( textFragmentDataBeforeAtomicContent.GetNonCollapsedRangeInTexts(
textFragmentDataBeforeAtomicContent textFragmentDataBeforeAtomicContent
.InvisibleTrailingWhiteSpaceRangeRef()); .InvisibleTrailingWhiteSpaceRangeRef());
TextFragmentData textFragmentDataAfterAtomicContent( const TextFragmentData textFragmentDataAfterAtomicContent(
EditorDOMPoint::After(aAtomicContent), aEditingHost, Scan::EditableNodes, EditorDOMPoint::After(aAtomicContent),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAfterAtomicContent.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAfterAtomicContent.IsInitialized())) {
return EditorDOMRange(); // TODO: Make here return error with Err. return EditorDOMRange(); // TODO: Make here return error with Err.
@@ -720,15 +717,14 @@ EditorDOMRange WSRunScanner::GetRangeForDeletingBlockElementBoundaries(
.IsBefore(EditorRawDOMPoint( .IsBefore(EditorRawDOMPoint(
const_cast<Element*>(&aRightBlockElement)))); const_cast<Element*>(&aRightBlockElement))));
const Element* editingHost = aHTMLEditor.ComputeEditingHost();
EditorDOMRange range; EditorDOMRange range;
// Include trailing invisible white-spaces in aLeftBlockElement. // Include trailing invisible white-spaces in aLeftBlockElement.
TextFragmentData textFragmentDataAtEndOfLeftBlockElement( const TextFragmentData textFragmentDataAtEndOfLeftBlockElement(
Scan::EditableNodes,
aPointContainingTheOtherBlock.GetContainer() == &aLeftBlockElement aPointContainingTheOtherBlock.GetContainer() == &aLeftBlockElement
? aPointContainingTheOtherBlock ? aPointContainingTheOtherBlock
: EditorDOMPoint::AtEndOf(const_cast<Element&>(aLeftBlockElement)), : EditorDOMPoint::AtEndOf(const_cast<Element&>(aLeftBlockElement)),
editingHost, BlockInlineCheck::UseComputedDisplayOutsideStyle); BlockInlineCheck::UseComputedDisplayOutsideStyle);
if (NS_WARN_IF(!textFragmentDataAtEndOfLeftBlockElement.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtEndOfLeftBlockElement.IsInitialized())) {
return EditorDOMRange(); // TODO: Make here return error with Err. return EditorDOMRange(); // TODO: Make here return error with Err.
} }
@@ -750,12 +746,13 @@ EditorDOMRange WSRunScanner::GetRangeForDeletingBlockElementBoundaries(
} }
} }
// Include leading invisible white-spaces in aRightBlockElement. // Include leading invisible white-spaces in aRightBlockElement.
TextFragmentData textFragmentDataAtStartOfRightBlockElement( const TextFragmentData textFragmentDataAtStartOfRightBlockElement(
Scan::EditableNodes,
aPointContainingTheOtherBlock.GetContainer() == &aRightBlockElement && aPointContainingTheOtherBlock.GetContainer() == &aRightBlockElement &&
!aPointContainingTheOtherBlock.IsEndOfContainer() !aPointContainingTheOtherBlock.IsEndOfContainer()
? aPointContainingTheOtherBlock.NextPoint() ? aPointContainingTheOtherBlock.NextPoint()
: EditorDOMPoint(const_cast<Element*>(&aRightBlockElement), 0u), : EditorDOMPoint(const_cast<Element*>(&aRightBlockElement), 0u),
editingHost, BlockInlineCheck::UseComputedDisplayOutsideStyle); BlockInlineCheck::UseComputedDisplayOutsideStyle);
if (NS_WARN_IF(!textFragmentDataAtStartOfRightBlockElement.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtStartOfRightBlockElement.IsInitialized())) {
return EditorDOMRange(); // TODO: Make here return error with Err. return EditorDOMRange(); // TODO: Make here return error with Err.
} }
@@ -773,14 +770,14 @@ EditorDOMRange WSRunScanner::GetRangeForDeletingBlockElementBoundaries(
// static // static
EditorDOMRange EditorDOMRange
WSRunScanner::GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries( WSRunScanner::GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries(
Element* aEditingHost, const EditorDOMRange& aRange) { const EditorDOMRange& aRange) {
MOZ_ASSERT(aRange.IsPositionedAndValid()); MOZ_ASSERT(aRange.IsPositionedAndValid());
MOZ_ASSERT(aRange.EndRef().IsSetAndValid()); MOZ_ASSERT(aRange.EndRef().IsSetAndValid());
MOZ_ASSERT(aRange.StartRef().IsSetAndValid()); MOZ_ASSERT(aRange.StartRef().IsSetAndValid());
EditorDOMRange result; EditorDOMRange result;
TextFragmentData textFragmentDataAtStart( const TextFragmentData textFragmentDataAtStart(
aRange.StartRef(), aEditingHost, Scan::EditableNodes, aRange.StartRef(),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized())) {
return EditorDOMRange(); // TODO: Make here return error with Err. return EditorDOMRange(); // TODO: Make here return error with Err.
@@ -815,8 +812,9 @@ WSRunScanner::GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries(
result.SetStart(aRange.StartRef()); result.SetStart(aRange.StartRef());
} }
TextFragmentData textFragmentDataAtEnd( const TextFragmentData textFragmentDataAtEnd(
aRange.EndRef(), aEditingHost, BlockInlineCheck::UseComputedDisplayStyle); Scan::EditableNodes, aRange.EndRef(),
BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized())) {
return EditorDOMRange(); // TODO: Make here return error with Err. return EditorDOMRange(); // TODO: Make here return error with Err.
} }
@@ -860,8 +858,7 @@ WSRunScanner::GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries(
// static // static
Result<bool, nsresult> Result<bool, nsresult>
WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent( WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent(
const HTMLEditor& aHTMLEditor, nsRange& aRange, const HTMLEditor& aHTMLEditor, nsRange& aRange) {
const Element* aEditingHost) {
MOZ_ASSERT(aRange.IsPositioned()); MOZ_ASSERT(aRange.IsPositioned());
MOZ_ASSERT(!aRange.IsInAnySelection(), MOZ_ASSERT(!aRange.IsInAnySelection(),
"Changing range in selection may cause running script"); "Changing range in selection may cause running script");
@@ -896,8 +893,8 @@ WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent(
// If next content is a visible `<br>` element, special inline content // If next content is a visible `<br>` element, special inline content
// (e.g., `<img>`, non-editable text node, etc) or a block level void // (e.g., `<img>`, non-editable text node, etc) or a block level void
// element like `<hr>`, the range should start with it. // element like `<hr>`, the range should start with it.
TextFragmentData textFragmentDataAtStart( const TextFragmentData textFragmentDataAtStart(
EditorRawDOMPoint(aRange.StartRef()), aEditingHost, Scan::EditableNodes, EditorRawDOMPoint(aRange.StartRef()),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized())) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
@@ -919,8 +916,8 @@ WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent(
// If previous content is a visible `<br>` element, special inline content // If previous content is a visible `<br>` element, special inline content
// (e.g., `<img>`, non-editable text node, etc) or a block level void // (e.g., `<img>`, non-editable text node, etc) or a block level void
// element like `<hr>`, the range should end after it. // element like `<hr>`, the range should end after it.
TextFragmentData textFragmentDataAtEnd( const TextFragmentData textFragmentDataAtEnd(
EditorRawDOMPoint(aRange.EndRef()), aEditingHost, Scan::EditableNodes, EditorRawDOMPoint(aRange.EndRef()),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized())) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);

View File

@@ -422,6 +422,17 @@ class MOZ_STACK_CLASS WSRunScanner final {
using WSType = WSScanResult::WSType; using WSType = WSScanResult::WSType;
enum class IgnoreNonEditableNodes : bool { No, Yes }; enum class IgnoreNonEditableNodes : bool { No, Yes };
enum class StopAtNonEditableNode : bool { No, Yes };
enum class Scan : bool { All, EditableNodes };
[[nodiscard]] constexpr static IgnoreNonEditableNodes
ShouldIgnoreNonEditableSiblingsOrDescendants(Scan aScan) {
return static_cast<IgnoreNonEditableNodes>(static_cast<bool>(aScan));
}
[[nodiscard]] constexpr static StopAtNonEditableNode
ShouldStopAtNonEditableNode(Scan aScan) {
return static_cast<StopAtNonEditableNode>(static_cast<bool>(aScan));
}
template <typename EditorDOMPointType> template <typename EditorDOMPointType>
WSRunScanner(const Element* aEditingHost, WSRunScanner(const Element* aEditingHost,
@@ -429,7 +440,7 @@ class MOZ_STACK_CLASS WSRunScanner final {
BlockInlineCheck aBlockInlineCheck) BlockInlineCheck aBlockInlineCheck)
: mScanStartPoint(aScanStartPoint.template To<EditorDOMPoint>()), : mScanStartPoint(aScanStartPoint.template To<EditorDOMPoint>()),
mEditingHost(const_cast<Element*>(aEditingHost)), mEditingHost(const_cast<Element*>(aEditingHost)),
mTextFragmentDataAtStart(mScanStartPoint, mEditingHost, mTextFragmentDataAtStart(Scan::EditableNodes, mScanStartPoint,
aBlockInlineCheck), aBlockInlineCheck),
mBlockInlineCheck(aBlockInlineCheck) {} mBlockInlineCheck(aBlockInlineCheck) {}
@@ -515,27 +526,23 @@ class MOZ_STACK_CLASS WSRunScanner final {
* only invisible white-spaces and there is previous or next text node. * only invisible white-spaces and there is previous or next text node.
*/ */
template <typename EditorDOMPointType> template <typename EditorDOMPointType>
static EditorDOMPointType GetAfterLastVisiblePoint( static EditorDOMPointType GetAfterLastVisiblePoint(Text& aTextNode);
Text& aTextNode, const Element* aAncestorLimiter);
template <typename EditorDOMPointType> template <typename EditorDOMPointType>
static EditorDOMPointType GetFirstVisiblePoint( static EditorDOMPointType GetFirstVisiblePoint(Text& aTextNode);
Text& aTextNode, const Element* aAncestorLimiter);
/** /**
* GetRangeInTextNodesToForwardDeleteFrom() returns the range to remove * GetRangeInTextNodesToForwardDeleteFrom() returns the range to remove
* text when caret is at aPoint. * text when caret is at aPoint.
*/ */
static Result<EditorDOMRangeInTexts, nsresult> static Result<EditorDOMRangeInTexts, nsresult>
GetRangeInTextNodesToForwardDeleteFrom(const EditorDOMPoint& aPoint, GetRangeInTextNodesToForwardDeleteFrom(const EditorDOMPoint& aPoint);
const Element& aEditingHost);
/** /**
* GetRangeInTextNodesToBackspaceFrom() returns the range to remove text * GetRangeInTextNodesToBackspaceFrom() returns the range to remove text
* when caret is at aPoint. * when caret is at aPoint.
*/ */
static Result<EditorDOMRangeInTexts, nsresult> static Result<EditorDOMRangeInTexts, nsresult>
GetRangeInTextNodesToBackspaceFrom(const EditorDOMPoint& aPoint, GetRangeInTextNodesToBackspaceFrom(const EditorDOMPoint& aPoint);
const Element& aEditingHost);
/** /**
* GetRangesForDeletingAtomicContent() returns the range to delete * GetRangesForDeletingAtomicContent() returns the range to delete
@@ -543,7 +550,7 @@ class MOZ_STACK_CLASS WSRunScanner final {
* be included into the range. * be included into the range.
*/ */
static EditorDOMRange GetRangesForDeletingAtomicContent( static EditorDOMRange GetRangesForDeletingAtomicContent(
Element* aEditingHost, const nsIContent& aAtomicContent); const nsIContent& aAtomicContent);
/** /**
* GetRangeForDeleteBlockElementBoundaries() returns a range starting from end * GetRangeForDeleteBlockElementBoundaries() returns a range starting from end
@@ -576,15 +583,14 @@ class MOZ_STACK_CLASS WSRunScanner final {
* is in adjacent text nodes. Returns true if this modifies the range. * is in adjacent text nodes. Returns true if this modifies the range.
*/ */
static Result<bool, nsresult> ShrinkRangeIfStartsFromOrEndsAfterAtomicContent( static Result<bool, nsresult> ShrinkRangeIfStartsFromOrEndsAfterAtomicContent(
const HTMLEditor& aHTMLEditor, nsRange& aRange, const HTMLEditor& aHTMLEditor, nsRange& aRange);
const Element* aEditingHost);
/** /**
* GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries() returns * GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries() returns
* extended range if range boundaries of aRange are in invisible white-spaces. * extended range if range boundaries of aRange are in invisible white-spaces.
*/ */
static EditorDOMRange GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries( static EditorDOMRange GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries(
Element* aEditingHost, const EditorDOMRange& aRange); const EditorDOMRange& aRange);
/** /**
* GetPrecedingBRElementUnlessVisibleContentFound() scans a `<br>` element * GetPrecedingBRElementUnlessVisibleContentFound() scans a `<br>` element
@@ -595,7 +601,7 @@ class MOZ_STACK_CLASS WSRunScanner final {
template <typename EditorDOMPointType> template <typename EditorDOMPointType>
MOZ_NEVER_INLINE_DEBUG static HTMLBRElement* MOZ_NEVER_INLINE_DEBUG static HTMLBRElement*
GetPrecedingBRElementUnlessVisibleContentFound( GetPrecedingBRElementUnlessVisibleContentFound(
Element* aEditingHost, const EditorDOMPointType& aPoint, const Element* aEditingHost, const EditorDOMPointType& aPoint,
BlockInlineCheck aBlockInlineCheck) { BlockInlineCheck aBlockInlineCheck) {
MOZ_ASSERT(aPoint.IsSetAndValid()); MOZ_ASSERT(aPoint.IsSetAndValid());
// XXX This method behaves differently even in similar point. // XXX This method behaves differently even in similar point.
@@ -610,7 +616,8 @@ class MOZ_STACK_CLASS WSRunScanner final {
} }
// TODO: Scan for end boundary is redundant in this case, we should optimize // TODO: Scan for end boundary is redundant in this case, we should optimize
// it. // it.
TextFragmentData textFragmentData(aPoint, aEditingHost, aBlockInlineCheck); TextFragmentData textFragmentData(Scan::EditableNodes, aPoint,
aBlockInlineCheck, aEditingHost);
return textFragmentData.StartsFromBRElement() return textFragmentData.StartsFromBRElement()
? textFragmentData.StartReasonBRElementPtr() ? textFragmentData.StartReasonBRElementPtr()
: nullptr; : nullptr;
@@ -937,7 +944,9 @@ class MOZ_STACK_CLASS WSRunScanner final {
template <typename EditorDOMPointType> template <typename EditorDOMPointType>
static BoundaryData ScanCollapsibleWhiteSpaceStartFrom( static BoundaryData ScanCollapsibleWhiteSpaceStartFrom(
const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData, const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData,
BlockInlineCheck aBlockInlineCheck, const Element& aAncestorLimiter); BlockInlineCheck aBlockInlineCheck,
StopAtNonEditableNode aStopAtNonEditableNode,
const Element& aAncestorLimiter);
/** /**
* ScanCollapsibleWhiteSpaceEndFrom() returns end boundary data of * ScanCollapsibleWhiteSpaceEndFrom() returns end boundary data of
@@ -952,7 +961,9 @@ class MOZ_STACK_CLASS WSRunScanner final {
template <typename EditorDOMPointType> template <typename EditorDOMPointType>
static BoundaryData ScanCollapsibleWhiteSpaceEndFrom( static BoundaryData ScanCollapsibleWhiteSpaceEndFrom(
const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData, const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData,
BlockInlineCheck aBlockInlineCheck, const Element& aAncestorLimiter); BlockInlineCheck aBlockInlineCheck,
StopAtNonEditableNode aStopAtNonEditableNode,
const Element& aAncestorLimiter);
BoundaryData() = default; BoundaryData() = default;
template <typename EditorDOMPointType> template <typename EditorDOMPointType>
@@ -1059,15 +1070,16 @@ class MOZ_STACK_CLASS WSRunScanner final {
public: public:
TextFragmentData() = delete; TextFragmentData() = delete;
/**
* If aScanMode is Scan::EditableNodes and aPoint is in an editable node,
* this scans only in the editing host. Therefore, it's same as that
* aAncestorLimiter is specified to the editing host.
*/
template <typename EditorDOMPointType> template <typename EditorDOMPointType>
TextFragmentData(const WSRunScanner& aWSRunScanner, TextFragmentData(Scan aScanMode, const EditorDOMPointType& aPoint,
const EditorDOMPointType& aPoint) BlockInlineCheck aBlockInlineCheck,
: TextFragmentData(aPoint, aWSRunScanner.mEditingHost, const Element* aAncestorLimiter = nullptr);
aWSRunScanner.mBlockInlineCheck) {}
template <typename EditorDOMPointType>
TextFragmentData(const EditorDOMPointType& aPoint,
const Element* aEditingHost,
BlockInlineCheck aBlockInlineCheck);
bool IsInitialized() const { bool IsInitialized() const {
return mStart.Initialized() && mEnd.Initialized(); return mStart.Initialized() && mEnd.Initialized();
@@ -1496,11 +1508,11 @@ class MOZ_STACK_CLASS WSRunScanner final {
BoundaryData mStart; BoundaryData mStart;
BoundaryData mEnd; BoundaryData mEnd;
NoBreakingSpaceData mNBSPData; NoBreakingSpaceData mNBSPData;
RefPtr<const Element> mEditingHost;
mutable Maybe<EditorDOMRange> mLeadingWhiteSpaceRange; mutable Maybe<EditorDOMRange> mLeadingWhiteSpaceRange;
mutable Maybe<EditorDOMRange> mTrailingWhiteSpaceRange; mutable Maybe<EditorDOMRange> mTrailingWhiteSpaceRange;
mutable Maybe<VisibleWhiteSpacesData> mVisibleWhiteSpacesData; mutable Maybe<VisibleWhiteSpacesData> mVisibleWhiteSpacesData;
BlockInlineCheck mBlockInlineCheck; BlockInlineCheck mBlockInlineCheck;
Scan mScanMode;
}; };
const TextFragmentData& TextFragmentDataAtStartRef() const { const TextFragmentData& TextFragmentDataAtStartRef() const {

View File

@@ -28,17 +28,17 @@ using LeafNodeType = HTMLEditUtils::LeafNodeType;
using LeafNodeTypes = HTMLEditUtils::LeafNodeTypes; using LeafNodeTypes = HTMLEditUtils::LeafNodeTypes;
template WSRunScanner::TextFragmentData::TextFragmentData( template WSRunScanner::TextFragmentData::TextFragmentData(
const EditorDOMPoint& aPoint, const Element* aEditingHost, Scan aScanMode, const EditorDOMPoint& aPoint,
BlockInlineCheck aBlockInlineCheck); BlockInlineCheck aBlockInlineCheck, const Element* aAncestorLimiter);
template WSRunScanner::TextFragmentData::TextFragmentData( template WSRunScanner::TextFragmentData::TextFragmentData(
const EditorRawDOMPoint& aPoint, const Element* aEditingHost, Scan aScanMode, const EditorRawDOMPoint& aPoint,
BlockInlineCheck aBlockInlineCheck); BlockInlineCheck aBlockInlineCheck, const Element* aAncestorLimiter);
template WSRunScanner::TextFragmentData::TextFragmentData( template WSRunScanner::TextFragmentData::TextFragmentData(
const EditorDOMPointInText& aPoint, const Element* aEditingHost, Scan aScanMode, const EditorDOMPointInText& aPoint,
BlockInlineCheck aBlockInlineCheck); BlockInlineCheck aBlockInlineCheck, const Element* aAncestorLimiter);
template WSRunScanner::TextFragmentData::TextFragmentData( template WSRunScanner::TextFragmentData::TextFragmentData(
const EditorRawDOMPointInText& aPoint, const Element* aEditingHost, Scan aScanMode, const EditorRawDOMPointInText& aPoint,
BlockInlineCheck aBlockInlineCheck); BlockInlineCheck aBlockInlineCheck, const Element* aAncestorLimiter);
NS_INSTANTIATE_METHOD_RETURNING_ANY_EDITOR_DOM_POINT( NS_INSTANTIATE_METHOD_RETURNING_ANY_EDITOR_DOM_POINT(
WSRunScanner::TextFragmentData::GetInclusiveNextCharPoint, WSRunScanner::TextFragmentData::GetInclusiveNextCharPoint,
@@ -119,31 +119,36 @@ constexpr static const AncestorTypes kScanEditableRootAncestorTypes = {
template <typename EditorDOMPointType> template <typename EditorDOMPointType>
WSRunScanner::TextFragmentData::TextFragmentData( WSRunScanner::TextFragmentData::TextFragmentData(
const EditorDOMPointType& aPoint, const Element* aEditingHost, Scan aScanMode, const EditorDOMPointType& aPoint,
BlockInlineCheck aBlockInlineCheck) BlockInlineCheck aBlockInlineCheck,
: mEditingHost(aEditingHost), mBlockInlineCheck(aBlockInlineCheck) { const Element* aAncestorLimiter /* = nullptr */)
: mBlockInlineCheck(aBlockInlineCheck), mScanMode(aScanMode) {
if (NS_WARN_IF(!aPoint.IsInContentNodeAndValidInComposedDoc()) || if (NS_WARN_IF(!aPoint.IsInContentNodeAndValidInComposedDoc()) ||
NS_WARN_IF(!aPoint.GetContainerOrContainerParentElement())) { NS_WARN_IF(!aPoint.GetContainerOrContainerParentElement())) {
// We don't need to support composing in uncomposed tree. // We don't need to support composing in uncomposed tree.
return; return;
} }
MOZ_ASSERT_IF(
aAncestorLimiter,
aPoint.template ContainerAs<nsIContent>()->IsInclusiveDescendantOf(
aAncestorLimiter));
mScanStartPoint = aPoint.template To<EditorDOMPoint>(); mScanStartPoint = aPoint.template To<EditorDOMPoint>();
const Element* const const Element* const
editableBlockElementOrInlineEditingHostOrNonEditableRootElement = editableBlockElementOrInlineEditingHostOrNonEditableRootElement =
HTMLEditUtils::GetInclusiveAncestorElement( HTMLEditUtils::GetInclusiveAncestorElement(
*mScanStartPoint.ContainerAs<nsIContent>(), *mScanStartPoint.ContainerAs<nsIContent>(),
HTMLEditUtils::IsSimplyEditableNode( aScanMode == Scan::EditableNodes ? kScanEditableRootAncestorTypes
*mScanStartPoint.ContainerAs<nsIContent>()) : kScanAnyRootAncestorTypes,
? kScanEditableRootAncestorTypes aBlockInlineCheck, aAncestorLimiter);
: kScanAnyRootAncestorTypes,
aBlockInlineCheck);
if (NS_WARN_IF( if (NS_WARN_IF(
!editableBlockElementOrInlineEditingHostOrNonEditableRootElement)) { !editableBlockElementOrInlineEditingHostOrNonEditableRootElement)) {
return; return;
} }
mStart = BoundaryData::ScanCollapsibleWhiteSpaceStartFrom( mStart = BoundaryData::ScanCollapsibleWhiteSpaceStartFrom(
mScanStartPoint, &mNBSPData, aBlockInlineCheck, mScanStartPoint, &mNBSPData, aBlockInlineCheck,
ShouldStopAtNonEditableNode(aScanMode),
*editableBlockElementOrInlineEditingHostOrNonEditableRootElement); *editableBlockElementOrInlineEditingHostOrNonEditableRootElement);
MOZ_ASSERT_IF(mStart.IsNonCollapsibleCharacters(), MOZ_ASSERT_IF(mStart.IsNonCollapsibleCharacters(),
!mStart.PointRef().IsPreviousCharPreformattedNewLine()); !mStart.PointRef().IsPreviousCharPreformattedNewLine());
@@ -151,6 +156,7 @@ WSRunScanner::TextFragmentData::TextFragmentData(
mStart.PointRef().IsPreviousCharPreformattedNewLine()); mStart.PointRef().IsPreviousCharPreformattedNewLine());
mEnd = BoundaryData::ScanCollapsibleWhiteSpaceEndFrom( mEnd = BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
mScanStartPoint, &mNBSPData, aBlockInlineCheck, mScanStartPoint, &mNBSPData, aBlockInlineCheck,
ShouldStopAtNonEditableNode(aScanMode),
*editableBlockElementOrInlineEditingHostOrNonEditableRootElement); *editableBlockElementOrInlineEditingHostOrNonEditableRootElement);
MOZ_ASSERT_IF(mEnd.IsNonCollapsibleCharacters(), MOZ_ASSERT_IF(mEnd.IsNonCollapsibleCharacters(),
!mEnd.PointRef().IsCharPreformattedNewLine()); !mEnd.PointRef().IsCharPreformattedNewLine());
@@ -225,8 +231,12 @@ template <typename EditorDOMPointType>
WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData:: WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData::
BoundaryData::ScanCollapsibleWhiteSpaceStartFrom( BoundaryData::ScanCollapsibleWhiteSpaceStartFrom(
const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData, const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData,
BlockInlineCheck aBlockInlineCheck, const Element& aAncestorLimiter) { BlockInlineCheck aBlockInlineCheck,
StopAtNonEditableNode aStopAtNonEditableNode,
const Element& aAncestorLimiter) {
MOZ_ASSERT(aPoint.IsSetAndValid()); MOZ_ASSERT(aPoint.IsSetAndValid());
MOZ_ASSERT(HTMLEditUtils::IsSimplyEditableNode(*aPoint.GetContainer()) ==
HTMLEditUtils::IsSimplyEditableNode(aAncestorLimiter));
if (aPoint.IsInTextNode() && !aPoint.IsStartOfContainer()) { if (aPoint.IsInTextNode() && !aPoint.IsStartOfContainer()) {
Maybe<BoundaryData> startInTextNode = Maybe<BoundaryData> startInTextNode =
@@ -239,14 +249,17 @@ WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData::
// preceding nodes. // preceding nodes.
return BoundaryData::ScanCollapsibleWhiteSpaceStartFrom( return BoundaryData::ScanCollapsibleWhiteSpaceStartFrom(
EditorDOMPoint(aPoint.template ContainerAs<Text>(), 0), aNBSPData, EditorDOMPoint(aPoint.template ContainerAs<Text>(), 0), aNBSPData,
aBlockInlineCheck, aAncestorLimiter); aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
} }
// Then, we need to check previous leaf node. // Then, we need to check previous leaf node.
const auto leafNodeTypes =
aStopAtNonEditableNode == StopAtNonEditableNode::Yes
? LeafNodeTypes{LeafNodeType::LeafNodeOrNonEditableNode}
: LeafNodeTypes{LeafNodeType::OnlyLeafNode};
nsIContent* previousLeafContentOrBlock = nsIContent* previousLeafContentOrBlock =
HTMLEditUtils::GetPreviousLeafContentOrPreviousBlockElement( HTMLEditUtils::GetPreviousLeafContentOrPreviousBlockElement(
aPoint, {LeafNodeType::LeafNodeOrNonEditableNode}, aBlockInlineCheck, aPoint, leafNodeTypes, aBlockInlineCheck, &aAncestorLimiter);
&aAncestorLimiter);
if (!previousLeafContentOrBlock) { if (!previousLeafContentOrBlock) {
// No previous content means that we reached the aAncestorLimiter boundary. // No previous content means that we reached the aAncestorLimiter boundary.
return BoundaryData( return BoundaryData(
@@ -263,7 +276,9 @@ WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData::
} }
if (!previousLeafContentOrBlock->IsText() || if (!previousLeafContentOrBlock->IsText() ||
!previousLeafContentOrBlock->IsEditable()) { (aStopAtNonEditableNode == StopAtNonEditableNode::Yes &&
HTMLEditUtils::IsSimplyEditableNode(*previousLeafContentOrBlock) !=
HTMLEditUtils::IsSimplyEditableNode(aAncestorLimiter))) {
// it's a break or a special node, like <img>, that is not a block and // it's a break or a special node, like <img>, that is not a block and
// not a break but still serves as a terminator to ws runs. // not a break but still serves as a terminator to ws runs.
return BoundaryData(aPoint, *previousLeafContentOrBlock, return BoundaryData(aPoint, *previousLeafContentOrBlock,
@@ -278,7 +293,7 @@ WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData::
// looking for the previous one. // looking for the previous one.
return BoundaryData::ScanCollapsibleWhiteSpaceStartFrom( return BoundaryData::ScanCollapsibleWhiteSpaceStartFrom(
EditorDOMPointInText(previousLeafContentOrBlock->AsText(), 0), EditorDOMPointInText(previousLeafContentOrBlock->AsText(), 0),
aNBSPData, aBlockInlineCheck, aAncestorLimiter); aNBSPData, aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
} }
Maybe<BoundaryData> startInTextNode = Maybe<BoundaryData> startInTextNode =
@@ -293,7 +308,7 @@ WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData::
// preceding nodes. // preceding nodes.
return BoundaryData::ScanCollapsibleWhiteSpaceStartFrom( return BoundaryData::ScanCollapsibleWhiteSpaceStartFrom(
EditorDOMPointInText(previousLeafContentOrBlock->AsText(), 0), aNBSPData, EditorDOMPointInText(previousLeafContentOrBlock->AsText(), 0), aNBSPData,
aBlockInlineCheck, aAncestorLimiter); aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
} }
// static // static
@@ -361,8 +376,12 @@ template <typename EditorDOMPointType>
WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData::BoundaryData
WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom( WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData, const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData,
BlockInlineCheck aBlockInlineCheck, const Element& aAncestorLimiter) { BlockInlineCheck aBlockInlineCheck,
StopAtNonEditableNode aStopAtNonEditableNode,
const Element& aAncestorLimiter) {
MOZ_ASSERT(aPoint.IsSetAndValid()); MOZ_ASSERT(aPoint.IsSetAndValid());
MOZ_ASSERT(HTMLEditUtils::IsSimplyEditableNode(*aPoint.GetContainer()) ==
HTMLEditUtils::IsSimplyEditableNode(aAncestorLimiter));
if (aPoint.IsInTextNode() && !aPoint.IsEndOfContainer()) { if (aPoint.IsInTextNode() && !aPoint.IsEndOfContainer()) {
Maybe<BoundaryData> endInTextNode = Maybe<BoundaryData> endInTextNode =
@@ -375,14 +394,17 @@ WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
// following nodes. // following nodes.
return BoundaryData::ScanCollapsibleWhiteSpaceEndFrom( return BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
EditorDOMPointInText::AtEndOf(*aPoint.template ContainerAs<Text>()), EditorDOMPointInText::AtEndOf(*aPoint.template ContainerAs<Text>()),
aNBSPData, aBlockInlineCheck, aAncestorLimiter); aNBSPData, aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
} }
// Then, we need to check next leaf node. // Then, we need to check next leaf node.
const auto leafNodeTypes =
aStopAtNonEditableNode == StopAtNonEditableNode::Yes
? LeafNodeTypes{LeafNodeType::LeafNodeOrNonEditableNode}
: LeafNodeTypes{LeafNodeType::OnlyLeafNode};
nsIContent* nextLeafContentOrBlock = nsIContent* nextLeafContentOrBlock =
HTMLEditUtils::GetNextLeafContentOrNextBlockElement( HTMLEditUtils::GetNextLeafContentOrNextBlockElement(
aPoint, {LeafNodeType::LeafNodeOrNonEditableNode}, aBlockInlineCheck, aPoint, leafNodeTypes, aBlockInlineCheck, &aAncestorLimiter);
&aAncestorLimiter);
if (!nextLeafContentOrBlock) { if (!nextLeafContentOrBlock) {
// No next content means that we reached aAncestorLimiter boundary. // No next content means that we reached aAncestorLimiter boundary.
return BoundaryData( return BoundaryData(
@@ -401,7 +423,9 @@ WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
} }
if (!nextLeafContentOrBlock->IsText() || if (!nextLeafContentOrBlock->IsText() ||
!nextLeafContentOrBlock->IsEditable()) { (aStopAtNonEditableNode == StopAtNonEditableNode::Yes &&
HTMLEditUtils::IsSimplyEditableNode(*nextLeafContentOrBlock) !=
HTMLEditUtils::IsSimplyEditableNode(aAncestorLimiter))) {
// we encountered a break or a special node, like <img>, // we encountered a break or a special node, like <img>,
// that is not a block and not a break but still // that is not a block and not a break but still
// serves as a terminator to ws runs. // serves as a terminator to ws runs.
@@ -417,7 +441,7 @@ WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
// looking for the next one. // looking for the next one.
return BoundaryData::ScanCollapsibleWhiteSpaceEndFrom( return BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
EditorDOMPointInText(nextLeafContentOrBlock->AsText(), 0), aNBSPData, EditorDOMPointInText(nextLeafContentOrBlock->AsText(), 0), aNBSPData,
aBlockInlineCheck, aAncestorLimiter); aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
} }
Maybe<BoundaryData> endInTextNode = Maybe<BoundaryData> endInTextNode =
@@ -432,7 +456,7 @@ WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
// following nodes. // following nodes.
return BoundaryData::ScanCollapsibleWhiteSpaceEndFrom( return BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
EditorDOMPointInText::AtEndOf(*nextLeafContentOrBlock->AsText()), EditorDOMPointInText::AtEndOf(*nextLeafContentOrBlock->AsText()),
aNBSPData, aBlockInlineCheck, aAncestorLimiter); aNBSPData, aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
} }
const EditorDOMRange& const EditorDOMRange&
@@ -526,7 +550,8 @@ WSRunScanner::TextFragmentData::GetNonCollapsedRangeInTexts(
aRange.StartRef().IsInTextNode() aRange.StartRef().IsInTextNode()
? aRange.StartRef().AsInText() ? aRange.StartRef().AsInText()
: GetInclusiveNextCharPoint<EditorDOMPointInText>( : GetInclusiveNextCharPoint<EditorDOMPointInText>(
aRange.StartRef(), IgnoreNonEditableNodes::Yes); aRange.StartRef(),
ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
if (!firstPoint.IsSet()) { if (!firstPoint.IsSet()) {
return EditorDOMRangeInTexts(); return EditorDOMRangeInTexts();
} }
@@ -537,7 +562,8 @@ WSRunScanner::TextFragmentData::GetNonCollapsedRangeInTexts(
// FYI: GetPreviousCharPoint() returns last character's point of preceding // FYI: GetPreviousCharPoint() returns last character's point of preceding
// text node if it's not empty, but we need end of the text node here. // text node if it's not empty, but we need end of the text node here.
endPoint = GetPreviousCharPoint<EditorDOMPointInText>( endPoint = GetPreviousCharPoint<EditorDOMPointInText>(
aRange.EndRef(), IgnoreNonEditableNodes::Yes); aRange.EndRef(),
ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
if (endPoint.IsSet() && endPoint.IsAtLastContent()) { if (endPoint.IsSet() && endPoint.IsAtLastContent()) {
MOZ_ALWAYS_TRUE(endPoint.AdvanceOffset()); MOZ_ALWAYS_TRUE(endPoint.AdvanceOffset());
} }
@@ -712,7 +738,7 @@ WSRunScanner::TextFragmentData::GetReplaceRangeDataAtEndOfDeletionRange(
return ReplaceRangeData(); return ReplaceRangeData();
} }
auto nextCharOfStartOfEnd = GetInclusiveNextCharPoint<EditorDOMPointInText>( auto nextCharOfStartOfEnd = GetInclusiveNextCharPoint<EditorDOMPointInText>(
endToDelete, IgnoreNonEditableNodes::Yes); endToDelete, ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
if (!nextCharOfStartOfEnd.IsSet() || if (!nextCharOfStartOfEnd.IsSet() ||
nextCharOfStartOfEnd.IsEndOfContainer() || nextCharOfStartOfEnd.IsEndOfContainer() ||
!nextCharOfStartOfEnd.IsCharCollapsibleASCIISpace()) { !nextCharOfStartOfEnd.IsCharCollapsibleASCIISpace()) {
@@ -724,13 +750,13 @@ WSRunScanner::TextFragmentData::GetReplaceRangeDataAtEndOfDeletionRange(
aTextFragmentDataAtStartToDelete aTextFragmentDataAtStartToDelete
.GetFirstASCIIWhiteSpacePointCollapsedTo<EditorDOMPointInText>( .GetFirstASCIIWhiteSpacePointCollapsedTo<EditorDOMPointInText>(
nextCharOfStartOfEnd, nsIEditor::eNone, nextCharOfStartOfEnd, nsIEditor::eNone,
IgnoreNonEditableNodes::Yes); ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
} }
const auto endOfCollapsibleASCIIWhiteSpaces = const auto endOfCollapsibleASCIIWhiteSpaces =
aTextFragmentDataAtStartToDelete aTextFragmentDataAtStartToDelete
.GetEndOfCollapsibleASCIIWhiteSpaces<EditorDOMPointInText>( .GetEndOfCollapsibleASCIIWhiteSpaces<EditorDOMPointInText>(
nextCharOfStartOfEnd, nsIEditor::eNone, nextCharOfStartOfEnd, nsIEditor::eNone,
IgnoreNonEditableNodes::Yes); ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
return ReplaceRangeData(nextCharOfStartOfEnd, return ReplaceRangeData(nextCharOfStartOfEnd,
endOfCollapsibleASCIIWhiteSpaces, endOfCollapsibleASCIIWhiteSpaces,
nsDependentSubstring(&HTMLEditUtils::kNBSP, 1)); nsDependentSubstring(&HTMLEditUtils::kNBSP, 1));
@@ -791,7 +817,7 @@ WSRunScanner::TextFragmentData::GetReplaceRangeDataAtStartOfDeletionRange(
return ReplaceRangeData(); return ReplaceRangeData();
} }
auto atPreviousCharOfStart = GetPreviousCharPoint<EditorDOMPointInText>( auto atPreviousCharOfStart = GetPreviousCharPoint<EditorDOMPointInText>(
startToDelete, IgnoreNonEditableNodes::Yes); startToDelete, ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
if (!atPreviousCharOfStart.IsSet() || if (!atPreviousCharOfStart.IsSet() ||
atPreviousCharOfStart.IsEndOfContainer() || atPreviousCharOfStart.IsEndOfContainer() ||
!atPreviousCharOfStart.IsCharCollapsibleASCIISpace()) { !atPreviousCharOfStart.IsCharCollapsibleASCIISpace()) {
@@ -802,11 +828,12 @@ WSRunScanner::TextFragmentData::GetReplaceRangeDataAtStartOfDeletionRange(
atPreviousCharOfStart = atPreviousCharOfStart =
GetFirstASCIIWhiteSpacePointCollapsedTo<EditorDOMPointInText>( GetFirstASCIIWhiteSpacePointCollapsedTo<EditorDOMPointInText>(
atPreviousCharOfStart, nsIEditor::eNone, atPreviousCharOfStart, nsIEditor::eNone,
IgnoreNonEditableNodes::Yes); ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
} }
const auto endOfCollapsibleASCIIWhiteSpaces = const auto endOfCollapsibleASCIIWhiteSpaces =
GetEndOfCollapsibleASCIIWhiteSpaces<EditorDOMPointInText>( GetEndOfCollapsibleASCIIWhiteSpaces<EditorDOMPointInText>(
atPreviousCharOfStart, nsIEditor::eNone, IgnoreNonEditableNodes::Yes); atPreviousCharOfStart, nsIEditor::eNone,
ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
return ReplaceRangeData(atPreviousCharOfStart, return ReplaceRangeData(atPreviousCharOfStart,
endOfCollapsibleASCIIWhiteSpaces, endOfCollapsibleASCIIWhiteSpaces,
nsDependentSubstring(&HTMLEditUtils::kNBSP, 1)); nsDependentSubstring(&HTMLEditUtils::kNBSP, 1));
@@ -1250,7 +1277,7 @@ EditorDOMPointInText WSRunScanner::TextFragmentData::
// about what is after it. What is after it now will end up after the // about what is after it. What is after it now will end up after the
// inserted object. // inserted object.
const auto atPreviousChar = GetPreviousCharPoint<EditorDOMPointInText>( const auto atPreviousChar = GetPreviousCharPoint<EditorDOMPointInText>(
aPointToInsert, IgnoreNonEditableNodes::Yes); aPointToInsert, ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
if (!atPreviousChar.IsSet() || atPreviousChar.IsEndOfContainer() || if (!atPreviousChar.IsSet() || atPreviousChar.IsEndOfContainer() ||
!atPreviousChar.IsCharNBSP() || !atPreviousChar.IsCharNBSP() ||
EditorUtils::IsWhiteSpacePreformatted( EditorUtils::IsWhiteSpacePreformatted(
@@ -1259,8 +1286,9 @@ EditorDOMPointInText WSRunScanner::TextFragmentData::
} }
const auto atPreviousCharOfPreviousChar = const auto atPreviousCharOfPreviousChar =
GetPreviousCharPoint<EditorDOMPointInText>(atPreviousChar, GetPreviousCharPoint<EditorDOMPointInText>(
IgnoreNonEditableNodes::Yes); atPreviousChar,
ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
if (atPreviousCharOfPreviousChar.IsSet()) { if (atPreviousCharOfPreviousChar.IsSet()) {
// If the previous char is in different text node and it's preformatted, // If the previous char is in different text node and it's preformatted,
// we shouldn't touch it. // we shouldn't touch it.
@@ -1307,7 +1335,7 @@ EditorDOMPointInText WSRunScanner::TextFragmentData::
// in the ws abut an inserted text, so we don't have to worry about what is // in the ws abut an inserted text, so we don't have to worry about what is
// before it. What is before it now will end up before the inserted text. // before it. What is before it now will end up before the inserted text.
const auto atNextChar = GetInclusiveNextCharPoint<EditorDOMPointInText>( const auto atNextChar = GetInclusiveNextCharPoint<EditorDOMPointInText>(
aPointToInsert, IgnoreNonEditableNodes::Yes); aPointToInsert, ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
if (!atNextChar.IsSet() || NS_WARN_IF(atNextChar.IsEndOfContainer()) || if (!atNextChar.IsSet() || NS_WARN_IF(atNextChar.IsEndOfContainer()) ||
!atNextChar.IsCharNBSP() || !atNextChar.IsCharNBSP() ||
EditorUtils::IsWhiteSpacePreformatted(*atNextChar.ContainerAs<Text>())) { EditorUtils::IsWhiteSpacePreformatted(*atNextChar.ContainerAs<Text>())) {
@@ -1317,7 +1345,7 @@ EditorDOMPointInText WSRunScanner::TextFragmentData::
const auto atNextCharOfNextCharOfNBSP = const auto atNextCharOfNextCharOfNBSP =
GetInclusiveNextCharPoint<EditorDOMPointInText>( GetInclusiveNextCharPoint<EditorDOMPointInText>(
atNextChar.NextPoint<EditorRawDOMPointInText>(), atNextChar.NextPoint<EditorRawDOMPointInText>(),
IgnoreNonEditableNodes::Yes); ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
if (atNextCharOfNextCharOfNBSP.IsSet()) { if (atNextCharOfNextCharOfNBSP.IsSet()) {
// If the next char is in different text node and it's preformatted, // If the next char is in different text node and it's preformatted,
// we shouldn't touch it. // we shouldn't touch it.

View File

@@ -821,7 +821,7 @@ Result<MoveNodeResult, nsresult> WhiteSpaceVisibilityKeeper::
Result<CreateLineBreakResult, nsresult> Result<CreateLineBreakResult, nsresult>
WhiteSpaceVisibilityKeeper::InsertLineBreak( WhiteSpaceVisibilityKeeper::InsertLineBreak(
LineBreakType aLineBreakType, HTMLEditor& aHTMLEditor, LineBreakType aLineBreakType, HTMLEditor& aHTMLEditor,
const EditorDOMPoint& aPointToInsert, const Element& aEditingHost) { const EditorDOMPoint& aPointToInsert) {
if (MOZ_UNLIKELY(NS_WARN_IF(!aPointToInsert.IsSet()))) { if (MOZ_UNLIKELY(NS_WARN_IF(!aPointToInsert.IsSet()))) {
return Err(NS_ERROR_INVALID_ARG); return Err(NS_ERROR_INVALID_ARG);
} }
@@ -830,10 +830,10 @@ WhiteSpaceVisibilityKeeper::InsertLineBreak(
// meanwhile, the pre case is handled in HandleInsertText() in // meanwhile, the pre case is handled in HandleInsertText() in
// HTMLEditSubActionHandler.cpp // HTMLEditSubActionHandler.cpp
TextFragmentData textFragmentDataAtInsertionPoint( const TextFragmentData textFragmentDataAtInsertionPoint(
aPointToInsert, &aEditingHost, BlockInlineCheck::UseComputedDisplayStyle); Scan::EditableNodes, aPointToInsert,
if (MOZ_UNLIKELY( BlockInlineCheck::UseComputedDisplayStyle);
NS_WARN_IF(!textFragmentDataAtInsertionPoint.IsInitialized()))) { if (NS_WARN_IF(!textFragmentDataAtInsertionPoint.IsInitialized())) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
} }
EditorDOMRange invisibleLeadingWhiteSpaceRangeOfNewLine = EditorDOMRange invisibleLeadingWhiteSpaceRangeOfNewLine =
@@ -1036,8 +1036,7 @@ WhiteSpaceVisibilityKeeper::InsertLineBreak(
// static // static
Result<InsertTextResult, nsresult> WhiteSpaceVisibilityKeeper::ReplaceText( Result<InsertTextResult, nsresult> WhiteSpaceVisibilityKeeper::ReplaceText(
HTMLEditor& aHTMLEditor, const nsAString& aStringToInsert, HTMLEditor& aHTMLEditor, const nsAString& aStringToInsert,
const EditorDOMRange& aRangeToBeReplaced, InsertTextTo aInsertTextTo, const EditorDOMRange& aRangeToBeReplaced, InsertTextTo aInsertTextTo) {
const Element& aEditingHost) {
// MOOSE: for now, we always assume non-PRE formatting. Fix this later. // MOOSE: for now, we always assume non-PRE formatting. Fix this later.
// meanwhile, the pre case is handled in HandleInsertText() in // meanwhile, the pre case is handled in HandleInsertText() in
// HTMLEditSubActionHandler.cpp // HTMLEditSubActionHandler.cpp
@@ -1051,8 +1050,8 @@ Result<InsertTextResult, nsresult> WhiteSpaceVisibilityKeeper::ReplaceText(
return InsertTextResult(); return InsertTextResult();
} }
TextFragmentData textFragmentDataAtStart( const TextFragmentData textFragmentDataAtStart(
aRangeToBeReplaced.StartRef(), &aEditingHost, Scan::EditableNodes, aRangeToBeReplaced.StartRef(),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
if (MOZ_UNLIKELY(NS_WARN_IF(!textFragmentDataAtStart.IsInitialized()))) { if (MOZ_UNLIKELY(NS_WARN_IF(!textFragmentDataAtStart.IsInitialized()))) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
@@ -1063,7 +1062,7 @@ Result<InsertTextResult, nsresult> WhiteSpaceVisibilityKeeper::ReplaceText(
TextFragmentData textFragmentDataAtEnd = TextFragmentData textFragmentDataAtEnd =
aRangeToBeReplaced.Collapsed() aRangeToBeReplaced.Collapsed()
? textFragmentDataAtStart ? textFragmentDataAtStart
: TextFragmentData(aRangeToBeReplaced.EndRef(), &aEditingHost, : TextFragmentData(Scan::EditableNodes, aRangeToBeReplaced.EndRef(),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
if (MOZ_UNLIKELY(NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized()))) { if (MOZ_UNLIKELY(NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized()))) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
@@ -1433,8 +1432,8 @@ Result<CaretPoint, nsresult>
WhiteSpaceVisibilityKeeper::DeletePreviousWhiteSpace( WhiteSpaceVisibilityKeeper::DeletePreviousWhiteSpace(
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPoint, HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPoint,
const Element& aEditingHost) { const Element& aEditingHost) {
TextFragmentData textFragmentDataAtDeletion( const TextFragmentData textFragmentDataAtDeletion(
aPoint, &aEditingHost, BlockInlineCheck::UseComputedDisplayStyle); Scan::EditableNodes, aPoint, BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAtDeletion.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtDeletion.IsInitialized())) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
} }
@@ -1553,8 +1552,8 @@ Result<CaretPoint, nsresult>
WhiteSpaceVisibilityKeeper::DeleteInclusiveNextWhiteSpace( WhiteSpaceVisibilityKeeper::DeleteInclusiveNextWhiteSpace(
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPoint, HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPoint,
const Element& aEditingHost) { const Element& aEditingHost) {
TextFragmentData textFragmentDataAtDeletion( const TextFragmentData textFragmentDataAtDeletion(
aPoint, &aEditingHost, BlockInlineCheck::UseComputedDisplayStyle); Scan::EditableNodes, aPoint, BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAtDeletion.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtDeletion.IsInitialized())) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
} }
@@ -1760,13 +1759,13 @@ Result<CaretPoint, nsresult> WhiteSpaceVisibilityKeeper::
NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED); NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED);
TextFragmentData textFragmentDataAtStart( TextFragmentData textFragmentDataAtStart(
rangeToDelete.StartRef(), &aEditingHost, Scan::EditableNodes, rangeToDelete.StartRef(),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized())) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
} }
TextFragmentData textFragmentDataAtEnd( TextFragmentData textFragmentDataAtEnd(
rangeToDelete.EndRef(), &aEditingHost, Scan::EditableNodes, rangeToDelete.EndRef(),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized())) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
@@ -1879,10 +1878,10 @@ Result<CaretPoint, nsresult> WhiteSpaceVisibilityKeeper::
// should retrieve the latest data for avoiding to delete/replace // should retrieve the latest data for avoiding to delete/replace
// unexpected range. // unexpected range.
textFragmentDataAtStart = textFragmentDataAtStart =
TextFragmentData(rangeToDelete.StartRef(), &aEditingHost, TextFragmentData(Scan::EditableNodes, rangeToDelete.StartRef(),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
textFragmentDataAtEnd = textFragmentDataAtEnd =
TextFragmentData(rangeToDelete.EndRef(), &aEditingHost, TextFragmentData(Scan::EditableNodes, rangeToDelete.EndRef(),
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
} }
} }
@@ -1939,8 +1938,8 @@ Result<CaretPoint, nsresult> WhiteSpaceVisibilityKeeper::
nsresult nsresult
WhiteSpaceVisibilityKeeper::MakeSureToKeepVisibleWhiteSpacesVisibleAfterSplit( WhiteSpaceVisibilityKeeper::MakeSureToKeepVisibleWhiteSpacesVisibleAfterSplit(
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPointToSplit) { HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPointToSplit) {
TextFragmentData textFragmentDataAtSplitPoint( const TextFragmentData textFragmentDataAtSplitPoint(
aPointToSplit, aHTMLEditor.ComputeEditingHost(), Scan::EditableNodes, aPointToSplit,
BlockInlineCheck::UseComputedDisplayStyle); BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentDataAtSplitPoint.IsInitialized())) { if (NS_WARN_IF(!textFragmentDataAtSplitPoint.IsInitialized())) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@@ -2113,8 +2112,8 @@ nsresult WhiteSpaceVisibilityKeeper::NormalizeVisibleWhiteSpacesAt(
MOZ_ASSERT(aPoint.IsInContentNode()); MOZ_ASSERT(aPoint.IsInContentNode());
MOZ_ASSERT(EditorUtils::IsEditableContent( MOZ_ASSERT(EditorUtils::IsEditableContent(
*aPoint.template ContainerAs<nsIContent>(), EditorType::HTML)); *aPoint.template ContainerAs<nsIContent>(), EditorType::HTML));
TextFragmentData textFragmentData(aPoint, &aEditingHost, const TextFragmentData textFragmentData(
BlockInlineCheck::UseComputedDisplayStyle); Scan::EditableNodes, aPoint, BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentData.IsInitialized())) { if (NS_WARN_IF(!textFragmentData.IsInitialized())) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@@ -2469,9 +2468,8 @@ Result<CaretPoint, nsresult>
WhiteSpaceVisibilityKeeper::DeleteInvisibleASCIIWhiteSpaces( WhiteSpaceVisibilityKeeper::DeleteInvisibleASCIIWhiteSpaces(
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPoint) { HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPoint) {
MOZ_ASSERT(aPoint.IsSet()); MOZ_ASSERT(aPoint.IsSet());
Element* editingHost = aHTMLEditor.ComputeEditingHost(); const TextFragmentData textFragmentData(
TextFragmentData textFragmentData(aPoint, editingHost, Scan::EditableNodes, aPoint, BlockInlineCheck::UseComputedDisplayStyle);
BlockInlineCheck::UseComputedDisplayStyle);
if (NS_WARN_IF(!textFragmentData.IsInitialized())) { if (NS_WARN_IF(!textFragmentData.IsInitialized())) {
return Err(NS_ERROR_FAILURE); return Err(NS_ERROR_FAILURE);
} }

View File

@@ -45,6 +45,7 @@ class WhiteSpaceVisibilityKeeper final {
using InsertTextTo = EditorBase::InsertTextTo; using InsertTextTo = EditorBase::InsertTextTo;
using LineBreakType = HTMLEditor::LineBreakType; using LineBreakType = HTMLEditor::LineBreakType;
using PointPosition = WSRunScanner::PointPosition; using PointPosition = WSRunScanner::PointPosition;
using Scan = WSRunScanner::Scan;
using TextFragmentData = WSRunScanner::TextFragmentData; using TextFragmentData = WSRunScanner::TextFragmentData;
using VisibleWhiteSpacesData = WSRunScanner::VisibleWhiteSpacesData; using VisibleWhiteSpacesData = WSRunScanner::VisibleWhiteSpacesData;
@@ -222,8 +223,7 @@ class WhiteSpaceVisibilityKeeper final {
[[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CreateLineBreakResult, [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CreateLineBreakResult,
nsresult> nsresult>
InsertLineBreak(LineBreakType aLineBreakType, HTMLEditor& aHTMLEditor, InsertLineBreak(LineBreakType aLineBreakType, HTMLEditor& aHTMLEditor,
const EditorDOMPoint& aPointToInsert, const EditorDOMPoint& aPointToInsert);
const Element& aEditingHost);
/** /**
* Insert aStringToInsert to aPointToInsert and makes any needed adjustments * Insert aStringToInsert to aPointToInsert and makes any needed adjustments
@@ -239,10 +239,10 @@ class WhiteSpaceVisibilityKeeper final {
[[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<InsertTextResult, nsresult> [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<InsertTextResult, nsresult>
InsertText(HTMLEditor& aHTMLEditor, const nsAString& aStringToInsert, InsertText(HTMLEditor& aHTMLEditor, const nsAString& aStringToInsert,
const EditorDOMPointType& aPointToInsert, const EditorDOMPointType& aPointToInsert,
InsertTextTo aInsertTextTo, const Element& aEditingHost) { InsertTextTo aInsertTextTo) {
return WhiteSpaceVisibilityKeeper::ReplaceText( return WhiteSpaceVisibilityKeeper::ReplaceText(
aHTMLEditor, aStringToInsert, EditorDOMRange(aPointToInsert), aHTMLEditor, aStringToInsert, EditorDOMRange(aPointToInsert),
aInsertTextTo, aEditingHost); aInsertTextTo);
} }
/** /**
@@ -259,7 +259,7 @@ class WhiteSpaceVisibilityKeeper final {
[[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<InsertTextResult, nsresult> [[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<InsertTextResult, nsresult>
ReplaceText(HTMLEditor& aHTMLEditor, const nsAString& aStringToInsert, ReplaceText(HTMLEditor& aHTMLEditor, const nsAString& aStringToInsert,
const EditorDOMRange& aRangeToBeReplaced, const EditorDOMRange& aRangeToBeReplaced,
InsertTextTo aInsertTextTo, const Element& aEditingHost); InsertTextTo aInsertTextTo);
/** /**
* Delete previous white-space of aPoint. This automatically keeps visibility * Delete previous white-space of aPoint. This automatically keeps visibility