Bug 1460509 - part 38: Make HTMLEditRules::ReturnInListItem() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato
MozReview-Commit-ID: Jl0oiBCuYPb
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1928,18 +1928,24 @@ HTMLEditRules::WillInsertBreak(bool* aCa
endOfBlockParent);
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
}
nsCOMPtr<Element> listItem = IsInListItem(blockParent);
if (listItem && listItem != host) {
- ReturnInListItem(*listItem, *atStartOfSelection.GetContainer(),
- atStartOfSelection.Offset());
+ nsresult rv =
+ ReturnInListItem(*listItem, *atStartOfSelection.GetContainer(),
+ atStartOfSelection.Offset());
+ if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
+ "Failed to insert break into list item");
*aHandled = true;
return NS_OK;
}
if (HTMLEditUtils::IsHeader(*blockParent)) {
// Headers: close (or split) header
ReturnInHeader(*blockParent, *atStartOfSelection.GetContainer(),
atStartOfSelection.Offset());
@@ -7754,19 +7760,16 @@ HTMLEditRules::SplitParagraph(
IgnoredErrorResult ignoredError;
SelectionRef().Collapse(atChild, ignoredError);
NS_WARNING_ASSERTION(!ignoredError.Failed(),
"Failed to collapse selection at the child");
}
return NS_OK;
}
-/**
- * ReturnInListItem: do the right thing for returns pressed in list items
- */
nsresult
HTMLEditRules::ReturnInListItem(Element& aListItem,
nsINode& aNode,
int32_t aOffset)
{
MOZ_ASSERT(IsEditorDataAvailable());
MOZ_ASSERT(HTMLEditUtils::IsListItem(&aListItem));
@@ -7782,93 +7785,123 @@ HTMLEditRules::ReturnInListItem(Element&
nsCOMPtr<nsIContent> leftListNode = aListItem.GetParent();
// Are we the last list item in the list?
if (!HTMLEditorRef().IsLastEditableChild(&aListItem)) {
// We need to split the list!
EditorRawDOMPoint atListItem(&aListItem);
ErrorResult error;
leftListNode =
HTMLEditorRef().SplitNodeWithTransaction(atListItem, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
}
// Are we in a sublist?
EditorRawDOMPoint atNextSiblingOfLeftList(leftListNode);
DebugOnly<bool> advanced = atNextSiblingOfLeftList.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to advance offset after the right list node");
if (HTMLEditUtils::IsList(atNextSiblingOfLeftList.GetContainer())) {
// If so, move item out of this list and into the grandparent list
nsresult rv =
HTMLEditorRef().MoveNodeWithTransaction(aListItem,
atNextSiblingOfLeftList);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
ErrorResult error;
SelectionRef().Collapse(RawRangeBoundary(&aListItem, 0), error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
} else {
// Otherwise kill this item
nsresult rv = HTMLEditorRef().DeleteNodeWithTransaction(aListItem);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Time to insert a paragraph
nsAtom& paraAtom = DefaultParagraphSeparator();
// We want a wrapper even if we separate with <br>
RefPtr<Element> pNode =
HTMLEditorRef().CreateNodeWithTransaction(¶Atom == nsGkAtoms::br ?
*nsGkAtoms::p : paraAtom,
atNextSiblingOfLeftList);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!pNode)) {
return NS_ERROR_FAILURE;
}
// Append a <br> to it
RefPtr<Element> brElement =
HTMLEditorRef().InsertBrElementWithTransaction(
SelectionRef(), EditorRawDOMPoint(pNode, 0));
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
// Set selection to before the break
ErrorResult error;
SelectionRef().Collapse(EditorRawDOMPoint(pNode, 0), error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
}
return NS_OK;
}
// Else we want a new list item at the same list level. Get ws code to
// adjust any ws.
nsCOMPtr<nsINode> selNode = &aNode;
nsresult rv =
WSRunObject::PrepareToSplitAcrossBlocks(&HTMLEditorRef(),
address_of(selNode), &aOffset);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (NS_WARN_IF(!selNode->IsContent())) {
return NS_ERROR_FAILURE;
}
// Now split the list item.
SplitNodeResult splitListItemResult =
HTMLEditorRef().SplitNodeDeepWithTransaction(
aListItem, EditorRawDOMPoint(selNode, aOffset),
SplitAtEdges::eAllowToCreateEmptyContainer);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(splitListItemResult.Succeeded(),
"Failed to split the list item");
// Hack: until I can change the damaged doc range code back to being
// extra-inclusive, I have to manually detect certain list items that may be
// left empty.
nsCOMPtr<nsIContent> prevItem =
HTMLEditorRef().GetPriorHTMLSibling(&aListItem);
@@ -7898,46 +7931,63 @@ HTMLEditRules::ReturnInListItem(Element&
nsAtom* listAtom = nodeAtom == nsGkAtoms::dt ? nsGkAtoms::dd
: nsGkAtoms::dt;
MOZ_DIAGNOSTIC_ASSERT(itemOffset != -1);
EditorRawDOMPoint atNextListItem(list, aListItem.GetNextSibling(),
itemOffset + 1);
RefPtr<Element> newListItem =
HTMLEditorRef().CreateNodeWithTransaction(*listAtom,
atNextListItem);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!newListItem)) {
return NS_ERROR_FAILURE;
}
rv = HTMLEditorRef().DeleteNodeWithTransaction(aListItem);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
ErrorResult error;
SelectionRef().Collapse(EditorRawDOMPoint(newListItem, 0), error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
RefPtr<Element> brElement;
nsresult rv =
HTMLEditorRef().CopyLastEditableChildStylesWithTransaction(
*prevItem->AsElement(), aListItem,
address_of(brElement));
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
if (brElement) {
EditorRawDOMPoint atBrNode(brElement);
if (NS_WARN_IF(!atBrNode.IsSetAndValid())) {
return NS_ERROR_FAILURE;
}
ErrorResult error;
SelectionRef().Collapse(atBrNode, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
} else {
WSRunObject wsObj(&HTMLEditorRef(), &aListItem, 0);
nsCOMPtr<nsINode> visNode;
@@ -7948,33 +7998,44 @@ HTMLEditRules::ReturnInListItem(Element&
if (wsType == WSType::special || wsType == WSType::br ||
visNode->IsHTMLElement(nsGkAtoms::hr)) {
EditorRawDOMPoint atVisNode(visNode);
if (NS_WARN_IF(!atVisNode.IsSetAndValid())) {
return NS_ERROR_FAILURE;
}
ErrorResult error;
SelectionRef().Collapse(atVisNode, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
rv = SelectionRef().Collapse(visNode, visOffset);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
}
}
ErrorResult error;
SelectionRef().Collapse(EditorRawDOMPoint(&aListItem, 0), error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
nsresult
HTMLEditRules::MakeBlockquote(nsTArray<OwningNonNull<nsINode>>& aNodeArray)
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -396,17 +396,29 @@ protected:
* If this is not nullptr, the <br> node may be
* removed.
*/
template<typename PT, typename CT>
nsresult SplitParagraph(Element& aParentDivOrP,
const EditorDOMPointBase<PT, CT>& aStartOfRightNode,
nsIContent* aBRNode);
- nsresult ReturnInListItem(Element& aHeader, nsINode& aNode, int32_t aOffset);
+ /**
+ * ReturnInListItem() handles insertParagraph command (i.e., handling
+ * Enter key press) in a list item element.
+ *
+ * @param aListItem The list item which has the following point.
+ * @param aNode Typically, Selection start container, where to
+ * insert a break.
+ * @param aOffset Typically, Selection start offset in the
+ * start container, where to insert a break.
+ */
+ MOZ_MUST_USE nsresult
+ ReturnInListItem(Element& aListItem, nsINode& aNode, int32_t aOffset);
+
nsresult AfterEditInner(EditAction action,
nsIEditor::EDirection aDirection);
nsresult RemovePartOfBlock(Element& aBlock, nsIContent& aStartChild,
nsIContent& aEndChild);
void SplitBlock(Element& aBlock,
nsIContent& aStartChild,
nsIContent& aEndChild,
nsIContent** aOutLeftNode = nullptr,