Bug 1368544 - Part 1. Use root node for mozInlineSpellChecker::SpellCheckAfterEditorChange on setText trasaction. r?masayuki
textarea element will use fallback code (using TextEditor::DeleteSelection) to set empty value for SetText.
Actually, if EditorBase::HandleInlineSpellCheck returns error in AfterEdit, we might not create bogus node and trailing br node. Since SetText's fallback uses DeleteSelection, SpellCheckAfterEditorChange will return error when previous selection is invalid on SetText transaction.
mozInineSpellChecker::SpellCheckAfterEditorChange creates the range between previousSelection and anchorNode. So when using setText, we should set the range of all text, and we should not use previous selection for SpellCheckAfterEditorChange.
MozReview-Commit-ID: 7eDzMdRmOSz
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -182,22 +182,34 @@ TextEditRules::BeforeEdit(EditAction act
mDidExplicitlySetInterline = false;
if (!mActionNesting) {
// let rules remember the top level action
mTheAction = action;
}
mActionNesting++;
// get the selection and cache the position before editing
- NS_ENSURE_STATE(mTextEditor);
- RefPtr<Selection> selection = mTextEditor->GetSelection();
+ if (NS_WARN_IF(!mTextEditor)) {
+ return NS_ERROR_FAILURE;
+ }
+ RefPtr<TextEditor> textEditor = mTextEditor;
+ RefPtr<Selection> selection = textEditor->GetSelection();
NS_ENSURE_STATE(selection);
- mCachedSelectionNode = selection->GetAnchorNode();
- selection->GetAnchorOffset(&mCachedSelectionOffset);
+ if (action == EditAction::setText) {
+ // setText replaces all text, so mCachedSelectionNode might be invalid on
+ // AfterEdit.
+ // Since this will be used as start position of spellchecker, we should
+ // use root instead.
+ mCachedSelectionNode = textEditor->GetRoot();
+ mCachedSelectionOffset = 0;
+ } else {
+ mCachedSelectionNode = selection->GetAnchorNode();
+ selection->GetAnchorOffset(&mCachedSelectionOffset);
+ }
return NS_OK;
}
NS_IMETHODIMP
TextEditRules::AfterEdit(EditAction action,
nsIEditor::EDirection aDirection)
{
@@ -216,16 +228,19 @@ TextEditRules::AfterEdit(EditAction acti
NS_ENSURE_STATE(mTextEditor);
nsresult rv =
mTextEditor->HandleInlineSpellCheck(action, selection,
GetAsDOMNode(mCachedSelectionNode),
mCachedSelectionOffset,
nullptr, 0, nullptr, 0);
NS_ENSURE_SUCCESS(rv, rv);
+ // no longer uses mCachedSelectionNode, so release it.
+ mCachedSelectionNode = nullptr;
+
// if only trailing <br> remaining remove it
rv = RemoveRedundantTrailingBR();
if (NS_FAILED(rv)) {
return rv;
}
// detect empty doc
rv = CreateBogusNodeIfNeeded(selection);