Bug 1792387 - part 3-1: Make `HTMLEditor::DoSplitNode()` adjust selection for both split node directions r=m_kato

This patch adds new path to adjust selection for the new split node direction.
So this does not change any behavior of the existing path.

Differential Revision: https://phabricator.services.mozilla.com/D158100
This commit is contained in:
Masayuki Nakano 2022-09-30 22:20:20 +00:00
Родитель 68073f0bbf
Коммит 8fd837d307
5 изменённых файлов: 53 добавлений и 37 удалений

Просмотреть файл

@ -4853,7 +4853,8 @@ SplitNodeResult HTMLEditor::SplitNodeDeepWithTransaction(
}
SplitNodeResult HTMLEditor::DoSplitNode(const EditorDOMPoint& aStartOfRightNode,
nsIContent& aNewNode) {
nsIContent& aNewNode,
SplitNodeDirection aDirection) {
// Ensure computing the offset if it's intialized with a child content node.
Unused << aStartOfRightNode.Offset();
@ -4999,30 +5000,45 @@ SplitNodeResult HTMLEditor::DoSplitNode(const EditorDOMPoint& aStartOfRightNode,
continue;
}
// Split the selection into existing node and new node.
if (savedRange.mStartContainer == aStartOfRightNode.GetContainer()) {
if (savedRange.mStartOffset < aStartOfRightNode.Offset()) {
savedRange.mStartContainer = &aNewNode;
} else if (savedRange.mStartOffset >= aStartOfRightNode.Offset()) {
savedRange.mStartOffset -= aStartOfRightNode.Offset();
} else {
NS_WARNING(
"The stored start offset was smaller than the right node offset");
savedRange.mStartOffset = 0u;
auto AdjustDOMPoint = [&](nsCOMPtr<nsINode>& aContainer,
uint32_t& aOffset) {
if (aContainer != aStartOfRightNode.GetContainer()) {
return;
}
}
if (savedRange.mEndContainer == aStartOfRightNode.GetContainer()) {
if (savedRange.mEndOffset < aStartOfRightNode.Offset()) {
savedRange.mEndContainer = &aNewNode;
} else if (savedRange.mEndOffset >= aStartOfRightNode.Offset()) {
savedRange.mEndOffset -= aStartOfRightNode.Offset();
} else {
NS_WARNING(
"The stored end offset was smaller than the right node offset");
savedRange.mEndOffset = 0u;
if (aDirection == SplitNodeDirection::LeftNodeIsNewOne) {
// If the container is the right node and offset is before the split
// point, the content was moved into aNewNode. So, just changing the
// container will point proper position.
if (aOffset < aStartOfRightNode.Offset()) {
aContainer = &aNewNode;
return;
}
// If the container is the right node and offset equals or is larger
// than the split point, we need to decrease the offset since some
// content before the split point was moved to aNewNode.
if (aOffset >= aStartOfRightNode.Offset()) {
aOffset -= aStartOfRightNode.Offset();
return;
}
NS_WARNING("The stored offset was smaller than the right node offset");
aOffset = 0u;
return;
}
}
// If the container is the left node and offset is after the split
// point, the content was moved from the right node to aNewNode.
// So, we need to change the container to aNewNode and decrease the
// offset.
if (aOffset >= aStartOfRightNode.Offset()) {
aContainer = &aNewNode;
aOffset -= aStartOfRightNode.Offset();
}
};
AdjustDOMPoint(savedRange.mStartContainer, savedRange.mStartOffset);
AdjustDOMPoint(savedRange.mEndContainer, savedRange.mEndOffset);
RefPtr<nsRange> newRange =
nsRange::Create(savedRange.mStartContainer, savedRange.mStartOffset,
@ -5066,12 +5082,12 @@ SplitNodeResult HTMLEditor::DoSplitNode(const EditorDOMPoint& aStartOfRightNode,
DebugOnly<nsresult> rvIgnored = RangeUpdaterRef().SelAdjSplitNode(
*aStartOfRightNode.ContainerAs<nsIContent>(), aStartOfRightNode.Offset(),
aNewNode, GetSplitNodeDirection());
aNewNode, aDirection);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"RangeUpdater::SelAdjSplitNode() failed, but ignored");
return SplitNodeResult(aNewNode, *aStartOfRightNode.ContainerAs<nsIContent>(),
GetSplitNodeDirection());
aDirection);
}
JoinNodesResult HTMLEditor::JoinNodesWithTransaction(

Просмотреть файл

@ -978,20 +978,20 @@ class HTMLEditor final : public EditorBase,
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult OnModifyDocument();
/**
* DoSplitNode() inserts aNewNode (left node before the container of
* aStartOfRightNode (right node), and moves all content before
* DoSplitNode() inserts aNewNode and moves all content before or after
* aStartOfRightNode to aNewNode.
*
* @param aStartOfRightNode The point to split. Its container will be
* the right node, i.e., becomes aNewNode's
* next sibling. And the point will be start
* of the right node.
* @param aNewNode The new node called as left node, so, this
* becomes the container of all previous content
* before aPointToSplit.
* @param aStartOfRightNode The point to split. The container will keep
* having following or previous content of this.
* @param aNewNode The new node called. The previous or following
* content of aStartOfRightNode will be moved into
* this node.
* @param aDirection Whether aNewNode will have previous or following
* content of aStartOfRightNode.
*/
MOZ_CAN_RUN_SCRIPT SplitNodeResult
DoSplitNode(const EditorDOMPoint& aStartOfRightNode, nsIContent& aNewNode);
DoSplitNode(const EditorDOMPoint& aStartOfRightNode, nsIContent& aNewNode,
SplitNodeDirection aDirection);
/**
* DoJoinNodes() merges contents in aContentToRemove to aContentToKeep and

Просмотреть файл

@ -177,7 +177,7 @@ NS_IMETHODIMP JoinNodesTransaction::UndoTransaction() {
const SplitNodeResult splitNodeResult = htmlEditor->DoSplitNode(
EditorDOMPoint(mKeepingContent,
std::min(mJoinedOffset, mKeepingContent->Length())),
removedContent);
removedContent, GetSplitNodeDirection());
NS_WARNING_ASSERTION(splitNodeResult.isOk(),
"HTMLEditor::DoSplitNode() failed");
// When adding caret suggestion to SplitNodeResult, here didn't change

Просмотреть файл

@ -334,7 +334,7 @@ nsresult RangeUpdater::SelAdjSplitNode(nsIContent& aOriginalContent,
}
} else if (aOffset >= aSplitOffset) {
aContainer = &aNewContent;
aOffset = aSplitOffset - aOffset;
aOffset -= aSplitOffset;
}
};

Просмотреть файл

@ -154,7 +154,7 @@ SplitNodeResult SplitNodeTransaction::DoTransactionInternal(
SplitNodeResult splitNodeResult = aHTMLEditor.DoSplitNode(
EditorDOMPoint(&aSplittingContent,
std::min(aSplitOffset, aSplittingContent.Length())),
aNewContent);
aNewContent, GetSplitNodeDirection());
NS_WARNING_ASSERTION(splitNodeResult.isOk(),
"HTMLEditor::DoSplitNode() failed");
// When adding caret suggestion to SplitNodeResult, here didn't change