зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1766355 - part 6: Make `HTMLEditor::MoveOneHardLineContents` return `MoveNodeResult` with caret point suggestion r=m_kato
Differential Revision: https://phabricator.services.mozilla.com/D146402
This commit is contained in:
Родитель
48083b339b
Коммит
e0d3f2aa96
|
@ -2098,8 +2098,9 @@ class HTMLEditor final : public EditorBase,
|
|||
ErrorResult& aError);
|
||||
|
||||
/**
|
||||
* MoveOneHardLineContents() moves the content in a hard line which contains
|
||||
* aPointInHardLine to aPointToInsert or end of aPointToInsert's container.
|
||||
* MoveOneHardLineContentsWithTransaction() moves the content in a hard line
|
||||
* which contains aPointInHardLine to aPointToInsert or end of
|
||||
* aPointToInsert's container.
|
||||
*
|
||||
* @param aPointInHardLine A point in a hard line. All nodes in
|
||||
* same hard line will be moved.
|
||||
|
@ -2116,7 +2117,8 @@ class HTMLEditor final : public EditorBase,
|
|||
* container while we're moving nodes.
|
||||
*/
|
||||
enum class MoveToEndOfContainer { Yes, No };
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT MoveNodeResult MoveOneHardLineContents(
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT MoveNodeResult
|
||||
MoveOneHardLineContentsWithTransaction(
|
||||
const EditorDOMPoint& aPointInHardLine,
|
||||
const EditorDOMPoint& aPointToInsert,
|
||||
MoveToEndOfContainer aMoveToEndOfContainer = MoveToEndOfContainer::No);
|
||||
|
@ -4670,7 +4672,7 @@ class HTMLEditor final : public EditorBase,
|
|||
// DeleteTextAndTextNodesWithTransaction,
|
||||
// JoinNearestEditableNodesWithTransaction,
|
||||
// MoveChildrenWithTransaction,
|
||||
// MoveOneHardLineContents,
|
||||
// MoveOneHardLineContentsWithTransaction,
|
||||
// MoveToEndOfCOntainer,
|
||||
// SplitAncestorStyledInlineElementsAt,
|
||||
// TreatEmptyTextNodes
|
||||
|
|
|
@ -4673,8 +4673,9 @@ Result<bool, nsresult> HTMLEditor::CanMoveOrDeleteSomethingInHardLine(
|
|||
|
||||
// If there is only a padding `<br>` element in a empty block, it's selected
|
||||
// by `SelectBRElementIfCollapsedInEmptyBlock()`. However, it won't be
|
||||
// moved. Although it'll be deleted, `MoveOneHardLineContents()` returns
|
||||
// "ignored". Therefore, we should return `false` in this case.
|
||||
// moved. Although it'll be deleted,
|
||||
// `MoveOneHardLineContentsWithTransaction()` returns "ignored". Therefore,
|
||||
// we should return `false` in this case.
|
||||
if (nsIContent* childContent = oneLineRange->GetChildAtStartOffset()) {
|
||||
if (childContent->IsHTMLElement(nsGkAtoms::br) &&
|
||||
childContent->GetParent()) {
|
||||
|
@ -4735,7 +4736,7 @@ Result<bool, nsresult> HTMLEditor::CanMoveOrDeleteSomethingInHardLine(
|
|||
return startPoint.GetNextSiblingOfChild() != endPoint.GetChild();
|
||||
}
|
||||
|
||||
MoveNodeResult HTMLEditor::MoveOneHardLineContents(
|
||||
MoveNodeResult HTMLEditor::MoveOneHardLineContentsWithTransaction(
|
||||
const EditorDOMPoint& aPointInHardLine,
|
||||
const EditorDOMPoint& aPointToInsert,
|
||||
MoveToEndOfContainer
|
||||
|
@ -4764,89 +4765,54 @@ MoveNodeResult HTMLEditor::MoveOneHardLineContents(
|
|||
return MoveNodeIgnored(std::move(pointToInsert));
|
||||
}
|
||||
|
||||
uint32_t offset = pointToInsert.Offset();
|
||||
MoveNodeResult moveContentsInLineResult;
|
||||
MoveNodeResult moveContentsInLineResult = MoveNodeIgnored(pointToInsert);
|
||||
for (auto& content : arrayOfContents) {
|
||||
if (aMoveToEndOfContainer == MoveToEndOfContainer::Yes) {
|
||||
// For backward compatibility, we should move contents to end of the
|
||||
// container if this is called with MoveToEndOfContainer::Yes.
|
||||
offset = pointToInsert.GetContainer()->Length();
|
||||
// For backward compatibility, we should move contents to end of the
|
||||
// container if this is called with MoveToEndOfContainer::Yes.
|
||||
// And also if pointToInsert has been made invalid with removing preceding
|
||||
// children, we should move the content to the end of the container.
|
||||
if (aMoveToEndOfContainer == MoveToEndOfContainer::Yes ||
|
||||
(MayHaveMutationEventListeners() &&
|
||||
MOZ_UNLIKELY(!moveContentsInLineResult.NextInsertionPointRef()
|
||||
.IsSetAndValid()))) {
|
||||
pointToInsert.SetToEndOf(pointToInsert.GetContainer());
|
||||
} else {
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
moveContentsInLineResult.NextInsertionPointRef().IsSet());
|
||||
pointToInsert = moveContentsInLineResult.NextInsertionPointRef();
|
||||
}
|
||||
// get the node to act on
|
||||
// If the content is a block element, move all children of it to the
|
||||
// new container, and then, remove the (probably) empty block element.
|
||||
if (HTMLEditUtils::IsBlockElement(content)) {
|
||||
// For block nodes, move their contents only, then delete block.
|
||||
moveContentsInLineResult |= MoveChildrenWithTransaction(
|
||||
MOZ_KnownLive(*content->AsElement()),
|
||||
EditorDOMPoint(pointToInsert.GetContainer(), offset));
|
||||
MOZ_KnownLive(*content->AsElement()), pointToInsert);
|
||||
if (moveContentsInLineResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::MoveChildrenWithTransaction() failed");
|
||||
return moveContentsInLineResult;
|
||||
}
|
||||
nsresult rv = moveContentsInLineResult.SuggestCaretPointTo(
|
||||
*this, {SuggestCaret::OnlyIfHasSuggestion,
|
||||
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
|
||||
SuggestCaret::AndIgnoreTrivialError});
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("MoveNodeResult::SuggestCaretPointTo() failed");
|
||||
return MoveNodeResult(rv);
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
|
||||
"MoveNodeResult::SuggestCaretPointTo() failed, but ignored");
|
||||
offset = moveContentsInLineResult.NextInsertionPointRef().Offset();
|
||||
moveContentsInLineResult.MarkAsHandled();
|
||||
// MOZ_KnownLive because 'arrayOfContents' is guaranteed to
|
||||
// keep it alive.
|
||||
DebugOnly<nsresult> rvIgnored =
|
||||
DeleteNodeWithTransaction(MOZ_KnownLive(*content));
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
moveContentsInLineResult.IgnoreCaretPointSuggestion();
|
||||
return MoveNodeResult(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rvIgnored),
|
||||
"HTMLEditor::DeleteNodeWithTransaction() failed, but ignored");
|
||||
moveContentsInLineResult.MarkAsHandled();
|
||||
if (MayHaveMutationEventListeners()) {
|
||||
// Mutation event listener may make `offset` value invalid with
|
||||
// removing some previous children while we call
|
||||
// `DeleteNodeWithTransaction()` so that we should adjust it here.
|
||||
offset = std::min(offset, pointToInsert.GetContainer()->Length());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// XXX Different from the above block, we ignore error of moving nodes.
|
||||
// MOZ_KnownLive because 'arrayOfContents' is guaranteed to
|
||||
// keep it alive.
|
||||
MoveNodeResult moveNodeResult = MoveNodeOrChildrenWithTransaction(
|
||||
MOZ_KnownLive(content),
|
||||
EditorDOMPoint(pointToInsert.GetContainer(), offset));
|
||||
if (NS_WARN_IF(moveNodeResult.EditorDestroyed())) {
|
||||
moveContentsInLineResult.IgnoreCaretPointSuggestion();
|
||||
return MoveNodeResult(NS_ERROR_EDITOR_DESTROYED);
|
||||
moveContentsInLineResult |= MoveNodeOrChildrenWithTransaction(
|
||||
MOZ_KnownLive(content), pointToInsert);
|
||||
if (moveContentsInLineResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::MoveNodeOrChildrenWithTransaction() failed");
|
||||
return moveContentsInLineResult;
|
||||
}
|
||||
if (moveNodeResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::MoveNodeOrChildrenWithTransaction() failed, but "
|
||||
"ignored");
|
||||
continue;
|
||||
}
|
||||
nsresult rv = moveNodeResult.SuggestCaretPointTo(
|
||||
*this, {SuggestCaret::OnlyIfHasSuggestion,
|
||||
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
|
||||
SuggestCaret::AndIgnoreTrivialError});
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("MoveNodeResult::SuggestCaretPointTo() failed");
|
||||
return MoveNodeResult(rv);
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
rv != NS_ERROR_EDITOR_NO_EDITABLE_RANGE,
|
||||
"MoveNodeResult::SuggestCaretPointTo() failed, but ignored");
|
||||
offset = moveNodeResult.NextInsertionPointRef().Offset();
|
||||
moveContentsInLineResult |= moveNodeResult;
|
||||
}
|
||||
|
||||
NS_WARNING_ASSERTION(
|
||||
moveContentsInLineResult.isOk(),
|
||||
"Last HTMLEditor::MoveNodeOrChildrenWithTransaction() failed");
|
||||
return moveContentsInLineResult;
|
||||
}
|
||||
|
||||
|
|
|
@ -276,7 +276,8 @@ EditActionResult WhiteSpaceVisibilityKeeper::
|
|||
// behavior, we should mark as handled.
|
||||
ret.MarkAsHandled();
|
||||
} else {
|
||||
// XXX Why do we ignore the result of MoveOneHardLineContents()?
|
||||
// XXX Why do we ignore the result of
|
||||
// MoveOneHardLineContentsWithTransaction()?
|
||||
NS_ASSERTION(rightBlockElement == afterRightBlockChild.GetContainer(),
|
||||
"The relation is not guaranteed but assumed");
|
||||
#ifdef DEBUG
|
||||
|
@ -284,16 +285,18 @@ EditActionResult WhiteSpaceVisibilityKeeper::
|
|||
aHTMLEditor.CanMoveOrDeleteSomethingInHardLine(EditorRawDOMPoint(
|
||||
rightBlockElement, afterRightBlockChild.Offset()));
|
||||
#endif // #ifdef DEBUG
|
||||
MoveNodeResult moveNodeResult = aHTMLEditor.MoveOneHardLineContents(
|
||||
EditorDOMPoint(rightBlockElement, afterRightBlockChild.Offset()),
|
||||
EditorDOMPoint(&aLeftBlockElement, 0u),
|
||||
HTMLEditor::MoveToEndOfContainer::Yes);
|
||||
MoveNodeResult moveNodeResult =
|
||||
aHTMLEditor.MoveOneHardLineContentsWithTransaction(
|
||||
EditorDOMPoint(rightBlockElement, afterRightBlockChild.Offset()),
|
||||
EditorDOMPoint(&aLeftBlockElement, 0u),
|
||||
HTMLEditor::MoveToEndOfContainer::Yes);
|
||||
if (moveNodeResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::MoveOneHardLineContents(MoveToEndOfContainer::Yes) "
|
||||
"failed");
|
||||
"HTMLEditor::MoveOneHardLineContentsWithTransaction("
|
||||
"MoveToEndOfContainer::Yes) failed");
|
||||
return EditActionResult(moveNodeResult.unwrapErr());
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(!firstLineHasContent.isErr());
|
||||
if (firstLineHasContent.inspect()) {
|
||||
|
@ -304,8 +307,9 @@ EditActionResult WhiteSpaceVisibilityKeeper::
|
|||
"Failed to consider whether moving or not something");
|
||||
}
|
||||
#endif // #ifdef DEBUG
|
||||
// When MoveNodeResult starts to store caret point, here does not do
|
||||
// nothing.
|
||||
|
||||
// We don't need to update selection here because of dontChangeMySelection
|
||||
// above.
|
||||
moveNodeResult.IgnoreCaretPointSuggestion();
|
||||
ret |= moveNodeResult;
|
||||
// Now, all children of rightBlockElement were moved to leftBlockElement.
|
||||
|
@ -552,10 +556,11 @@ EditActionResult WhiteSpaceVisibilityKeeper::
|
|||
MOZ_DIAGNOSTIC_ASSERT(atPreviousContent.IsSetAndValid());
|
||||
}
|
||||
|
||||
MoveNodeResult moveNodeResult = aHTMLEditor.MoveOneHardLineContents(
|
||||
EditorDOMPoint(&aRightBlockElement, 0u), atPreviousContent);
|
||||
MoveNodeResult moveNodeResult =
|
||||
aHTMLEditor.MoveOneHardLineContentsWithTransaction(
|
||||
EditorDOMPoint(&aRightBlockElement, 0u), atPreviousContent);
|
||||
if (moveNodeResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::MoveOneHardLineContents() failed");
|
||||
NS_WARNING("HTMLEditor::MoveOneHardLineContentsWithTransaction() failed");
|
||||
return EditActionResult(moveNodeResult.unwrapErr());
|
||||
}
|
||||
|
||||
|
@ -569,8 +574,9 @@ EditActionResult WhiteSpaceVisibilityKeeper::
|
|||
"Failed to consider whether moving or not something");
|
||||
}
|
||||
#endif // #ifdef DEBUG
|
||||
// When MoveNodeResult starts to store caret point, here does not do
|
||||
// nothing.
|
||||
|
||||
// We don't need to update selection here because of dontChangeMySelection
|
||||
// above.
|
||||
moveNodeResult.IgnoreCaretPointSuggestion();
|
||||
ret |= moveNodeResult;
|
||||
}
|
||||
|
@ -664,14 +670,15 @@ EditActionResult WhiteSpaceVisibilityKeeper::
|
|||
#endif // #ifdef DEBUG
|
||||
|
||||
// Nodes are dissimilar types.
|
||||
MoveNodeResult moveNodeResult = aHTMLEditor.MoveOneHardLineContents(
|
||||
EditorDOMPoint(&aRightBlockElement, 0u),
|
||||
EditorDOMPoint(&aLeftBlockElement, 0u),
|
||||
HTMLEditor::MoveToEndOfContainer::Yes);
|
||||
MoveNodeResult moveNodeResult =
|
||||
aHTMLEditor.MoveOneHardLineContentsWithTransaction(
|
||||
EditorDOMPoint(&aRightBlockElement, 0u),
|
||||
EditorDOMPoint(&aLeftBlockElement, 0u),
|
||||
HTMLEditor::MoveToEndOfContainer::Yes);
|
||||
if (moveNodeResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::MoveOneHardLineContents(MoveToEndOfContainer::Yes) "
|
||||
"failed");
|
||||
"HTMLEditor::MoveOneHardLineContentsWithTransaction("
|
||||
"MoveToEndOfContainer::Yes) failed");
|
||||
return EditActionResult(moveNodeResult.unwrapErr());
|
||||
}
|
||||
|
||||
|
@ -685,8 +692,9 @@ EditActionResult WhiteSpaceVisibilityKeeper::
|
|||
"Failed to consider whether moving or not something");
|
||||
}
|
||||
#endif // #ifdef DEBUG
|
||||
// When MoveNodeResult starts to store caret point, here does not do
|
||||
// nothing.
|
||||
|
||||
// We don't need to update selection here because of dontChangeMySelection
|
||||
// above.
|
||||
moveNodeResult.IgnoreCaretPointSuggestion();
|
||||
ret |= moveNodeResult;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче