Bug 1451672 - part 5: Rename EditorBase::JoinNodes() and related methods with "WithTransaction" postfix r=m_kato

This patch renames:
EditorBase::JoinNodes() -> EditorBase::JoinNodesWithTransaction()
EditorBase::JoinNodeDeep() -> EditorBase::JoinNodesDeepWithTransaction()
HTMLEditRules::JoinNodesSmart() ->
  HTMLEditRules::JoinNearestEditableNodesWithTransaction()
HTMLEditRules::TryToJoinBlocks() ->
  HTMLEditRules::TryToJoinBlocksWithTransaction()

MozReview-Commit-ID: Ao16GhAcyIZ

--HG--
extra : rebase_source : 6746735c339cf2799e94137de87c7a7dce6efded
This commit is contained in:
Masayuki Nakano 2018-04-10 03:46:44 +09:00
parent a1a45ac179
commit 8b1e0b6b9c
6 changed files with 105 additions and 56 deletions

View File

@ -1543,12 +1543,12 @@ EditorBase::JoinNodes(nsIDOMNode* aLeftNode,
nsCOMPtr<nsINode> leftNode = do_QueryInterface(aLeftNode);
nsCOMPtr<nsINode> rightNode = do_QueryInterface(aRightNode);
NS_ENSURE_STATE(leftNode && rightNode && leftNode->GetParentNode());
return JoinNodes(*leftNode, *rightNode);
return JoinNodesWithTransaction(*leftNode, *rightNode);
}
nsresult
EditorBase::JoinNodes(nsINode& aLeftNode,
nsINode& aRightNode)
EditorBase::JoinNodesWithTransaction(nsINode& aLeftNode,
nsINode& aRightNode)
{
nsCOMPtr<nsINode> parent = aLeftNode.GetParentNode();
MOZ_ASSERT(parent);
@ -4146,13 +4146,9 @@ EditorBase::SplitNodeDeepWithTransaction(
return SplitNodeResult(NS_ERROR_FAILURE);
}
/**
* This joins two like nodes "deeply", joining children as appropriate.
* Returns the point of the join, or (nullptr, -1) in case of error.
*/
EditorDOMPoint
EditorBase::JoinNodeDeep(nsIContent& aLeftNode,
nsIContent& aRightNode)
EditorBase::JoinNodesDeepWithTransaction(nsIContent& aLeftNode,
nsIContent& aRightNode)
{
// While the rightmost children and their descendants of the left node match
// the leftmost children and their descendants of the right node, join them
@ -4168,7 +4164,7 @@ EditorBase::JoinNodeDeep(nsIContent& aLeftNode,
uint32_t length = leftNodeToJoin->Length();
// Do the join
nsresult rv = JoinNodes(*leftNodeToJoin, *rightNodeToJoin);
nsresult rv = JoinNodesWithTransaction(*leftNodeToJoin, *rightNodeToJoin);
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditorDOMPoint();
}

View File

@ -389,7 +389,17 @@ public:
SplitNodeWithTransaction(const EditorDOMPointBase<PT, CT>& aStartOfRightNode,
ErrorResult& aResult);
nsresult JoinNodes(nsINode& aLeftNode, nsINode& aRightNode);
/**
* JoinNodesWithTransaction() joins aLeftNode and aRightNode. Content of
* aLeftNode will be merged into aRightNode. Actual implemenation of this
* method is JoinNodesImpl(). So, see its explanation for the detail.
*
* @param aLeftNode Will be removed from the DOM tree.
* @param aRightNode The node which will be new container of the content of
* aLeftNode.
*/
nsresult JoinNodesWithTransaction(nsINode& aLeftNode, nsINode& aRightNode);
nsresult MoveNode(nsIContent* aNode, nsINode* aParent, int32_t aOffset);
/**
@ -803,7 +813,11 @@ public:
ErrorResult& aError);
/**
* JoinNodes() takes 2 nodes and merge their content|children.
* JoinNodesImpl() merges contents in aNodeToJoin to aNodeToKeep and remove
* aNodeToJoin from the DOM tree. aNodeToJoin and aNodeToKeep must have
* same parent, aParent. Additionally, if one of aNodeToJoin or aNodeToKeep
* is a text node, the other must be a text node.
*
* @param aNodeToKeep The node that will remain after the join.
* @param aNodeToJoin The node that will be joined with aNodeToKeep.
* There is no requirement that the two nodes be of the
@ -1275,8 +1289,20 @@ public:
const EditorDOMPointBase<PT, CT>& aDeepestStartOfRightNode,
SplitAtEdges aSplitAtEdges);
EditorDOMPoint JoinNodeDeep(nsIContent& aLeftNode,
nsIContent& aRightNode);
/**
* 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 aLeftNode The node which will be removed form the tree.
* @param aRightNode The node which will be inserted the contents of
* aLeftNode.
* @return The point of the first child of the last right node.
*/
EditorDOMPoint JoinNodesDeepWithTransaction(nsIContent& aLeftNode,
nsIContent& aRightNode);
nsresult GetString(const nsAString& name, nsAString& value);

View File

@ -2198,10 +2198,10 @@ HTMLEditRules::WillDeleteSelection(Selection* aSelection,
// origCollapsed is used later to determine whether we should join blocks. We
// don't really care about bCollapsed because it will be modified by
// ExtendSelectionForDelete later. TryToJoinBlocks() should happen if the
// original selection is collapsed and the cursor is at the end of a block
// element, in which case ExtendSelectionForDelete would always make the
// selection not collapsed.
// ExtendSelectionForDelete later. TryToJoinBlocksWithTransaction() should
// happen if the original selection is collapsed and the cursor is at the end
// of a block element, in which case ExtendSelectionForDelete would always
// make the selection not collapsed.
bool bCollapsed = aSelection->Collapsed();
bool join = false;
bool origCollapsed = bCollapsed;
@ -2468,7 +2468,9 @@ HTMLEditRules::WillDeleteSelection(Selection* aSelection,
// Are they both text nodes? If so, join them!
if (startNode == stepbrother && startNode->GetAsText() &&
sibling->GetAsText()) {
EditorDOMPoint pt = JoinNodesSmart(*sibling, *startNode->AsContent());
EditorDOMPoint pt =
JoinNearestEditableNodesWithTransaction(*sibling,
*startNode->AsContent());
if (NS_WARN_IF(!pt.IsSet())) {
return NS_ERROR_FAILURE;
}
@ -2564,7 +2566,8 @@ HTMLEditRules::WillDeleteSelection(Selection* aSelection,
NS_ENSURE_STATE(leftNode && leftNode->IsContent() &&
rightNode && rightNode->IsContent());
EditActionResult ret =
TryToJoinBlocks(*leftNode->AsContent(), *rightNode->AsContent());
TryToJoinBlocksWithTransaction(*leftNode->AsContent(),
*rightNode->AsContent());
*aHandled |= ret.Handled();
*aCancel |= ret.Canceled();
if (NS_WARN_IF(ret.Failed())) {
@ -2572,9 +2575,9 @@ HTMLEditRules::WillDeleteSelection(Selection* aSelection,
}
}
// If TryToJoinBlocks() didn't handle it and it's not canceled,
// user may want to modify the start leaf node or the last leaf node
// of the block.
// If TryToJoinBlocksWithTransaction() didn't handle it and it's not
// canceled, user may want to modify the start leaf node or the last leaf
// node of the block.
if (!*aHandled && !*aCancel && leafNode != startNode) {
int32_t offset =
aAction == nsIEditor::ePrevious ?
@ -2632,7 +2635,8 @@ HTMLEditRules::WillDeleteSelection(Selection* aSelection,
address_of(selPointNode), &selPointOffset);
NS_ENSURE_STATE(leftNode->IsContent() && rightNode->IsContent());
EditActionResult ret =
TryToJoinBlocks(*leftNode->AsContent(), *rightNode->AsContent());
TryToJoinBlocksWithTransaction(*leftNode->AsContent(),
*rightNode->AsContent());
// This should claim that trying to join the block means that
// this handles the action because the caller shouldn't do anything
// anymore in this case.
@ -2735,7 +2739,8 @@ HTMLEditRules::WillDeleteSelection(Selection* aSelection,
// Join blocks
NS_ENSURE_STATE(mHTMLEditor);
EditorDOMPoint pt =
mHTMLEditor->JoinNodeDeep(*leftParent, *rightParent);
mHTMLEditor->JoinNodesDeepWithTransaction(*leftParent,
*rightParent);
if (NS_WARN_IF(!pt.IsSet())) {
return NS_ERROR_FAILURE;
}
@ -2813,7 +2818,8 @@ HTMLEditRules::WillDeleteSelection(Selection* aSelection,
}
if (join) {
EditActionResult ret = TryToJoinBlocks(*leftParent, *rightParent);
EditActionResult ret =
TryToJoinBlocksWithTransaction(*leftParent, *rightParent);
MOZ_ASSERT(*aHandled);
*aCancel |= ret.Canceled();
if (NS_WARN_IF(ret.Failed())) {
@ -2980,8 +2986,8 @@ HTMLEditRules::GetGoodSelPointForNode(nsINode& aNode,
}
EditActionResult
HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
nsIContent& aRightNode)
HTMLEditRules::TryToJoinBlocksWithTransaction(nsIContent& aLeftNode,
nsIContent& aRightNode)
{
if (NS_WARN_IF(!mHTMLEditor)) {
return EditActionIgnored(NS_ERROR_UNEXPECTED);
@ -3282,7 +3288,8 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
if (mergeLists || leftBlock->NodeInfo()->NameAtom() ==
rightBlock->NodeInfo()->NameAtom()) {
// Nodes are same type. merge them.
EditorDOMPoint pt = JoinNodesSmart(*leftBlock, *rightBlock);
EditorDOMPoint pt =
JoinNearestEditableNodesWithTransaction(*leftBlock, *rightBlock);
if (pt.IsSet() && mergeLists) {
RefPtr<Element> newBlock =
ConvertListType(rightBlock, existingList, nsGkAtoms::li);
@ -7830,16 +7837,9 @@ HTMLEditRules::MaybeSplitAncestorsForInsertWithTransaction(
return splitNodeResult;
}
/**
* JoinNodesSmart: Join two nodes, doing whatever makes sense for their
* children (which often means joining them, too). aNodeLeft & aNodeRight must
* be same type of node.
*
* Returns the point where they're merged, or (nullptr, -1) on failure.
*/
EditorDOMPoint
HTMLEditRules::JoinNodesSmart(nsIContent& aNodeLeft,
nsIContent& aNodeRight)
HTMLEditRules::JoinNearestEditableNodesWithTransaction(nsIContent& aNodeLeft,
nsIContent& aNodeRight)
{
// Caller responsible for left and right node being the same type
nsCOMPtr<nsINode> parent = aNodeLeft.GetParentNode();
@ -7866,7 +7866,7 @@ HTMLEditRules::JoinNodesSmart(nsIContent& aNodeLeft,
// Separate join rules for differing blocks
if (HTMLEditUtils::IsList(&aNodeLeft) || aNodeLeft.GetAsText()) {
// For lists, merge shallow (wouldn't want to combine list items)
nsresult rv = mHTMLEditor->JoinNodes(aNodeLeft, aNodeRight);
nsresult rv = mHTMLEditor->JoinNodesWithTransaction(aNodeLeft, aNodeRight);
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditorDOMPoint();
}
@ -7894,7 +7894,7 @@ HTMLEditRules::JoinNodesSmart(nsIContent& aNodeLeft,
if (NS_WARN_IF(!mHTMLEditor)) {
return EditorDOMPoint();
}
nsresult rv = mHTMLEditor->JoinNodes(aNodeLeft, aNodeRight);
nsresult rv = mHTMLEditor->JoinNodesWithTransaction(aNodeLeft, aNodeRight);
if (NS_WARN_IF(NS_FAILED(rv))) {
return EditorDOMPoint();
}
@ -7908,7 +7908,7 @@ HTMLEditRules::JoinNodesSmart(nsIContent& aNodeLeft,
if (NS_WARN_IF(!mHTMLEditor)) {
return EditorDOMPoint();
}
return JoinNodesSmart(*lastLeft, *firstRight);
return JoinNearestEditableNodesWithTransaction(*lastLeft, *firstRight);
}
return ret;
}

View File

@ -186,12 +186,13 @@ protected:
nsIEditor::EDirection aAction);
/**
* TryToJoinBlocks() tries to join two block elements. The right element is
* always joined to the left element. If the elements are the same type and
* not nested within each other, JoinNodesSmart() is called (example, joining
* two list items together into one). If the elements are not the same type,
* or one is a descendant of the other, we instead destroy the right block
* placing its children into leftblock. DTD containment rules are followed
* TryToJoinBlocksWithTransaction() tries to join two block elements. The
* right element is always joined to the left element. If the elements are
* the same type and not nested within each other,
* JoinEditableNodesWithTransaction() is called (example, joining two list
* items together into one). If the elements are not the same type, or one
* is a descendant of the other, we instead destroy the right block placing
* its children into leftblock. DTD containment rules are followed
* throughout.
*
* @return Sets canceled to true if the operation should do
@ -202,8 +203,8 @@ protected:
* be joined or it's impossible to join them but it's not
* unexpected case, this returns true with this.
*/
EditActionResult TryToJoinBlocks(nsIContent& aLeftNode,
nsIContent& aRightNode);
EditActionResult TryToJoinBlocksWithTransaction(nsIContent& aLeftNode,
nsIContent& aRightNode);
/**
* MoveBlock() moves the content from aRightBlock starting from aRightOffset
@ -459,8 +460,30 @@ protected:
nsAtom& aTag,
const EditorDOMPointBase<PT, CT>& aStartOfDeepestRightNode);
EditorDOMPoint JoinNodesSmart(nsIContent& aNodeLeft,
nsIContent& aNodeRight);
/**
* JoinNearestEditableNodesWithTransaction() joins two editable nodes which
* are themselves or the nearest editable node of aLeftNode and aRightNode.
* XXX This method's behavior is odd. For example, if user types Backspace
* key at the second editable paragraph in this case:
* <div contenteditable>
* <p>first editable paragraph</p>
* <p contenteditable="false">non-editable paragraph</p>
* <p>second editable paragraph</p>
* </div>
* The first editable paragraph's content will be moved into the second
* editable paragraph and the non-editable paragraph becomes the first
* paragraph of the editor. I don't think that it's expected behavior of
* any users...
*
* @param aLeftNode The node which will be removed.
* @param aRightNode The node which will be inserted the content of
* aLeftNode.
* @return The point at the first child of aRightNode.
*/
EditorDOMPoint
JoinNearestEditableNodesWithTransaction(nsIContent& aLeftNode,
nsIContent& aRightNode);
Element* GetTopEnclosingMailCite(nsINode& aNode);
nsresult PopListItem(nsIContent& aListItem, bool* aOutOfList = nullptr);
nsresult RemoveListStructure(Element& aList);

View File

@ -3625,7 +3625,7 @@ HTMLEditor::GetEnclosingTable(nsIDOMNode* aNode)
* This method scans the selection for adjacent text nodes
* and collapses them into a single text node.
* "adjacent" means literally adjacent siblings of the same parent.
* Uses EditorBase::JoinNodes so action is undoable.
* Uses EditorBase::JoinNodesWithTransaction() so action is undoable.
* Should be called within the context of a batch transaction.
*/
nsresult
@ -3668,8 +3668,10 @@ HTMLEditor::CollapseAdjacentTextNodes(nsRange* aInRange)
// get the prev sibling of the right node, and see if its leftTextNode
nsCOMPtr<nsINode> prevSibOfRightNode = rightTextNode->GetPreviousSibling();
if (prevSibOfRightNode && prevSibOfRightNode == leftTextNode) {
rv = JoinNodes(*leftTextNode, *rightTextNode);
NS_ENSURE_SUCCESS(rv, rv);
rv = JoinNodesWithTransaction(*leftTextNode, *rightTextNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
textNodes.RemoveElementAt(0); // remove the leftmost text node from the list

View File

@ -366,8 +366,10 @@ HTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
nsresult rv = MoveNode(&aNode, previousSibling, -1);
NS_ENSURE_SUCCESS(rv, rv);
if (IsSimpleModifiableNode(nextSibling, &aProperty, aAttribute, &aValue)) {
rv = JoinNodes(*previousSibling, *nextSibling);
NS_ENSURE_SUCCESS(rv, rv);
rv = JoinNodesWithTransaction(*previousSibling, *nextSibling);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}