mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 489259. Grab the parent chain for our OnStateChange calls before we fire onload and possibly change the docshell tree. r=jst
This commit is contained in:
parent
7341083936
commit
453903551e
@ -946,26 +946,33 @@ void nsDocLoader::doStopDocumentLoad(nsIRequest *request,
|
||||
this, buffer.get(), aStatus));
|
||||
#endif /* DEBUG */
|
||||
|
||||
// Firing STATE_STOP|STATE_IS_DOCUMENT will fire onload handlers.
|
||||
// Grab our parent chain before doing that so we can still dispatch
|
||||
// STATE_STOP|STATE_IS_WINDW_STATE_IS_NETWORK to them all, even if
|
||||
// the onload handlers rearrange the docshell tree.
|
||||
WebProgressList list;
|
||||
GatherAncestorWebProgresses(list);
|
||||
|
||||
//
|
||||
// Fire an OnStateChange(...) notification indicating the the
|
||||
// current document has finished loading...
|
||||
//
|
||||
FireOnStateChange(this,
|
||||
request,
|
||||
nsIWebProgressListener::STATE_STOP |
|
||||
nsIWebProgressListener::STATE_IS_DOCUMENT,
|
||||
aStatus);
|
||||
PRInt32 flags = nsIWebProgressListener::STATE_STOP |
|
||||
nsIWebProgressListener::STATE_IS_DOCUMENT;
|
||||
for (PRUint32 i = 0; i < list.Length(); ++i) {
|
||||
list[i]->DoFireOnStateChange(this, request, flags, aStatus);
|
||||
}
|
||||
|
||||
//
|
||||
// Fire a final OnStateChange(...) notification indicating the the
|
||||
// current document has finished loading...
|
||||
//
|
||||
FireOnStateChange(this,
|
||||
request,
|
||||
nsIWebProgressListener::STATE_STOP |
|
||||
nsIWebProgressListener::STATE_IS_WINDOW |
|
||||
nsIWebProgressListener::STATE_IS_NETWORK,
|
||||
aStatus);
|
||||
flags = nsIWebProgressListener::STATE_STOP |
|
||||
nsIWebProgressListener::STATE_IS_WINDOW |
|
||||
nsIWebProgressListener::STATE_IS_NETWORK;
|
||||
for (PRUint32 i = 0; i < list.Length(); ++i) {
|
||||
list[i]->DoFireOnStateChange(this, request, flags, aStatus);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1295,11 +1302,29 @@ void nsDocLoader::FireOnProgressChange(nsDocLoader *aLoadInitiator,
|
||||
}
|
||||
}
|
||||
|
||||
void nsDocLoader::GatherAncestorWebProgresses(WebProgressList& aList)
|
||||
{
|
||||
for (nsDocLoader* loader = this; loader; loader = loader->mParent) {
|
||||
aList.AppendElement(loader);
|
||||
}
|
||||
}
|
||||
|
||||
void nsDocLoader::FireOnStateChange(nsIWebProgress *aProgress,
|
||||
nsIRequest *aRequest,
|
||||
PRInt32 aStateFlags,
|
||||
nsresult aStatus)
|
||||
{
|
||||
WebProgressList list;
|
||||
GatherAncestorWebProgresses(list);
|
||||
for (PRUint32 i = 0; i < list.Length(); ++i) {
|
||||
list[i]->DoFireOnStateChange(aProgress, aRequest, aStateFlags, aStatus);
|
||||
}
|
||||
}
|
||||
|
||||
void nsDocLoader::DoFireOnStateChange(nsIWebProgress * const aProgress,
|
||||
nsIRequest * const aRequest,
|
||||
PRInt32 &aStateFlags,
|
||||
const nsresult aStatus)
|
||||
{
|
||||
//
|
||||
// Remove the STATE_IS_NETWORK bit if necessary.
|
||||
@ -1359,11 +1384,6 @@ void nsDocLoader::FireOnStateChange(nsIWebProgress *aProgress,
|
||||
}
|
||||
|
||||
mListenerInfoList.Compact();
|
||||
|
||||
// Pass the notification up to the parent...
|
||||
if (mParent) {
|
||||
mParent->FireOnStateChange(aProgress, aRequest, aStateFlags, aStatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "pldhash.h"
|
||||
#include "prclist.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
struct nsRequestInfo;
|
||||
struct nsListenerInfo;
|
||||
@ -154,11 +155,29 @@ protected:
|
||||
PRInt64 aTotalProgress,
|
||||
PRInt64 aMaxTotalProgress);
|
||||
|
||||
// This should be at least 2 long since we'll generally always
|
||||
// have the current page and the global docloader on the ancestor
|
||||
// list. But to deal with frames it's better to make it a bit
|
||||
// longer, and it's always a stack temporary so there's no real
|
||||
// reason not to.
|
||||
typedef nsAutoTArray<nsRefPtr<nsDocLoader>, 8> WebProgressList;
|
||||
void GatherAncestorWebProgresses(WebProgressList& aList);
|
||||
|
||||
void FireOnStateChange(nsIWebProgress *aProgress,
|
||||
nsIRequest* request,
|
||||
PRInt32 aStateFlags,
|
||||
nsresult aStatus);
|
||||
|
||||
// The guts of FireOnStateChange, but does not call itself on our ancestors.
|
||||
// The arguments that are const are const so that we can detect cases when
|
||||
// DoFireOnStateChange wants to propagate changes to the next web progress
|
||||
// at compile time. The ones that are not, are references so that such
|
||||
// changes can be propagated.
|
||||
void DoFireOnStateChange(nsIWebProgress * const aProgress,
|
||||
nsIRequest* const request,
|
||||
PRInt32 &aStateFlags,
|
||||
const nsresult aStatus);
|
||||
|
||||
void FireOnStatusChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
|
Loading…
Reference in New Issue
Block a user