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-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: http://svn.webkit.org/repository/webkit/trunk@88682 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt
index abac76f..b4700bc 100644
--- a/Source/WebCore/CMakeLists.txt
+++ b/Source/WebCore/CMakeLists.txt
@@ -989,6 +989,7 @@
loader/cache/CachedXSLStyleSheet.cpp
loader/cache/MemoryCache.cpp
+ loader/icon/IconController.cpp
loader/icon/IconDatabase.cpp
loader/icon/IconDatabaseBase.cpp
loader/icon/IconLoader.cpp
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 800092f..7035593 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -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.
diff --git a/Source/WebCore/GNUmakefile.list.am b/Source/WebCore/GNUmakefile.list.am
index 759f07c..5a744bf 100644
--- a/Source/WebCore/GNUmakefile.list.am
+++ b/Source/WebCore/GNUmakefile.list.am
@@ -2094,6 +2094,8 @@
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 \
diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi
index 93fb39e..9b4fd54 100644
--- a/Source/WebCore/WebCore.gypi
+++ b/Source/WebCore/WebCore.gypi
@@ -675,6 +675,7 @@
'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',
@@ -3408,6 +3409,7 @@
'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',
diff --git a/Source/WebCore/WebCore.pro b/Source/WebCore/WebCore.pro
index f37cadf..ad36fc4 100644
--- a/Source/WebCore/WebCore.pro
+++ b/Source/WebCore/WebCore.pro
@@ -870,6 +870,7 @@
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 @@
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 \
diff --git a/Source/WebCore/WebCore.vcproj/WebCore.vcproj b/Source/WebCore/WebCore.vcproj/WebCore.vcproj
index 49c3f94..449fe6d 100755
--- a/Source/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/Source/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -25917,6 +25917,14 @@
Name="icon"
>
<File
+ RelativePath="..\loader\icon\IconController.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\loader\icon\IconController.h"
+ >
+ </File>
+ <File
RelativePath="..\loader\icon\IconDatabase.cpp"
>
</File>
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index f00daee..731219d 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -3170,6 +3170,8 @@
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, ); }; };
@@ -9787,6 +9789,8 @@
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>"; };
@@ -13977,6 +13981,8 @@
5126E6B60A2E3AEF005C29FA /* icon */ = {
isa = PBXGroup;
children = (
+ 97E4028D13A696ED00913D67 /* IconController.cpp */,
+ 97E4028E13A696ED00913D67 /* IconController.h */,
5126E6B90A2E3B12005C29FA /* IconDatabase.cpp */,
5126E6BA0A2E3B12005C29FA /* IconDatabase.h */,
516953951329A3C800B92D04 /* IconDatabaseBase.cpp */,
@@ -23188,6 +23194,7 @@
439D334313A6911C00C20F4F /* SVGAnimatedType.h in Headers */,
439D334413A6911C00C20F4F /* SVGAnimatedTypeAnimator.h in Headers */,
439D334513A6911C00C20F4F /* SVGAnimatorFactory.h in Headers */,
+ 97E4029013A696ED00913D67 /* IconController.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -25921,6 +25928,7 @@
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;
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index d3bc675..dd19f5d 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -2115,12 +2115,10 @@
// 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 @@
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)
diff --git a/Source/WebCore/inspector/InspectorResourceAgent.cpp b/Source/WebCore/inspector/InspectorResourceAgent.cpp
index 29cc182..66ba746 100644
--- a/Source/WebCore/inspector/InspectorResourceAgent.cpp
+++ b/Source/WebCore/inspector/InspectorResourceAgent.cpp
@@ -237,7 +237,7 @@
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;
diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp
index 67ab924..7b36621 100644
--- a/Source/WebCore/loader/DocumentLoader.cpp
+++ b/Source/WebCore/loader/DocumentLoader.cpp
@@ -865,7 +865,7 @@
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 @@
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*)
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index bc7b461..89396a0 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -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 @@
, 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 @@
parser->stopParsing();
parser->finish();
}
-
- if (m_iconLoader)
- m_iconLoader->stopLoading();
+
+ icon()->stopLoader();
}
bool FrameLoader::closeURL()
@@ -464,82 +461,6 @@
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 @@
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 @@
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() : "";
diff --git a/Source/WebCore/loader/FrameLoader.h b/Source/WebCore/loader/FrameLoader.h
index dbe280a..c53a365 100644
--- a/Source/WebCore/loader/FrameLoader.h
+++ b/Source/WebCore/loader/FrameLoader.h
@@ -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 FrameNetworkingContext;
class HistoryItem;
class HTMLFormElement;
-class IconLoader;
class NavigationAction;
class NetworkingContext;
class Page;
@@ -102,6 +101,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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
index 0000000..77d52ee
--- /dev/null
+++ b/Source/WebCore/loader/icon/IconController.cpp
@@ -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
index 0000000..90c4197
--- /dev/null
+++ b/Source/WebCore/loader/icon/IconController.h
@@ -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
diff --git a/Source/WebCore/loader/icon/IconLoader.cpp b/Source/WebCore/loader/icon/IconLoader.cpp
index 96e6954..bede65c 100644
--- a/Source/WebCore/loader/icon/IconLoader.cpp
+++ b/Source/WebCore/loader/icon/IconLoader.cpp
@@ -69,12 +69,12 @@
// 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 @@
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.
diff --git a/Source/WebCore/loader/icon/IconLoader.h b/Source/WebCore/loader/icon/IconLoader.h
index 0664676..f6d5b81 100644
--- a/Source/WebCore/loader/icon/IconLoader.h
+++ b/Source/WebCore/loader/icon/IconLoader.h
@@ -42,12 +42,12 @@
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 @@
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 @@
RefPtr<SubresourceLoader> m_resourceLoader;
bool m_loadIsInProgress;
-}; // class IconLoader
+};
} // namespace WebCore