Fix for bug 430624 (Crash [@ nsDocShellEditorData::DetachFromWindow] with spellcheck attribute). Patch by cpearce, r=peterv, sr=jst.
This commit is contained in:
@@ -1011,12 +1011,9 @@ nsDocShell::FirePageHideNotification(PRBool aIsUnload)
|
||||
kids[i]->FirePageHideNotification(aIsUnload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now make sure our editor, if any, is detached before we go
|
||||
// any farther.
|
||||
if (mEditorData && aIsUnload) {
|
||||
DetachEditorFromWindow();
|
||||
// Now make sure our editor, if any, is detached before we go
|
||||
// any farther.
|
||||
DetachEditorFromWindow();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -3377,11 +3374,6 @@ nsDocShell::Reload(PRUint32 aReloadFlags)
|
||||
}
|
||||
|
||||
|
||||
// Need to purge detached editor here, else when we reload a page,
|
||||
// the detached editor state causes SetDesignMode() to fail.
|
||||
if (mOSHE)
|
||||
mOSHE->SetEditorData(nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -4885,8 +4877,13 @@ nsDocShell::Embed(nsIContentViewer * aContentViewer,
|
||||
SetBaseUrlForWyciwyg(aContentViewer);
|
||||
}
|
||||
// XXX What if SetupNewViewer fails?
|
||||
if (mLSHE)
|
||||
if (mLSHE) {
|
||||
// Restore the editing state, if it's stored in session history.
|
||||
if (mLSHE->HasDetachedEditor()) {
|
||||
ReattachEditorToWindow(mLSHE);
|
||||
}
|
||||
SetHistoryEntry(&mOSHE, mLSHE);
|
||||
}
|
||||
|
||||
PRBool updateHistory = PR_TRUE;
|
||||
|
||||
@@ -5332,29 +5329,20 @@ nsDocShell::CanSavePresentation(PRUint32 aLoadType,
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDocShell::HasDetachedEditor()
|
||||
{
|
||||
return (mOSHE && mOSHE->HasDetachedEditor()) ||
|
||||
(mLSHE && mLSHE->HasDetachedEditor());
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::ReattachEditorToWindow(nsIDOMWindow *aWindow, nsISHEntry *aSHEntry)
|
||||
nsDocShell::ReattachEditorToWindow(nsISHEntry *aSHEntry)
|
||||
{
|
||||
NS_ASSERTION(!mEditorData,
|
||||
"Why reattach an editor when we already have one?");
|
||||
NS_ASSERTION(aWindow,
|
||||
"Need a window to reattach to.");
|
||||
NS_ASSERTION(HasDetachedEditor(),
|
||||
NS_ASSERTION(aSHEntry && aSHEntry->HasDetachedEditor(),
|
||||
"Reattaching when there's not a detached editor.");
|
||||
|
||||
if (mEditorData || !aWindow || !aSHEntry)
|
||||
if (mEditorData || !aSHEntry)
|
||||
return;
|
||||
|
||||
mEditorData = aSHEntry->ForgetEditorData();
|
||||
if (mEditorData) {
|
||||
nsresult res = mEditorData->ReattachToWindow(aWindow);
|
||||
nsresult res = mEditorData->ReattachToWindow(this);
|
||||
NS_ASSERTION(NS_SUCCEEDED(res), "Failed to reattach editing session");
|
||||
}
|
||||
}
|
||||
@@ -5362,18 +5350,21 @@ nsDocShell::ReattachEditorToWindow(nsIDOMWindow *aWindow, nsISHEntry *aSHEntry)
|
||||
void
|
||||
nsDocShell::DetachEditorFromWindow(nsISHEntry *aSHEntry)
|
||||
{
|
||||
if (!aSHEntry || !mEditorData)
|
||||
if (!mEditorData)
|
||||
return;
|
||||
|
||||
NS_ASSERTION(!aSHEntry->HasDetachedEditor(),
|
||||
"Why detach an editor twice?");
|
||||
NS_ASSERTION(!aSHEntry || !aSHEntry->HasDetachedEditor(),
|
||||
"Detaching editor when it's already detached.");
|
||||
|
||||
nsresult res = mEditorData->DetachFromWindow();
|
||||
NS_ASSERTION(NS_SUCCEEDED(res), "Failed to detach editor");
|
||||
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
// Make aSHEntry hold the owning ref to the editor data.
|
||||
aSHEntry->SetEditorData(mEditorData.forget());
|
||||
// Make aSHEntry hold the owning ref to the editor data.
|
||||
if (aSHEntry)
|
||||
aSHEntry->SetEditorData(mEditorData.forget());
|
||||
else
|
||||
mEditorData = nsnull;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -5390,7 +5381,8 @@ nsDocShell::DetachEditorFromWindow(nsISHEntry *aSHEntry)
|
||||
void
|
||||
nsDocShell::DetachEditorFromWindow()
|
||||
{
|
||||
DetachEditorFromWindow(mOSHE);
|
||||
if (mOSHE)
|
||||
DetachEditorFromWindow(mOSHE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -5542,6 +5534,10 @@ nsDocShell::FinishRestore()
|
||||
}
|
||||
}
|
||||
|
||||
if (mOSHE && mOSHE->HasDetachedEditor()) {
|
||||
ReattachEditorToWindow(mOSHE);
|
||||
}
|
||||
|
||||
if (mContentViewer) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mContentViewer->GetDOMDocument(getter_AddRefs(domDoc));
|
||||
@@ -6010,11 +6006,6 @@ nsDocShell::RestoreFromHistory()
|
||||
}
|
||||
}
|
||||
|
||||
if (HasDetachedEditor()) {
|
||||
nsCOMPtr<nsIDOMWindow> domWin = do_QueryInterface(privWin);
|
||||
ReattachEditorToWindow(domWin, mLSHE);
|
||||
}
|
||||
|
||||
// Simulate the completion of the load.
|
||||
nsDocShell::FinishRestore();
|
||||
|
||||
@@ -7153,10 +7144,6 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
|
||||
mLoadType = aLoadType;
|
||||
|
||||
// Detach the current editor so that it can be restored from the
|
||||
// bfcache later.
|
||||
DetachEditorFromWindow();
|
||||
|
||||
// mLSHE should be assigned to aSHEntry, only after Stop() has
|
||||
// been called. But when loading an error page, do not clear the
|
||||
// mLSHE for the real page.
|
||||
@@ -7220,22 +7207,6 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
nsCOMPtr<nsIChannel> chan(do_QueryInterface(req));
|
||||
DisplayLoadError(rv, aURI, nsnull, chan);
|
||||
}
|
||||
|
||||
if (aSHEntry) {
|
||||
if (aLoadType & LOAD_CMD_HISTORY) {
|
||||
// We've just loaded a page from session history. Reattach
|
||||
// its editing session if it has one.
|
||||
nsCOMPtr<nsIDOMWindow> domWin;
|
||||
CallGetInterface(this, static_cast<nsIDOMWindow**>(getter_AddRefs(domWin)));
|
||||
ReattachEditorToWindow(domWin, aSHEntry);
|
||||
} else {
|
||||
// This is a non-history load from a session history entry. Purge any
|
||||
// previous editing sessions, so that the the editing session will
|
||||
// be recreated. This can happen when we reload something that's
|
||||
// in the bfcache.
|
||||
aSHEntry->SetEditorData(nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
@@ -8735,9 +8706,12 @@ nsDocShell::ShouldDiscardLayoutState(nsIHttpChannel * aChannel)
|
||||
NS_IMETHODIMP nsDocShell::GetEditor(nsIEditor * *aEditor)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEditor);
|
||||
nsresult rv = EnsureEditorData();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
if (!mEditorData) {
|
||||
*aEditor = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return mEditorData->GetEditor(aEditor);
|
||||
}
|
||||
|
||||
@@ -9043,9 +9017,12 @@ nsDocShell::EnsureScriptEnvironment()
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::EnsureEditorData()
|
||||
{
|
||||
NS_ASSERTION(!HasDetachedEditor(), "EnsureEditorData() called when detached.\n");
|
||||
|
||||
if (!mEditorData && !mIsBeingDestroyed && !HasDetachedEditor()) {
|
||||
PRBool openDocHasDetachedEditor = mOSHE && mOSHE->HasDetachedEditor();
|
||||
if (!mEditorData && !mIsBeingDestroyed && !openDocHasDetachedEditor) {
|
||||
// We shouldn't recreate the editor data if it already exists, or
|
||||
// we're shutting down, or we already have a detached editor data
|
||||
// stored in the session history. We should only have one editordata
|
||||
// per docshell.
|
||||
mEditorData = new nsDocShellEditorData(this);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user