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,11 +6497,21 @@ nsresult HTMLEditor::SplitInlinesAndCollectEditTargetNodes(
if (NS_FAILED(rv)) {
return rv;
}
rv = MaybeSplitElementsAtEveryBRElement(aOutArrayOfContents, aEditSubAction);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv),
"HTMLEditor::MaybeSplitElementsAtEveryBRElement() failed");
return rv;
const Result<EditorDOMPoint, nsresult> splitResult =
MaybeSplitElementsAtEveryBRElement(aOutArrayOfContents, aEditSubAction);
if (MOZ_UNLIKELY(splitResult.isErr())) {
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 NS_OK;
}
nsresult HTMLEditor::SplitTextNodesAtRangeEnd(
@ -6733,7 +6743,7 @@ nsresult HTMLEditor::CollectEditTargetNodes(
return NS_OK;
}
nsresult HTMLEditor::MaybeSplitElementsAtEveryBRElement(
Result<EditorDOMPoint, nsresult> HTMLEditor::MaybeSplitElementsAtEveryBRElement(
nsTArray<OwningNonNull<nsIContent>>& aArrayOfContents,
EditSubAction aEditSubAction) {
// 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::eSetPositionToAbsolute:
case EditSubAction::eIndent:
case EditSubAction::eOutdent:
case EditSubAction::eOutdent: {
EditorDOMPoint pointToPutCaret;
for (int32_t i = aArrayOfContents.Length() - 1; i >= 0; i--) {
OwningNonNull<nsIContent>& content = aArrayOfContents[i];
if (HTMLEditUtils::IsInlineElement(content) &&
@ -6753,21 +6764,25 @@ nsresult HTMLEditor::MaybeSplitElementsAtEveryBRElement(
AutoTArray<OwningNonNull<nsIContent>, 24> arrayOfInlineContents;
// MOZ_KnownLive because 'aArrayOfContents' is guaranteed to keep it
// alive.
nsresult rv = SplitElementsAtEveryBRElement(MOZ_KnownLive(content),
arrayOfInlineContents);
if (NS_FAILED(rv)) {
Result<EditorDOMPoint, nsresult> splitResult =
SplitElementsAtEveryBRElement(MOZ_KnownLive(content),
arrayOfInlineContents);
if (splitResult.isErr()) {
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
aArrayOfContents.RemoveElementAt(i);
aArrayOfContents.InsertElementsAt(i, arrayOfInlineContents);
}
}
return NS_OK;
return pointToPutCaret;
}
default:
return NS_OK;
return EditorDOMPoint();
}
}
@ -6887,7 +6902,7 @@ nsresult HTMLEditor::SplitParentInlineElementsAtRangeEdges(
return NS_OK;
}
nsresult HTMLEditor::SplitElementsAtEveryBRElement(
Result<EditorDOMPoint, nsresult> HTMLEditor::SplitElementsAtEveryBRElement(
nsIContent& aMostAncestorToBeSplit,
nsTArray<OwningNonNull<nsIContent>>& aOutArrayOfContents) {
MOZ_ASSERT(IsEditActionDataAvailable());
@ -6900,29 +6915,25 @@ nsresult HTMLEditor::SplitElementsAtEveryBRElement(
// If there aren't any breaks, just put inNode itself in the array
if (arrayOfBRElements.IsEmpty()) {
aOutArrayOfContents.AppendElement(aMostAncestorToBeSplit);
return NS_OK;
return EditorDOMPoint();
}
// Else we need to bust up aMostAncestorToBeSplit along all the breaks
nsCOMPtr<nsIContent> nextContent = &aMostAncestorToBeSplit;
EditorDOMPoint pointToPutCaret;
for (OwningNonNull<HTMLBRElement>& brElement : arrayOfBRElements) {
EditorDOMPoint atBRNode(brElement);
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);
if (splitNodeResult.isErr()) {
NS_WARNING("HTMLEditor::SplitNodeDeepWithTransaction() failed");
return splitNodeResult.unwrapErr();
}
nsresult rv = splitNodeResult.SuggestCaretPointTo(
*this, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt});
if (NS_FAILED(rv)) {
NS_WARNING("SplitNodeResult::SuggestCaretPointTo() failed");
return rv;
return Err(splitNodeResult.unwrapErr());
}
splitNodeResult.MoveCaretPointTo(pointToPutCaret,
{SuggestCaret::OnlyIfHasSuggestion});
// Put previous node at the split point.
if (nsIContent* previousContent = splitNodeResult.GetPreviousContent()) {
// 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.
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
// MOZ_KnownLive because 'arrayOfBRElements' is guaranteed to keep it alive.
const MoveNodeResult moveBRElementResult = MoveNodeWithTransaction(
MoveNodeResult moveBRElementResult = MoveNodeWithTransaction(
MOZ_KnownLive(brElement),
splitNodeResult.AtNextContent<EditorDOMPoint>());
if (moveBRElementResult.isErr()) {
NS_WARNING("HTMLEditor::MoveNodeWithTransaction() failed");
return moveBRElementResult.unwrapErr();
return Err(moveBRElementResult.unwrapErr());
}
rv = moveBRElementResult.SuggestCaretPointTo(
*this, {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");
moveBRElementResult.MoveCaretPointTo(pointToPutCaret,
{SuggestCaret::OnlyIfHasSuggestion});
aOutArrayOfContents.AppendElement(brElement);
nextContent = splitNodeResult.GetNextContent();
@ -6962,7 +6961,7 @@ nsresult HTMLEditor::SplitElementsAtEveryBRElement(
// Now tack on remaining next node.
aOutArrayOfContents.AppendElement(*nextContent);
return NS_OK;
return pointToPutCaret;
}
// static

View File

@ -1158,8 +1158,11 @@ class HTMLEditor final : public EditorBase,
* is first leaf node of
* aMostAncestorToBeSplit, starting from
* 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,
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.
* If split a node, it in aArrayOfContents is replaced with split nodes and
* <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,
EditSubAction aEditSubAction);