fix for bug 73640 - make uri loader support "true" weak references so we can implement them from JavaScript

sr=mscott
r=jag


git-svn-id: svn://10.0.0.236/trunk@90665 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
alecf%netscape.com
2001-03-28 18:09:03 +00:00
parent 326874f76b
commit 4ebe32a8dd
6 changed files with 68 additions and 39 deletions

View File

@@ -891,7 +891,9 @@ nsPSMComponent::HandleContent(const char * aContentType,
return NS_ERROR_FAILURE;
}
NS_IMPL_ISUPPORTS(CertContentListener, NS_GET_IID(nsIURIContentListener));
NS_IMPL_ISUPPORTS2(CertContentListener,
nsIURIContentListener,
nsISupportsWeakReference);
CertContentListener::CertContentListener()

View File

@@ -47,7 +47,9 @@
// Now we need a content listener to register
//--------------------------------------------
class CertContentListener : public nsIURIContentListener {
class CertContentListener : public nsIURIContentListener,
public nsSupportsWeakReference
{
public:
CertContentListener();
virtual ~CertContentListener();

View File

@@ -55,7 +55,10 @@
static NS_DEFINE_CID(kTransactionManagerCID, NS_TRANSACTIONMANAGER_CID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
NS_IMPL_THREADSAFE_ISUPPORTS2(nsMsgWindow, nsIMsgWindow, nsIURIContentListener)
NS_IMPL_THREADSAFE_ISUPPORTS3(nsMsgWindow,
nsIMsgWindow,
nsIURIContentListener,
nsISupportsWeakReference)
nsMsgWindow::nsMsgWindow()
{

View File

@@ -34,7 +34,10 @@
#include "nsCOMPtr.h"
class nsMsgWindow : public nsIMsgWindow, public nsIURIContentListener {
class nsMsgWindow : public nsIMsgWindow,
public nsIURIContentListener,
public nsSupportsWeakReference
{
public:

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
@@ -42,7 +42,6 @@
#include "nsIDocShellTreeItem.h"
#include "nsIDocShellTreeOwner.h"
#include "nsVoidArray.h"
#include "nsXPIDLString.h"
#include "nsString.h"
@@ -455,7 +454,7 @@ nsresult nsDocumentOpenInfo::RetargetOutput(nsIRequest *request, const char * aS
nsURILoader::nsURILoader()
{
NS_INIT_ISUPPORTS();
m_listeners = new nsVoidArray();
NS_NewISupportsArray(getter_AddRefs(m_listeners));
// Check pref to see if we should prevent frameset spoofing
mValidateOrigin = PR_TRUE; // secure by default, pref disables check
@@ -467,8 +466,6 @@ nsURILoader::nsURILoader()
nsURILoader::~nsURILoader()
{
if (m_listeners)
delete m_listeners;
}
NS_IMPL_ADDREF(nsURILoader);
@@ -482,18 +479,25 @@ NS_INTERFACE_MAP_END
NS_IMETHODIMP nsURILoader::RegisterContentListener(nsIURIContentListener * aContentListener)
{
nsresult rv = NS_OK;
if (m_listeners)
m_listeners->AppendElement(aContentListener);
else
rv = NS_ERROR_FAILURE;
if (!m_listeners) return NS_ERROR_FAILURE;
nsWeakPtr weakListener = do_GetWeakReference(aContentListener);
NS_ASSERTION(weakListener, "your URIContentListener must support weak refs!\n");
if (weakListener)
m_listeners->AppendElement(weakListener);
return rv;
}
NS_IMETHODIMP nsURILoader::UnRegisterContentListener(nsIURIContentListener * aContentListener)
{
if (m_listeners)
m_listeners->RemoveElement(aContentListener);
if (!m_listeners) return NS_OK;
nsWeakPtr weakListener = do_GetWeakReference(aContentListener);
if (weakListener)
m_listeners->RemoveElement(weakListener);
return NS_OK;
}
@@ -976,31 +980,35 @@ NS_IMETHODIMP nsURILoader::DispatchContent(const char * aContentType,
NS_ENSURE_ARG(aContentType);
NS_ENSURE_ARG(request);
// okay, now we've discovered the content type. We need to do the following:
// (1) We always start with the original content listener (if any) that originated the request
// and then ask if it can handle the content.
// (2) if it can't, we'll move on to the registered content listeners and give
// them a crack at handling the content.
// (3) if we cannot find a registered content lister to handle the type, then we move on to
// phase II which is to try to find a content handler in the registry for the content type.
// hitting this phase usually means we'll be creating a new window or handing off to an
// external application.
// okay, now we've discovered the content type. We need to do the
// following:
// (1) We always start with the original content listener (if any)
// that originated the request and then ask if it can handle the
// content.
// (2) if it can't, we'll move on to the registered content
// listeners and give them a crack at handling the content.
// (3) if we cannot find a registered content lister to handle the
// type, then we move on to phase II which is to try to find a
// content handler in the registry for the content type.
// hitting this phase usually means we'll be creating a new
// window or handing off to an external application.
nsresult rv = NS_OK;
nsCOMPtr<nsIURIContentListener> listenerToUse = aContentListener;
PRBool skipRetargetingSearch = PR_FALSE;
// How do we determine whether we need to ask any registered content listeners if they
// want a crack at the content?
// (1) if the window target is blank or new, then we don't want to ask...
// How do we determine whether we need to ask any registered content
// listeners if they want a crack at the content?
// (1) if the window target is blank or new, then we don't want to
// ask...
if (!nsCRT::strcasecmp(aWindowTarget, "_blank") || !nsCRT::strcasecmp(aWindowTarget, "_new"))
skipRetargetingSearch = PR_TRUE;
else
{
// (2) if the original content listener is NULL and we have a target name then we
// must not be a window open with that target name so skip the content listener search
// and skip to the part that brings up the new window.
// (2) if the original content listener is NULL and we have a
// target name then we must not be a window open with that
// target name so skip the content listener search and skip to
// the part that brings up the new window.
if (aWindowTarget && *aWindowTarget && !aContentListener)
skipRetargetingSearch = PR_TRUE;
}
@@ -1014,20 +1022,32 @@ NS_IMETHODIMP nsURILoader::DispatchContent(const char * aContentType,
aCommand, aWindowTarget, aContentTypeToUse);
if (!foundContentHandler) // if it can't handle the content, scan through the list of registered listeners
// if it can't handle the content, scan through the list of
// registered listeners
if (!foundContentHandler)
{
PRInt32 i = 0;
// keep looping until we get a content listener back
for(i = 0; i < m_listeners->Count() && !foundContentHandler; i++)
PRUint32 count; m_listeners->Count(&count);
for(i = 0; i < PRInt32(count) && !foundContentHandler; i++)
{
//nsIURIContentListener's aren't refcounted.
nsIURIContentListener * listener =(nsIURIContentListener*)m_listeners->ElementAt(i);
nsWeakPtr weakListener;
m_listeners->QueryElementAt(i, NS_GET_IID(nsIWeakReference),
getter_AddRefs(weakListener));
nsCOMPtr<nsIURIContentListener> listener =
do_QueryReferent(weakListener);
if (listener)
{
foundContentHandler = ShouldHandleContent(listener, aContentType,
aCommand, aWindowTarget, aContentTypeToUse);
if (foundContentHandler)
listenerToUse = listener;
} else {
// remove from the listener list, and reset i
m_listeners->RemoveElementAt(i);
i--;
}
} // for loop
} // if we can't handle the content

View File

@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
@@ -25,12 +25,11 @@
#include "nsCURILoader.h"
#include "nsISupportsUtils.h"
#include "nsISupportsArray.h"
#include "nsCOMPtr.h"
#include "nsIInterfaceRequestor.h"
#include "nsString.h"
class nsVoidArray;
class nsURILoader : public nsIURILoader
{
public:
@@ -43,8 +42,8 @@ public:
protected:
// we shouldn't need to have an owning ref count on registered
// content listeners because they are supposed to unregister themselves
// when they go away.
nsVoidArray * m_listeners;
// when they go away. This array stores weak references
nsCOMPtr<nsISupportsArray> m_listeners;
// If set, we will try to prevent frame spoofing (set by pref in constructor)
PRBool mValidateOrigin;