diff --git a/content/xbl/src/nsXBLService.cpp b/content/xbl/src/nsXBLService.cpp index 49b9cefa2e2..9738488ee06 100644 --- a/content/xbl/src/nsXBLService.cpp +++ b/content/xbl/src/nsXBLService.cpp @@ -30,6 +30,7 @@ #include "nsIURI.h" #include "nsIURL.h" #include "nsIChannel.h" +#include "nsIHTTPChannel.h" #include "nsXPIDLString.h" #include "nsIParser.h" #include "nsParserCIID.h" @@ -55,6 +56,65 @@ static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID); static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX What's up with this??? static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID); +// nsXBLStreamListener, a helper class used for +// asynchronous parsing of URLs +/* Header file */ +class nsXBLStreamListener : public nsIStreamListener +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSISTREAMOBSERVER + + nsXBLStreamListener(nsIStreamListener* aInner); + virtual ~nsXBLStreamListener(); + /* additional members */ + nsCOMPtr mInner; +}; + +/* Implementation file */ +NS_IMPL_ISUPPORTS2(nsXBLStreamListener, nsIStreamListener, nsIStreamObserver) + +nsXBLStreamListener::nsXBLStreamListener(nsIStreamListener* aInner) +{ + NS_INIT_ISUPPORTS(); + /* member initializers and constructor code */ + mInner = aInner; +} + +nsXBLStreamListener::~nsXBLStreamListener() +{ + /* destructor code */ +} + +/* void onDataAvailable (in nsIChannel channel, in nsISupports ctxt, in nsIInputStream inStr, in unsigned long sourceOffset, in unsigned long count); */ +NS_IMETHODIMP +nsXBLStreamListener::OnDataAvailable(nsIChannel* aChannel, nsISupports* aCtxt, nsIInputStream* aInStr, + PRUint32 aSourceOffset, PRUint32 aCount) +{ + if (mInner) + return mInner->OnDataAvailable(aChannel, aCtxt, aInStr, aSourceOffset, aCount); + return NS_ERROR_FAILURE; +} + +/* void onStartRequest (in nsIChannel channel, in nsISupports ctxt); */ +NS_IMETHODIMP +nsXBLStreamListener::OnStartRequest(nsIChannel* aChannel, nsISupports* aCtxt) +{ + if (mInner) + return mInner->OnStartRequest(aChannel, aCtxt); + return NS_ERROR_FAILURE; +} + +/* void onStopRequest (in nsIChannel channel, in nsISupports ctxt, in nsresult status, in wstring statusArg); */ +NS_IMETHODIMP +nsXBLStreamListener::OnStopRequest(nsIChannel* aChannel, nsISupports* aCtxt, nsresult aStatus, const PRUnichar* aStatusArg) +{ + if (mInner) + return mInner->OnStopRequest(aChannel, aCtxt, aStatus, aStatusArg); + return NS_ERROR_FAILURE; +} + // nsProxyStream // A helper class used for synchronous parsing of URLs. class nsProxyStream : public nsIInputStream @@ -250,7 +310,6 @@ nsXBLService::LoadBindings(nsIContent* aContent, const nsString& aURL, PRBool aA nsCOMPtr newBinding; nsCAutoString url; url.AssignWithConversion(aURL); if (NS_FAILED(rv = GetBinding(url, getter_AddRefs(newBinding)))) { - NS_ERROR("Failed loading an XBL document for content node."); return rv; } @@ -258,7 +317,7 @@ nsXBLService::LoadBindings(nsIContent* aContent, const nsString& aURL, PRBool aA nsCAutoString str = "Failed to locate XBL binding. XBL is now using id instead of name to reference bindings. Make sure you have switched over. The invalid binding name is: "; str.AppendWithConversion(aURL); NS_ERROR(str); - return NS_ERROR_FAILURE; + return NS_OK; } if (aAugmentFlag) { @@ -606,6 +665,15 @@ nsXBLService::FetchBindingDocument(nsIURI* aURI, nsIDocument** aResult) return rv; } + nsCOMPtr http(do_QueryInterface(channel)); + if (http) { + // Need to be asynchronous + nsXBLStreamListener* xblListener = new nsXBLStreamListener(listener); + NS_ADDREF(xblListener); + http->AsyncRead(xblListener, nsnull); + return NS_OK; + } + // Now do a blocking synchronous parse of the file. nsCOMPtr in; PRUint32 sourceOffset = 0; diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index f4c3a6b0b9e..2fa75fdb29f 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -7482,7 +7482,9 @@ nsCSSFrameConstructor::ConstructFrameInternal( nsIPresShell* aPresShe return rv; // Load the bindings. - xblService->LoadBindings(aContent, ui->mBehavior, PR_FALSE, getter_AddRefs(binding)); + rv = xblService->LoadBindings(aContent, ui->mBehavior, PR_FALSE, getter_AddRefs(binding)); + if (NS_FAILED(rv)) + return NS_OK; nsCOMPtr baseTag; PRInt32 nameSpaceID; diff --git a/layout/html/style/src/nsCSSFrameConstructor.cpp b/layout/html/style/src/nsCSSFrameConstructor.cpp index f4c3a6b0b9e..2fa75fdb29f 100644 --- a/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -7482,7 +7482,9 @@ nsCSSFrameConstructor::ConstructFrameInternal( nsIPresShell* aPresShe return rv; // Load the bindings. - xblService->LoadBindings(aContent, ui->mBehavior, PR_FALSE, getter_AddRefs(binding)); + rv = xblService->LoadBindings(aContent, ui->mBehavior, PR_FALSE, getter_AddRefs(binding)); + if (NS_FAILED(rv)) + return NS_OK; nsCOMPtr baseTag; PRInt32 nameSpaceID; diff --git a/layout/xbl/src/nsXBLService.cpp b/layout/xbl/src/nsXBLService.cpp index 49b9cefa2e2..9738488ee06 100644 --- a/layout/xbl/src/nsXBLService.cpp +++ b/layout/xbl/src/nsXBLService.cpp @@ -30,6 +30,7 @@ #include "nsIURI.h" #include "nsIURL.h" #include "nsIChannel.h" +#include "nsIHTTPChannel.h" #include "nsXPIDLString.h" #include "nsIParser.h" #include "nsParserCIID.h" @@ -55,6 +56,65 @@ static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID); static NS_DEFINE_CID(kParserCID, NS_PARSER_IID); // XXX What's up with this??? static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID); +// nsXBLStreamListener, a helper class used for +// asynchronous parsing of URLs +/* Header file */ +class nsXBLStreamListener : public nsIStreamListener +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSISTREAMOBSERVER + + nsXBLStreamListener(nsIStreamListener* aInner); + virtual ~nsXBLStreamListener(); + /* additional members */ + nsCOMPtr mInner; +}; + +/* Implementation file */ +NS_IMPL_ISUPPORTS2(nsXBLStreamListener, nsIStreamListener, nsIStreamObserver) + +nsXBLStreamListener::nsXBLStreamListener(nsIStreamListener* aInner) +{ + NS_INIT_ISUPPORTS(); + /* member initializers and constructor code */ + mInner = aInner; +} + +nsXBLStreamListener::~nsXBLStreamListener() +{ + /* destructor code */ +} + +/* void onDataAvailable (in nsIChannel channel, in nsISupports ctxt, in nsIInputStream inStr, in unsigned long sourceOffset, in unsigned long count); */ +NS_IMETHODIMP +nsXBLStreamListener::OnDataAvailable(nsIChannel* aChannel, nsISupports* aCtxt, nsIInputStream* aInStr, + PRUint32 aSourceOffset, PRUint32 aCount) +{ + if (mInner) + return mInner->OnDataAvailable(aChannel, aCtxt, aInStr, aSourceOffset, aCount); + return NS_ERROR_FAILURE; +} + +/* void onStartRequest (in nsIChannel channel, in nsISupports ctxt); */ +NS_IMETHODIMP +nsXBLStreamListener::OnStartRequest(nsIChannel* aChannel, nsISupports* aCtxt) +{ + if (mInner) + return mInner->OnStartRequest(aChannel, aCtxt); + return NS_ERROR_FAILURE; +} + +/* void onStopRequest (in nsIChannel channel, in nsISupports ctxt, in nsresult status, in wstring statusArg); */ +NS_IMETHODIMP +nsXBLStreamListener::OnStopRequest(nsIChannel* aChannel, nsISupports* aCtxt, nsresult aStatus, const PRUnichar* aStatusArg) +{ + if (mInner) + return mInner->OnStopRequest(aChannel, aCtxt, aStatus, aStatusArg); + return NS_ERROR_FAILURE; +} + // nsProxyStream // A helper class used for synchronous parsing of URLs. class nsProxyStream : public nsIInputStream @@ -250,7 +310,6 @@ nsXBLService::LoadBindings(nsIContent* aContent, const nsString& aURL, PRBool aA nsCOMPtr newBinding; nsCAutoString url; url.AssignWithConversion(aURL); if (NS_FAILED(rv = GetBinding(url, getter_AddRefs(newBinding)))) { - NS_ERROR("Failed loading an XBL document for content node."); return rv; } @@ -258,7 +317,7 @@ nsXBLService::LoadBindings(nsIContent* aContent, const nsString& aURL, PRBool aA nsCAutoString str = "Failed to locate XBL binding. XBL is now using id instead of name to reference bindings. Make sure you have switched over. The invalid binding name is: "; str.AppendWithConversion(aURL); NS_ERROR(str); - return NS_ERROR_FAILURE; + return NS_OK; } if (aAugmentFlag) { @@ -606,6 +665,15 @@ nsXBLService::FetchBindingDocument(nsIURI* aURI, nsIDocument** aResult) return rv; } + nsCOMPtr http(do_QueryInterface(channel)); + if (http) { + // Need to be asynchronous + nsXBLStreamListener* xblListener = new nsXBLStreamListener(listener); + NS_ADDREF(xblListener); + http->AsyncRead(xblListener, nsnull); + return NS_OK; + } + // Now do a blocking synchronous parse of the file. nsCOMPtr in; PRUint32 sourceOffset = 0;