Bug 1460509 - part 65: Make HTMLEditRules::WillHTMLIndent() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r=m_kato

MozReview-Commit-ID: 2jZh8GtC7BA

--HG--
extra : rebase_source : e0fe459ce72d2123dde811445193508c81b27102
This commit is contained in:
Masayuki Nakano 2018-05-17 18:14:01 +09:00
parent 0829b9a5a2
commit ba826bb7b6
2 changed files with 74 additions and 7 deletions

View File

@ -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<OwningNonNull<nsINode>> 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<Element> 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<nsINode> 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;
}

View File

@ -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