зеркало из https://github.com/mozilla/gecko-dev.git
Bug 444546 - Don't dispatch progress event more often than every 350msec, r+sr=sicking
This commit is contained in:
Родитель
c05203160f
Коммит
15b52ddb80
|
@ -143,6 +143,8 @@
|
|||
#define NS_BADCERTHANDLER_CONTRACTID \
|
||||
"@mozilla.org/content/xmlhttprequest-bad-cert-handler;1"
|
||||
|
||||
#define NS_PROGRESS_EVENT_INTERVAL 350
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMEventListenerWrapper)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEventListenerWrapper)
|
||||
|
@ -1042,7 +1044,11 @@ nsAccessControlLRUCache* nsXMLHttpRequest::sAccessControlCache = nsnull;
|
|||
nsXMLHttpRequest::nsXMLHttpRequest()
|
||||
: mRequestObserver(nsnull), mState(XML_HTTP_REQUEST_UNINITIALIZED),
|
||||
mUploadTransferred(0), mUploadTotal(0), mUploadComplete(PR_TRUE),
|
||||
mErrorLoad(PR_FALSE), mFirstStartRequestSeen(PR_FALSE)
|
||||
mUploadProgress(0), mUploadProgressMax(0),
|
||||
mErrorLoad(PR_FALSE), mTimerIsActive(PR_FALSE),
|
||||
mProgressEventWasDelayed(PR_FALSE),
|
||||
mLoadLengthComputable(PR_FALSE), mLoadTotal(0),
|
||||
mFirstStartRequestSeen(PR_FALSE)
|
||||
{
|
||||
nsLayoutStatics::AddRef();
|
||||
}
|
||||
|
@ -1215,6 +1221,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLHttpRequest)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XMLHttpRequest)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
|
||||
|
||||
|
@ -1487,6 +1494,7 @@ nsXMLHttpRequest::Abort()
|
|||
mACGetChannel->Cancel(NS_BINDING_ABORTED);
|
||||
}
|
||||
mResponseXML = nsnull;
|
||||
PRUint32 responseLength = mResponseBody.Length();
|
||||
mResponseBody.Truncate();
|
||||
mState |= XML_HTTP_REQUEST_ABORTED;
|
||||
|
||||
|
@ -1498,7 +1506,8 @@ nsXMLHttpRequest::Abort()
|
|||
|
||||
if (!(mState & XML_HTTP_REQUEST_SYNCLOOPING)) {
|
||||
NS_NAMED_LITERAL_STRING(abortStr, ABORT_STR);
|
||||
DispatchProgressEvent(this, abortStr, PR_FALSE, mResponseBody.Length(), 0);
|
||||
DispatchProgressEvent(this, abortStr, mLoadLengthComputable, responseLength,
|
||||
mLoadTotal);
|
||||
if (mUpload && !mUploadComplete) {
|
||||
mUploadComplete = PR_TRUE;
|
||||
DispatchProgressEvent(mUpload, abortStr, PR_TRUE, mUploadTransferred,
|
||||
|
@ -2037,7 +2046,7 @@ IsSameOrBaseChannel(nsIRequest* aPossibleBase, nsIChannel* aChannel)
|
|||
NS_IMETHODIMP
|
||||
nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||
{
|
||||
nsresult rv;
|
||||
nsresult rv = NS_OK;
|
||||
if (!mFirstStartRequestSeen && mRequestObserver) {
|
||||
mFirstStartRequestSeen = PR_TRUE;
|
||||
mRequestObserver->OnStartRequest(request, ctxt);
|
||||
|
@ -2181,6 +2190,14 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// We won't get any progress events anyway if we didn't have progress
|
||||
// events when starting the request - so maybe no need to start timer here.
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
(mState & XML_HTTP_REQUEST_ASYNC) &&
|
||||
HasListenersFor(NS_LITERAL_STRING(PROGRESS_STR))) {
|
||||
StartProgressEventTimer();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2414,6 +2431,10 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
|||
// By default we don't have any upload, so mark upload complete.
|
||||
mUploadComplete = PR_TRUE;
|
||||
mErrorLoad = PR_FALSE;
|
||||
mLoadLengthComputable = PR_FALSE;
|
||||
mLoadTotal = 0;
|
||||
mUploadProgress = 0;
|
||||
mUploadProgressMax = 0;
|
||||
if (aBody && httpChannel && !method.EqualsLiteral("GET")) {
|
||||
nsXPIDLString serial;
|
||||
nsCOMPtr<nsIInputStream> postDataStream;
|
||||
|
@ -2741,6 +2762,11 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (!mUploadComplete &&
|
||||
HasListenersFor(NS_LITERAL_STRING(UPLOADPROGRESS_STR)) ||
|
||||
(mUpload && mUpload->HasListenersFor(NS_LITERAL_STRING(PROGRESS_STR)))) {
|
||||
StartProgressEventTimer();
|
||||
}
|
||||
DispatchProgressEvent(this, NS_LITERAL_STRING(LOADSTART_STR), PR_FALSE,
|
||||
0, 0);
|
||||
if (mUpload && !mUploadComplete) {
|
||||
|
@ -3047,6 +3073,12 @@ nsXMLHttpRequest::ChangeState(PRUint32 aState, PRBool aBroadcast)
|
|||
mState |= aState;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mProgressNotifier &&
|
||||
!(aState & (XML_HTTP_REQUEST_LOADED | XML_HTTP_REQUEST_INTERACTIVE))) {
|
||||
mTimerIsActive = PR_FALSE;
|
||||
mProgressNotifier->Cancel();
|
||||
}
|
||||
|
||||
if ((mState & XML_HTTP_REQUEST_ASYNC) &&
|
||||
(aState & XML_HTTP_REQUEST_LOADSTATES) && // Broadcast load states only
|
||||
aBroadcast) {
|
||||
|
@ -3125,16 +3157,28 @@ nsXMLHttpRequest::OnProgress(nsIRequest *aRequest, nsISupports *aContext, PRUint
|
|||
total -= headerSize;
|
||||
}
|
||||
mUploadTransferred = loaded;
|
||||
mUploadProgress = aProgress;
|
||||
mUploadProgressMax = aProgressMax;
|
||||
} else {
|
||||
mLoadLengthComputable = lengthComputable;
|
||||
mLoadTotal = mLoadLengthComputable ? total : 0;
|
||||
}
|
||||
|
||||
if (mTimerIsActive) {
|
||||
// The progress event will be dispatched when the notifier calls Notify().
|
||||
mProgressEventWasDelayed = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!mErrorLoad) {
|
||||
StartProgressEventTimer();
|
||||
NS_NAMED_LITERAL_STRING(progress, PROGRESS_STR);
|
||||
NS_NAMED_LITERAL_STRING(uploadprogress, UPLOADPROGRESS_STR);
|
||||
DispatchProgressEvent(this, upload ? uploadprogress : progress, PR_TRUE,
|
||||
lengthComputable, loaded, lengthComputable ? total : 0,
|
||||
aProgress, aProgressMax);
|
||||
|
||||
if (upload && mUpload) {
|
||||
if (upload && mUpload && !mUploadComplete) {
|
||||
NS_WARN_IF_FALSE(mUploadTotal == PRUint32(total), "Wrong upload total?");
|
||||
DispatchProgressEvent(mUpload, progress, PR_TRUE, lengthComputable, loaded,
|
||||
lengthComputable ? total : 0, aProgress, aProgressMax);
|
||||
|
@ -3248,6 +3292,56 @@ nsXMLHttpRequest::GetUpload(nsIXMLHttpRequestUpload** aUpload)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXMLHttpRequest::Notify(nsITimer* aTimer)
|
||||
{
|
||||
mTimerIsActive = PR_FALSE;
|
||||
if (NS_SUCCEEDED(CheckInnerWindowCorrectness()) && !mErrorLoad) {
|
||||
if (mProgressEventWasDelayed) {
|
||||
mProgressEventWasDelayed = PR_FALSE;
|
||||
if (!(XML_HTTP_REQUEST_MPART_HEADERS & mState)) {
|
||||
StartProgressEventTimer();
|
||||
// We're uploading if our state is XML_HTTP_REQUEST_OPENED or
|
||||
// XML_HTTP_REQUEST_SENT
|
||||
if ((XML_HTTP_REQUEST_OPENED | XML_HTTP_REQUEST_SENT) & mState) {
|
||||
DispatchProgressEvent(this, NS_LITERAL_STRING(UPLOADPROGRESS_STR),
|
||||
PR_TRUE, PR_TRUE, mUploadTransferred,
|
||||
mUploadTotal, mUploadProgress,
|
||||
mUploadProgressMax);
|
||||
if (mUpload && !mUploadComplete) {
|
||||
DispatchProgressEvent(mUpload, NS_LITERAL_STRING(PROGRESS_STR),
|
||||
PR_TRUE, PR_TRUE, mUploadTransferred,
|
||||
mUploadTotal, mUploadProgress,
|
||||
mUploadProgressMax);
|
||||
}
|
||||
} else {
|
||||
DispatchProgressEvent(this, NS_LITERAL_STRING(PROGRESS_STR),
|
||||
mLoadLengthComputable, mResponseBody.Length(),
|
||||
mLoadTotal);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (mProgressNotifier) {
|
||||
mProgressNotifier->Cancel();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLHttpRequest::StartProgressEventTimer()
|
||||
{
|
||||
if (!mProgressNotifier) {
|
||||
mProgressNotifier = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
}
|
||||
if (mProgressNotifier) {
|
||||
mProgressEventWasDelayed = PR_FALSE;
|
||||
mTimerIsActive = PR_TRUE;
|
||||
mProgressNotifier->Cancel();
|
||||
mProgressNotifier->InitWithCallback(this, NS_PROGRESS_EVENT_INTERVAL,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsXMLHttpRequest::nsHeaderVisitor, nsIHttpHeaderVisitor)
|
||||
|
||||
NS_IMETHODIMP nsXMLHttpRequest::
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "prtime.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsDOMProgressEvent.h"
|
||||
|
||||
|
@ -251,7 +252,8 @@ class nsXMLHttpRequest : public nsXHREventTarget,
|
|||
public nsIProgressEventSink,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsSupportsWeakReference,
|
||||
public nsIJSNativeInitializer
|
||||
public nsIJSNativeInitializer,
|
||||
public nsITimerCallback
|
||||
{
|
||||
public:
|
||||
nsXMLHttpRequest();
|
||||
|
@ -293,6 +295,9 @@ public:
|
|||
// nsIInterfaceRequestor
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
// nsITimerCallback
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
// nsIJSNativeInitializer
|
||||
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
|
||||
PRUint32 argc, jsval* argv);
|
||||
|
@ -394,6 +399,8 @@ protected:
|
|||
*/
|
||||
nsresult CheckChannelForCrossSiteRequest(nsIChannel* aChannel);
|
||||
|
||||
void StartProgressEventTimer();
|
||||
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
@ -445,9 +452,17 @@ protected:
|
|||
PRUint32 mUploadTransferred;
|
||||
PRUint32 mUploadTotal;
|
||||
PRPackedBool mUploadComplete;
|
||||
PRUint64 mUploadProgress; // For legacy
|
||||
PRUint64 mUploadProgressMax; // For legacy
|
||||
|
||||
PRPackedBool mErrorLoad;
|
||||
|
||||
PRPackedBool mTimerIsActive;
|
||||
PRPackedBool mProgressEventWasDelayed;
|
||||
PRPackedBool mLoadLengthComputable;
|
||||
PRUint32 mLoadTotal; // 0 if not known.
|
||||
nsCOMPtr<nsITimer> mProgressNotifier;
|
||||
|
||||
PRPackedBool mFirstStartRequestSeen;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче