Bug 1815639 - part 8: Make HTMLEditor::InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary stop touching Selection directly r=m_kato

Depends on D169753

Differential Revision: https://phabricator.services.mozilla.com/D169754
This commit is contained in:
Masayuki Nakano 2023-02-21 10:45:10 +00:00
parent 5885f9eaa8
commit 39598d7624
3 changed files with 109 additions and 67 deletions

View File

@ -452,15 +452,25 @@ nsresult HTMLEditor::OnEndHandlingTopLevelEditSubActionInternal() {
NS_WARNING("There was no selection range");
return NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE;
}
nsresult rv = InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
newCaretPosition);
if (NS_FAILED(rv)) {
Result<CaretPoint, nsresult> caretPointOrError =
InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
newCaretPosition);
if (MOZ_UNLIKELY(caretPointOrError.isErr())) {
NS_WARNING(
"HTMLEditor::"
"InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary() "
"failed");
return caretPointOrError.unwrapErr();
}
nsresult rv = caretPointOrError.unwrap().SuggestCaretPointTo(
*this, {SuggestCaret::OnlyIfHasSuggestion});
if (NS_FAILED(rv)) {
NS_WARNING("CaretPoint::SuggestCaretPointTo() failed");
return rv;
}
NS_WARNING_ASSERTION(
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"CaretPoint::SuggestCaretPointTo() failed, but ignored");
}
// add in any needed <br>s, and remove any unneeded ones.
@ -3133,13 +3143,14 @@ HTMLEditor::DeleteTextAndNormalizeSurroundingWhiteSpaces(
{
AutoTrackDOMPoint trackingNewCaretPosition(RangeUpdaterRef(),
&newCaretPosition);
nsresult rv = InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
newCaretPosition);
if (NS_FAILED(rv)) {
Result<CaretPoint, nsresult> caretPointOrError =
InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
newCaretPosition);
if (MOZ_UNLIKELY(caretPointOrError.isErr())) {
NS_WARNING(
"HTMLEditor::"
"InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary() failed");
return Err(rv);
return caretPointOrError;
}
}
if (!newCaretPosition.IsSetAndValid()) {
@ -3149,38 +3160,39 @@ HTMLEditor::DeleteTextAndNormalizeSurroundingWhiteSpaces(
return CaretPoint(std::move(newCaretPosition));
}
nsresult HTMLEditor::InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
Result<CaretPoint, nsresult>
HTMLEditor::InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
const EditorDOMPoint& aPointToInsert) {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(aPointToInsert.IsSet());
if (!aPointToInsert.IsInContentNode()) {
return NS_OK;
return CaretPoint(EditorDOMPoint());
}
// If container of the point is not in a block, we don't need to put a
// `<br>` element here.
if (!HTMLEditUtils::IsBlockElement(
*aPointToInsert.ContainerAs<nsIContent>())) {
return NS_OK;
return CaretPoint(EditorDOMPoint());
}
WSRunScanner wsRunScanner(ComputeEditingHost(), aPointToInsert);
// If the point is not start of a hard line, we don't need to put a `<br>`
// element here.
if (!wsRunScanner.StartsFromHardLineBreak()) {
return NS_OK;
return CaretPoint(EditorDOMPoint());
}
// If the point is not end of a hard line or the hard line does not end with
// block boundary, we don't need to put a `<br>` element here.
if (!wsRunScanner.EndsByBlockBoundary()) {
return NS_OK;
return CaretPoint(EditorDOMPoint());
}
// If we cannot insert a `<br>` element here, do nothing.
if (!HTMLEditUtils::CanNodeContain(*aPointToInsert.GetContainer(),
*nsGkAtoms::br)) {
return NS_OK;
return CaretPoint(EditorDOMPoint());
}
Result<CreateElementResult, nsresult> insertBRElementResult = InsertBRElement(
@ -3188,12 +3200,9 @@ nsresult HTMLEditor::InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
if (MOZ_UNLIKELY(insertBRElementResult.isErr())) {
NS_WARNING(
"HTMLEditor::InsertBRElement(WithTransaction::Yes, ePrevious) failed");
return insertBRElementResult.unwrapErr();
return insertBRElementResult.propagateErr();
}
nsresult rv = insertBRElementResult.inspect().SuggestCaretPointTo(*this, {});
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"CreateElementResult::SuggestCaretPointTo() failed");
return rv;
return CaretPoint(insertBRElementResult.unwrap().UnwrapCaretPoint());
}
Result<EditActionResult, nsresult>

View File

@ -1505,12 +1505,11 @@ class HTMLEditor final : public EditorBase,
const Element& aEditingHost);
/**
* InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary() determines if
* aPointToInsert is start of a hard line and end of the line (i.e, the
* line is empty) and the line ends with block boundary, inserts a `<br>`
* element.
* Determine if aPointToInsert is start of a hard line and end of the line
* (i.e, in an empty line) and the line ends with block boundary, inserts a
* `<br>` element.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CaretPoint, nsresult>
InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
const EditorDOMPoint& aPointToInsert);

View File

@ -2158,15 +2158,23 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
NS_WARNING("There was no selection range");
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
}
nsresult rv =
Result<CaretPoint, nsresult> caretPointOrError =
aHTMLEditor.InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
newCaretPosition);
if (NS_FAILED(rv)) {
if (MOZ_UNLIKELY(caretPointOrError.isErr())) {
NS_WARNING(
"HTMLEditor::InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary()"
" failed");
return caretPointOrError.propagateErr();
}
nsresult rv = caretPointOrError.unwrap().SuggestCaretPointTo(
aHTMLEditor, {SuggestCaret::OnlyIfHasSuggestion});
if (NS_FAILED(rv)) {
NS_WARNING("CaretPoint::SuggestCaretPointTo() failed");
return Err(rv);
}
NS_WARNING_ASSERTION(rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"CaretPoint::SuggestCaretPointTo() failed, but ignored");
return EditActionResult::HandledResult();
}
@ -2235,24 +2243,28 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
NS_WARNING("Mutation event listener changed the DOM tree");
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
}
Result<CaretPoint, nsresult> caretPointOrError =
aHTMLEditor.DeleteTextWithTransaction(
visibleTextNode, startToDelete.Offset(),
endToDelete.Offset() - startToDelete.Offset());
if (MOZ_UNLIKELY(caretPointOrError.isErr())) {
NS_WARNING("HTMLEditor::DeleteTextWithTransaction() failed");
return caretPointOrError.propagateErr();
{
Result<CaretPoint, nsresult> caretPointOrError =
aHTMLEditor.DeleteTextWithTransaction(
visibleTextNode, startToDelete.Offset(),
endToDelete.Offset() - startToDelete.Offset());
if (MOZ_UNLIKELY(caretPointOrError.isErr())) {
NS_WARNING("HTMLEditor::DeleteTextWithTransaction() failed");
return caretPointOrError.propagateErr();
}
nsresult rv = caretPointOrError.inspect().SuggestCaretPointTo(
aHTMLEditor, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});
if (NS_FAILED(rv)) {
NS_WARNING("CaretPoint::SuggestCaretPointTo() failed");
return Err(rv);
}
NS_WARNING_ASSERTION(
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"CaretPoint::SuggestCaretPointTo() failed, but ignored");
}
nsresult rv = caretPointOrError.inspect().SuggestCaretPointTo(
aHTMLEditor, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});
if (NS_FAILED(rv)) {
NS_WARNING("CaretPoint::SuggestCaretPointTo() failed");
return Err(rv);
}
NS_WARNING_ASSERTION(rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"CaretPoint::SuggestCaretPointTo() failed, but ignored");
// XXX When Backspace key is pressed, Chromium removes following empty
// text nodes when removing the last character of the non-empty text
@ -2267,7 +2279,8 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
// non-empty text node. For now, we should keep our traditional
// behavior same as Chromium for backward compatibility.
rv = DeleteNodeIfInvisibleAndEditableTextNode(aHTMLEditor, visibleTextNode);
nsresult rv =
DeleteNodeIfInvisibleAndEditableTextNode(aHTMLEditor, visibleTextNode);
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
return Err(NS_ERROR_EDITOR_DESTROYED);
}
@ -2287,14 +2300,23 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
// that we should use EditorDOMPoint::AtEndOf(visibleTextNode)
// instead. (Perhaps, we don't and/or shouldn't need to do this
// if the text node is preformatted.)
rv = aHTMLEditor.InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
newCaretPosition);
if (NS_FAILED(rv)) {
Result<CaretPoint, nsresult> caretPointOrError =
aHTMLEditor.InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
newCaretPosition);
if (MOZ_UNLIKELY(caretPointOrError.isErr())) {
NS_WARNING(
"HTMLEditor::InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary()"
" failed");
return caretPointOrError.propagateErr();
}
rv = caretPointOrError.unwrap().SuggestCaretPointTo(
aHTMLEditor, {SuggestCaret::OnlyIfHasSuggestion});
if (NS_FAILED(rv)) {
NS_WARNING("CaretPoint::SuggestCaretPointTo() failed");
return Err(rv);
}
NS_WARNING_ASSERTION(rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"CaretPoint::SuggestCaretPointTo() failed, but ignored");
// Remember that we did a ranged delete for the benefit of
// AfterEditInner().
@ -2544,25 +2566,28 @@ HTMLEditor::AutoDeleteRangesHandler::HandleDeleteAtomicContent(
MOZ_ASSERT(!HTMLEditUtils::IsInvisibleBRElement(aAtomicContent));
MOZ_ASSERT(&aAtomicContent != aWSRunScannerAtCaret.GetEditingHost());
Result<CaretPoint, nsresult> caretPointOrError =
WhiteSpaceVisibilityKeeper::DeleteContentNodeAndJoinTextNodesAroundIt(
aHTMLEditor, aAtomicContent, aCaretPoint, aEditingHost);
if (MOZ_UNLIKELY(caretPointOrError.isErr())) {
NS_WARNING(
"WhiteSpaceVisibilityKeeper::DeleteContentNodeAndJoinTextNodesAroundIt("
") failed");
return caretPointOrError.propagateErr();
{
Result<CaretPoint, nsresult> caretPointOrError =
WhiteSpaceVisibilityKeeper::DeleteContentNodeAndJoinTextNodesAroundIt(
aHTMLEditor, aAtomicContent, aCaretPoint, aEditingHost);
if (MOZ_UNLIKELY(caretPointOrError.isErr())) {
NS_WARNING(
"WhiteSpaceVisibilityKeeper::"
"DeleteContentNodeAndJoinTextNodesAroundIt() failed");
return caretPointOrError.propagateErr();
}
nsresult rv = caretPointOrError.unwrap().SuggestCaretPointTo(
aHTMLEditor, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});
if (NS_FAILED(rv)) {
NS_WARNING("CaretPoint::SuggestCaretPointTo() failed");
return Err(rv);
}
NS_WARNING_ASSERTION(
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"CaretPoint::SuggestCaretPointTo() failed, but ignored");
}
nsresult rv = caretPointOrError.unwrap().SuggestCaretPointTo(
aHTMLEditor, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});
if (NS_FAILED(rv)) {
NS_WARNING("CaretPoint::SuggestCaretPointTo() failed");
return Err(rv);
}
NS_WARNING_ASSERTION(rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"CaretPoint::SuggestCaretPointTo() failed, but ignored");
const auto newCaretPosition =
aHTMLEditor.GetFirstSelectionStartPoint<EditorDOMPoint>();
@ -2571,14 +2596,23 @@ HTMLEditor::AutoDeleteRangesHandler::HandleDeleteAtomicContent(
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
}
rv = aHTMLEditor.InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
newCaretPosition);
if (NS_FAILED(rv)) {
Result<CaretPoint, nsresult> caretPointOrError =
aHTMLEditor.InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary(
newCaretPosition);
if (MOZ_UNLIKELY(caretPointOrError.isErr())) {
NS_WARNING(
"HTMLEditor::InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary()"
" failed");
return caretPointOrError.propagateErr();
}
nsresult rv = caretPointOrError.unwrap().SuggestCaretPointTo(
aHTMLEditor, {SuggestCaret::OnlyIfHasSuggestion});
if (NS_FAILED(rv)) {
NS_WARNING("CaretPoint::SuggestCaretPointTo() failed");
return Err(rv);
}
NS_WARNING_ASSERTION(rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"CaretPoint::SuggestCaretPointTo() failed, but ignored");
return EditActionResult::HandledResult();
}