зеркало из https://github.com/mozilla/gecko-dev.git
Fix bug # 20339: get busy animation back for FTP. r=waterson
This commit is contained in:
Родитель
0aba552bc6
Коммит
f8137540fc
|
@ -17,6 +17,10 @@
|
||||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||||
* Rights Reserved.
|
* Rights Reserved.
|
||||||
*
|
*
|
||||||
|
* Original Author(s):
|
||||||
|
* Chris Waterson <waterson@netscape.com>
|
||||||
|
* Robert John Churchill <rjc@netscape.com>
|
||||||
|
*
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||||
*/
|
*/
|
||||||
|
@ -61,6 +65,8 @@
|
||||||
#include "nsIInterfaceRequestor.h"
|
#include "nsIInterfaceRequestor.h"
|
||||||
#include "iostream.h"
|
#include "iostream.h"
|
||||||
#include "nsITextToSubURI.h"
|
#include "nsITextToSubURI.h"
|
||||||
|
#include "nsITimer.h"
|
||||||
|
#include "nsISupportsArray.h"
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -89,6 +95,7 @@ class nsHTTPIndex : public nsIHTTPIndex, public nsIRDFDataSource
|
||||||
private:
|
private:
|
||||||
static nsIRDFResource *kNC_Child;
|
static nsIRDFResource *kNC_Child;
|
||||||
static nsIRDFResource *kNC_loading;
|
static nsIRDFResource *kNC_loading;
|
||||||
|
static nsIRDFLiteral *kTrueLiteral;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// We grab a reference to the content viewer container (which
|
// We grab a reference to the content viewer container (which
|
||||||
|
@ -98,12 +105,15 @@ protected:
|
||||||
// an OnStartRequest() notification
|
// an OnStartRequest() notification
|
||||||
|
|
||||||
nsCOMPtr<nsIRDFDataSource> mInner;
|
nsCOMPtr<nsIRDFDataSource> mInner;
|
||||||
|
nsCOMPtr<nsISupportsArray> mConnectionList;
|
||||||
|
nsCOMPtr<nsITimer> mTimer;
|
||||||
nsISupports *mContainer; // [WEAK]
|
nsISupports *mContainer; // [WEAK]
|
||||||
nsCString mBaseURL;
|
nsCString mBaseURL;
|
||||||
|
|
||||||
nsHTTPIndex(nsISupports* aContainer);
|
nsHTTPIndex(nsISupports* aContainer);
|
||||||
nsresult Init(nsIURI* aBaseURL);
|
nsresult Init(nsIURI* aBaseURL);
|
||||||
PRBool isWellknownContainerURI(nsIRDFResource *r);
|
PRBool isWellknownContainerURI(nsIRDFResource *r);
|
||||||
|
static void FireTimer(nsITimer* aTimer, void* aClosure);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsHTTPIndex();
|
nsHTTPIndex();
|
||||||
|
@ -198,6 +208,7 @@ PRInt32 gRefCnt = 0;
|
||||||
|
|
||||||
nsIRDFResource *nsHTTPIndex::kNC_Child;
|
nsIRDFResource *nsHTTPIndex::kNC_Child;
|
||||||
nsIRDFResource *nsHTTPIndex::kNC_loading;
|
nsIRDFResource *nsHTTPIndex::kNC_loading;
|
||||||
|
nsIRDFLiteral *nsHTTPIndex::kTrueLiteral;
|
||||||
|
|
||||||
nsrefcnt nsHTTPIndexParser::gRefCntParser = 0;
|
nsrefcnt nsHTTPIndexParser::gRefCntParser = 0;
|
||||||
nsIRDFService* nsHTTPIndexParser::gRDF;
|
nsIRDFService* nsHTTPIndexParser::gRDF;
|
||||||
|
@ -322,6 +333,7 @@ nsHTTPIndexParser::Create(nsHTTPIndex* aHTTPIndex,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsHTTPIndexParser, nsIStreamListener, nsIStreamObserver);
|
NS_IMPL_THREADSAFE_ISUPPORTS2(nsHTTPIndexParser, nsIStreamListener, nsIStreamObserver);
|
||||||
|
|
||||||
|
|
||||||
|
@ -919,7 +931,7 @@ nsHTTPIndexParser::ParseInt(nsIRDFResource *arc, nsString& aValue, nsIRDFNode**
|
||||||
//
|
//
|
||||||
|
|
||||||
nsHTTPIndex::nsHTTPIndex()
|
nsHTTPIndex::nsHTTPIndex()
|
||||||
: mInner(nsnull), mContainer(nsnull)
|
: mInner(nsnull), mContainer(nsnull), mTimer(nsnull), mConnectionList(nsnull)
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
}
|
}
|
||||||
|
@ -927,7 +939,7 @@ nsHTTPIndex::nsHTTPIndex()
|
||||||
|
|
||||||
|
|
||||||
nsHTTPIndex::nsHTTPIndex(nsISupports* aContainer)
|
nsHTTPIndex::nsHTTPIndex(nsISupports* aContainer)
|
||||||
: mInner(nsnull), mContainer(aContainer)
|
: mInner(nsnull), mContainer(aContainer), mTimer(nsnull), mConnectionList(nsnull)
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
}
|
}
|
||||||
|
@ -941,6 +953,18 @@ nsHTTPIndex::~nsHTTPIndex()
|
||||||
NS_IF_RELEASE(kNC_Child);
|
NS_IF_RELEASE(kNC_Child);
|
||||||
NS_IF_RELEASE(kNC_loading);
|
NS_IF_RELEASE(kNC_loading);
|
||||||
|
|
||||||
|
NS_IF_RELEASE(kTrueLiteral);
|
||||||
|
|
||||||
|
if (mTimer)
|
||||||
|
{
|
||||||
|
// be sure to cancel the timer, as it holds a
|
||||||
|
// weak reference back to nsHTTPIndex
|
||||||
|
mTimer->Cancel();
|
||||||
|
mTimer = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
mConnectionList = nsnull;
|
||||||
|
|
||||||
if (gRDF)
|
if (gRDF)
|
||||||
{
|
{
|
||||||
nsServiceManager::ReleaseService(kRDFServiceCID, gRDF);
|
nsServiceManager::ReleaseService(kRDFServiceCID, gRDF);
|
||||||
|
@ -975,9 +999,15 @@ nsHTTPIndex::Init()
|
||||||
gRDF->GetResource(NC_NAMESPACE_URI "child", &kNC_Child);
|
gRDF->GetResource(NC_NAMESPACE_URI "child", &kNC_Child);
|
||||||
gRDF->GetResource(NC_NAMESPACE_URI "loading", &kNC_loading);
|
gRDF->GetResource(NC_NAMESPACE_URI "loading", &kNC_loading);
|
||||||
|
|
||||||
// register this as a named data source with the RDF service
|
rv = gRDF->GetLiteral(NS_ConvertASCIItoUCS2("true").GetUnicode(), &kTrueLiteral);
|
||||||
|
if (NS_FAILED(rv)) return(rv);
|
||||||
|
|
||||||
|
if (NS_FAILED(rv = NS_NewISupportsArray(getter_AddRefs(mConnectionList))))
|
||||||
|
return(rv);
|
||||||
|
|
||||||
|
// (do this last) register this as a named data source with the RDF service
|
||||||
rv = gRDF->RegisterDataSource(this, PR_FALSE);
|
rv = gRDF->RegisterDataSource(this, PR_FALSE);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return(rv);
|
||||||
}
|
}
|
||||||
return(NS_OK);
|
return(NS_OK);
|
||||||
}
|
}
|
||||||
|
@ -1032,7 +1062,7 @@ nsHTTPIndex::Create(nsIURI* aBaseURL, nsISupports* aContainer, nsIHTTPIndex** aR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS2(nsHTTPIndex, nsIHTTPIndex, nsIRDFDataSource);
|
NS_IMPL_THREADSAFE_ISUPPORTS2(nsHTTPIndex, nsIHTTPIndex, nsIRDFDataSource);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1183,47 +1213,6 @@ nsHTTPIndex::GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, PRBo
|
||||||
{
|
{
|
||||||
nsresult rv = NS_ERROR_UNEXPECTED;
|
nsresult rv = NS_ERROR_UNEXPECTED;
|
||||||
|
|
||||||
if (isWellknownContainerURI(aSource) && (aProperty == kNC_Child))
|
|
||||||
{
|
|
||||||
PRBool doNetworkRequest = PR_TRUE;
|
|
||||||
if (NS_SUCCEEDED(rv) && (_retval))
|
|
||||||
{
|
|
||||||
// check and see if we already have data for the search in question;
|
|
||||||
// if we do, BeginSearchRequest() won't bother doing the search again,
|
|
||||||
// otherwise it will kickstart it
|
|
||||||
PRBool hasResults = PR_FALSE;
|
|
||||||
if (NS_SUCCEEDED((*_retval)->HasMoreElements(&hasResults)) && (hasResults == PR_TRUE))
|
|
||||||
{
|
|
||||||
doNetworkRequest = PR_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (doNetworkRequest == PR_TRUE)
|
|
||||||
{
|
|
||||||
const char *uri = nsnull;
|
|
||||||
aSource->GetValueConst(&uri);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> url;
|
|
||||||
if (NS_SUCCEEDED(rv = NS_NewURI(getter_AddRefs(url), uri)))
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIChannel> channel;
|
|
||||||
if (NS_SUCCEEDED(rv = NS_OpenURI(getter_AddRefs(channel), url, nsnull, nsnull)))
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIStreamListener> listener;
|
|
||||||
if (NS_SUCCEEDED(rv = CreateListener(getter_AddRefs(listener))))
|
|
||||||
{
|
|
||||||
if (NS_SUCCEEDED(rv = channel->AsyncRead(listener, aSource)))
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIRDFLiteral> trueLiteral;
|
|
||||||
gRDF->GetLiteral(NS_ConvertASCIItoUCS2("true").GetUnicode(),
|
|
||||||
getter_AddRefs(trueLiteral));
|
|
||||||
rv = mInner->Assert(aSource, kNC_loading, trueLiteral, PR_TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mInner)
|
if (mInner)
|
||||||
{
|
{
|
||||||
rv = mInner->GetTargets(aSource, aProperty, aTruthValue, _retval);
|
rv = mInner->GetTargets(aSource, aProperty, aTruthValue, _retval);
|
||||||
|
@ -1232,9 +1221,119 @@ nsHTTPIndex::GetTargets(nsIRDFResource *aSource, nsIRDFResource *aProperty, PRBo
|
||||||
{
|
{
|
||||||
rv = NS_NewEmptyEnumerator(_retval);
|
rv = NS_NewEmptyEnumerator(_retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isWellknownContainerURI(aSource) && (aProperty == kNC_Child))
|
||||||
|
{
|
||||||
|
PRBool doNetworkRequest = PR_TRUE;
|
||||||
|
if (NS_SUCCEEDED(rv) && (_retval))
|
||||||
|
{
|
||||||
|
// check and see if we already have data for the search in question;
|
||||||
|
// if we do, don't bother doing the search again
|
||||||
|
PRBool hasResults = PR_FALSE;
|
||||||
|
if (NS_SUCCEEDED((*_retval)->HasMoreElements(&hasResults)) &&
|
||||||
|
(hasResults == PR_TRUE))
|
||||||
|
{
|
||||||
|
doNetworkRequest = PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: if we need to do a network request, do it out-of-band
|
||||||
|
// (because the XUL template builder isn't re-entrant)
|
||||||
|
// by using a global connection list and an immediately-firing timer
|
||||||
|
|
||||||
|
if ((doNetworkRequest == PR_TRUE) && (mConnectionList))
|
||||||
|
{
|
||||||
|
PRInt32 connectionIndex = mConnectionList->IndexOf(aSource);
|
||||||
|
if (connectionIndex < 0)
|
||||||
|
{
|
||||||
|
// add aSource into list of connections to make
|
||||||
|
mConnectionList->AppendElement(aSource);
|
||||||
|
|
||||||
|
// if we don't have a timer about to fire, create one
|
||||||
|
// which should fire as soon as possible (out-of-band)
|
||||||
|
if (!mTimer)
|
||||||
|
{
|
||||||
|
mTimer = do_CreateInstance("component://netscape/timer", &rv);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a timer");
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
{
|
||||||
|
mTimer->Init(nsHTTPIndex::FireTimer, this, 1,
|
||||||
|
NS_PRIORITY_LOWEST, NS_TYPE_ONE_SHOT);
|
||||||
|
// Note: don't addref "this" as we'll cancel the
|
||||||
|
// timer in the httpIndex destructor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return(rv);
|
return(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsHTTPIndex::FireTimer(nsITimer* aTimer, void* aClosure)
|
||||||
|
{
|
||||||
|
nsHTTPIndex *httpIndex = NS_STATIC_CAST(nsHTTPIndex *, aClosure);
|
||||||
|
if (!httpIndex) return;
|
||||||
|
|
||||||
|
// Note: process ALL outstanding connection requests;
|
||||||
|
// don't return out of this loop as mTimer needs to be cancelled afterwards
|
||||||
|
if (httpIndex->mConnectionList)
|
||||||
|
{
|
||||||
|
PRUint32 numItems = 0;
|
||||||
|
PRInt32 loop;
|
||||||
|
httpIndex->mConnectionList->Count(&numItems);
|
||||||
|
if (numItems > 0)
|
||||||
|
{
|
||||||
|
for (loop=((PRInt32)numItems)-1; loop>=0; loop--)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISupports> isupports;
|
||||||
|
httpIndex->mConnectionList->GetElementAt((PRUint32)loop, getter_AddRefs(isupports));
|
||||||
|
httpIndex->mConnectionList->RemoveElementAt((PRUint32)loop);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIRDFResource> aSource;
|
||||||
|
if (isupports) aSource = do_QueryInterface(isupports);
|
||||||
|
const char *uri = nsnull;
|
||||||
|
if (aSource) aSource->GetValueConst(&uri);
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
nsCOMPtr<nsIURI> url;
|
||||||
|
if (uri)
|
||||||
|
{
|
||||||
|
rv = NS_NewURI(getter_AddRefs(url), uri);
|
||||||
|
}
|
||||||
|
nsCOMPtr<nsIChannel> channel;
|
||||||
|
if (NS_SUCCEEDED(rv) && (url))
|
||||||
|
{
|
||||||
|
rv = NS_OpenURI(getter_AddRefs(channel), url, nsnull, nsnull);
|
||||||
|
}
|
||||||
|
nsCOMPtr<nsIStreamListener> listener;
|
||||||
|
if (NS_SUCCEEDED(rv) && (channel))
|
||||||
|
{
|
||||||
|
rv = httpIndex->CreateListener(getter_AddRefs(listener));
|
||||||
|
}
|
||||||
|
if (NS_SUCCEEDED(rv) && (listener))
|
||||||
|
{
|
||||||
|
if (NS_SUCCEEDED(rv = channel->AsyncRead(listener, aSource)))
|
||||||
|
{
|
||||||
|
// mark aSource as "loading"
|
||||||
|
rv = httpIndex->mInner->Assert(aSource, kNC_loading, kTrueLiteral, PR_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// after firing off any/all of the connections
|
||||||
|
// be sure to cancel the timer
|
||||||
|
if (httpIndex->mTimer)
|
||||||
|
{
|
||||||
|
// be sure to cancel the timer, as it holds a
|
||||||
|
// weak reference back to nsHTTPIndex
|
||||||
|
httpIndex->mTimer->Cancel();
|
||||||
|
httpIndex->mTimer = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTTPIndex::Assert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget,
|
nsHTTPIndex::Assert(nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget,
|
||||||
PRBool aTruthValue)
|
PRBool aTruthValue)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче