Bug 1460509 - part 33: Make HTMLEditRules::JoinNearestEditableNodesWithTransaction() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato
Unfortunately, we need to make it take out argument for returning new first
child point of right node. If we can create JoinNodesResult which have
nsresult and EditorDOMPoint, we can avoid that, but EditorBase::JoinNodes()
does not want it. So, even if we create such class, only 2 callers of the
methods are its users...
MozReview-Commit-ID: 1zwVZ0FriwN
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -2667,19 +2667,23 @@ HTMLEditRules::WillDeleteSelection(nsIEd
// Is there a prior node and are they siblings?
nsCOMPtr<nsINode> stepbrother;
if (sibling) {
stepbrother = HTMLEditorRef().GetNextHTMLSibling(sibling);
}
// Are they both text nodes? If so, join them!
if (startNode == stepbrother && startNode->GetAsText() &&
sibling->GetAsText()) {
- EditorDOMPoint pt =
+ EditorDOMPoint pt;
+ nsresult rv =
JoinNearestEditableNodesWithTransaction(*sibling,
- *startNode->AsContent());
+ *startNode->AsContent(), &pt);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (NS_WARN_IF(!pt.IsSet())) {
return NS_ERROR_FAILURE;
}
// Fix up selection
ErrorResult error;
SelectionRef().Collapse(pt, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
@@ -3511,18 +3515,22 @@ HTMLEditRules::TryToJoinBlocksWithTransa
}
// Do br adjustment.
nsCOMPtr<Element> brNode =
CheckForInvisibleBR(*leftBlock, BRLocation::blockEnd);
EditActionResult ret(NS_OK);
if (mergeLists || leftBlock->NodeInfo()->NameAtom() ==
rightBlock->NodeInfo()->NameAtom()) {
// Nodes are same type. merge them.
- EditorDOMPoint pt =
- JoinNearestEditableNodesWithTransaction(*leftBlock, *rightBlock);
+ EditorDOMPoint pt;
+ nsresult rv =
+ JoinNearestEditableNodesWithTransaction(*leftBlock, *rightBlock, &pt);
+ if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+ return EditActionIgnored(NS_ERROR_EDITOR_DESTROYED);
+ }
if (pt.IsSet() && mergeLists) {
RefPtr<Element> newBlock =
ConvertListType(rightBlock, existingList, nsGkAtoms::li);
}
ret.MarkAsHandled();
} else {
// Nodes are dissimilar types.
ret |= MoveBlock(*leftBlock, *rightBlock, -1, 0);
@@ -8377,82 +8385,102 @@ HTMLEditRules::MaybeSplitAncestorsForIns
*pointToInsert.GetChild(),
aStartOfDeepestRightNode,
SplitAtEdges::eAllowToCreateEmptyContainer);
NS_WARNING_ASSERTION(splitNodeResult.Succeeded(),
"Failed to split the node for insert the element");
return splitNodeResult;
}
-EditorDOMPoint
-HTMLEditRules::JoinNearestEditableNodesWithTransaction(nsIContent& aNodeLeft,
- nsIContent& aNodeRight)
+nsresult
+HTMLEditRules::JoinNearestEditableNodesWithTransaction(
+ nsIContent& aNodeLeft,
+ nsIContent& aNodeRight,
+ EditorDOMPoint* aNewFirstChildOfRightNode)
{
MOZ_ASSERT(IsEditorDataAvailable());
+ MOZ_ASSERT(aNewFirstChildOfRightNode);
// Caller responsible for left and right node being the same type
nsCOMPtr<nsINode> parent = aNodeLeft.GetParentNode();
if (NS_WARN_IF(!parent)) {
- return EditorDOMPoint();
- }
- int32_t parOffset = parent->ComputeIndexOf(&aNodeLeft);
+ return NS_ERROR_FAILURE;
+ }
nsCOMPtr<nsINode> rightParent = aNodeRight.GetParentNode();
// If they don't have the same parent, first move the right node to after the
// left one
if (parent != rightParent) {
+ int32_t parOffset = parent->ComputeIndexOf(&aNodeLeft);
nsresult rv =
HTMLEditorRef().MoveNodeWithTransaction(
aNodeRight, EditorRawDOMPoint(parent, parOffset));
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
- return EditorDOMPoint();
+ return rv;
}
}
EditorDOMPoint ret(&aNodeRight, aNodeLeft.Length());
// 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 =
HTMLEditorRef().JoinNodesWithTransaction(aNodeLeft, aNodeRight);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
- return EditorDOMPoint();
- }
- return ret;
+ return rv;
+ }
+ *aNewFirstChildOfRightNode = Move(ret);
+ return NS_OK;
}
// Remember the last left child, and first right child
nsCOMPtr<nsIContent> lastLeft =
HTMLEditorRef().GetLastEditableChild(aNodeLeft);
if (NS_WARN_IF(!lastLeft)) {
- return EditorDOMPoint();
+ return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIContent> firstRight =
HTMLEditorRef().GetFirstEditableChild(aNodeRight);
if (NS_WARN_IF(!firstRight)) {
- return EditorDOMPoint();
+ return NS_ERROR_FAILURE;
}
// For list items, divs, etc., merge smart
nsresult rv = HTMLEditorRef().JoinNodesWithTransaction(aNodeLeft, aNodeRight);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
- return EditorDOMPoint();
+ return rv;
}
if (lastLeft && firstRight &&
HTMLEditorRef().AreNodesSameType(lastLeft, firstRight) &&
(lastLeft->GetAsText() ||
(lastLeft->IsElement() && firstRight->IsElement() &&
CSSEditUtils::ElementsSameStyle(lastLeft->AsElement(),
firstRight->AsElement())))) {
- return JoinNearestEditableNodesWithTransaction(*lastLeft, *firstRight);
- }
- return ret;
+ nsresult rv =
+ JoinNearestEditableNodesWithTransaction(*lastLeft, *firstRight,
+ aNewFirstChildOfRightNode);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
+ }
+ *aNewFirstChildOfRightNode = Move(ret);
+ return NS_OK;
}
Element*
HTMLEditRules::GetTopEnclosingMailCite(nsINode& aNode)
{
nsCOMPtr<Element> ret;
for (nsCOMPtr<nsINode> node = &aNode; node; node = node->GetParentNode()) {
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -545,21 +545,23 @@ protected:
* 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.
+ * @param aNewFirstChildOfRightNode
+ * The point at the first child of aRightNode.
*/
- EditorDOMPoint
- JoinNearestEditableNodesWithTransaction(nsIContent& aLeftNode,
- nsIContent& aRightNode);
+ MOZ_MUST_USE nsresult
+ JoinNearestEditableNodesWithTransaction(
+ nsIContent& aLeftNode, nsIContent& aRightNode,
+ EditorDOMPoint* aNewFirstChildOfRightNode);
Element* GetTopEnclosingMailCite(nsINode& aNode);
/**
* PopListItem() tries to move aListItem outside its parent. If it's
* in a middle of a list element, the parent list element is split before
* aListItem. Then, moves aListItem to before its parent list element.
* I.e., moves aListItem between the 2 list elements if original parent