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..36325d187b81481791c2de88e13b3a6af9b96675 100644 |
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp |
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp |
@@ -253,6 +253,10 @@ void FrameLoader::saveScrollState() |
void FrameLoader::dispatchUnloadEvent() |
{ |
+ // If the frame is unloading, the provisional loader should no longer be |
+ // protected. It will be detached soon. |
+ if (m_provisionalDocumentLoader) |
+ m_provisionalDocumentLoader->setProtect(false); |
saveScrollState(); |
if (m_frame->document() && !SVGImage::isInSVGImage(m_frame->document())) |
@@ -686,7 +690,8 @@ void FrameLoader::detachDocumentLoader(RefPtrWillBeMember<DocumentLoader>& loade |
return; |
loader->detachFromFrame(); |
- loader = nullptr; |
+ if (!loader || !loader->frame()) |
+ loader = nullptr; |
} |
void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScriptValue> stateObject, FrameLoadType frameLoadType, HistoryLoadType historyLoadType, ClientRedirectPolicy clientRedirect) |
@@ -992,6 +997,8 @@ void FrameLoader::stopAllLoaders() |
} |
m_frame->document()->suppressLoadEvent(); |
+ // Don't stop loading the provisional loader if it is being protected (i.e. |
+ // it is about to be committed) See prepareForCommit() for more details. |
if (m_provisionalDocumentLoader) |
m_provisionalDocumentLoader->stopLoading(); |
if (m_documentLoader) |
@@ -1062,17 +1069,22 @@ bool FrameLoader::prepareForCommit() |
// we need to abandon the current load. |
if (pdl != m_provisionalDocumentLoader) |
return false; |
+ // detachFromFrame() will abort XHRs that haven't completed, which can |
+ // trigger event listeners for 'abort'. These event listeners might call |
+ // window.stop(), which will in turn detach the provisional document loader. |
+ // At this point, the provisional document loader should not detach, because |
+ // then the FrameLoader would not have any attached DocumentLoaders. |
if (m_documentLoader) { |
FrameNavigationDisabler navigationDisabler(*m_frame); |
+ m_provisionalDocumentLoader->setProtect(true); |
detachDocumentLoader(m_documentLoader); |
+ if (m_provisionalDocumentLoader) |
+ m_provisionalDocumentLoader->setProtect(false); |
} |
- // detachFromFrame() will abort XHRs that haven't completed, which can |
- // trigger event listeners for 'abort'. These event listeners might detach |
- // the frame. |
- // TODO(dcheng): Investigate if this can be moved above the check that |
- // m_provisionalDocumentLoader hasn't changed. |
+ // 'abort' listeners can also detach the frame. |
if (!m_frame->client()) |
return false; |
+ ASSERT(m_provisionalDocumentLoader == pdl); |
// No more events will be dispatched so detach the Document. |
// TODO(yoav): Should we also be nullifying domWindow's document (or domWindow) since the doc is now detached? |
if (m_frame->document()) |