DOMWindow List now holds on to a docshell interface rather than a webshell. Tweaked some of the finding of named frames to adhere to spec. GlobalWindowImpl now in many places talks to the webshell object as a docshell rather than the old webshell interfaces. Fixed bug #21970. r=vidur

This commit is contained in:
tbogard%aol.net 1999-12-17 22:25:22 +00:00
parent 615c192cb9
commit 1f9c8343b4
3 changed files with 105 additions and 102 deletions

View File

@ -17,64 +17,44 @@
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Contributor(s):
* travis@netscape.com
*/
#include "nsCOMPtr.h"
#include "nsDOMWindowList.h"
#include "nsIWebShell.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeNode.h"
#include "nsIDocShellTreeItem.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindow.h"
#include "nsIInterfaceRequestor.h"
static NS_DEFINE_IID(kIDOMWindowCollectionIID, NS_IDOMWINDOWCOLLECTION_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDOMWindowIID, NS_IDOMWINDOW_IID);
nsDOMWindowList::nsDOMWindowList(nsIWebShell *aWebShell)
nsDOMWindowList::nsDOMWindowList(nsIDocShell *aDocShell)
{
NS_INIT_REFCNT();
mScriptObject = nsnull;
//Not refcnted. Ref is nulled out be nsGlobalWindow when its
//WebShell nulls its ref out.
mWebShell = aWebShell;
SetDocShell(aDocShell);
}
nsDOMWindowList::~nsDOMWindowList()
{
}
nsresult nsDOMWindowList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIDOMWindowCollectionIID)) {
*aInstancePtr = (void*)(nsIDOMWindowCollection*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMWindowCollection*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsDOMWindowList)
NS_IMPL_RELEASE(nsDOMWindowList)
NS_INTERFACE_MAP_BEGIN(nsDOMWindowList)
NS_INTERFACE_MAP_ENTRY(nsIDOMWindowCollection)
NS_INTERFACE_MAP_ENTRY(nsIScriptObjectOwner)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowCollection)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsDOMWindowList::SetWebShell(nsIWebShell* aWebShell)
nsDOMWindowList::SetDocShell(nsIDocShell* aDocShell)
{
mWebShell = aWebShell;
nsCOMPtr<nsIDocShellTreeNode> docShellAsNode(do_QueryInterface(aDocShell));
mDocShellNode = docShellAsNode.get(); // Weak Reference
return NS_OK;
}
@ -82,28 +62,28 @@ nsDOMWindowList::SetWebShell(nsIWebShell* aWebShell)
NS_IMETHODIMP
nsDOMWindowList::GetLength(PRUint32* aLength)
{
PRInt32 mLength;
nsresult ret;
PRInt32 length;
ret = mWebShell->GetChildCount(mLength);
*aLength = mLength;
ret = mDocShellNode->GetChildCount(&length);
*aLength = length;
return ret;
}
NS_IMETHODIMP
nsDOMWindowList::Item(PRUint32 aIndex, nsIDOMWindow** aReturn)
{
nsCOMPtr<nsIWebShell> item;
nsCOMPtr<nsIDocShellTreeItem> item;
mWebShell->ChildAt(aIndex, *getter_AddRefs(item));
mDocShellNode->GetChildAt(aIndex, getter_AddRefs(item));
nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(item));
if (NS_WARN_IF_FALSE(globalObject, "Couldn't get to the globalObject")) {
*aReturn = nsnull;
NS_ASSERTION(globalObject, "Couldn't get to the globalObject");
if (globalObject) {
CallQueryInterface(globalObject.get(), aReturn);
}
else {
CallQueryInterface(globalObject.get(), aReturn);
*aReturn = nsnull;
}
return NS_OK;
}
@ -111,16 +91,18 @@ nsDOMWindowList::Item(PRUint32 aIndex, nsIDOMWindow** aReturn)
NS_IMETHODIMP
nsDOMWindowList::NamedItem(const nsString& aName, nsIDOMWindow** aReturn)
{
nsCOMPtr<nsIWebShell> item;
nsCOMPtr<nsIDocShellTreeItem> item;
mWebShell->FindChildWithName(aName.GetUnicode(), *getter_AddRefs(item));
mDocShellNode->FindChildWithName(aName.GetUnicode(), PR_FALSE,
nsnull, getter_AddRefs(item));
nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(item));
if (NS_WARN_IF_FALSE(globalObject, "Couldn't get to the globalObject")) {
*aReturn = nsnull;
NS_ASSERTION(globalObject, "Couldn't get to the globalObject");
if (globalObject) {
CallQueryInterface(globalObject.get(), aReturn);
}
else {
CallQueryInterface(globalObject.get(), aReturn);
*aReturn = nsnull;
}
return NS_OK;
}

View File

@ -17,7 +17,8 @@
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Contributor(s):
* travis@netscape.com
*/
#ifndef nsDOMWindowList_h___
#define nsDOMWindowList_h___
@ -27,14 +28,15 @@
#include "nsIScriptObjectOwner.h"
#include "nsString.h"
class nsIWebShell;
class nsIDocShellTreeNode;
class nsIDocShell;
class nsIDOMWindow;
class nsDOMWindowList : public nsIDOMWindowCollection,
public nsIScriptObjectOwner
{
public:
nsDOMWindowList(nsIWebShell *aWebShell);
nsDOMWindowList(nsIDocShell *aDocShell);
virtual ~nsDOMWindowList();
NS_DECL_ISUPPORTS
@ -49,10 +51,10 @@ public:
NS_IMETHOD SetScriptObject(void *aScriptObject);
//local methods
NS_IMETHOD SetWebShell(nsIWebShell* aWebShell);
NS_IMETHOD SetDocShell(nsIDocShell* aDocShell);
protected:
nsIWebShell *mWebShell;
nsIDocShellTreeNode* mDocShellNode; //Weak Reference
void *mScriptObject;
};

View File

@ -55,6 +55,8 @@
#include "nsIBrowserWindow.h"
#include "nsIWebShell.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeNode.h"
#include "nsIDocShellTreeItem.h"
#include "nsIBaseWindow.h"
#include "nsIScriptGlobalObjectOwner.h"
#include "nsIDocument.h"
@ -381,6 +383,7 @@ GlobalWindowImpl::SetNewDocument(nsIDOMDocument *aDocument)
NS_IMETHODIMP
GlobalWindowImpl::SetWebShell(nsIWebShell *aWebShell)
{
nsCOMPtr<nsIDocShell> aDocShell(do_QueryInterface(aWebShell));
//mWebShell isn't refcnt'd here. WebShell calls SetWebShell(nsnull) when deleted.
// When SetWebShell(nsnull) is called, drop our references to the
@ -410,7 +413,7 @@ GlobalWindowImpl::SetWebShell(nsIWebShell *aWebShell)
mHistory->SetWebShell(aWebShell);
}
if (nsnull != mFrames) {
mFrames->SetWebShell(aWebShell);
mFrames->SetDocShell(aDocShell);
}
if (mWebShell) {
@ -690,12 +693,18 @@ GlobalWindowImpl::GetParent(nsIDOMWindow** aParent)
if(!mWebShell)
return NS_OK;
nsCOMPtr<nsIWebShell> parentWebShell;
mWebShell->GetParent(*getter_AddRefs(parentWebShell));
if(parentWebShell)
NS_ENSURE_SUCCESS(WebShellToDOMWindow(parentWebShell, aParent),
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mWebShell));
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocShellTreeItem> parent;
docShellAsItem->GetSameTypeParent(getter_AddRefs(parent));
if(parent)
{
nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(parent));
NS_ENSURE_SUCCESS(CallQueryInterface(globalObject.get(), aParent),
NS_ERROR_FAILURE);
}
else
{
*aParent = NS_STATIC_CAST(nsIDOMWindow*, this);
@ -725,11 +734,13 @@ GlobalWindowImpl::GetTop(nsIDOMWindow** aTop)
*aTop = nsnull;
if (nsnull != mWebShell) {
nsIWebShell *rootWebShell;
mWebShell->GetRootWebShell(rootWebShell);
if (nsnull != rootWebShell) {
WebShellToDOMWindow(rootWebShell, aTop);
NS_RELEASE(rootWebShell);
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mWebShell));
nsCOMPtr<nsIDocShellTreeItem> root;
docShellAsItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
if (root) {
nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(root));
CallQueryInterface(globalObject.get(), aTop);
}
}
@ -769,8 +780,9 @@ GlobalWindowImpl::GetClosed(PRBool* aClosed)
NS_IMETHODIMP
GlobalWindowImpl::GetFrames(nsIDOMWindowCollection** aFrames)
{
if ((nsnull == mFrames) && (nsnull != mWebShell)) {
mFrames = new nsDOMWindowList(mWebShell);
nsCOMPtr<nsIDocShell> mDocShell(do_QueryInterface(mWebShell));
if ((nsnull == mFrames) && (mDocShell)) {
mFrames = new nsDOMWindowList(mDocShell);
if (nsnull == mFrames) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -840,9 +852,10 @@ GlobalWindowImpl::SetDefaultStatus(const nsString& aDefaultStatus)
NS_IMETHODIMP
GlobalWindowImpl::GetName(nsString& aName)
{
const PRUnichar *name = nsnull;
if (nsnull != mWebShell) {
mWebShell->GetName(&name);
nsXPIDLString name;
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mWebShell));
if (docShellAsItem) {
docShellAsItem->GetName(getter_Copies(name));
}
aName = name;
return NS_OK;
@ -852,8 +865,9 @@ NS_IMETHODIMP
GlobalWindowImpl::SetName(const nsString& aName)
{
nsresult result = NS_OK;
if (nsnull != mWebShell) {
result = mWebShell->SetName(aName.GetUnicode());
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mWebShell));
if (docShellAsItem) {
result = docShellAsItem->SetName(aName.GetUnicode());
}
return result;
}
@ -1764,7 +1778,7 @@ GlobalWindowImpl::DropTimeout(nsTimeoutImpl *aTimeout,
if (--aTimeout->ref_count > 0) {
return;
}
if (!aContext)
aContext = mContext;
if (aContext) {
@ -2304,11 +2318,13 @@ GlobalWindowImpl::OpenInternal(JSContext *cx,
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocShellTreeItem> newShellAsItem(do_QueryInterface(newOuterShell));
NS_ASSERTION(newShellAsItem, "We got a shell that isn't an item!");
if (nameSpecified) {
newOuterShell->SetName(name.GetUnicode());
newShellAsItem->SetName(name.GetUnicode());
}
else {
newOuterShell->SetName(nsnull);
newShellAsItem->SetName(nsnull);
}
newOuterShell->LoadURL(mAbsURL.GetUnicode());
SizeAndShowOpenedWebShell(newOuterShell, options, windowIsNew, aDialog);
@ -2830,9 +2846,10 @@ GlobalWindowImpl::GetProperty(JSContext *aContext, jsval aID, jsval *aVp)
else if (PL_strcmp("title", cString) == 0) {
if (mWebShell) {
// See if we're a chrome shell.
nsWebShellType type;
mWebShell->GetWebShellType(type);
if (type == nsWebShellChrome) {
PRInt32 type;
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mWebShell));
docShellAsItem->GetItemType(&type);
if (type == nsIDocShellTreeItem::typeChrome) {
nsCOMPtr<nsIBrowserWindow> browser;
if (NS_OK == GetBrowserWindowInterface(*getter_AddRefs(browser)) && browser) {
// We got a browser window interface
@ -2886,9 +2903,10 @@ GlobalWindowImpl::SetProperty(JSContext *aContext, jsval aID, jsval *aVp)
else if (PL_strcmp("title", cString) == 0) {
if (mWebShell) {
// See if we're a chrome shell.
nsWebShellType type;
mWebShell->GetWebShellType(type);
if (type == nsWebShellChrome) {
PRInt32 type;
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mWebShell));
docShellAsItem->GetItemType(&type);
if (type == nsIDocShellTreeItem::typeChrome) {
nsCOMPtr<nsIBrowserWindow> browser;
if (NS_OK == GetBrowserWindowInterface(*getter_AddRefs(browser)) && browser) {
// We got a browser window interface
@ -2924,11 +2942,13 @@ GlobalWindowImpl::Resolve(JSContext *aContext, jsval aID)
JSVAL_NULL, nsnull, nsnull, 0);
}
else if (nsnull != mWebShell) {
nsCOMPtr<nsIDocShellTreeNode> docShellAsNode(do_QueryInterface(mWebShell));
PRInt32 count;
if (NS_SUCCEEDED(mWebShell->GetChildCount(count)) && count) {
nsIWebShell *child = nsnull;
nsAutoString name(JS_GetStringBytes(JS_ValueToString(aContext, aID)));
if (NS_SUCCEEDED(mWebShell->FindChildWithName(name.GetUnicode(), child))) {
if (NS_SUCCEEDED(docShellAsNode->GetChildCount(&count)) && count) {
nsCOMPtr<nsIDocShellTreeItem> child;
nsAutoString name(JS_GetStringBytes(JS_ValueToString(aContext, aID)));
if (NS_SUCCEEDED(docShellAsNode->FindChildWithName(name.GetUnicode(),
PR_FALSE, nsnull, getter_AddRefs(child)))) {
if (child) {
JSObject *childObj;
//We found a subframe of the right name. The rest of this is to get its script object.
@ -2950,7 +2970,6 @@ GlobalWindowImpl::Resolve(JSContext *aContext, jsval aID)
JS_GetStringBytes(JS_ValueToString(aContext, aID)),
OBJECT_TO_JSVAL(childObj), nsnull, nsnull, 0);
}
NS_RELEASE(child);
}
}
}
@ -3541,31 +3560,31 @@ NS_IMETHODIMP
GlobalWindowImpl::GetPrivateParent(nsPIDOMWindow** aParent)
{
nsCOMPtr<nsIDOMWindow> parent;
*aParent = nsnull; // Set to null so we can bail out later
GetParent(getter_AddRefs(parent));
if(NS_STATIC_CAST(nsIDOMWindow*, this) == parent.get())
{
nsCOMPtr<nsIContent> chromeElement(do_QueryInterface(mChromeEventHandler));
if(chromeElement)
{
nsCOMPtr<nsIDocument> doc;
NS_ENSURE_SUCCESS(chromeElement->GetDocument(*getter_AddRefs(doc)),
NS_ERROR_FAILURE);
if(!chromeElement)
return NS_OK; // This is ok, just means a null parent.
nsCOMPtr<nsIScriptGlobalObject> globalObject;
doc->GetScriptGlobalObject(getter_AddRefs(globalObject));
NS_ENSURE_TRUE(globalObject, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocument> doc;
chromeElement->GetDocument(*getter_AddRefs(doc));
if(!doc)
return NS_OK; // This is ok, just means a null parent.
parent = do_QueryInterface(globalObject);
}
else
parent = nsnull;
nsCOMPtr<nsIScriptGlobalObject> globalObject;
doc->GetScriptGlobalObject(getter_AddRefs(globalObject));
if(!globalObject)
return NS_OK; // This is ok, just means a null parent.
parent = do_QueryInterface(globalObject);
}
if(parent)
NS_ENSURE_SUCCESS(CallQueryInterface(parent.get(), aParent), NS_ERROR_FAILURE);
else
*aParent = nsnull;
CallQueryInterface(parent.get(), aParent);
return NS_OK;
}