Bug 1940377 - part 2: Make HandleInsertLineBreak use the new normalizer if it's available r=m_kato

When inserting a `<br>` element or a preformatted line break at middle of a
`Text`, we need to split it first.  At this time, we should normalize the
surrounding white-spaces before split.  Then, we can use only one
`ReplaceTextTransaction` instance for the normalization in the most cases.

Differential Revision: https://phabricator.services.mozilla.com/D239464
This commit is contained in:
Masayuki Nakano
2025-03-08 00:23:15 +00:00
parent f7f5dd6a64
commit cb5f775b5c
8 changed files with 825 additions and 205 deletions

View File

@@ -4191,6 +4191,13 @@ Result<CaretPoint, nsresult> HTMLEditor::DeleteTextWithTransaction(
return caretPointOrError;
}
Result<InsertTextResult, nsresult> HTMLEditor::ReplaceTextWithTransaction(
dom::Text& aTextNode, const ReplaceWhiteSpacesData& aData) {
return ReplaceTextWithTransaction(aTextNode, aData.mReplaceStartOffset,
aData.ReplaceLength(),
aData.mNormalizedString);
}
Result<InsertTextResult, nsresult> HTMLEditor::ReplaceTextWithTransaction(
Text& aTextNode, uint32_t aOffset, uint32_t aLength,
const nsAString& aStringToInsert) {
@@ -4382,7 +4389,16 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::PrepareToInsertLineBreak(
!CanInsertLineBreak(*aPointToInsert.ContainerAs<nsIContent>()))) {
return Err(NS_ERROR_FAILURE);
}
return aPointToInsert;
if (!StaticPrefs::editor_white_space_normalization_blink_compatible()) {
return aPointToInsert;
}
Result<EditorDOMPoint, nsresult> pointToInsertOrError =
WhiteSpaceVisibilityKeeper::NormalizeWhiteSpacesToSplitAt(
*this, aPointToInsert);
if (NS_WARN_IF(pointToInsertOrError.isErr())) {
return pointToInsertOrError.propagateErr();
}
return pointToInsertOrError.unwrap();
}
// If the text node is not in an element node, we cannot insert a line break
@@ -4394,21 +4410,34 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::PrepareToInsertLineBreak(
return Err(NS_ERROR_FAILURE);
}
if (aPointToInsert.IsStartOfContainer()) {
Result<EditorDOMPoint, nsresult> pointToInsertOrError =
StaticPrefs::editor_white_space_normalization_blink_compatible()
? WhiteSpaceVisibilityKeeper::NormalizeWhiteSpacesToSplitAt(
*this, aPointToInsert)
: aPointToInsert;
if (NS_WARN_IF(pointToInsertOrError.isErr())) {
return pointToInsertOrError.propagateErr();
}
const EditorDOMPoint pointToInsert = pointToInsertOrError.unwrap();
if (!pointToInsert.IsInTextNode()) {
return pointToInsert.ParentPoint();
}
if (pointToInsert.IsStartOfContainer()) {
// Insert before the text node.
return aPointToInsert.ParentPoint();
return pointToInsert.ParentPoint();
}
if (aPointToInsert.IsEndOfContainer()) {
if (pointToInsert.IsEndOfContainer()) {
// Insert after the text node.
return EditorDOMPoint::After(*aPointToInsert.ContainerAs<Text>());
return EditorDOMPoint::After(*pointToInsert.ContainerAs<Text>());
}
MOZ_DIAGNOSTIC_ASSERT(aPointToInsert.IsSetAndValid());
MOZ_DIAGNOSTIC_ASSERT(pointToInsert.IsSetAndValid());
// Unfortunately, we need to split the text node at the offset.
Result<SplitNodeResult, nsresult> splitTextNodeResult =
SplitNodeWithTransaction(aPointToInsert);
SplitNodeWithTransaction(pointToInsert);
if (MOZ_UNLIKELY(splitTextNodeResult.isErr())) {
NS_WARNING("HTMLEditor::SplitNodeWithTransaction() failed");
return splitTextNodeResult.propagateErr();