Save the user-set notification callbacks when we set ourselves on the channel,

and forward various notifications to them.  Bug 292391, r=biesi, sr=darin, a=asa
This commit is contained in:
bzbarsky%mit.edu 2005-05-06 21:05:26 +00:00
Родитель 7f68836319
Коммит 2bf72b11b7
2 изменённых файлов: 63 добавлений и 5 удалений

Просмотреть файл

@ -1296,6 +1296,9 @@ nsXMLHttpRequest::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult
NS_ENSURE_TRUE(channel, NS_ERROR_UNEXPECTED);
channel->SetNotificationCallbacks(nsnull);
mNotificationCallbacks = nsnull;
mChannelEventSink = nsnull;
mProgressEventSink = nsnull;
if (NS_FAILED(status)) {
// This can happen if the server is unreachable. Other possible
@ -1534,6 +1537,7 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
}
// Hook us up to listen to redirects and the like
mChannel->GetNotificationCallbacks(getter_AddRefs(mNotificationCallbacks));
mChannel->SetNotificationCallbacks(this);
nsCOMPtr<nsIStreamListener> listener;
@ -1839,6 +1843,14 @@ nsXMLHttpRequest::OnChannelRedirect(nsIChannel *aOldChannel,
return rv;
}
if (mChannelEventSink) {
nsresult rv =
mChannelEventSink->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
if (NS_FAILED(rv)) {
return rv;
}
}
mChannel = aNewChannel;
return NS_OK;
@ -1851,8 +1863,7 @@ nsXMLHttpRequest::OnChannelRedirect(nsIChannel *aOldChannel,
NS_IMETHODIMP
nsXMLHttpRequest::OnProgress(nsIRequest *aRequest, nsISupports *aContext, PRUint64 aProgress, PRUint64 aProgressMax)
{
if (mOnProgressListener)
{
if (mOnProgressListener) {
nsCOMPtr<nsIDOMEvent> event;
nsEvent evt(PR_TRUE, NS_EVENT_NULL); // what name do we make up here?
nsresult rv = CreateEvent(&evt, getter_AddRefs(event));
@ -1866,13 +1877,21 @@ nsXMLHttpRequest::OnProgress(nsIRequest *aRequest, nsISupports *aContext, PRUint
NotifyEventListeners(mOnProgressListener, nsnull, event);
}
if (mProgressEventSink) {
mProgressEventSink->OnProgress(aRequest, aContext, aProgress,
aProgressMax);
}
return NS_OK;
}
NS_IMETHODIMP
nsXMLHttpRequest::OnStatus(nsIRequest *aRequest, nsISupports *aContext, nsresult aStatus, const PRUnichar *aStatusArg)
{
// nothing to do here...
if (mProgressEventSink) {
mProgressEventSink->OnStatus(aRequest, aContext, aStatus, aStatusArg);
}
return NS_OK;
}
@ -1882,8 +1901,34 @@ nsXMLHttpRequest::OnStatus(nsIRequest *aRequest, nsISupports *aContext, nsresult
NS_IMETHODIMP
nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
{
if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
NS_ENSURE_ARG_POINTER(aResult);
// Make sure to return ourselves for the channel event sink interface and
// progress event sink interface, no matter what. We can forward these to
// mNotificationCallbacks if it wants to get notifications for them. But we
// need to see these notifications for proper functioning.
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
mChannelEventSink = do_GetInterface(mNotificationCallbacks);
*aResult = NS_STATIC_CAST(nsIChannelEventSink*, this);
NS_ADDREF_THIS();
return NS_OK;
} else if (aIID.Equals(NS_GET_IID(nsIProgressEventSink))) {
mProgressEventSink = do_GetInterface(mNotificationCallbacks);
*aResult = NS_STATIC_CAST(nsIProgressEventSink*, this);
NS_ADDREF_THIS();
return NS_OK;
}
// Now give mNotificationCallbacks (if non-null) a chance to return the
// desired interface. Note that this means that it can override our
// nsIAuthPrompt impl, but that's fine, if it has a better auth prompt idea.
if (mNotificationCallbacks) {
nsresult rv = mNotificationCallbacks->GetInterface(aIID, aResult);
if (NS_SUCCEEDED(rv)) {
NS_ASSERTION(*aResult, "Lying nsIInterfaceRequestor implementation!");
return rv;
}
}
if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
*aResult = nsnull;
nsresult rv;

Просмотреть файл

@ -176,6 +176,19 @@ protected:
nsCString mOverrideMimeType;
/**
* The notification callbacks the channel had when Send() was
* called. We want to forward things here as needed.
*/
nsCOMPtr<nsIInterfaceRequestor> mNotificationCallbacks;
/**
* Sink interfaces that we implement that mNotificationCallbacks may
* want to also be notified for. These are inited lazily if we're
* asked for the relevant interface.
*/
nsCOMPtr<nsIChannelEventSink> mChannelEventSink;
nsCOMPtr<nsIProgressEventSink> mProgressEventSink;
PRUint32 mState;
};