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