2011-06-13 Adam Barth <abarth@webkit.org>
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Jun 2011 20:36:03 +0000 (20:36 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 13 Jun 2011 20:36:03 +0000 (20:36 +0000)
        Reviewed by Nate Chapin.

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

        * src/WebFrameImpl.cpp:
        (WebKit::WebFrameImpl::iconURLs):
2011-06-13  Adam Barth  <abarth@webkit.org>

        Reviewed by Nate Chapin.

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

        This new class contains all the icon-related logic from FrameLoader.
        The icon-related logic and state has almost zero interaction with the
        rest of FrameLoader and is better handled as a separate concern.

        * CMakeLists.txt:
        * GNUmakefile.list.am:
        * WebCore.gypi:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * dom/Document.cpp:
        (WebCore::Document::implicitClose):
        (WebCore::Document::setIconURL):
        * inspector/InspectorResourceAgent.cpp:
        (WebCore::InspectorResourceAgent::didReceiveResponse):
        * loader/DocumentLoader.cpp:
        (WebCore::DocumentLoader::iconLoadDecisionAvailable):
        (WebCore::DocumentLoader::continueIconLoadWithDecision):
        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::FrameLoader):
        (WebCore::FrameLoader::stop):
        * loader/FrameLoader.h:
        (WebCore::FrameLoader::icon):
        * loader/icon/IconLoader.cpp:
        (WebCore::IconLoader::startLoading):
        (WebCore::IconLoader::finishLoading):
        * loader/icon/IconLoader.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@88682 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.pro
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/Document.cpp
Source/WebCore/inspector/InspectorResourceAgent.cpp
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/FrameLoader.h
Source/WebCore/loader/icon/IconController.cpp [new file with mode: 0644]
Source/WebCore/loader/icon/IconController.h [new file with mode: 0644]
Source/WebCore/loader/icon/IconLoader.cpp
Source/WebCore/loader/icon/IconLoader.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/WebFrameImpl.cpp

index abac76f..b4700bc 100644 (file)
@@ -989,6 +989,7 @@ SET(WebCore_SOURCES
     loader/cache/CachedXSLStyleSheet.cpp
     loader/cache/MemoryCache.cpp
 
+    loader/icon/IconController.cpp
     loader/icon/IconDatabase.cpp
     loader/icon/IconDatabaseBase.cpp
     loader/icon/IconLoader.cpp
index 800092f..7035593 100644 (file)
@@ -1,3 +1,38 @@
+2011-06-13  Adam Barth  <abarth@webkit.org>
+
+        Reviewed by Nate Chapin.
+
+        Factor IconController out of FrameLoader
+        https://bugs.webkit.org/show_bug.cgi?id=62509
+
+        This new class contains all the icon-related logic from FrameLoader.
+        The icon-related logic and state has almost zero interaction with the
+        rest of FrameLoader and is better handled as a separate concern.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * dom/Document.cpp:
+        (WebCore::Document::implicitClose):
+        (WebCore::Document::setIconURL):
+        * inspector/InspectorResourceAgent.cpp:
+        (WebCore::InspectorResourceAgent::didReceiveResponse):
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::iconLoadDecisionAvailable):
+        (WebCore::DocumentLoader::continueIconLoadWithDecision):
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::FrameLoader):
+        (WebCore::FrameLoader::stop):
+        * loader/FrameLoader.h:
+        (WebCore::FrameLoader::icon):
+        * loader/icon/IconLoader.cpp:
+        (WebCore::IconLoader::startLoading):
+        (WebCore::IconLoader::finishLoading):
+        * loader/icon/IconLoader.h:
+
 2011-06-13  Nate Chapin  <japhet@chromium.org>
 
         Reviewed by Darin Fisher.
index 759f07c..5a744bf 100644 (file)
@@ -2094,6 +2094,8 @@ webcore_sources += \
        Source/WebCore/loader/FTPDirectoryParser.h \
        Source/WebCore/loader/HistoryController.cpp \
        Source/WebCore/loader/HistoryController.h \
+       Source/WebCore/loader/icon/IconController.cpp \
+       Source/WebCore/loader/icon/IconController.h \
        Source/WebCore/loader/icon/IconDatabaseClient.h \
        Source/WebCore/loader/icon/IconDatabase.cpp \
        Source/WebCore/loader/icon/IconDatabase.h \
index 93fb39e..9b4fd54 100644 (file)
             'loader/cache/CachedResourceLoader.h',
             'loader/cache/CachedResourceRequest.h',
             'loader/cache/MemoryCache.h',
+            'loader/icon/IconController.h',
             'loader/icon/IconDatabase.h',
             'loader/icon/IconDatabaseBase.h',
             'loader/icon/IconDatabaseClient.h',
             'loader/cache/CachedXSLStyleSheet.h',
             'loader/cache/MemoryCache.cpp',
             'loader/cf/ResourceLoaderCFNet.cpp',
+            'loader/icon/IconController.cpp',
             'loader/icon/IconDatabase.cpp',
             'loader/icon/IconDatabaseBase.cpp',
             'loader/icon/IconLoader.cpp',
index f37cadf..ad36fc4 100644 (file)
@@ -870,6 +870,7 @@ SOURCES += \
     loader/FrameLoaderStateMachine.cpp \
     loader/HistoryController.cpp \
     loader/FTPDirectoryParser.cpp \
+    loader/icon/IconController.cpp \
     loader/icon/IconDatabaseBase.cpp \
     loader/icon/IconLoader.cpp \
     loader/ImageLoader.cpp \
@@ -1819,6 +1820,7 @@ HEADERS += \
     loader/FrameLoader.h \
     loader/FrameLoaderStateMachine.h \
     loader/FTPDirectoryParser.h \
+    loader/icon/IconController.h \
     loader/icon/IconDatabase.h \
     loader/icon/IconDatabaseBase.h \
     loader/icon/IconLoader.h \
index 49c3f94..449fe6d 100755 (executable)
                                Name="icon"
                                >
                                <File
+                                       RelativePath="..\loader\icon\IconController.cpp"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\loader\icon\IconController.h"
+                                       >
+                               </File>
+                               <File
                                        RelativePath="..\loader\icon\IconDatabase.cpp"
                                        >
                                </File>
index f00daee..731219d 100644 (file)
                97C471DC12F925BD0086354B /* ContentSecurityPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 97C471DA12F925BD0086354B /* ContentSecurityPolicy.h */; settings = {ATTRIBUTES = (Private, ); }; };
                97DCE20110807C750057D394 /* HistoryController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97DCE1FF10807C750057D394 /* HistoryController.cpp */; };
                97DCE20210807C750057D394 /* HistoryController.h in Headers */ = {isa = PBXBuildFile; fileRef = 97DCE20010807C750057D394 /* HistoryController.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               97E4028F13A696ED00913D67 /* IconController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97E4028D13A696ED00913D67 /* IconController.cpp */; };
+               97E4029013A696ED00913D67 /* IconController.h in Headers */ = {isa = PBXBuildFile; fileRef = 97E4028E13A696ED00913D67 /* IconController.h */; settings = {ATTRIBUTES = (Private, ); }; };
                97EF7DFE107E55B700D7C49C /* ScriptControllerBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97EF7DFD107E55B700D7C49C /* ScriptControllerBase.cpp */; };
                98EB1F951313FE0500D0E1EA /* NotImplemented.h in Headers */ = {isa = PBXBuildFile; fileRef = 98EB1F941313FE0500D0E1EA /* NotImplemented.h */; settings = {ATTRIBUTES = (Private, ); }; };
                9B417064125662B3006B28FC /* ApplyBlockElementCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B417062125662B3006B28FC /* ApplyBlockElementCommand.h */; settings = {ATTRIBUTES = (Private, ); }; };
                97C471DA12F925BD0086354B /* ContentSecurityPolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentSecurityPolicy.h; sourceTree = "<group>"; };
                97DCE1FF10807C750057D394 /* HistoryController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HistoryController.cpp; sourceTree = "<group>"; };
                97DCE20010807C750057D394 /* HistoryController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HistoryController.h; sourceTree = "<group>"; };
+               97E4028D13A696ED00913D67 /* IconController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IconController.cpp; sourceTree = "<group>"; };
+               97E4028E13A696ED00913D67 /* IconController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IconController.h; sourceTree = "<group>"; };
                97EF7DFD107E55B700D7C49C /* ScriptControllerBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptControllerBase.cpp; sourceTree = "<group>"; };
                98EB1F941313FE0500D0E1EA /* NotImplemented.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotImplemented.h; sourceTree = "<group>"; };
                9B417062125662B3006B28FC /* ApplyBlockElementCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplyBlockElementCommand.h; sourceTree = "<group>"; };
                5126E6B60A2E3AEF005C29FA /* icon */ = {
                        isa = PBXGroup;
                        children = (
+                               97E4028D13A696ED00913D67 /* IconController.cpp */,
+                               97E4028E13A696ED00913D67 /* IconController.h */,
                                5126E6B90A2E3B12005C29FA /* IconDatabase.cpp */,
                                5126E6BA0A2E3B12005C29FA /* IconDatabase.h */,
                                516953951329A3C800B92D04 /* IconDatabaseBase.cpp */,
                                439D334313A6911C00C20F4F /* SVGAnimatedType.h in Headers */,
                                439D334413A6911C00C20F4F /* SVGAnimatedTypeAnimator.h in Headers */,
                                439D334513A6911C00C20F4F /* SVGAnimatorFactory.h in Headers */,
+                               97E4029013A696ED00913D67 /* IconController.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
                                977E2E0E12F0FC9C00C13379 /* XSSAuditor.cpp in Sources */,
                                FD537352137B651800008DCE /* ZeroPole.cpp in Sources */,
+                               97E4028F13A696ED00913D67 /* IconController.cpp in Sources */,
                                4381763B13A697D4007D1187 /* SVGAnimatedLength.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
index d3bc675..dd19f5d 100644 (file)
@@ -2115,12 +2115,10 @@ void Document::implicitClose()
     // But those add a dynamic component to the favicon that has UI 
     // ramifications, and we need to decide what is the Right Thing To Do(tm)
     Frame* f = frame();
-    if (f)
-        f->loader()->startIconLoader();
-
-    // Resume the animations (or start them)
-    if (f)
+    if (f) {
+        f->loader()->icon()->startLoader();
         f->animation()->resumeAnimationsForDocument(this);
+    }
 
     ImageLoader::dispatchPendingBeforeLoadEvents();
     ImageLoader::dispatchPendingLoadEvents();
@@ -4318,7 +4316,7 @@ void Document::setIconURL(const String& url, const String& mimeType, IconType ic
     else if (!mimeType.isEmpty())
         setIconURL(newURL);
     if (Frame* f = frame())
-        f->loader()->setIconURL(newURL);
+        f->loader()->icon()->setURL(newURL);
 }
 
 void Document::setIconURL(const IconURL& iconURL)
index 29cc182..66ba746 100644 (file)
@@ -237,7 +237,7 @@ void InspectorResourceAgent::didReceiveResponse(unsigned long identifier, Docume
             if (response.mimeType().isEmpty())
                 resourceResponse->setString("mimeType", cachedResource->response().mimeType());
         }
-        if (equalIgnoringFragmentIdentifier(response.url(), loader->frameLoader()->iconURL()))
+        if (equalIgnoringFragmentIdentifier(response.url(), loader->frameLoader()->icon()->url()))
             type = InspectorPageAgent::ImageResource;
         else if (equalIgnoringFragmentIdentifier(response.url(), loader->url()) && type == InspectorPageAgent::OtherResource)
             type = InspectorPageAgent::DocumentResource;
index 67ab924..7b36621 100644 (file)
@@ -865,7 +865,7 @@ void DocumentLoader::transferLoadingResourcesFromPage(Page* oldPage)
 void DocumentLoader::iconLoadDecisionAvailable()
 {
     if (m_frame)
-        m_frame->loader()->iconLoadDecisionReceived(iconDatabase().synchronousLoadDecisionForIconURL(KURL(frameLoader()->iconURL()), this));
+        m_frame->loader()->icon()->loadDecisionReceived(iconDatabase().synchronousLoadDecisionForIconURL(frameLoader()->icon()->url(), this));
 }
 
 static void iconLoadDecisionCallback(IconLoadDecision decision, void* context)
@@ -886,7 +886,7 @@ void DocumentLoader::continueIconLoadWithDecision(IconLoadDecision decision)
     ASSERT(m_iconLoadDecisionCallback);
     m_iconLoadDecisionCallback = 0;
     if (m_frame)
-        m_frame->loader()->continueIconLoadWithDecision(decision);
+        m_frame->loader()->icon()->continueLoadWithDecision(decision);
 }
 
 static void iconDataCallback(SharedBuffer*, void*)
index bc7b461..89396a0 100644 (file)
@@ -71,9 +71,6 @@
 #include "HTMLObjectElement.h"
 #include "HTTPParsers.h"
 #include "HistoryItem.h"
-#include "IconDatabase.h"
-#include "IconLoader.h"
-#include "IconURL.h"
 #include "InspectorController.h"
 #include "InspectorInstrumentation.h"
 #include "Logging.h"
@@ -186,6 +183,7 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
     , m_history(frame)
     , m_notifer(frame)
     , m_subframeLoader(frame)
+    , m_icon(frame)
     , m_state(FrameStateCommittedPage)
     , m_loadType(FrameLoadTypeStandard)
     , m_delegateIsHandlingProvisionalLoadError(false)
@@ -447,9 +445,8 @@ void FrameLoader::stop()
         parser->stopParsing();
         parser->finish();
     }
-
-    if (m_iconLoader)
-        m_iconLoader->stopLoading();
+    
+    icon()->stopLoader();
 }
 
 bool FrameLoader::closeURL()
@@ -464,82 +461,6 @@ bool FrameLoader::closeURL()
     return true;
 }
 
-KURL FrameLoader::iconURL()
-{
-    IconURLs urls = iconURLs(Favicon);
-    return urls.isEmpty() ? KURL() : urls[0].m_iconURL;
-}
-
-IconURLs FrameLoader::iconURLs(int iconTypes)
-{
-    IconURLs iconURLs;
-    // If this isn't a top level frame, return
-    if (m_frame->tree() && m_frame->tree()->parent())
-        return iconURLs;
-
-    if (iconTypes & Favicon && !fillIconURL(Favicon, &iconURLs))
-        iconURLs.append(getDefaultIconURL(Favicon));
-
-#if ENABLE(TOUCH_ICON_LOADING)
-    bool havePrecomposedIcon = false;
-    if (iconTypes & TouchPrecomposedIcon)
-        havePrecomposedIcon = fillIconURL(TouchPrecomposedIcon, &iconURLs);
-
-    bool haveTouchIcon = false;
-    if (iconTypes & TouchIcon)
-        haveTouchIcon = fillIconURL(TouchIcon, &iconURLs);
-
-    // Only return the default touch icons when the both were required and neither was gotten.
-    if (iconTypes & TouchPrecomposedIcon && iconTypes & TouchIcon && !havePrecomposedIcon && !haveTouchIcon) {
-        iconURLs.append(getDefaultIconURL(TouchPrecomposedIcon));
-        iconURLs.append(getDefaultIconURL(TouchIcon));
-    }
-#endif
-    return iconURLs;
-}
-
-bool FrameLoader::fillIconURL(IconType iconType, IconURLs* iconURLs)
-{
-    // If we have an iconURL from a Link element, return that
-    IconURL url = m_frame->document()->iconURL(iconType);
-    if (url.m_iconURL.isEmpty())
-        return false;
-
-    iconURLs->append(url);
-
-    return true;
-}
-
-IconURL FrameLoader::getDefaultIconURL(IconType iconType)
-{
-    // Don't return a favicon iconURL unless we're http or https
-    KURL documentURL = m_frame->document()->url();
-    if (!documentURL.protocolInHTTPFamily())
-        return IconURL();
-
-    KURL url;
-    bool couldSetProtocol = url.setProtocol(documentURL.protocol());
-    ASSERT_UNUSED(couldSetProtocol, couldSetProtocol);
-    url.setHost(documentURL.host());
-    if (documentURL.hasPort())
-        url.setPort(documentURL.port());
-    if (iconType == Favicon) {
-        url.setPath("/favicon.ico");
-        return IconURL(KURL(ParsedURLString, url), Favicon);
-    }
-#if ENABLE(TOUCH_ICON_LOADING)
-    if (iconType == TouchPrecomposedIcon) {
-        url.setPath("/apple-touch-icon-precomposed.png");
-        return IconURL(KURL(ParsedURLString, url), TouchPrecomposedIcon);
-    }
-    if (iconType == TouchIcon) {
-        url.setPath("/apple-touch-icon.png");
-        return IconURL(KURL(ParsedURLString, url), TouchIcon);
-    }
-#endif
-    return IconURL();
-}
-
 bool FrameLoader::didOpenURL(const KURL& url)
 {
     if (m_frame->navigationScheduler()->redirectScheduledDuringLoad()) {
@@ -732,115 +653,6 @@ void FrameLoader::didEndDocument()
     m_isLoadingMainResource = false;
 }
 
-// Callback for the old-style synchronous IconDatabase interface.
-void FrameLoader::iconLoadDecisionReceived(IconLoadDecision iconLoadDecision)
-{
-    if (!m_mayLoadIconLater)
-        return;
-    LOG(IconDatabase, "FrameLoader %p was told a load decision is available for its icon", this);
-    continueIconLoadWithDecision(iconLoadDecision);
-    m_mayLoadIconLater = false;
-}
-
-void FrameLoader::startIconLoader()
-{
-    // FIXME: We kick off the icon loader when the frame is done receiving its main resource.
-    // But we should instead do it when we're done parsing the head element.
-    if (!isLoadingMainFrame())
-        return;
-
-    if (!iconDatabase().isEnabled())
-        return;
-    
-    KURL url(iconURL());
-    String urlString(url.string());
-    if (urlString.isEmpty())
-        return;
-
-    // People who want to avoid loading images generally want to avoid loading all images, unless an exception has been made for site icons.
-    // Now that we've accounted for URL mapping, avoid starting the network load if images aren't set to display automatically.
-    Settings* settings = m_frame->settings();
-    if (settings && !settings->loadsImagesAutomatically() && !settings->loadsSiteIconsIgnoringImageLoadingSetting())
-        return;
-
-    // If we're reloading the page, always start the icon load now.
-    if (loadType() == FrameLoadTypeReload && loadType() == FrameLoadTypeReloadFromOrigin) {
-        continueIconLoadWithDecision(IconLoadYes);
-        return;
-    }
-
-    if (iconDatabase().supportsAsynchronousMode()) {
-        m_documentLoader->getIconLoadDecisionForIconURL(urlString);
-        // Commit the icon url mapping to the database just in case we don't end up loading later.
-        commitIconURLToIconDatabase(url);
-        return;
-    }
-    
-    IconLoadDecision decision = iconDatabase().synchronousLoadDecisionForIconURL(urlString, m_documentLoader.get());
-
-    if (decision == IconLoadUnknown) {
-        // In this case, we may end up loading the icon later, but we still want to commit the icon url mapping to the database
-        // just in case we don't end up loading later - if we commit the mapping a second time after the load, that's no big deal
-        // We also tell the client to register for the notification that the icon is received now so it isn't missed in case the 
-        // icon is later read in from disk
-        LOG(IconDatabase, "FrameLoader %p might load icon %s later", this, urlString.ascii().data());
-        m_mayLoadIconLater = true;    
-        m_client->registerForIconNotification();
-        commitIconURLToIconDatabase(url);
-        return;
-    }
-
-    continueIconLoadWithDecision(decision);
-}
-
-void FrameLoader::continueIconLoadWithDecision(IconLoadDecision iconLoadDecision)
-{
-    ASSERT(iconLoadDecision != IconLoadUnknown);
-    
-    //  FIXME (<rdar://problem/9168605>) - We should support in-memory-only private browsing icons in asynchronous icon database mode.
-    if (iconDatabase().supportsAsynchronousMode() && m_frame->page()->settings()->privateBrowsingEnabled())
-        return;
-        
-    if (iconLoadDecision == IconLoadNo) {
-        KURL url(iconURL());
-        String urlString(url.string());
-        
-        LOG(IconDatabase, "FrameLoader::startIconLoader() - Told not to load this icon, committing iconURL %s to database for pageURL mapping", urlString.ascii().data());
-        commitIconURLToIconDatabase(url);
-        
-        if (iconDatabase().supportsAsynchronousMode()) {
-            m_documentLoader->getIconDataForIconURL(urlString);
-            return;
-        }
-        
-        // We were told not to load this icon - that means this icon is already known by the database
-        // If the icon data hasn't been read in from disk yet, kick off the read of the icon from the database to make sure someone
-        // has done it. This is after registering for the notification so the WebView can call the appropriate delegate method.
-        // Otherwise if the icon data *is* available, notify the delegate
-        if (!iconDatabase().synchronousIconDataKnownForIconURL(urlString)) {
-            LOG(IconDatabase, "Told not to load icon %s but icon data is not yet available - registering for notification and requesting load from disk", urlString.ascii().data());
-            m_client->registerForIconNotification();
-            iconDatabase().synchronousIconForPageURL(m_frame->document()->url().string(), IntSize(0, 0));
-            iconDatabase().synchronousIconForPageURL(originalRequestURL().string(), IntSize(0, 0));
-        } else
-            m_client->dispatchDidReceiveIcon();
-            
-        return;
-    } 
-    
-    if (!m_iconLoader)
-        m_iconLoader = IconLoader::create(m_frame);
-        
-    m_iconLoader->startLoading();
-}
-
-void FrameLoader::commitIconURLToIconDatabase(const KURL& icon)
-{
-    LOG(IconDatabase, "Committing iconURL %s to database for pageURLs %s and %s", icon.string().ascii().data(), m_frame->document()->url().string().ascii().data(), originalRequestURL().string().ascii().data());
-    iconDatabase().setIconURLForPageURL(icon.string(), m_frame->document()->url().string());
-    iconDatabase().setIconURLForPageURL(icon.string(), originalRequestURL().string());
-}
-
 void FrameLoader::finishedParsing()
 {
     m_frame->injectUserScripts(InjectAtDocumentEnd);
@@ -3344,16 +3156,6 @@ void FrameLoader::setTitle(const StringWithDirection& title)
     documentLoader()->setTitle(title);
 }
 
-void FrameLoader::setIconURL(const IconURL& iconURL)
-{
-    documentLoader()->setIconURL(iconURL);
-}
-
-KURL FrameLoader::originalRequestURL() const
-{
-    return activeDocumentLoader()->originalRequest().url();
-}
-
 String FrameLoader::referrer() const
 {
     return m_documentLoader ? m_documentLoader->request().httpReferrer() : "";
index dbe280a..c53a365 100644 (file)
@@ -35,7 +35,7 @@
 #include "FrameLoaderStateMachine.h"
 #include "FrameLoaderTypes.h"
 #include "HistoryController.h"
-#include "IconDatabaseBase.h"
+#include "IconController.h"
 #include "IconURL.h"
 #include "PolicyChecker.h"
 #include "ResourceLoadNotifier.h"
@@ -65,7 +65,6 @@ class FrameLoaderClient;
 class FrameNetworkingContext;
 class HistoryItem;
 class HTMLFormElement;
-class IconLoader;
 class NavigationAction;
 class NetworkingContext;
 class Page;
@@ -102,6 +101,7 @@ public:
     HistoryController* history() const { return &m_history; }
     ResourceLoadNotifier* notifier() const { return &m_notifer; }
     SubframeLoader* subframeLoader() const { return &m_subframeLoader; }
+    IconController* icon() const { return &m_icon; }
 
     // FIXME: This is not cool, people. There are too many different functions that all start loads.
     // We should aim to consolidate these into a smaller set of functions, and try to reuse more of
@@ -219,13 +219,6 @@ public:
     void didEndDocument();
     void willSetEncoding();
 
-    // Returns favicon.
-    KURL iconURL();
-
-    // Returns the given iconTypes' IconURLs, iconTypes could be any combination of IconType.
-    IconURLs iconURLs(int iconTypes);
-    void commitIconURLToIconDatabase(const KURL&);
-
     KURL baseURL() const;
 
     void handledOnloadEvents();
@@ -272,17 +265,12 @@ public:
     void cancelAndClear();
 
     void setTitle(const StringWithDirection&);
-    void setIconURL(const IconURL&);
 
     void commitProvisionalLoad();
     bool isLoadingFromCachedPage() const { return m_loadingFromCachedPage; }
 
     FrameLoaderStateMachine* stateMachine() const { return &m_stateMachine; }
 
-    void startIconLoader();
-    void iconLoadDecisionReceived(IconLoadDecision);
-    void continueIconLoadWithDecision(IconLoadDecision);
-
     bool shouldAllowNavigation(Frame* targetFrame) const;
     Frame* findFrameForNavigation(const AtomicString& name);
 
@@ -409,15 +397,10 @@ private:
     void scheduleCheckLoadComplete();
     void startCheckCompleteTimer();
 
-    KURL originalRequestURL() const;
-
     bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
 
     void updateSandboxFlags();
 
-    bool fillIconURL(IconType, IconURLs*);
-    IconURL getDefaultIconURL(IconType);
-
     Frame* m_frame;
     FrameLoaderClient* m_client;
 
@@ -426,6 +409,7 @@ private:
     mutable ResourceLoadNotifier m_notifer;
     mutable SubframeLoader m_subframeLoader;
     mutable FrameLoaderStateMachine m_stateMachine;
+    mutable IconController m_icon;
 
     FrameState m_state;
     FrameLoadType m_loadType;
@@ -458,9 +442,6 @@ private:
 
     KURL m_workingURL;
 
-    OwnPtr<IconLoader> m_iconLoader;
-    bool m_mayLoadIconLater;
-
     bool m_needsClear;
 
     KURL m_submittedFormURL;
diff --git a/Source/WebCore/loader/icon/IconController.cpp b/Source/WebCore/loader/icon/IconController.cpp
new file mode 100644 (file)
index 0000000..77d52ee
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2008 Alp Toker <alp@atoker.com>
+ * Copyright (C) Research In Motion Limited 2009. All rights reserved.
+ * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IconController.h"
+
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "Frame.h"
+#include "FrameLoaderClient.h"
+#include "IconDatabase.h"
+#include "IconDatabaseBase.h"
+#include "IconLoader.h"
+#include "IconURL.h"
+#include "Logging.h"
+#include "Page.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+IconController::IconController(Frame* frame)
+    : m_frame(frame)
+    , m_waitingForLoadDecision(false)
+{
+}
+
+IconController::~IconController()
+{
+}
+
+KURL IconController::url()
+{
+    IconURLs iconURLs = urlsForTypes(Favicon);
+    return iconURLs.isEmpty() ? KURL() : iconURLs[0].m_iconURL;
+}
+
+IconURLs IconController::urlsForTypes(int iconTypes)
+{
+    IconURLs iconURLs;
+    if (m_frame->tree() && m_frame->tree()->parent())
+        return iconURLs;
+
+    if (iconTypes & Favicon && !appendToIconURLs(Favicon, &iconURLs))
+        iconURLs.append(defaultURL(Favicon));
+
+#if ENABLE(TOUCH_ICON_LOADING)
+    bool havePrecomposedIcon = false;
+    if (iconTypes & TouchPrecomposedIcon)
+        havePrecomposedIcon = appendToIconURLs(TouchPrecomposedIcon, &iconURLs);
+
+    bool haveTouchIcon = false;
+    if (iconTypes & TouchIcon)
+        haveTouchIcon = appendToIconURLs(TouchIcon, &iconURLs);
+
+    // Only return the default touch icons when the both were required and neither was gotten.
+    if (iconTypes & TouchPrecomposedIcon && iconTypes & TouchIcon && !havePrecomposedIcon && !haveTouchIcon) {
+        iconURLs.append(defaultURL(TouchPrecomposedIcon));
+        iconURLs.append(defaultURL(TouchIcon));
+    }
+#endif
+    return iconURLs;
+}
+
+void IconController::commitToDatabase(const KURL& icon)
+{
+    LOG(IconDatabase, "Committing iconURL %s to database for pageURLs %s and %s", icon.string().ascii().data(), m_frame->document()->url().string().ascii().data(), m_frame->loader()->initialRequest().url().string().ascii().data());
+    iconDatabase().setIconURLForPageURL(icon.string(), m_frame->document()->url().string());
+    iconDatabase().setIconURLForPageURL(icon.string(), m_frame->loader()->initialRequest().url().string());
+}
+
+void IconController::setURL(const IconURL& iconURL)
+{
+    m_frame->loader()->documentLoader()->setIconURL(iconURL);
+}
+
+void IconController::startLoader()
+{
+    // FIXME: We kick off the icon loader when the frame is done receiving its main resource.
+    // But we should instead do it when we're done parsing the head element.
+    if (!m_frame->loader()->isLoadingMainFrame())
+        return;
+
+    if (!iconDatabase().isEnabled())
+        return;
+
+    KURL iconURL(url());
+    String urlString(iconURL.string());
+    if (urlString.isEmpty())
+        return;
+
+    // People who want to avoid loading images generally want to avoid loading all images, unless an exception has been made for site icons.
+    // Now that we've accounted for URL mapping, avoid starting the network load if images aren't set to display automatically.
+    Settings* settings = m_frame->settings();
+    if (settings && !settings->loadsImagesAutomatically() && !settings->loadsSiteIconsIgnoringImageLoadingSetting())
+        return;
+
+    // If we're reloading the page, always start the icon load now.
+    // FIXME: How can this condition ever be true?
+    if (m_frame->loader()->loadType() == FrameLoadTypeReload && m_frame->loader()->loadType() == FrameLoadTypeReloadFromOrigin) {
+        continueLoadWithDecision(IconLoadYes);
+        return;
+    }
+
+    if (iconDatabase().supportsAsynchronousMode()) {
+        m_frame->loader()->documentLoader()->getIconLoadDecisionForIconURL(urlString);
+        // Commit the icon url mapping to the database just in case we don't end up loading later.
+        commitToDatabase(iconURL);
+        return;
+    }
+
+    IconLoadDecision decision = iconDatabase().synchronousLoadDecisionForIconURL(urlString, m_frame->loader()->documentLoader());
+
+    if (decision == IconLoadUnknown) {
+        // In this case, we may end up loading the icon later, but we still want to commit the icon url mapping to the database
+        // just in case we don't end up loading later - if we commit the mapping a second time after the load, that's no big deal
+        // We also tell the client to register for the notification that the icon is received now so it isn't missed in case the 
+        // icon is later read in from disk
+        LOG(IconDatabase, "IconController %p might load icon %s later", this, urlString.ascii().data());
+        m_waitingForLoadDecision = true;    
+        m_frame->loader()->client()->registerForIconNotification();
+        commitToDatabase(iconURL);
+        return;
+    }
+
+    continueLoadWithDecision(decision);
+}
+
+void IconController::stopLoader()
+{
+    if (m_iconLoader)
+        m_iconLoader->stopLoading();
+}
+
+// Callback for the old-style synchronous IconDatabase interface.
+void IconController::loadDecisionReceived(IconLoadDecision iconLoadDecision)
+{
+    if (!m_waitingForLoadDecision)
+        return;
+    LOG(IconDatabase, "IconController %p was told a load decision is available for its icon", this);
+    continueLoadWithDecision(iconLoadDecision);
+    m_waitingForLoadDecision = false;
+}
+
+void IconController::continueLoadWithDecision(IconLoadDecision iconLoadDecision)
+{
+    ASSERT(iconLoadDecision != IconLoadUnknown);
+
+    //  FIXME (<rdar://problem/9168605>) - We should support in-memory-only private browsing icons in asynchronous icon database mode.
+    if (iconDatabase().supportsAsynchronousMode() && m_frame->page()->settings()->privateBrowsingEnabled())
+        return;
+
+    if (iconLoadDecision == IconLoadNo) {
+        KURL iconURL(url());
+        String urlString(iconURL.string());
+
+        LOG(IconDatabase, "IconController::startLoader() - Told not to load this icon, committing iconURL %s to database for pageURL mapping", urlString.ascii().data());
+        commitToDatabase(iconURL);
+
+        if (iconDatabase().supportsAsynchronousMode()) {
+            m_frame->loader()->documentLoader()->getIconDataForIconURL(urlString);
+            return;
+        }
+
+        // We were told not to load this icon - that means this icon is already known by the database
+        // If the icon data hasn't been read in from disk yet, kick off the read of the icon from the database to make sure someone
+        // has done it. This is after registering for the notification so the WebView can call the appropriate delegate method.
+        // Otherwise if the icon data *is* available, notify the delegate
+        if (!iconDatabase().synchronousIconDataKnownForIconURL(urlString)) {
+            LOG(IconDatabase, "Told not to load icon %s but icon data is not yet available - registering for notification and requesting load from disk", urlString.ascii().data());
+            m_frame->loader()->client()->registerForIconNotification();
+            iconDatabase().synchronousIconForPageURL(m_frame->document()->url().string(), IntSize(0, 0));
+            iconDatabase().synchronousIconForPageURL(m_frame->loader()->initialRequest().url().string(), IntSize(0, 0));
+        } else
+            m_frame->loader()->client()->dispatchDidReceiveIcon();
+
+        return;
+    } 
+
+    if (!m_iconLoader)
+        m_iconLoader = IconLoader::create(m_frame);
+
+    m_iconLoader->startLoading();
+}
+
+bool IconController::appendToIconURLs(IconType iconType, IconURLs* iconURLs)
+{
+    IconURL url = m_frame->document()->iconURL(iconType);
+    if (url.m_iconURL.isEmpty())
+        return false;
+
+    iconURLs->append(url);
+    return true;
+}
+
+IconURL IconController::defaultURL(IconType iconType)
+{
+    // Don't return a favicon iconURL unless we're http or https
+    KURL documentURL = m_frame->document()->url();
+    if (!documentURL.protocolInHTTPFamily())
+        return IconURL();
+
+    KURL url;
+    bool couldSetProtocol = url.setProtocol(documentURL.protocol());
+    ASSERT_UNUSED(couldSetProtocol, couldSetProtocol);
+    url.setHost(documentURL.host());
+    if (documentURL.hasPort())
+        url.setPort(documentURL.port());
+    if (iconType == Favicon) {
+        url.setPath("/favicon.ico");
+        return IconURL(url, Favicon);
+    }
+#if ENABLE(TOUCH_ICON_LOADING)
+    if (iconType == TouchPrecomposedIcon) {
+        url.setPath("/apple-touch-icon-precomposed.png");
+        return IconURL(url, TouchPrecomposedIcon);
+    }
+    if (iconType == TouchIcon) {
+        url.setPath("/apple-touch-icon.png");
+        return IconURL(url, TouchIcon);
+    }
+#endif
+    return IconURL();
+}
+
+}
diff --git a/Source/WebCore/loader/icon/IconController.h b/Source/WebCore/loader/icon/IconController.h
new file mode 100644 (file)
index 0000000..90c4197
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) Research In Motion Limited 2009. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IconController_h
+#define IconController_h
+
+#include "IconDatabaseBase.h"
+#include "IconURL.h"
+#include "KURL.h"
+
+namespace WebCore {
+
+class Frame;
+class IconLoader;
+
+class IconController {
+    WTF_MAKE_NONCOPYABLE(IconController);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit IconController(Frame*);
+    ~IconController();
+
+    KURL url();
+    IconURLs urlsForTypes(int iconTypes);
+
+    // FIXME: We should inline this function into its one caller!
+    void setURL(const IconURL&);
+
+    void startLoader();
+    void stopLoader();
+
+    void loadDecisionReceived(IconLoadDecision);
+    void continueLoadWithDecision(IconLoadDecision);
+
+    void commitToDatabase(const KURL& icon);
+
+private:
+    bool appendToIconURLs(IconType, IconURLs*);
+    IconURL defaultURL(IconType);
+
+    Frame* m_frame;
+
+    OwnPtr<IconLoader> m_iconLoader;
+    bool m_waitingForLoadDecision;
+};
+
+} // namespace WebCore
+
+#endif
index 96e6954..bede65c 100644 (file)
@@ -69,12 +69,12 @@ void IconLoader::startLoading()
     // SubresourceLoader::create returns.
     m_loadIsInProgress = true;
 
-    ResourceRequest resourceRequest(m_frame->loader()->iconURL());
+    ResourceRequest resourceRequest(m_frame->loader()->icon()->url());
     resourceRequest.setPriority(ResourceLoadPriorityLow);
 
     RefPtr<SubresourceLoader> loader = resourceLoadScheduler()->scheduleSubresourceLoad(m_frame, this, resourceRequest);
     if (!loader)
-        LOG_ERROR("Failed to start load for icon at url %s", m_frame->loader()->iconURL().string().ascii().data());
+        LOG_ERROR("Failed to start load for icon at url %s", m_frame->loader()->icon()->url().string().ascii().data());
 
     // Store the handle so we can cancel the load if stopLoading is called later.
     // But only do it if the load hasn't already completed.
@@ -157,7 +157,7 @@ void IconLoader::finishLoading(const KURL& iconURL, PassRefPtr<SharedBuffer> dat
     
     if (!iconURL.isEmpty() && m_loadIsInProgress) {
         LOG(IconDatabase, "IconLoader::finishLoading() - Committing iconURL %s to database", iconURL.string().ascii().data());
-        m_frame->loader()->commitIconURLToIconDatabase(iconURL);
+        m_frame->loader()->icon()->commitToDatabase(iconURL);
         // Setting the icon data only after committing to the database ensures that the data is
         // kept in memory (so it does not have to be read from the database asynchronously), since
         // there is a page URL referencing it.
index 0664676..f6d5b81 100644 (file)
@@ -42,12 +42,12 @@ class IconLoader : private SubresourceLoaderClient {
 public:
     static PassOwnPtr<IconLoader> create(Frame*);
     ~IconLoader();
-    
+
     void startLoading();
     void stopLoading();
 
 private:
-    IconLoader(Frame*);
+    explicit IconLoader(Frame*);
 
     virtual void didReceiveResponse(SubresourceLoader*, const ResourceResponse&);
     virtual void didReceiveData(SubresourceLoader*, const char*, int);
@@ -55,7 +55,7 @@ private:
     virtual void didFail(SubresourceLoader*, const ResourceError&);
 
     virtual void didReceiveAuthenticationChallenge(SubresourceLoader*, const AuthenticationChallenge&);
-    
+
     void finishLoading(const KURL&, PassRefPtr<SharedBuffer> data);
     void clearLoadingState();
 
@@ -63,7 +63,7 @@ private:
 
     RefPtr<SubresourceLoader> m_resourceLoader;
     bool m_loadIsInProgress;
-}; // class IconLoader
+};
 
 } // namespace WebCore
 
index 9f9eac4..b8ae61f 100755 (executable)
@@ -1,3 +1,13 @@
+2011-06-13  Adam Barth  <abarth@webkit.org>
+
+        Reviewed by Nate Chapin.
+
+        Factor IconController out of FrameLoader
+        https://bugs.webkit.org/show_bug.cgi?id=62509
+
+        * src/WebFrameImpl.cpp:
+        (WebKit::WebFrameImpl::iconURLs):
+
 2011-06-12  Adam Barth  <abarth@webkit.org>
 
         Reviewed by Alexey Proskuryakov.
index 7ea0d3f..219a6e9 100644 (file)
@@ -531,7 +531,7 @@ WebVector<WebIconURL> WebFrameImpl::iconURLs(int iconTypes) const
     // The URL to the icon may be in the header. As such, only
     // ask the loader for the icon if it's finished loading.
     if (frameLoader->state() == FrameStateComplete)
-        return frameLoader->iconURLs(iconTypes);
+        return frameLoader->icon()->urlsForTypes(iconTypes);
     return WebVector<WebIconURL>();
 }