2009-10-07  Adam Barth  <abarth@webkit.org>

        Reviewed by Darin Adler.

        Factor PolicyChecker out of FrameLoader
        https://bugs.webkit.org/show_bug.cgi?id=30155

        Move the policy callback to the policy object.

        * WebCoreSupport/FrameLoaderClientQt.cpp:
        (WebCore::FrameLoaderClientQt::callPolicyFunction):
2009-10-07  Adam Barth  <abarth@webkit.org>

        Reviewed by Darin Adler.

        Factor PolicyChecker out of FrameLoader
        https://bugs.webkit.org/show_bug.cgi?id=30155

        Move the policy callback to the policy object.

        * WebCoreSupport/FrameLoaderClientGtk.cpp:
        (WebKit::FrameLoaderClient::dispatchWillSubmitForm):
        (WebKit::FrameLoaderClient::dispatchDecidePolicyForMIMEType):
        (WebKit::FrameLoaderClient::dispatchDecidePolicyForNewWindowAction):
        (WebKit::FrameLoaderClient::dispatchDecidePolicyForNavigationAction):
2009-10-07  Adam Barth  <abarth@webkit.org>

        Reviewed by Darin Adler.

        Factor PolicyChecker out of FrameLoader
        https://bugs.webkit.org/show_bug.cgi?id=30155

        Move the policy callback to the policy object.

        * WebFrame.cpp:
        (WebFrame::dispatchWillSubmitForm):
        (WebFrame::receivedPolicyDecision):
        (WebFrame::dispatchDecidePolicyForMIMEType):
        (WebFrame::dispatchDecidePolicyForNewWindowAction):
        (WebFrame::dispatchDecidePolicyForNavigationAction):
2009-10-07  Adam Barth  <abarth@webkit.org>

        Reviewed by Darin Adler.

        Factor PolicyChecker out of FrameLoader
        https://bugs.webkit.org/show_bug.cgi?id=30155

        Move the policy callback to the policy object.

        * WebKitSupport/FrameLoaderClientWx.cpp:
        (WebCore::FrameLoaderClientWx::dispatchWillSubmitForm):
        (WebCore::FrameLoaderClientWx::dispatchDecidePolicyForMIMEType):
        (WebCore::FrameLoaderClientWx::dispatchDecidePolicyForNewWindowAction):
        (WebCore::FrameLoaderClientWx::dispatchDecidePolicyForNavigationAction):
2009-10-07  Adam Barth  <abarth@webkit.org>

        Reviewed by Darin Adler.

        Factor PolicyChecker out of FrameLoader
        https://bugs.webkit.org/show_bug.cgi?id=30155

        Move the policy callback to the policy object.

        * WebCoreSupport/WebFrameLoaderClient.mm:
        (WebFrameLoaderClient::dispatchWillSubmitForm):
        (WebFrameLoaderClient::receivedPolicyDecison):
2009-10-07  Adam Barth  <abarth@webkit.org>

        Reviewed by Darin Adler.

        Factor PolicyChecker out of FrameLoader
        https://bugs.webkit.org/show_bug.cgi?id=30155

        Move the policy callback to the policy object.

        * WebCoreSupport/FrameLoaderClientHaiku.cpp:
        (WebCore::FrameLoaderClientHaiku::dispatchWillSubmitForm):
        (WebCore::FrameLoaderClientHaiku::dispatchDecidePolicyForMIMEType):
        (WebCore::FrameLoaderClientHaiku::dispatchDecidePolicyForNewWindowAction):
        (WebCore::FrameLoaderClientHaiku::dispatchDecidePolicyForNavigationAction):
2009-10-07  Adam Barth  <abarth@webkit.org>

        Reviewed by Darin Adler.

        Factor PolicyChecker out of FrameLoader
        https://bugs.webkit.org/show_bug.cgi?id=30155

        This patch separates PolicyChecker from FrameLoader.  Loader policy is
        in change of managing the FrameLoaderClient callbacks.  Ideally, it
        shouldn't know anything about FrameLoader, but I couldn't quite remove
        all knowledge (although we might be able to do more later).  In a
        future patch, I'll move PolicyChecker into a separate file.

        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::FrameLoader):
        (WebCore::FrameLoader::loadURL):
        (WebCore::FrameLoader::load):
        (WebCore::FrameLoader::loadWithDocumentLoader):
        (WebCore::PolicyChecker::handleUnimplementablePolicy):
        (WebCore::PolicyChecker::cannotShowMIMEType):
        (WebCore::PolicyChecker::PolicyChecker):
        (WebCore::PolicyChecker::checkNavigationPolicy):
        (WebCore::PolicyChecker::checkContentPolicy):
        (WebCore::FrameLoader::shouldReloadToHandleUnreachableURL):
        (WebCore::FrameLoader::stopAllLoaders):
        (WebCore::PolicyChecker::cancelCheck):
        (WebCore::PolicyChecker::stopCheck):
        (WebCore::PolicyChecker::continueAfterContentPolicy):
        (WebCore::PolicyChecker::continueLoadAfterWillSubmitForm):
        (WebCore::FrameLoader::continueLoadAfterWillSubmitForm):
        (WebCore::FrameLoader::loadPostRequest):
        (WebCore::FrameLoader::continueFragmentScrollAfterNavigationPolicy):
        (WebCore::PolicyChecker::checkNewWindowPolicy):
        (WebCore::PolicyChecker::continueAfterNewWindowPolicy):
        (WebCore::PolicyChecker::continueAfterNavigationPolicy):
        (WebCore::FrameLoader::continueLoadAfterNavigationPolicy):
        * loader/FrameLoader.h:
        (WebCore::PolicyChecker::loadType):
        (WebCore::PolicyChecker::setLoadType):
        (WebCore::PolicyChecker::delegateIsDecidingNavigationPolicy):
        (WebCore::PolicyChecker::delegateIsHandlingUnimplementablePolicy):
        (WebCore::FrameLoader::policy):
        * loader/FrameLoaderClient.h:
        * loader/MainResourceLoader.cpp:
        (WebCore::MainResourceLoader::didCancel):
        (WebCore::MainResourceLoader::willSendRequest):
        (WebCore::MainResourceLoader::continueAfterContentPolicy):
        (WebCore::MainResourceLoader::didReceiveResponse):
        * svg/graphics/SVGImage.cpp:
        (WebCore::SVGImage::dataChanged):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49284 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp
index 9966d41..57a7a79 100644
--- a/WebCore/loader/FrameLoader.cpp
+++ b/WebCore/loader/FrameLoader.cpp
@@ -166,12 +166,10 @@
 FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
     : m_frame(frame)
     , m_client(client)
+    , m_policyChecker(frame)
     , m_state(FrameStateCommittedPage)
     , m_loadType(FrameLoadTypeStandard)
-    , m_policyLoadType(FrameLoadTypeStandard)
     , m_delegateIsHandlingProvisionalLoadError(false)
-    , m_delegateIsDecidingNavigationPolicy(false)
-    , m_delegateIsHandlingUnimplementablePolicy(false)
     , m_firstLayoutDone(false)
     , m_quickRedirectComing(false)
     , m_sentRedirectNotification(false)
@@ -1978,7 +1976,8 @@
     NavigationAction action(newURL, newLoadType, isFormSubmission, event);
 
     if (!targetFrame && !frameName.isEmpty()) {
-        checkNewWindowPolicy(action, request, formState.release(), frameName);
+        policyChecker()->checkNewWindowPolicy(action, FrameLoader::callContinueLoadAfterNewWindowPolicy,
+            request, formState.release(), frameName, this);
         return;
     }
 
@@ -1991,9 +1990,9 @@
     // work properly.
     if (shouldScrollToAnchor(isFormSubmission, newLoadType, newURL)) {
         oldDocumentLoader->setTriggeringAction(action);
-        stopPolicyCheck();
-        m_policyLoadType = newLoadType;
-        checkNavigationPolicy(request, oldDocumentLoader.get(), formState.release(),
+        policyChecker()->stopCheck();
+        policyChecker()->setLoadType(newLoadType);
+        policyChecker()->checkNavigationPolicy(request, oldDocumentLoader.get(), formState.release(),
             callContinueFragmentScrollAfterNavigationPolicy, this);
     } else {
         // must grab this now, since this load may stop the previous load and clear this flag
@@ -2042,7 +2041,7 @@
         return;
     }
 
-    checkNewWindowPolicy(NavigationAction(request.url(), NavigationTypeOther), request, 0, frameName);
+    policyChecker()->checkNewWindowPolicy(NavigationAction(request.url(), NavigationTypeOther), FrameLoader::callContinueLoadAfterNewWindowPolicy, request, 0, frameName, this);
 }
 
 void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, bool lockHistory, FrameLoadType type, PassRefPtr<FormState> formState)
@@ -2100,30 +2099,30 @@
     if (m_unloadEventBeingDispatched)
         return;
 
-    m_policyLoadType = type;
+    policyChecker()->setLoadType(type);
     RefPtr<FormState> formState = prpFormState;
     bool isFormSubmission = formState;
 
     const KURL& newURL = loader->request().url();
 
-    if (shouldScrollToAnchor(isFormSubmission, m_policyLoadType, newURL)) {
+    if (shouldScrollToAnchor(isFormSubmission, policyChecker()->loadType(), newURL)) {
         RefPtr<DocumentLoader> oldDocumentLoader = m_documentLoader;
-        NavigationAction action(newURL, m_policyLoadType, isFormSubmission);
+        NavigationAction action(newURL, policyChecker()->loadType(), isFormSubmission);
 
         oldDocumentLoader->setTriggeringAction(action);
-        stopPolicyCheck();
-        checkNavigationPolicy(loader->request(), oldDocumentLoader.get(), formState,
+        policyChecker()->stopCheck();
+        policyChecker()->checkNavigationPolicy(loader->request(), oldDocumentLoader.get(), formState,
             callContinueFragmentScrollAfterNavigationPolicy, this);
     } else {
         if (Frame* parent = m_frame->tree()->parent())
             loader->setOverrideEncoding(parent->loader()->documentLoader()->overrideEncoding());
 
-        stopPolicyCheck();
+        policyChecker()->stopCheck();
         setPolicyDocumentLoader(loader);
         if (loader->triggeringAction().isEmpty())
-            loader->setTriggeringAction(NavigationAction(newURL, m_policyLoadType, isFormSubmission));
+            loader->setTriggeringAction(NavigationAction(newURL, policyChecker()->loadType(), isFormSubmission));
 
-        checkNavigationPolicy(loader->request(), loader, formState,
+        policyChecker()->checkNavigationPolicy(loader->request(), loader, formState,
             callContinueLoadAfterNavigationPolicy, this);
     }
 }
@@ -2164,16 +2163,16 @@
     return error.isNull();
 }
 
-void FrameLoader::handleUnimplementablePolicy(const ResourceError& error)
+void PolicyChecker::handleUnimplementablePolicy(const ResourceError& error)
 {
     m_delegateIsHandlingUnimplementablePolicy = true;
-    m_client->dispatchUnableToImplementPolicy(error);
+    m_frame->loader()->client()->dispatchUnableToImplementPolicy(error);
     m_delegateIsHandlingUnimplementablePolicy = false;
 }
 
-void FrameLoader::cannotShowMIMEType(const ResourceResponse& response)
+void PolicyChecker::cannotShowMIMEType(const ResourceResponse& response)
 {
-    handleUnimplementablePolicy(m_client->cannotShowMIMETypeError(response));
+    handleUnimplementablePolicy(m_frame->loader()->client()->cannotShowMIMETypeError(response));
 }
 
 ResourceError FrameLoader::interruptionForPolicyChangeError(const ResourceRequest& request)
@@ -2181,33 +2180,24 @@
     return m_client->interruptForPolicyChangeError(request);
 }
 
-void FrameLoader::checkNavigationPolicy(const ResourceRequest& newRequest, NavigationPolicyDecisionFunction function, void* argument)
+PolicyChecker::PolicyChecker(Frame* frame)
+    : m_frame(frame)
+    , m_delegateIsDecidingNavigationPolicy(false)
+    , m_delegateIsHandlingUnimplementablePolicy(false)
+    , m_loadType(FrameLoadTypeStandard)
 {
-    checkNavigationPolicy(newRequest, activeDocumentLoader(), 0, function, argument);
 }
 
-void FrameLoader::checkContentPolicy(const String& MIMEType, ContentPolicyDecisionFunction function, void* argument)
+void PolicyChecker::checkNavigationPolicy(const ResourceRequest& newRequest, NavigationPolicyDecisionFunction function, void* argument)
 {
-    ASSERT(activeDocumentLoader());
-    
-    // Always show content with valid substitute data.
-    if (activeDocumentLoader()->substituteData().isValid()) {
-        function(argument, PolicyUse);
-        return;
-    }
+    checkNavigationPolicy(newRequest, m_frame->loader()->activeDocumentLoader(), 0, function, argument);
+}
 
-#if ENABLE(FTPDIR)
-    // Respect the hidden FTP Directory Listing pref so it can be tested even if the policy delegate might otherwise disallow it
-    Settings* settings = m_frame->settings();
-    if (settings && settings->forceFTPDirectoryListings() && MIMEType == "application/x-ftp-directory") {
-        function(argument, PolicyUse);
-        return;
-    }
-#endif
-
+void PolicyChecker::checkContentPolicy(const String& MIMEType, ContentPolicyDecisionFunction function, void* argument)
+{
     m_policyCheck.set(function, argument);
-    m_client->dispatchDecidePolicyForMIMEType(&FrameLoader::continueAfterContentPolicy,
-        MIMEType, activeDocumentLoader()->request());
+    m_frame->loader()->client()->dispatchDecidePolicyForMIMEType(&PolicyChecker::continueAfterContentPolicy,
+        MIMEType, m_frame->loader()->activeDocumentLoader()->request());
 }
 
 bool FrameLoader::shouldReloadToHandleUnreachableURL(DocumentLoader* docLoader)
@@ -2217,7 +2207,7 @@
     if (unreachableURL.isEmpty())
         return false;
 
-    if (!isBackForwardLoadType(m_policyLoadType))
+    if (!isBackForwardLoadType(policyChecker()->loadType()))
         return false;
 
     // We only treat unreachableURLs specially during the delegate callbacks
@@ -2226,7 +2216,7 @@
     // case handles malformed URLs and unknown schemes. Loading alternate content
     // at other times behaves like a standard load.
     DocumentLoader* compareDocumentLoader = 0;
-    if (m_delegateIsDecidingNavigationPolicy || m_delegateIsHandlingUnimplementablePolicy)
+    if (policyChecker()->delegateIsDecidingNavigationPolicy() || policyChecker()->delegateIsHandlingUnimplementablePolicy())
         compareDocumentLoader = m_policyDocumentLoader.get();
     else if (m_delegateIsHandlingProvisionalLoadError)
         compareDocumentLoader = m_provisionalDocumentLoader.get();
@@ -2381,7 +2371,7 @@
 
     m_inStopAllLoaders = true;
 
-    stopPolicyCheck();
+    policyChecker()->stopCheck();
 
     stopLoadingSubframes();
     if (m_provisionalDocumentLoader)
@@ -2861,9 +2851,9 @@
     return m_client->generatedMIMETypeForURLScheme(URLScheme);
 }
 
-void FrameLoader::cancelContentPolicyCheck()
+void PolicyChecker::cancelCheck()
 {
-    m_client->cancelPolicyCheck();
+    m_frame->loader()->client()->cancelPolicyCheck();
     m_policyCheck.clear();
 }
 
@@ -2986,9 +2976,9 @@
     return CachePolicyVerify;
 }
 
-void FrameLoader::stopPolicyCheck()
+void PolicyChecker::stopCheck()
 {
-    m_client->cancelPolicyCheck();
+    m_frame->loader()->client()->cancelPolicyCheck();
     PolicyCheck check = m_policyCheck;
     m_policyCheck.clear();
     check.cancel();
@@ -3092,14 +3082,21 @@
     ASSERT_NOT_REACHED();
 }
 
-void FrameLoader::continueAfterContentPolicy(PolicyAction policy)
+void PolicyChecker::continueAfterContentPolicy(PolicyAction policy)
 {
     PolicyCheck check = m_policyCheck;
     m_policyCheck.clear();
     check.call(policy);
 }
 
-void FrameLoader::continueLoadAfterWillSubmitForm(PolicyAction)
+void PolicyChecker::continueLoadAfterWillSubmitForm(PolicyAction)
+{
+    // See header file for an explaination of why this function
+    // isn't like the others.
+    m_frame->loader()->continueLoadAfterWillSubmitForm();
+}
+
+void FrameLoader::continueLoadAfterWillSubmitForm()
 {
     if (!m_provisionalDocumentLoader)
         return;
@@ -3396,7 +3393,7 @@
         if (Frame* targetFrame = formState ? 0 : findFrameForNavigation(frameName))
             targetFrame->loader()->loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, formState.release());
         else
-            checkNewWindowPolicy(action, workingResourceRequest, formState.release(), frameName);
+            policyChecker()->checkNewWindowPolicy(action, FrameLoader::callContinueLoadAfterNewWindowPolicy, workingResourceRequest, formState.release(), frameName, this);
     } else
         loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, formState.release());    
 }
@@ -3535,7 +3532,7 @@
 
 void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue)
 {
-    bool isRedirect = m_quickRedirectComing || m_policyLoadType == FrameLoadTypeRedirectWithLockedBackForwardList;
+    bool isRedirect = m_quickRedirectComing || policyChecker()->loadType() == FrameLoadTypeRedirectWithLockedBackForwardList;
     m_quickRedirectComing = false;
 
     if (!shouldContinue)
@@ -3591,16 +3588,15 @@
         && !m_frame->document()->isFrameSet();
 }
 
-void FrameLoader::checkNewWindowPolicy(const NavigationAction& action, const ResourceRequest& request,
-    PassRefPtr<FormState> formState, const String& frameName)
+void PolicyChecker::checkNewWindowPolicy(const NavigationAction& action, NewWindowPolicyDecisionFunction function,
+    const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, void* argument)
 {
-    m_policyCheck.set(request, formState, frameName,
-        callContinueLoadAfterNewWindowPolicy, this);
-    m_client->dispatchDecidePolicyForNewWindowAction(&FrameLoader::continueAfterNewWindowPolicy,
+    m_policyCheck.set(request, formState, frameName, function, argument);
+    m_frame->loader()->client()->dispatchDecidePolicyForNewWindowAction(&PolicyChecker::continueAfterNewWindowPolicy,
         action, request, formState, frameName);
 }
 
-void FrameLoader::continueAfterNewWindowPolicy(PolicyAction policy)
+void PolicyChecker::continueAfterNewWindowPolicy(PolicyAction policy)
 {
     PolicyCheck check = m_policyCheck;
     m_policyCheck.clear();
@@ -3610,7 +3606,7 @@
             check.clearRequest();
             break;
         case PolicyDownload:
-            m_client->startDownload(check.request());
+            m_frame->loader()->client()->startDownload(check.request());
             check.clearRequest();
             break;
         case PolicyUse:
@@ -3620,7 +3616,7 @@
     check.call(policy == PolicyUse);
 }
 
-void FrameLoader::checkNavigationPolicy(const ResourceRequest& request, DocumentLoader* loader,
+void PolicyChecker::checkNavigationPolicy(const ResourceRequest& request, DocumentLoader* loader,
     PassRefPtr<FormState> formState, NavigationPolicyDecisionFunction function, void* argument)
 {
     NavigationAction action = loader->triggeringAction();
@@ -3628,7 +3624,7 @@
         action = NavigationAction(request.url(), NavigationTypeOther);
         loader->setTriggeringAction(action);
     }
-        
+
     // Don't ask more than once for the same request or if we are loading an empty URL.
     // This avoids confusion on the part of the client.
     if (equalIgnoringHeaderFields(request, loader->lastCheckedRequest()) || (!request.isNull() && request.url().isEmpty())) {
@@ -3640,8 +3636,8 @@
     // We are always willing to show alternate content for unreachable URLs;
     // treat it like a reload so it maintains the right state for b/f list.
     if (loader->substituteData().isValid() && !loader->substituteData().failingURL().isEmpty()) {
-        if (isBackForwardLoadType(m_policyLoadType))
-            m_policyLoadType = FrameLoadTypeReload;
+        if (isBackForwardLoadType(m_loadType))
+            m_loadType = FrameLoadTypeReload;
         function(argument, request, 0, true);
         return;
     }
@@ -3651,31 +3647,31 @@
     m_policyCheck.set(request, formState.get(), function, argument);
 
     m_delegateIsDecidingNavigationPolicy = true;
-    m_client->dispatchDecidePolicyForNavigationAction(&FrameLoader::continueAfterNavigationPolicy,
+    m_frame->loader()->client()->dispatchDecidePolicyForNavigationAction(&PolicyChecker::continueAfterNavigationPolicy,
         action, request, formState);
     m_delegateIsDecidingNavigationPolicy = false;
 }
 
-void FrameLoader::continueAfterNavigationPolicy(PolicyAction policy)
+void PolicyChecker::continueAfterNavigationPolicy(PolicyAction policy)
 {
     PolicyCheck check = m_policyCheck;
     m_policyCheck.clear();
 
     bool shouldContinue = policy == PolicyUse;
-    
+
     switch (policy) {
         case PolicyIgnore:
             check.clearRequest();
             break;
         case PolicyDownload:
-            m_client->startDownload(check.request());
+            m_frame->loader()->client()->startDownload(check.request());
             check.clearRequest();
             break;
         case PolicyUse: {
             ResourceRequest request(check.request());
-            
-            if (!m_client->canHandleRequest(request)) {
-                handleUnimplementablePolicy(m_client->cannotShowURLError(check.request()));
+
+            if (!m_frame->loader()->client()->canHandleRequest(request)) {
+                handleUnimplementablePolicy(m_frame->loader()->cannotShowURLError(check.request()));
                 check.clearRequest();
                 shouldContinue = false;
             }
@@ -3720,7 +3716,7 @@
         // If the navigation request came from the back/forward menu, and we punt on it, we have the 
         // problem that we have optimistically moved the b/f cursor already, so move it back.  For sanity, 
         // we only do this when punting a navigation for the target frame or top-level frame.  
-        if ((isTargetItem || isLoadingMainFrame()) && isBackForwardLoadType(m_policyLoadType))
+        if ((isTargetItem || isLoadingMainFrame()) && isBackForwardLoadType(policyChecker()->loadType()))
             if (Page* page = m_frame->page()) {
                 Frame* mainFrame = page->mainFrame();
                 if (HistoryItem* resetItem = mainFrame->loader()->m_currentHistoryItem.get()) {
@@ -3732,7 +3728,7 @@
         return;
     }
 
-    FrameLoadType type = m_policyLoadType;
+    FrameLoadType type = policyChecker()->loadType();
     stopAllLoaders();
     
     // <rdar://problem/6250856> - In certain circumstances on pages with multiple frames, stopAllLoaders()
@@ -3757,7 +3753,7 @@
         return;
 
     if (formState)
-        m_client->dispatchWillSubmitForm(&FrameLoader::continueLoadAfterWillSubmitForm, formState);
+        m_client->dispatchWillSubmitForm(&PolicyChecker::continueLoadAfterWillSubmitForm, formState);
     else
         continueLoadAfterWillSubmitForm();
 }