Fix bug 306642 -- caller's shouldn't have to guess at how to force inner window

creation.  r+sr=jst
This commit is contained in:
bzbarsky%mit.edu 2005-12-11 20:38:29 +00:00
parent 62d52bad2c
commit 063002a639
4 changed files with 27 additions and 29 deletions

View File

@ -77,8 +77,8 @@ class nsIDocument;
struct nsTimeout; struct nsTimeout;
#define NS_PIDOMWINDOW_IID \ #define NS_PIDOMWINDOW_IID \
{ 0x207fe64a, 0x7123, 0x43d0, \ { 0xabb217ba, 0x2528, 0x467e, \
{ 0x91, 0x1d, 0x51, 0x19, 0x35, 0x9a, 0xb5, 0x77 } } { 0xaa, 0x29, 0xdd, 0x84, 0x2d, 0x97, 0x3c, 0x78 } }
class nsPIDOMWindow : public nsIDOMWindowInternal class nsPIDOMWindow : public nsIDOMWindowInternal
{ {
@ -280,6 +280,15 @@ public:
return mInnerWindow; return mInnerWindow;
} }
nsPIDOMWindow *EnsureInnerWindow()
{
NS_ASSERTION(IsOuterWindow(), "EnsureInnerWindow called on inner window");
// GetDocument forces inner window creation if there isn't one already
nsCOMPtr<nsIDOMDocument> doc;
GetDocument(getter_AddRefs(doc));
return GetCurrentInnerWindow();
}
PRBool IsInnerWindow() const PRBool IsInnerWindow() const
{ {
return mIsInnerWindow; return mIsInnerWindow;

View File

@ -5627,22 +5627,18 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// We're resolving a property on an outer window for which there // We're resolving a property on an outer window for which there
// is no inner window yet, and the window is not frozen // is no inner window yet, and the window is not frozen
// (i.e. we're not in the middle of initializing XPConnect // (i.e. we're not in the middle of initializing XPConnect
// classes on it). If the context is already initalized, trigger // classes on it). If the context is already initalized, force
// creation of a new inner window by calling GetDocument() on // creation of a new inner window. This will create a synthetic
// the outer window. This will create a synthetic about:blank // about:blank document, and an inner window which may be reused
// document, and an inner window which may be reused by the // by the actual document being loaded into this outer
// actual document being loaded into this outer window. This way // window. This way properties defined on the window before the
// properties defined on the window before the document load // document load started will be visible to the document once
// started will be visible to the document once it's loaded, // it's loaded, assuming same origin etc.
// assuming same origin etc.
nsIScriptContext *scx = win->GetContextInternal(); nsIScriptContext *scx = win->GetContextInternal();
if (scx && scx->IsContextInitialized()) { if (scx && scx->IsContextInitialized()) {
nsCOMPtr<nsIDOMDocument> doc;
win->GetDocument(getter_AddRefs(doc));
// Grab the new inner window. // Grab the new inner window.
innerWin = win->GetCurrentInnerWindowInternal(); innerWin = win->EnsureInnerWindowInternal();
if (!innerWin) { if (!innerWin) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;

View File

@ -266,6 +266,11 @@ public:
return NS_STATIC_CAST(nsGlobalWindow *, mInnerWindow); return NS_STATIC_CAST(nsGlobalWindow *, mInnerWindow);
} }
nsGlobalWindow *EnsureInnerWindowInternal()
{
return NS_STATIC_CAST(nsGlobalWindow *, EnsureInnerWindow());
}
PRBool IsFrozen() const PRBool IsFrozen() const
{ {
return mIsFrozen; return mIsFrozen;

View File

@ -150,12 +150,9 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel)
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(global)); nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(global));
// Get the document out of the window to make sure we create a new // Make sure we create a new inner window if one doesn't already exist (see
// inner window if one doesn't already exist (see bug 306630). // bug 306630).
nsCOMPtr<nsIDOMDocument> doc; nsPIDOMWindow *innerWin = win->EnsureInnerWindow();
win->GetDocument(getter_AddRefs(doc));
nsPIDOMWindow *innerWin = win->GetCurrentInnerWindow();
if (!innerWin) { if (!innerWin) {
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
@ -178,15 +175,6 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel)
return NS_ERROR_DOM_RETVAL_UNDEFINED; return NS_ERROR_DOM_RETVAL_UNDEFINED;
} }
// Now get the DOM Document. Accessing the document will create one
// if necessary. So, basically, this call ensures that a document gets
// created -- if necessary.
rv = domWindow->GetDocument(getter_AddRefs(doc));
NS_ASSERTION(doc, "No DOMDocument!");
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIScriptContext> scriptContext = global->GetContext(); nsCOMPtr<nsIScriptContext> scriptContext = global->GetContext();
if (!scriptContext) if (!scriptContext)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;