Bug 1460509 - part 26: Make HTMLEditRules::AdjustSelection() return NS_ERROR_EDITOR_DESTROYED if it causes destroying the editor r?m_kato
MozReview-Commit-ID: JCEvhhxNBgg
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -8811,24 +8811,24 @@ HTMLEditRules::AdjustSelection(nsIEditor
}
}
// make sure we aren't in an empty block - user will see no cursor. If this
// is happening, put a <br> in the block if allowed.
RefPtr<Element> theblock = HTMLEditorRef().GetBlock(*point.GetContainer());
if (theblock && HTMLEditorRef().IsEditable(theblock)) {
- bool bIsEmptyNode;
+ bool isEmptyNode;
nsresult rv =
- HTMLEditorRef().IsEmptyNode(theblock, &bIsEmptyNode, false, false);
+ HTMLEditorRef().IsEmptyNode(theblock, &isEmptyNode, false, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// check if br can go into the destination node
- if (bIsEmptyNode &&
+ if (isEmptyNode &&
HTMLEditorRef().CanContainTag(*point.GetContainer(), *nsGkAtoms::br)) {
Element* rootElement = HTMLEditorRef().GetRoot();
if (NS_WARN_IF(!rootElement)) {
return NS_ERROR_FAILURE;
}
if (point.GetContainer() == rootElement) {
// Our root node is completely empty. Don't add a <br> here.
// AfterEditInner() will add one for us when it calls
@@ -8870,20 +8870,28 @@ HTMLEditRules::AdjustSelection(nsIEditor
CreateElementResult createMozBrResult = CreateMozBR(point);
if (NS_WARN_IF(createMozBrResult.Failed())) {
return createMozBrResult.Rv();
}
point.Set(createMozBrResult.GetNewNode());
// selection stays *before* moz-br, sticking to it
ErrorResult error;
SelectionRef().SetInterlinePosition(true, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(!error.Failed(),
"Failed to set interline position");
error = NS_OK;
SelectionRef().Collapse(point, error);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ error.SuppressException();
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
} else {
nsCOMPtr<nsIContent> nextNode =
HTMLEditorRef().GetNextEditableHTMLNodeInBlock(*nearNode);
if (nextNode && TextEditUtils::IsMozBR(nextNode)) {
// selection between br and mozbr. make it stick to mozbr
@@ -8920,16 +8928,20 @@ HTMLEditRules::AdjustSelection(nsIEditor
nearNode = FindNearEditableNode(point, aAction);
if (!nearNode) {
return NS_OK;
}
EditorDOMPoint pt = GetGoodSelPointForNode(*nearNode, aAction);
ErrorResult error;
SelectionRef().Collapse(pt, 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;
}
template<typename PT, typename CT>
nsIContent*
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -592,17 +592,25 @@ protected:
nsresult CacheInlineStyles(nsINode* aNode);
nsresult ReapplyCachedStyles();
void ClearCachedStyles();
void AdjustSpecialBreaks();
nsresult AdjustWhitespace();
nsresult PinSelectionToNewBlock();
void CheckInterlinePosition();
- nsresult AdjustSelection(nsIEditor::EDirection aAction);
+
+ /**
+ * 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.
+ */
+ MOZ_MUST_USE nsresult AdjustSelection(nsIEditor::EDirection aAction);
/**
* FindNearEditableNode() tries to find an editable node near aPoint.
*
* @param aPoint The DOM point where to start to search from.
* @param aDirection If nsIEditor::ePrevious is set, this searches an
* editable node from next nodes. Otherwise, from
* previous nodes.