| Index: Source/core/loader/FrameLoader.cpp
|
| diff --git a/Source/core/loader/FrameLoader.cpp b/Source/core/loader/FrameLoader.cpp
|
| index 304c371f5110d69c71512192e838c482890aecb1..88d994da3e9427334ea4f709df7f5ff61c5bf3d1 100644
|
| --- a/Source/core/loader/FrameLoader.cpp
|
| +++ b/Source/core/loader/FrameLoader.cpp
|
| @@ -267,6 +267,12 @@ void FrameLoader::didExplicitOpen()
|
| m_frame->navigationScheduler().cancel();
|
| }
|
|
|
| +void FrameLoader::didStartForFrame(DocumentLoader* loader)
|
| +{
|
| + if (m_state == FrameStateProvisional && loader == m_provisionalDocumentLoader.get())
|
| + stopDocumentLoaders();
|
| +}
|
| +
|
| void FrameLoader::clear()
|
| {
|
| if (m_stateMachine.creatingInitialEmptyDocument())
|
| @@ -768,6 +774,12 @@ void FrameLoader::reload(ReloadPolicy reloadPolicy, const KURL& overrideURL, con
|
|
|
| void FrameLoader::stopAllLoaders()
|
| {
|
| + stopProvisionalLoaders();
|
| + stopDocumentLoaders();
|
| +}
|
| +
|
| +void FrameLoader::stopProvisionalLoaders()
|
| +{
|
| if (m_frame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal)
|
| return;
|
|
|
| @@ -781,25 +793,46 @@ void FrameLoader::stopAllLoaders()
|
|
|
| m_inStopAllLoaders = true;
|
|
|
| - for (RefPtr<Frame> child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling())
|
| - child->loader().stopAllLoaders();
|
| - if (m_provisionalDocumentLoader)
|
| + if (m_provisionalDocumentLoader) {
|
| m_provisionalDocumentLoader->stopLoading();
|
| - if (m_documentLoader)
|
| - m_documentLoader->stopLoading();
|
| -
|
| - if (m_provisionalDocumentLoader)
|
| m_provisionalDocumentLoader->detachFromFrame();
|
| + }
|
| +
|
| m_provisionalDocumentLoader = 0;
|
|
|
| - m_checkTimer.stop();
|
| + m_inStopAllLoaders = false;
|
| +
|
| + if (m_state == FrameStateProvisional)
|
| + m_client->didStopActiveLoader();
|
| +}
|
| +
|
| +void FrameLoader::stopDocumentLoaders()
|
| +{
|
| + if (m_frame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal)
|
| + return;
|
| +
|
| + // If this method is called from within this method, infinite recursion can occur (3442218). Avoid this.
|
| + if (m_inStopAllLoaders)
|
| + return;
|
| +
|
| + // Calling stopLoading() on the provisional document loader can blow away
|
| + // the frame from underneath.
|
| + RefPtr<Frame> protect(m_frame);
|
| +
|
| + m_inStopAllLoaders = true;
|
| +
|
| + for (RefPtr<Frame> child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling())
|
| + child->loader().stopAllLoaders();
|
| +
|
| + if (m_documentLoader)
|
| + m_documentLoader->stopLoading();
|
|
|
| m_inStopAllLoaders = false;
|
|
|
| // detachFromParent() can be called multiple times on same Frame, which
|
| // means we may no longer have a FrameLoaderClient to talk to.
|
| if (m_client)
|
| - m_client->didStopAllLoaders();
|
| + m_client->didStopActiveLoader();
|
| }
|
|
|
| void FrameLoader::didAccessInitialDocument()
|
| @@ -1292,8 +1325,7 @@ void FrameLoader::loadWithNavigationAction(const NavigationAction& action, Frame
|
| return;
|
| }
|
|
|
| - // A new navigation is in progress, so don't clear the history's provisional item.
|
| - stopAllLoaders();
|
| + stopProvisionalLoaders();
|
|
|
| // <rdar://problem/6250856> - In certain circumstances on pages with multiple frames, stopAllLoaders()
|
| // might detach the current FrameLoader, in which case we should bail on this newly defunct load.
|
|
|