Bug 339434: Crash trying to spellcheck in a closed window. Patch by pkasting@google.com. r=brettw, sr=bzbarsky
git-svn-id: svn://10.0.0.236/trunk@203331 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
5f7ca2b6d9
commit
22934e7775
@ -155,6 +155,7 @@ nsEditor::nsEditor()
|
||||
, mInIMEMode(PR_FALSE)
|
||||
, mIsIMEComposing(PR_FALSE)
|
||||
, mShouldTxnSetSelection(PR_TRUE)
|
||||
, mDidPreDestroy(PR_FALSE)
|
||||
, mActionListeners(nsnull)
|
||||
, mEditorObservers(nsnull)
|
||||
, mDocDirtyState(-1)
|
||||
@ -216,9 +217,6 @@ nsEditor::~nsEditor()
|
||||
delete mEditorObservers; // no need to release observers; we didn't addref them
|
||||
mEditorObservers = 0;
|
||||
|
||||
if (mInlineSpellChecker)
|
||||
mInlineSpellChecker->Cleanup();
|
||||
|
||||
if (mActionListeners)
|
||||
{
|
||||
PRInt32 i;
|
||||
@ -455,11 +453,21 @@ nsEditor::RemoveEventListeners()
|
||||
NS_IMETHODIMP
|
||||
nsEditor::PreDestroy()
|
||||
{
|
||||
// tell our listeners that the doc is going away
|
||||
NotifyDocumentListeners(eDocumentToBeDestroyed);
|
||||
if (!mDidPreDestroy) {
|
||||
// Let spellchecker clean up its observers etc.
|
||||
if (mInlineSpellChecker) {
|
||||
mInlineSpellChecker->Cleanup();
|
||||
mInlineSpellChecker = nsnull;
|
||||
}
|
||||
|
||||
// Unregister event listeners
|
||||
RemoveEventListeners();
|
||||
// tell our listeners that the doc is going away
|
||||
NotifyDocumentListeners(eDocumentToBeDestroyed);
|
||||
|
||||
// Unregister event listeners
|
||||
RemoveEventListeners();
|
||||
|
||||
mDidPreDestroy = PR_TRUE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1258,17 +1266,27 @@ NS_IMETHODIMP nsEditor::GetInlineSpellChecker(PRBool autoCreate,
|
||||
nsIInlineSpellChecker ** aInlineSpellChecker)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aInlineSpellChecker);
|
||||
nsresult rv;
|
||||
|
||||
if (mDidPreDestroy) {
|
||||
// Don't allow people to get or create the spell checker once the editor
|
||||
// is going away.
|
||||
*aInlineSpellChecker = nsnull;
|
||||
return autoCreate ? NS_ERROR_NOT_AVAILABLE : NS_OK;
|
||||
}
|
||||
|
||||
if (!mInlineSpellChecker && autoCreate) {
|
||||
nsresult rv;
|
||||
mInlineSpellChecker = do_CreateInstance(MOZ_INLINESPELLCHECKER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mInlineSpellChecker->Init(this);
|
||||
if (NS_FAILED(rv))
|
||||
mInlineSpellChecker = nsnull;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aInlineSpellChecker = mInlineSpellChecker);
|
||||
NS_IF_ADDREF(*aInlineSpellChecker = mInlineSpellChecker);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -607,7 +607,8 @@ protected:
|
||||
// This is different from mInIMEMode. see Bug 98434.
|
||||
|
||||
PRPackedBool mShouldTxnSetSelection; // turn off for conservative selection adjustment by txns
|
||||
// various listeners
|
||||
PRPackedBool mDidPreDestroy; // whether PreDestroy has been called
|
||||
// various listeners
|
||||
nsVoidArray* mActionListeners; // listens to all low level actions on the doc
|
||||
nsVoidArray* mEditorObservers; // just notify once per high level change
|
||||
nsCOMPtr<nsISupportsArray> mDocStateListeners;// listen to overall doc state (dirty or not, just created, etc)
|
||||
|
||||
@ -130,7 +130,21 @@ mozInlineSpellChecker::Init(nsIEditor *aEditor)
|
||||
|
||||
nsresult mozInlineSpellChecker::Cleanup()
|
||||
{
|
||||
return UnregisterEventListeners();
|
||||
mNumWordsInSpellSelection = 0;
|
||||
nsCOMPtr<nsISelection> spellCheckSelection;
|
||||
nsresult rv = GetSpellCheckSelection(getter_AddRefs(spellCheckSelection));
|
||||
if (NS_FAILED(rv)) {
|
||||
// Ensure we still unregister event listeners (but return a failure code)
|
||||
UnregisterEventListeners();
|
||||
} else {
|
||||
spellCheckSelection->RemoveAllRanges();
|
||||
|
||||
rv = UnregisterEventListeners();
|
||||
}
|
||||
|
||||
mSpellCheck = nsnull;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// mozInlineSpellChecker::CanEnableInlineSpellChecking
|
||||
@ -231,54 +245,43 @@ mozInlineSpellChecker::GetEnableRealTimeSpell(PRBool* aEnabled)
|
||||
NS_IMETHODIMP
|
||||
mozInlineSpellChecker::SetEnableRealTimeSpell(PRBool aEnabled)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
if (!aEnabled) {
|
||||
return Cleanup();
|
||||
}
|
||||
|
||||
if (aEnabled) {
|
||||
if (!mSpellCheck) {
|
||||
nsCOMPtr<nsIEditorSpellCheck> spellchecker = do_CreateInstance("@mozilla.org/editor/editorspellchecker;1", &res);
|
||||
if (NS_SUCCEEDED(res) && spellchecker)
|
||||
{
|
||||
nsCOMPtr<nsITextServicesFilter> filter = do_CreateInstance("@mozilla.org/editor/txtsrvfiltermail;1", &res);
|
||||
spellchecker->SetFilter(filter);
|
||||
nsCOMPtr<nsIEditor> editor (do_QueryReferent(mEditor));
|
||||
res = spellchecker->InitSpellChecker(editor, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if (!mSpellCheck) {
|
||||
nsresult res = NS_OK;
|
||||
nsCOMPtr<nsIEditorSpellCheck> spellchecker = do_CreateInstance("@mozilla.org/editor/editorspellchecker;1", &res);
|
||||
if (NS_SUCCEEDED(res) && spellchecker)
|
||||
{
|
||||
nsCOMPtr<nsITextServicesFilter> filter = do_CreateInstance("@mozilla.org/editor/txtsrvfiltermail;1", &res);
|
||||
spellchecker->SetFilter(filter);
|
||||
nsCOMPtr<nsIEditor> editor (do_QueryReferent(mEditor));
|
||||
res = spellchecker->InitSpellChecker(editor, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
nsCOMPtr<nsITextServicesDocument> tsDoc = do_CreateInstance("@mozilla.org/textservices/textservicesdocument;1", &res);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
nsCOMPtr<nsITextServicesDocument> tsDoc = do_CreateInstance("@mozilla.org/textservices/textservicesdocument;1", &res);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
res = tsDoc->SetFilter(filter);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = tsDoc->SetFilter(filter);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
res = tsDoc->InitWithEditor(editor);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = tsDoc->InitWithEditor(editor);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
mTextServicesDocument = tsDoc;
|
||||
mSpellCheck = spellchecker;
|
||||
mTextServicesDocument = tsDoc;
|
||||
mSpellCheck = spellchecker;
|
||||
|
||||
// spell checking is enabled, register our event listeners to track navigation
|
||||
RegisterEventListeners();
|
||||
}
|
||||
// spell checking is enabled, register our event listeners to track navigation
|
||||
RegisterEventListeners();
|
||||
}
|
||||
|
||||
// spellcheck the current contents. SpellCheckRange doesn't supply a created
|
||||
// range to DoSpellCheck, which in our case is the entire range. But this
|
||||
// optimization doesn't matter because there is nothing in the spellcheck
|
||||
// selection when starting, which triggers a better optimization.
|
||||
res = SpellCheckRange(nsnull);
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsISelection> spellCheckSelection;
|
||||
res = GetSpellCheckSelection(getter_AddRefs(spellCheckSelection));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
spellCheckSelection->RemoveAllRanges();
|
||||
mNumWordsInSpellSelection = 0;
|
||||
UnregisterEventListeners();
|
||||
mSpellCheck = nsnull;
|
||||
}
|
||||
|
||||
return res;
|
||||
// spellcheck the current contents. SpellCheckRange doesn't supply a created
|
||||
// range to DoSpellCheck, which in our case is the entire range. But this
|
||||
// optimization doesn't matter because there is nothing in the spellcheck
|
||||
// selection when starting, which triggers a better optimization.
|
||||
return SpellCheckRange(nsnull);
|
||||
}
|
||||
|
||||
// mozInlineSpellChecker::SpellCheckAfterEditorChange
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user