Bug 535926, async onload blocker, r=bz, sr=sicking

--HG--
extra : rebase_source : 9ca210a9b1d88d6791ff33e756fd64d6571f7462
This commit is contained in:
Olli Pettay 2010-04-27 12:48:52 +03:00
Родитель 495683a51b
Коммит cf4834d6fe
2 изменённых файлов: 32 добавлений и 2 удалений

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

@ -7172,6 +7172,15 @@ nsDocument::EnsureOnloadBlocker()
} }
} }
void
nsDocument::AsyncBlockOnload()
{
while (mAsyncOnloadBlockCount) {
--mAsyncOnloadBlockCount;
BlockOnload();
}
}
void void
nsDocument::BlockOnload() nsDocument::BlockOnload()
{ {
@ -7183,6 +7192,16 @@ nsDocument::BlockOnload()
// If mScriptGlobalObject is null, we shouldn't be messing with the loadgroup // If mScriptGlobalObject is null, we shouldn't be messing with the loadgroup
// -- it's not ours. // -- it's not ours.
if (mOnloadBlockCount == 0 && mScriptGlobalObject) { if (mOnloadBlockCount == 0 && mScriptGlobalObject) {
if (!nsContentUtils::IsSafeToRunScript()) {
// Because AddRequest may lead to OnStateChange calls in chrome,
// block onload only when there are no script blockers.
++mAsyncOnloadBlockCount;
if (mAsyncOnloadBlockCount == 1) {
nsContentUtils::AddScriptRunner(
NS_NEW_RUNNABLE_METHOD(nsDocument, this, AsyncBlockOnload));
}
return;
}
nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup(); nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
if (loadGroup) { if (loadGroup) {
loadGroup->AddRequest(mOnloadBlocker, nsnull); loadGroup->AddRequest(mOnloadBlocker, nsnull);
@ -7199,7 +7218,7 @@ nsDocument::UnblockOnload(PRBool aFireSync)
return; return;
} }
if (mOnloadBlockCount == 0) { if (mOnloadBlockCount == 0 && mAsyncOnloadBlockCount == 0) {
NS_NOTREACHED("More UnblockOnload() calls than BlockOnload() calls; dropping call"); NS_NOTREACHED("More UnblockOnload() calls than BlockOnload() calls; dropping call");
return; return;
} }
@ -7209,7 +7228,7 @@ nsDocument::UnblockOnload(PRBool aFireSync)
// If mScriptGlobalObject is null, we shouldn't be messing with the loadgroup // If mScriptGlobalObject is null, we shouldn't be messing with the loadgroup
// -- it's not ours. // -- it's not ours.
if (mOnloadBlockCount == 0 && mScriptGlobalObject) { if (mOnloadBlockCount == 0 && mScriptGlobalObject) {
if (aFireSync) { if (aFireSync && mAsyncOnloadBlockCount == 0) {
// Increment mOnloadBlockCount, since DoUnblockOnload will decrement it // Increment mOnloadBlockCount, since DoUnblockOnload will decrement it
++mOnloadBlockCount; ++mOnloadBlockCount;
DoUnblockOnload(); DoUnblockOnload();
@ -7260,6 +7279,11 @@ nsDocument::DoUnblockOnload()
return; return;
} }
if (mAsyncOnloadBlockCount != 0) {
// We need to wait until the async onload block has been handled.
PostUnblockOnloadEvent();
}
// If mScriptGlobalObject is null, we shouldn't be messing with the loadgroup // If mScriptGlobalObject is null, we shouldn't be messing with the loadgroup
// -- it's not ours. // -- it's not ours.
if (mScriptGlobalObject) { if (mScriptGlobalObject) {

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

@ -944,6 +944,9 @@ public:
virtual void RegisterFileDataUri(nsACString& aUri); virtual void RegisterFileDataUri(nsACString& aUri);
// Only BlockOnload should call this!
void AsyncBlockOnload();
protected: protected:
friend class nsNodeUtils; friend class nsNodeUtils;
void RegisterNamedItems(nsIContent *aContent); void RegisterNamedItems(nsIContent *aContent);
@ -1174,7 +1177,10 @@ private:
// 2) We haven't had Destroy() called on us yet. // 2) We haven't had Destroy() called on us yet.
nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState; nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
// Currently active onload blockers
PRUint32 mOnloadBlockCount; PRUint32 mOnloadBlockCount;
// Onload blockers which haven't been activated yet
PRUint32 mAsyncOnloadBlockCount;
nsCOMPtr<nsIRequest> mOnloadBlocker; nsCOMPtr<nsIRequest> mOnloadBlocker;
ReadyState mReadyState; ReadyState mReadyState;