Bug 1770877 - part 17: Make HTMLEditor::SplitElementsAtEveryBRElement and HTMLEditor::MaybeSplitElementsAtEveryBRElement stop touching Selection directly r=m_kato

Differential Revision: https://phabricator.services.mozilla.com/D149081
This commit is contained in:
Masayuki Nakano 2022-06-19 20:57:21 +00:00
parent b5798517e5
commit c5eaf27dcc
2 changed files with 51 additions and 45 deletions

View File

@ -6497,12 +6497,22 @@ nsresult HTMLEditor::SplitInlinesAndCollectEditTargetNodes(
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }
rv = MaybeSplitElementsAtEveryBRElement(aOutArrayOfContents, aEditSubAction); const Result<EditorDOMPoint, nsresult> splitResult =
NS_WARNING_ASSERTION( MaybeSplitElementsAtEveryBRElement(aOutArrayOfContents, aEditSubAction);
NS_SUCCEEDED(rv), if (MOZ_UNLIKELY(splitResult.isErr())) {
"HTMLEditor::MaybeSplitElementsAtEveryBRElement() failed"); NS_WARNING("HTMLEditor::MaybeSplitElementsAtEveryBRElement() failed");
return splitResult.inspectErr();
}
const EditorDOMPoint& pointToPutCaret = splitResult.inspect();
if (AllowsTransactionsToChangeSelection() && pointToPutCaret.IsSet()) {
nsresult rv = CollapseSelectionTo(pointToPutCaret);
if (NS_FAILED(rv)) {
NS_WARNING("EditorBase::CollapseSelectionTo() failed");
return rv; return rv;
} }
}
return NS_OK;
}
nsresult HTMLEditor::SplitTextNodesAtRangeEnd( nsresult HTMLEditor::SplitTextNodesAtRangeEnd(
nsTArray<OwningNonNull<nsRange>>& aArrayOfRanges) { nsTArray<OwningNonNull<nsRange>>& aArrayOfRanges) {
@ -6733,7 +6743,7 @@ nsresult HTMLEditor::CollectEditTargetNodes(
return NS_OK; return NS_OK;
} }
nsresult HTMLEditor::MaybeSplitElementsAtEveryBRElement( Result<EditorDOMPoint, nsresult> HTMLEditor::MaybeSplitElementsAtEveryBRElement(
nsTArray<OwningNonNull<nsIContent>>& aArrayOfContents, nsTArray<OwningNonNull<nsIContent>>& aArrayOfContents,
EditSubAction aEditSubAction) { EditSubAction aEditSubAction) {
// Post-process the list to break up inline containers that contain br's, but // Post-process the list to break up inline containers that contain br's, but
@ -6745,7 +6755,8 @@ nsresult HTMLEditor::MaybeSplitElementsAtEveryBRElement(
case EditSubAction::eSetOrClearAlignment: case EditSubAction::eSetOrClearAlignment:
case EditSubAction::eSetPositionToAbsolute: case EditSubAction::eSetPositionToAbsolute:
case EditSubAction::eIndent: case EditSubAction::eIndent:
case EditSubAction::eOutdent: case EditSubAction::eOutdent: {
EditorDOMPoint pointToPutCaret;
for (int32_t i = aArrayOfContents.Length() - 1; i >= 0; i--) { for (int32_t i = aArrayOfContents.Length() - 1; i >= 0; i--) {
OwningNonNull<nsIContent>& content = aArrayOfContents[i]; OwningNonNull<nsIContent>& content = aArrayOfContents[i];
if (HTMLEditUtils::IsInlineElement(content) && if (HTMLEditUtils::IsInlineElement(content) &&
@ -6753,21 +6764,25 @@ nsresult HTMLEditor::MaybeSplitElementsAtEveryBRElement(
AutoTArray<OwningNonNull<nsIContent>, 24> arrayOfInlineContents; AutoTArray<OwningNonNull<nsIContent>, 24> arrayOfInlineContents;
// MOZ_KnownLive because 'aArrayOfContents' is guaranteed to keep it // MOZ_KnownLive because 'aArrayOfContents' is guaranteed to keep it
// alive. // alive.
nsresult rv = SplitElementsAtEveryBRElement(MOZ_KnownLive(content), Result<EditorDOMPoint, nsresult> splitResult =
SplitElementsAtEveryBRElement(MOZ_KnownLive(content),
arrayOfInlineContents); arrayOfInlineContents);
if (NS_FAILED(rv)) { if (splitResult.isErr()) {
NS_WARNING("HTMLEditor::SplitElementsAtEveryBRElement() failed"); NS_WARNING("HTMLEditor::SplitElementsAtEveryBRElement() failed");
return rv; return splitResult;
}
if (splitResult.inspect().IsSet()) {
pointToPutCaret = splitResult.unwrap();
} }
// Put these nodes in aArrayOfContents, replacing the current node // Put these nodes in aArrayOfContents, replacing the current node
aArrayOfContents.RemoveElementAt(i); aArrayOfContents.RemoveElementAt(i);
aArrayOfContents.InsertElementsAt(i, arrayOfInlineContents); aArrayOfContents.InsertElementsAt(i, arrayOfInlineContents);
} }
} }
return NS_OK; return pointToPutCaret;
}
default: default:
return NS_OK; return EditorDOMPoint();
} }
} }
@ -6887,7 +6902,7 @@ nsresult HTMLEditor::SplitParentInlineElementsAtRangeEdges(
return NS_OK; return NS_OK;
} }
nsresult HTMLEditor::SplitElementsAtEveryBRElement( Result<EditorDOMPoint, nsresult> HTMLEditor::SplitElementsAtEveryBRElement(
nsIContent& aMostAncestorToBeSplit, nsIContent& aMostAncestorToBeSplit,
nsTArray<OwningNonNull<nsIContent>>& aOutArrayOfContents) { nsTArray<OwningNonNull<nsIContent>>& aOutArrayOfContents) {
MOZ_ASSERT(IsEditActionDataAvailable()); MOZ_ASSERT(IsEditActionDataAvailable());
@ -6900,29 +6915,25 @@ nsresult HTMLEditor::SplitElementsAtEveryBRElement(
// If there aren't any breaks, just put inNode itself in the array // If there aren't any breaks, just put inNode itself in the array
if (arrayOfBRElements.IsEmpty()) { if (arrayOfBRElements.IsEmpty()) {
aOutArrayOfContents.AppendElement(aMostAncestorToBeSplit); aOutArrayOfContents.AppendElement(aMostAncestorToBeSplit);
return NS_OK; return EditorDOMPoint();
} }
// Else we need to bust up aMostAncestorToBeSplit along all the breaks // Else we need to bust up aMostAncestorToBeSplit along all the breaks
nsCOMPtr<nsIContent> nextContent = &aMostAncestorToBeSplit; nsCOMPtr<nsIContent> nextContent = &aMostAncestorToBeSplit;
EditorDOMPoint pointToPutCaret;
for (OwningNonNull<HTMLBRElement>& brElement : arrayOfBRElements) { for (OwningNonNull<HTMLBRElement>& brElement : arrayOfBRElements) {
EditorDOMPoint atBRNode(brElement); EditorDOMPoint atBRNode(brElement);
if (NS_WARN_IF(!atBRNode.IsSet())) { if (NS_WARN_IF(!atBRNode.IsSet())) {
return NS_ERROR_FAILURE; return Err(NS_ERROR_FAILURE);
} }
const SplitNodeResult splitNodeResult = SplitNodeDeepWithTransaction( SplitNodeResult splitNodeResult = SplitNodeDeepWithTransaction(
*nextContent, atBRNode, SplitAtEdges::eAllowToCreateEmptyContainer); *nextContent, atBRNode, SplitAtEdges::eAllowToCreateEmptyContainer);
if (splitNodeResult.isErr()) { if (splitNodeResult.isErr()) {
NS_WARNING("HTMLEditor::SplitNodeDeepWithTransaction() failed"); NS_WARNING("HTMLEditor::SplitNodeDeepWithTransaction() failed");
return splitNodeResult.unwrapErr(); return Err(splitNodeResult.unwrapErr());
}
nsresult rv = splitNodeResult.SuggestCaretPointTo(
*this, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt});
if (NS_FAILED(rv)) {
NS_WARNING("SplitNodeResult::SuggestCaretPointTo() failed");
return rv;
} }
splitNodeResult.MoveCaretPointTo(pointToPutCaret,
{SuggestCaret::OnlyIfHasSuggestion});
// Put previous node at the split point. // Put previous node at the split point.
if (nsIContent* previousContent = splitNodeResult.GetPreviousContent()) { if (nsIContent* previousContent = splitNodeResult.GetPreviousContent()) {
// Might not be a left node. A break might have been at the very // Might not be a left node. A break might have been at the very
@ -6930,30 +6941,18 @@ nsresult HTMLEditor::SplitElementsAtEveryBRElement(
// SplitNodeDeepWithTransaction() would not actually split anything. // SplitNodeDeepWithTransaction() would not actually split anything.
aOutArrayOfContents.AppendElement(*previousContent); aOutArrayOfContents.AppendElement(*previousContent);
} }
// When adding caret suggestion to SplitNodeResult, here didn't change
// selection so that just ignore it.
splitNodeResult.IgnoreCaretPointSuggestion();
// Move break outside of container and also put in node list // Move break outside of container and also put in node list
// MOZ_KnownLive because 'arrayOfBRElements' is guaranteed to keep it alive. // MOZ_KnownLive because 'arrayOfBRElements' is guaranteed to keep it alive.
const MoveNodeResult moveBRElementResult = MoveNodeWithTransaction( MoveNodeResult moveBRElementResult = MoveNodeWithTransaction(
MOZ_KnownLive(brElement), MOZ_KnownLive(brElement),
splitNodeResult.AtNextContent<EditorDOMPoint>()); splitNodeResult.AtNextContent<EditorDOMPoint>());
if (moveBRElementResult.isErr()) { if (moveBRElementResult.isErr()) {
NS_WARNING("HTMLEditor::MoveNodeWithTransaction() failed"); NS_WARNING("HTMLEditor::MoveNodeWithTransaction() failed");
return moveBRElementResult.unwrapErr(); return Err(moveBRElementResult.unwrapErr());
} }
rv = moveBRElementResult.SuggestCaretPointTo( moveBRElementResult.MoveCaretPointTo(pointToPutCaret,
*this, {SuggestCaret::OnlyIfHasSuggestion, {SuggestCaret::OnlyIfHasSuggestion});
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});
if (NS_FAILED(rv)) {
NS_WARNING("MoveNodeResult::SuggestCaretPointTo() failed");
return rv;
}
NS_WARNING_ASSERTION(
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"MoveNodeResult::SuggestCaretPointTo() failed, but ignored");
aOutArrayOfContents.AppendElement(brElement); aOutArrayOfContents.AppendElement(brElement);
nextContent = splitNodeResult.GetNextContent(); nextContent = splitNodeResult.GetNextContent();
@ -6962,7 +6961,7 @@ nsresult HTMLEditor::SplitElementsAtEveryBRElement(
// Now tack on remaining next node. // Now tack on remaining next node.
aOutArrayOfContents.AppendElement(*nextContent); aOutArrayOfContents.AppendElement(*nextContent);
return NS_OK; return pointToPutCaret;
} }
// static // static

View File

@ -1158,8 +1158,11 @@ class HTMLEditor final : public EditorBase,
* is first leaf node of * is first leaf node of
* aMostAncestorToBeSplit, starting from * aMostAncestorToBeSplit, starting from
* the first <br> element. * the first <br> element.
* @return A suggest point to put caret if
* succeeded, but it may unset.
*/ */
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult SplitElementsAtEveryBRElement( [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditorDOMPoint, nsresult>
SplitElementsAtEveryBRElement(
nsIContent& aMostAncestorToBeSplit, nsIContent& aMostAncestorToBeSplit,
nsTArray<OwningNonNull<nsIContent>>& aOutArrayOfContents); nsTArray<OwningNonNull<nsIContent>>& aOutArrayOfContents);
@ -1168,8 +1171,12 @@ class HTMLEditor final : public EditorBase,
* for each given node when this needs to do that for aEditSubAction. * for each given node when this needs to do that for aEditSubAction.
* If split a node, it in aArrayOfContents is replaced with split nodes and * If split a node, it in aArrayOfContents is replaced with split nodes and
* <br> elements. * <br> elements.
*
* @return A suggest point to put caret if
* succeeded, but it may unset.
*/ */
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult MaybeSplitElementsAtEveryBRElement( [[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditorDOMPoint, nsresult>
MaybeSplitElementsAtEveryBRElement(
nsTArray<OwningNonNull<nsIContent>>& aArrayOfContents, nsTArray<OwningNonNull<nsIContent>>& aArrayOfContents,
EditSubAction aEditSubAction); EditSubAction aEditSubAction);