Index: third_party/WebKit/Source/core/loader/FrameLoader.cpp |
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp |
index 038cf60a8afc2b21412fab348d49efb7f0661d53..fe7a2985a995f9b3bc04e869811ff08d9b5a711f 100644 |
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp |
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp |
@@ -34,6 +34,8 @@ |
#include "core/loader/FrameLoader.h" |
+#include "base/debug/stack_trace.h" |
+ |
#include "bindings/core/v8/DOMWrapperWorld.h" |
#include "bindings/core/v8/ScriptController.h" |
#include "bindings/core/v8/SerializedScriptValue.h" |
@@ -228,7 +230,7 @@ void FrameLoader::setDefersLoading(bool defers) |
m_deferredHistoryLoad.clear(); |
} |
m_frame->navigationScheduler().startTimer(); |
- scheduleCheckCompleted(); |
+ checkCompleted(0); |
} |
} |
@@ -491,7 +493,7 @@ void FrameLoader::finishedParsing() |
if (client()) |
client()->dispatchDidFinishDocumentLoad(m_documentLoader ? m_documentLoader->isCommittedButEmpty() : true); |
- checkCompleted(); |
+ checkCompleted(1); |
if (!m_frame->view()) |
return; // We are being destroyed by something checkCompleted called. |
@@ -565,21 +567,29 @@ static bool shouldSendCompleteNotification(LocalFrame* frame) |
return frame->loader().documentLoader()->sentDidFinishLoad() && !frame->loader().provisionalDocumentLoader() && !frame->loader().client()->hasPendingNavigation(); |
} |
-void FrameLoader::checkCompleted() |
+void FrameLoader::checkCompletedNow(int) |
{ |
+ // fprintf(stderr, "checkCompletedNow(%p)\n", this); |
+ // base::debug::StackTrace().Print(); |
RefPtrWillBeRawPtr<LocalFrame> protect(m_frame.get()); |
- if (!shouldComplete(m_frame->document())) |
+ if (!shouldComplete(m_frame->document())) { |
+ // fprintf(stderr, "checkCompletedNow(%p): not shouldComplete(0\n", this); |
return; |
+ } |
// OK, completed. |
m_frame->document()->setReadyState(Document::Complete); |
- if (m_frame->document()->loadEventStillNeeded()) |
+ if (m_frame->document()->loadEventStillNeeded()) { |
+ // fprintf(stderr, "checkCompletedNow(%p): implicitClose()\n", this); |
m_frame->document()->implicitClose(); |
+ } |
m_frame->navigationScheduler().startTimer(); |
- if (m_frame->view()) |
+ if (m_frame->view()) { |
+ // fprintf(stderr, "checkCompletedNow(%p): handleLoadCompleted()\n", this); |
m_frame->view()->handleLoadCompleted(); |
+ } |
// The readystatechanged or load event may have disconnected this frame. |
if (!m_frame->client()) |
@@ -587,6 +597,7 @@ void FrameLoader::checkCompleted() |
if (shouldSendFinishNotification(m_frame)) { |
// Report mobile vs. desktop page statistics. This will only report on Android. |
+ // fprintf(stderr, "checkCompletedNow(%p): Finish Notification\n", this); |
if (m_frame->isMainFrame()) |
m_frame->document()->viewportDescription().reportMobilePageStats(m_frame); |
m_documentLoader->setSentDidFinishLoad(); |
@@ -597,6 +608,7 @@ void FrameLoader::checkCompleted() |
} |
if (shouldSendCompleteNotification(m_frame)) { |
+ // fprintf(stderr, "checkCompletedNow(%p): Complete Notification\n", this); |
m_progressTracker->progressCompleted(); |
// Retry restoring scroll offset since finishing loading disables content |
// size clamping. |
@@ -606,9 +618,10 @@ void FrameLoader::checkCompleted() |
m_frame->localDOMWindow()->finishedLoading(); |
} |
+ // fprintf(stderr, "checkCompletedNow(%p): Check Parent Notification\n", this); |
Frame* parent = m_frame->tree().parent(); |
if (parent && parent->isLocalFrame()) |
- toLocalFrame(parent)->loader().checkCompleted(); |
+ toLocalFrame(parent)->loader().checkCompleted(2); |
} |
void FrameLoader::checkTimerFired(Timer<FrameLoader>*) |
@@ -617,13 +630,37 @@ void FrameLoader::checkTimerFired(Timer<FrameLoader>*) |
if (page->defersLoading()) |
return; |
} |
- checkCompleted(); |
+ checkCompletedNow(-1); |
} |
-void FrameLoader::scheduleCheckCompleted() |
+void FrameLoader::checkCompleted(int n) |
{ |
+/* |
+ID Can be sync? |
+0 ? FrameLoader::setDefersLoading(bool defers) |
+1 N FrameLoader::finishedParsing() |
+2 Y FrameLoader::checkCompletedNow |
+3 Y? FrameLoader::loadInSameDocument |
+4 Y? FrameLoader::detach |
+5 N FrameLoader::receivedMainResourceError |
+6 N FrameFetchContext::didLoadResource() - matters |
+7 ? Document::close() |
+8 ? Document::loadEventDelayTimerFired |
+9 ? WebRemoteFrameImpl::didStopLoading() |
+10 ? HTMLImportTreeRoot::stateDidChange() |
+ |
+*/ |
+/* |
+ fprintf(stderr, "checkCompleted(%d)\n", n); |
+ if (n == 6) |
+ base::debug::StackTrace().Print(); |
+*/ |
+ if ((1<<2) & (1<<n)) { |
+ checkCompletedNow(-1); |
+ } else { |
if (!m_checkTimer.isActive()) |
m_checkTimer.startOneShot(0, BLINK_FROM_HERE); |
+ } |
} |
Frame* FrameLoader::opener() |
@@ -716,7 +753,7 @@ void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip |
m_documentLoader->initialScrollState().wasScrolledByUser = false; |
- checkCompleted(); |
+ checkCompleted(3); |
m_frame->localDOMWindow()->statePopped(stateObject ? stateObject : SerializedScriptValue::nullValue()); |
@@ -1000,10 +1037,13 @@ void FrameLoader::stopAllLoaders() |
detachDocumentLoader(m_provisionalDocumentLoader); |
+ if (m_checkTimer.isActive()) |
+ checkCompletedNow(-1); |
m_checkTimer.stop(); |
m_frame->navigationScheduler().cancel(); |
m_inStopAllLoaders = false; |
+ // checkCompletedNow(); |
} |
void FrameLoader::didAccessInitialDocument() |
@@ -1203,7 +1243,7 @@ void FrameLoader::detach() |
Frame* parent = m_frame->tree().parent(); |
if (parent && parent->isLocalFrame()) |
- toLocalFrame(parent)->loader().scheduleCheckCompleted(); |
+ toLocalFrame(parent)->loader().checkCompleted(4); |
if (m_progressTracker) { |
m_progressTracker->dispose(); |
m_progressTracker.clear(); |
@@ -1242,7 +1282,7 @@ void FrameLoader::receivedMainResourceError(DocumentLoader* loader, const Resour |
m_progressTracker->progressCompleted(); |
} |
} |
- checkCompleted(); |
+ checkCompleted(5); |
} |
bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType loadType, const KURL& url) |
@@ -1384,6 +1424,10 @@ void FrameLoader::startLoad(FrameLoadRequest& frameLoadRequest, FrameLoadType ty |
detachDocumentLoader(m_provisionalDocumentLoader); |
} |
+ if (m_checkTimer.isActive()) |
+ checkCompletedNow(-1); |
+ m_checkTimer.stop(); |
+ |
// beforeunload fired above, and detaching a DocumentLoader can fire |
// events, which can detach this frame. |
if (!m_frame->host()) |
@@ -1397,6 +1441,9 @@ void FrameLoader::startLoad(FrameLoadRequest& frameLoadRequest, FrameLoadType ty |
InspectorInstrumentation::didStartProvisionalLoad(m_frame); |
m_frame->navigationScheduler().cancel(); |
+ |
+ if (m_checkTimer.isActive()) |
+ checkCompletedNow(-1); |
m_checkTimer.stop(); |
m_loadType = type; |