mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 04:38:02 +00:00
Bug 1655392 - part 4: Give independent mode and handler for the next block of AutoBlockElementsJoiner::HandleDeleteNonCollapsedRanges()
r=m_kato
And now, `HTMLEditor::JoinNodesDeepWithTransaction()` is used only by `AutoBlockElementsJoiner`. Therefore, this patch moves it to the stack only class. Differential Revision: https://phabricator.services.mozilla.com/D86789
This commit is contained in:
parent
aa3497a28e
commit
9d1482c813
@ -3440,6 +3440,23 @@ bool HTMLEditor::AutoBlockElementsJoiner::PrepareToDeleteNonCollapsedRanges(
|
||||
mMode = Mode::DeleteContentInRanges;
|
||||
return true;
|
||||
}
|
||||
|
||||
// If left block and right block are adjuscent siblings and they are same
|
||||
// type of elements, we can merge them after deleting the selected contents.
|
||||
// MOOSE: this could conceivably screw up a table.. fix me.
|
||||
if (mLeftContent->GetParentNode() == mRightContent->GetParentNode() &&
|
||||
HTMLEditUtils::CanContentsBeJoined(
|
||||
*mLeftContent, *mRightContent,
|
||||
aHTMLEditor.IsCSSEnabled() ? StyleDifference::CompareIfSpanElements
|
||||
: StyleDifference::Ignore) &&
|
||||
// XXX What's special about these three types of block?
|
||||
(mLeftContent->IsHTMLElement(nsGkAtoms::p) ||
|
||||
HTMLEditUtils::IsListItem(mLeftContent) ||
|
||||
HTMLEditUtils::IsHeader(*mLeftContent))) {
|
||||
mMode = Mode::JoinBlocksInSameParent;
|
||||
return true;
|
||||
}
|
||||
|
||||
mMode = Mode::DeleteNonCollapsedRanges;
|
||||
return true;
|
||||
}
|
||||
@ -3490,6 +3507,48 @@ EditActionResult HTMLEditor::AutoBlockElementsJoiner::DeleteContentInRanges(
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
EditActionResult
|
||||
HTMLEditor::AutoBlockElementsJoiner::JoinBlockElementsInSameParent(
|
||||
HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount,
|
||||
nsIEditor::EStripWrappers aStripWrappers, AutoRangeArray& aRangesToDelete) {
|
||||
MOZ_ASSERT(aHTMLEditor.IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(!aRangesToDelete.IsCollapsed());
|
||||
MOZ_ASSERT(mMode == Mode::JoinBlocksInSameParent);
|
||||
MOZ_ASSERT(mLeftContent);
|
||||
MOZ_ASSERT(mLeftContent->IsElement());
|
||||
MOZ_ASSERT(aRangesToDelete.FirstRangeRef()
|
||||
->GetStartContainer()
|
||||
->IsInclusiveDescendantOf(mLeftContent));
|
||||
MOZ_ASSERT(mRightContent);
|
||||
MOZ_ASSERT(mRightContent->IsElement());
|
||||
MOZ_ASSERT(aRangesToDelete.FirstRangeRef()
|
||||
->GetEndContainer()
|
||||
->IsInclusiveDescendantOf(mRightContent));
|
||||
MOZ_ASSERT(mLeftContent->GetParentNode() == mRightContent->GetParentNode());
|
||||
|
||||
nsresult rv = aHTMLEditor.DeleteRangesWithTransaction(
|
||||
aDirectionAndAmount, aStripWrappers, aRangesToDelete);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("EditorBase::DeleteRangesWithTransaction() failed");
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
Result<EditorDOMPoint, nsresult> atFirstChildOfTheLastRightNodeOrError =
|
||||
JoinNodesDeepWithTransaction(aHTMLEditor, MOZ_KnownLive(*mLeftContent),
|
||||
MOZ_KnownLive(*mRightContent));
|
||||
if (atFirstChildOfTheLastRightNodeOrError.isErr()) {
|
||||
NS_WARNING("HTMLEditor::JoinNodesDeepWithTransaction() failed");
|
||||
return EditActionHandled(atFirstChildOfTheLastRightNodeOrError.unwrapErr());
|
||||
}
|
||||
MOZ_ASSERT(atFirstChildOfTheLastRightNodeOrError.inspect().IsSet());
|
||||
|
||||
rv = aHTMLEditor.CollapseSelectionTo(
|
||||
atFirstChildOfTheLastRightNodeOrError.inspect());
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::CollapseSelectionTo() failed");
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
EditActionResult
|
||||
HTMLEditor::AutoBlockElementsJoiner::HandleDeleteNonCollapsedRanges(
|
||||
HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount,
|
||||
@ -3508,43 +3567,6 @@ HTMLEditor::AutoBlockElementsJoiner::HandleDeleteNonCollapsedRanges(
|
||||
->GetEndContainer()
|
||||
->IsInclusiveDescendantOf(mRightContent));
|
||||
|
||||
// If left block and right block are adjuscent siblings and they are same
|
||||
// type of elements, we can merge them after deleting the selected contents.
|
||||
// MOOSE: this could conceivably screw up a table.. fix me.
|
||||
if (mLeftContent->GetParentNode() == mRightContent->GetParentNode() &&
|
||||
HTMLEditUtils::CanContentsBeJoined(
|
||||
*mLeftContent, *mRightContent,
|
||||
aHTMLEditor.IsCSSEnabled() ? StyleDifference::CompareIfSpanElements
|
||||
: StyleDifference::Ignore) &&
|
||||
// XXX What's special about these three types of block?
|
||||
(mLeftContent->IsHTMLElement(nsGkAtoms::p) ||
|
||||
HTMLEditUtils::IsListItem(mLeftContent) ||
|
||||
HTMLEditUtils::IsHeader(*mLeftContent))) {
|
||||
// First delete the selection
|
||||
nsresult rv = aHTMLEditor.DeleteRangesWithTransaction(
|
||||
aDirectionAndAmount, aStripWrappers, aRangesToDelete);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("EditorBase::DeleteRangesWithTransaction() failed");
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
// Join blocks
|
||||
Result<EditorDOMPoint, nsresult> atFirstChildOfTheLastRightNodeOrError =
|
||||
aHTMLEditor.JoinNodesDeepWithTransaction(MOZ_KnownLive(*mLeftContent),
|
||||
MOZ_KnownLive(*mRightContent));
|
||||
if (atFirstChildOfTheLastRightNodeOrError.isErr()) {
|
||||
NS_WARNING("HTMLEditor::JoinNodesDeepWithTransaction() failed");
|
||||
return EditActionHandled(
|
||||
atFirstChildOfTheLastRightNodeOrError.unwrapErr());
|
||||
}
|
||||
MOZ_ASSERT(atFirstChildOfTheLastRightNodeOrError.inspect().IsSet());
|
||||
// Fix up selection
|
||||
rv = aHTMLEditor.CollapseSelectionTo(
|
||||
atFirstChildOfTheLastRightNodeOrError.inspect());
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::CollapseSelectionTo() failed");
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
// Otherwise, delete every nodes in all ranges, then, clean up something.
|
||||
EditActionResult result(NS_OK);
|
||||
result.MarkAsHandled();
|
||||
@ -4464,8 +4486,10 @@ EditorDOMPoint HTMLEditor::GetGoodCaretPointFor(
|
||||
return EditorDOMPoint(&aContent);
|
||||
}
|
||||
|
||||
Result<EditorDOMPoint, nsresult> HTMLEditor::JoinNodesDeepWithTransaction(
|
||||
nsIContent& aLeftContent, nsIContent& aRightContent) {
|
||||
Result<EditorDOMPoint, nsresult>
|
||||
HTMLEditor::AutoBlockElementsJoiner::JoinNodesDeepWithTransaction(
|
||||
HTMLEditor& aHTMLEditor, nsIContent& aLeftContent,
|
||||
nsIContent& aRightContent) {
|
||||
// While the rightmost children and their descendants of the left node match
|
||||
// the leftmost children and their descendants of the right node, join them
|
||||
// up.
|
||||
@ -4476,17 +4500,17 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::JoinNodesDeepWithTransaction(
|
||||
|
||||
EditorDOMPoint ret;
|
||||
const HTMLEditUtils::StyleDifference kCompareStyle =
|
||||
IsCSSEnabled() ? StyleDifference::CompareIfSpanElements
|
||||
: StyleDifference::Ignore;
|
||||
aHTMLEditor.IsCSSEnabled() ? StyleDifference::CompareIfSpanElements
|
||||
: StyleDifference::Ignore;
|
||||
while (leftContentToJoin && rightContentToJoin && parentNode &&
|
||||
HTMLEditUtils::CanContentsBeJoined(
|
||||
*leftContentToJoin, *rightContentToJoin, kCompareStyle)) {
|
||||
uint32_t length = leftContentToJoin->Length();
|
||||
|
||||
// Do the join
|
||||
nsresult rv =
|
||||
JoinNodesWithTransaction(*leftContentToJoin, *rightContentToJoin);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
nsresult rv = aHTMLEditor.JoinNodesWithTransaction(*leftContentToJoin,
|
||||
*rightContentToJoin);
|
||||
if (NS_WARN_IF(aHTMLEditor.Destroyed())) {
|
||||
return Err(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -2363,23 +2363,6 @@ class HTMLEditor final : public TextEditor,
|
||||
const EditorDOMPoint& aDeepestStartOfRightNode,
|
||||
SplitAtEdges aSplitAtEdges);
|
||||
|
||||
/**
|
||||
* JoinNodesDeepWithTransaction() joins aLeftNode and aRightNode "deeply".
|
||||
* First, they are joined simply, then, new right node is assumed as the
|
||||
* child at length of the left node before joined and new left node is
|
||||
* assumed as its previous sibling. Then, they will be joined again.
|
||||
* And then, these steps are repeated.
|
||||
*
|
||||
* @param aLeftContent The node which will be removed form the tree.
|
||||
* @param aRightContent The node which will be inserted the contents of
|
||||
* aRightContent.
|
||||
* @return The point of the first child of the last right node.
|
||||
* The result is always set if this succeeded.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT Result<EditorDOMPoint, nsresult>
|
||||
JoinNodesDeepWithTransaction(nsIContent& aLeftContent,
|
||||
nsIContent& aRightContent);
|
||||
|
||||
/**
|
||||
* TryToJoinBlocksWithTransaction() tries to join two block elements. The
|
||||
* right element is always joined to the left element. If the elements are
|
||||
@ -2815,6 +2798,7 @@ class HTMLEditor final : public TextEditor,
|
||||
"AutoBlockElementsJoiner::DeleteBRElement() failed");
|
||||
return result;
|
||||
}
|
||||
case Mode::JoinBlocksInSameParent:
|
||||
case Mode::DeleteContentInRanges:
|
||||
case Mode::DeleteNonCollapsedRanges:
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
@ -2851,6 +2835,15 @@ class HTMLEditor final : public TextEditor,
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
"This mode should be handled in the other Run()");
|
||||
return EditActionResult(NS_ERROR_UNEXPECTED);
|
||||
case Mode::JoinBlocksInSameParent: {
|
||||
EditActionResult result =
|
||||
JoinBlockElementsInSameParent(aHTMLEditor, aDirectionAndAmount,
|
||||
aStripWrappers, aRangesToDelete);
|
||||
NS_WARNING_ASSERTION(result.Succeeded(),
|
||||
"AutoBlockElementsJoiner::"
|
||||
"JoinBlockElementsInSameParent() failed");
|
||||
return result;
|
||||
}
|
||||
case Mode::DeleteContentInRanges: {
|
||||
EditActionResult result =
|
||||
DeleteContentInRanges(aHTMLEditor, aDirectionAndAmount,
|
||||
@ -2892,6 +2885,11 @@ class HTMLEditor final : public TextEditor,
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
HandleDeleteCollapsedSelectionAtOtherBlockBoundary(
|
||||
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aCaretPoint);
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
JoinBlockElementsInSameParent(HTMLEditor& aHTMLEditor,
|
||||
nsIEditor::EDirection aDirectionAndAmount,
|
||||
nsIEditor::EStripWrappers aStripWrappers,
|
||||
AutoRangeArray& aRangesToDelete);
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult DeleteBRElement(
|
||||
HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount,
|
||||
const EditorDOMPoint& aCaretPoint);
|
||||
@ -2906,10 +2904,29 @@ class HTMLEditor final : public TextEditor,
|
||||
AutoRangeArray& aRangesToDelete,
|
||||
HTMLEditor::SelectionWasCollapsed aSelectionWasCollapsed);
|
||||
|
||||
/**
|
||||
* JoinNodesDeepWithTransaction() joins aLeftNode and aRightNode "deeply".
|
||||
* First, they are joined simply, then, new right node is assumed as the
|
||||
* child at length of the left node before joined and new left node is
|
||||
* assumed as its previous sibling. Then, they will be joined again.
|
||||
* And then, these steps are repeated.
|
||||
*
|
||||
* @param aLeftContent The node which will be removed form the tree.
|
||||
* @param aRightContent The node which will be inserted the contents of
|
||||
* aRightContent.
|
||||
* @return The point of the first child of the last right
|
||||
* node. The result is always set if this succeeded.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT Result<EditorDOMPoint, nsresult>
|
||||
JoinNodesDeepWithTransaction(HTMLEditor& aHTMLEditor,
|
||||
nsIContent& aLeftContent,
|
||||
nsIContent& aRightContent);
|
||||
|
||||
enum class Mode {
|
||||
NotInitialized,
|
||||
JoinCurrentBlock,
|
||||
JoinOtherBlock,
|
||||
JoinBlocksInSameParent,
|
||||
DeleteBRElement,
|
||||
DeleteContentInRanges,
|
||||
DeleteNonCollapsedRanges,
|
||||
|
Loading…
x
Reference in New Issue
Block a user