diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp
index be7ab8b2b342..7ca00d0aba3d 100644
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -4806,6 +4806,24 @@ HTMLEditRules::WillHTMLIndent(bool* aCancel,
return rv;
}
+ // IndentAroundSelectionWithHTML() creates AutoSelectionRestorer.
+ // Therefore, even if it returns NS_OK, editor might have been destroyed
+ // at restoring Selection.
+ rv = IndentAroundSelectionWithHTML();
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
+}
+
+nsresult
+HTMLEditRules::IndentAroundSelectionWithHTML()
+{
+ MOZ_ASSERT(IsEditorDataAvailable());
+
AutoSelectionRestorer selectionRestorer(&SelectionRef(), &HTMLEditorRef());
// convert the selection ranges into "promoted" selection ranges:
@@ -4818,8 +4836,9 @@ HTMLEditRules::WillHTMLIndent(bool* aCancel,
// use these ranges to contruct a list of nodes to act on.
nsTArray> arrayOfNodes;
- rv = GetNodesForOperation(arrayOfRanges, arrayOfNodes, EditAction::indent,
- TouchContent::yes);
+ nsresult rv =
+ GetNodesForOperation(arrayOfRanges, arrayOfNodes, EditAction::indent,
+ TouchContent::yes);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -4846,6 +4865,9 @@ HTMLEditRules::WillHTMLIndent(bool* aCancel,
RefPtr theBlock =
HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::blockquote,
splitNodeResult.SplitPoint());
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!theBlock)) {
return NS_ERROR_FAILURE;
}
@@ -4855,18 +4877,23 @@ HTMLEditRules::WillHTMLIndent(bool* aCancel,
while (!arrayOfNodes.IsEmpty()) {
OwningNonNull curNode = arrayOfNodes[0];
rv = HTMLEditorRef().DeleteNodeWithTransaction(*curNode);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
arrayOfNodes.RemoveElementAt(0);
}
- // put selection in new block
- *aHandled = true;
EditorRawDOMPoint atStartOfTheBlock(theBlock, 0);
- ErrorResult error;
- SelectionRef().Collapse(atStartOfTheBlock, error);
// Don't restore the selection
selectionRestorer.Abort();
+ ErrorResult error;
+ SelectionRef().Collapse(atStartOfTheBlock, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!error.Failed())) {
return error.StealNSResult();
}
@@ -4903,6 +4930,9 @@ HTMLEditRules::WillHTMLIndent(bool* aCancel,
rv = HTMLEditorRef().MoveNodeWithTransaction(
*curNode->AsContent(),
EditorRawDOMPoint(sibling, 0));
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -4920,6 +4950,9 @@ HTMLEditRules::WillHTMLIndent(bool* aCancel,
sibling->NodeInfo()->NamespaceID()) {
rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
*sibling);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -4946,6 +4979,9 @@ HTMLEditRules::WillHTMLIndent(bool* aCancel,
curList =
HTMLEditorRef().CreateNodeWithTransaction(
*containerName, splitNodeResult.SplitPoint());
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!curList)) {
return NS_ERROR_FAILURE;
}
@@ -4956,6 +4992,9 @@ HTMLEditRules::WillHTMLIndent(bool* aCancel,
// tuck the node into the end of the active list
rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
*curList);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -5002,12 +5041,18 @@ HTMLEditRules::WillHTMLIndent(bool* aCancel,
curList =
HTMLEditorRef().CreateNodeWithTransaction(
*containerName, splitNodeResult.SplitPoint());
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!curList)) {
return NS_ERROR_FAILURE;
}
}
rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*listItem, *curList);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -5042,6 +5087,9 @@ HTMLEditRules::WillHTMLIndent(bool* aCancel,
curQuote =
HTMLEditorRef().CreateNodeWithTransaction(*nsGkAtoms::blockquote,
splitNodeResult.SplitPoint());
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(!curQuote)) {
return NS_ERROR_FAILURE;
}
@@ -5053,6 +5101,9 @@ HTMLEditRules::WillHTMLIndent(bool* aCancel,
// tuck the node into the end of the active blockquote
rv = HTMLEditorRef().MoveNodeToEndWithTransaction(*curNode->AsContent(),
*curQuote);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
diff --git a/editor/libeditor/HTMLEditRules.h b/editor/libeditor/HTMLEditRules.h
index e462cd3c39ef..e17ede38c371 100644
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -329,7 +329,15 @@ protected:
nsresult WillRemoveList(bool aOrdered, bool* aCancel, bool* aHandled);
nsresult WillIndent(bool* aCancel, bool* aHandled);
nsresult WillCSSIndent(bool* aCancel, bool* aHandled);
- nsresult WillHTMLIndent(bool* aCancel, bool* aHandled);
+
+ /**
+ * Called before indenting around Selection and it's not in CSS mode.
+ * This method actually tries to indent the contents.
+ *
+ * @param aCancel Returns true if the operation is canceled.
+ * @param aHandled Returns true if the edit action is handled.
+ */
+ MOZ_MUST_USE nsresult WillHTMLIndent(bool* aCancel, bool* aHandled);
/**
* Called before outdenting around Selection. This method actually tries
@@ -537,6 +545,14 @@ protected:
MOZ_MUST_USE nsresult
AfterEditInner(EditAction action, nsIEditor::EDirection aDirection);
+ /**
+ * IndentAroundSelectionWithHTML() indents around Selection with HTML.
+ * This method creates AutoSelectionRestorer. Therefore, each caller
+ * need to check if the editor is still available even if this returns
+ * NS_OK.
+ */
+ MOZ_MUST_USE nsresult IndentAroundSelectionWithHTML();
+
/**
* OutdentAroundSelection() outdents contents around Selection.
* This method creates AutoSelectionRestorer. Therefore, each caller