Bug 1460509 - part 27: Make HTMLEditRules::PinSelectionToNewBlock() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato
MozReview-Commit-ID: GW0xI5BBxqU
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -552,16 +552,19 @@ HTMLEditRules::AfterEditInner(EditAction
WSRunObject(&HTMLEditorRef(), mRangeItem->mEndContainer,
mRangeItem->mEndOffset).AdjustWhitespace();
}
}
// if we created a new block, make sure selection lands in it
if (mNewBlock) {
rv = PinSelectionToNewBlock();
+ if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"Failed to pin selection to the new block");
mNewBlock = nullptr;
}
// adjust selection for insert text, html paste, and delete actions
if (aAction == EditAction::insertText ||
aAction == EditAction::insertIMEText ||
@@ -8666,17 +8669,19 @@ HTMLEditRules::PinSelectionToNewBlock()
RefPtr<nsRange> range = new nsRange(selectionStartPoint.GetContainer());
nsresult rv = range->CollapseTo(selectionStartPoint);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool nodeBefore, nodeAfter;
rv = nsRange::CompareNodeToRange(mNewBlock, range, &nodeBefore, &nodeAfter);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
if (nodeBefore && nodeAfter) {
return NS_OK; // selection is inside block
}
if (nodeBefore) {
// selection is after block. put at end of block.
nsCOMPtr<nsINode> tmp = HTMLEditorRef().GetLastEditableChild(*mNewBlock);
@@ -8690,16 +8695,20 @@ HTMLEditRules::PinSelectionToNewBlock()
} else {
endPoint.Set(tmp);
if (NS_WARN_IF(!endPoint.AdvanceOffset())) {
return NS_ERROR_FAILURE;
}
}
ErrorResult error;
SelectionRef().Collapse(endPoint, 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;
}
// selection is before block. put at start of block.
nsCOMPtr<nsINode> tmp = HTMLEditorRef().GetFirstEditableChild(*mNewBlock);
@@ -8710,16 +8719,20 @@ HTMLEditRules::PinSelectionToNewBlock()
if (EditorBase::IsTextNode(tmp) ||
HTMLEditorRef().IsContainer(tmp)) {
atStartOfBlock.Set(tmp);
} else {
atStartOfBlock.Set(tmp, 0);
}
ErrorResult error;
SelectionRef().Collapse(atStartOfBlock, 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;
}
void
HTMLEditRules::CheckInterlinePosition()
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -590,17 +590,23 @@ protected:
*/
MOZ_MUST_USE nsresult RemoveListStructure(Element& aListElement);
nsresult CacheInlineStyles(nsINode* aNode);
nsresult ReapplyCachedStyles();
void ClearCachedStyles();
void AdjustSpecialBreaks();
nsresult AdjustWhitespace();
- nsresult PinSelectionToNewBlock();
+
+ /**
+ * PinSelectionToNewBlock() may collapse Selection around mNewNode if it's
+ * necessary,
+ */
+ MOZ_MUST_USE nsresult PinSelectionToNewBlock();
+
void CheckInterlinePosition();
/**
* AdjustSelection() may adjust Selection range to nearest editable content.
* Despite of the name, this may change the DOM tree. If it needs to create
* a <br> to put caret, this tries to create a <br> element.
*
* @param aAction Maybe used to look for a good point to put caret.