summaryrefslogtreecommitdiff
path: root/Source/WebCore/loader/icon/IconController.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/loader/icon/IconController.cpp')
-rw-r--r--Source/WebCore/loader/icon/IconController.cpp170
1 files changed, 61 insertions, 109 deletions
diff --git a/Source/WebCore/loader/icon/IconController.cpp b/Source/WebCore/loader/icon/IconController.cpp
index 06c7a5e45..9a1a93148 100644
--- a/Source/WebCore/loader/icon/IconController.cpp
+++ b/Source/WebCore/loader/icon/IconController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2011, 2015 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>
@@ -16,7 +16,7 @@
* 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
+ * 3. Neither the name of Apple 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.
*
@@ -37,12 +37,14 @@
#include "Document.h"
#include "DocumentLoader.h"
+#include "ElementChildIterator.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
+#include "HTMLHeadElement.h"
+#include "HTMLLinkElement.h"
#include "IconDatabase.h"
-#include "IconDatabaseBase.h"
#include "IconLoader.h"
-#include "IconURL.h"
+#include "LinkIconType.h"
#include "Logging.h"
#include "MainFrame.h"
#include "Page.h"
@@ -53,7 +55,6 @@ namespace WebCore {
IconController::IconController(Frame& frame)
: m_frame(frame)
- , m_waitingForLoadDecision(false)
{
}
@@ -61,63 +62,57 @@ IconController::~IconController()
{
}
-URL IconController::url()
+static URL iconFromLinkElements(Frame& frame)
{
- IconURLs iconURLs = urlsForTypes(Favicon);
- return iconURLs.isEmpty() ? URL() : iconURLs[0].m_iconURL;
-}
-
-IconURL IconController::iconURL(IconType iconType) const
-{
- IconURL result;
- const Vector<IconURL>& iconURLs = m_frame.document()->iconURLs(iconType);
- Vector<IconURL>::const_iterator iter(iconURLs.begin());
- for (; iter != iconURLs.end(); ++iter) {
- if (result.m_iconURL.isEmpty() || !iter->m_mimeType.isEmpty())
- result = *iter;
+ // This function returns the first icon with a mime type.
+ // If no icon with mime type exists, the last icon is returned.
+ // It may make more sense to always return the last icon,
+ // but this implementation is consistent with previous behavior.
+
+ URL result;
+
+ auto* document = frame.document();
+ if (!document)
+ return result;
+
+ auto* head = document->head();
+ if (!head)
+ return result;
+
+ for (auto& linkElement : childrenOfType<HTMLLinkElement>(*head)) {
+ if (!linkElement.iconType())
+ continue;
+ if (*linkElement.iconType() != LinkIconType::Favicon)
+ continue;
+ if (linkElement.href().isEmpty())
+ continue;
+ result = linkElement.href();
+ if (!linkElement.type().isEmpty())
+ break;
}
return result;
}
-IconURLs IconController::urlsForTypes(int iconTypesMask)
+URL IconController::url()
{
- IconURLs iconURLs;
- if (m_frame.tree().parent())
- return iconURLs;
-
- if (iconTypesMask & Favicon && !appendToIconURLs(Favicon, &iconURLs))
- iconURLs.append(defaultURL(Favicon));
-
-#if ENABLE(TOUCH_ICON_LOADING)
- int missedIcons = 0;
- if (iconTypesMask & TouchPrecomposedIcon)
- missedIcons += appendToIconURLs(TouchPrecomposedIcon, &iconURLs) ? 0:1;
-
- if (iconTypesMask & TouchIcon)
- missedIcons += appendToIconURLs(TouchIcon, &iconURLs) ? 0:1;
-
- // Only return the default touch icons when the both were required and neither was gotten.
- if (missedIcons == 2) {
- iconURLs.append(defaultURL(TouchPrecomposedIcon));
- iconURLs.append(defaultURL(TouchIcon));
- }
-#endif
-
- // Finally, append all remaining icons of this type.
- const Vector<IconURL>& allIconURLs = m_frame.document()->iconURLs(iconTypesMask);
- for (Vector<IconURL>::const_iterator iter = allIconURLs.begin(); iter != allIconURLs.end(); ++iter) {
- int i;
- int iconCount = iconURLs.size();
- for (i = 0; i < iconCount; ++i) {
- if (*iter == iconURLs.at(i))
- break;
- }
- if (i == iconCount)
- iconURLs.append(*iter);
+ if (!m_frame.isMainFrame())
+ return URL();
+
+ auto icon = iconFromLinkElements(m_frame);
+ if (!icon.isEmpty())
+ return icon;
+
+ icon = m_frame.document()->completeURL(ASCIILiteral("/favicon.ico"));
+ if (icon.protocolIsInHTTPFamily()) {
+ // FIXME: Not sure we need to remove credentials like this.
+ // However this preserves behavior this code path has historically had.
+ icon.setUser(String());
+ icon.setPass(String());
+ return icon;
}
- return iconURLs;
+ return URL();
}
void IconController::commitToDatabase(const URL& icon)
@@ -142,9 +137,8 @@ void IconController::startLoader()
if (!documentCanHaveIcon(m_frame.document()->url()))
return;
- URL iconURL(url());
- String urlString(iconURL.string());
- if (urlString.isEmpty())
+ URL iconURL = url();
+ if (iconURL.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.
@@ -154,30 +148,30 @@ void IconController::startLoader()
// 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) {
+ if (m_frame.loader().loadType() == FrameLoadType::Reload && m_frame.loader().loadType() == FrameLoadType::ReloadFromOrigin) {
continueLoadWithDecision(IconLoadYes);
return;
}
if (iconDatabase().supportsAsynchronousMode()) {
// FIXME (<rdar://problem/9168605>) - We should support in-memory-only private browsing icons in asynchronous icon database mode.
- if (m_frame.page() && m_frame.page()->settings().privateBrowsingEnabled())
+ if (m_frame.page() && m_frame.page()->usesEphemeralSession())
return;
- m_frame.loader().documentLoader()->getIconLoadDecisionForIconURL(urlString);
+ m_frame.loader().documentLoader()->getIconLoadDecisionForIconURL(iconURL.string());
// 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());
+ IconLoadDecision decision = iconDatabase().synchronousLoadDecisionForIconURL(iconURL.string(), 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());
+ LOG(IconDatabase, "IconController %p might load icon %s later", this, iconURL.string().utf8().data());
m_waitingForLoadDecision = true;
m_frame.loader().client().registerForIconNotification();
commitToDatabase(iconURL);
@@ -208,16 +202,15 @@ void IconController::continueLoadWithDecision(IconLoadDecision iconLoadDecision)
ASSERT(iconLoadDecision != IconLoadUnknown);
if (iconLoadDecision == IconLoadNo) {
- URL iconURL(url());
- String urlString(iconURL.string());
- if (urlString.isEmpty())
+ URL iconURL = url();
+ if (iconURL.isEmpty())
return;
- LOG(IconDatabase, "IconController::startLoader() - Told not to load this icon, committing iconURL %s to database for pageURL mapping", urlString.ascii().data());
+ LOG(IconDatabase, "IconController::startLoader() - Told not to load this icon, committing iconURL %s to database for pageURL mapping", iconURL.string().utf8().data());
commitToDatabase(iconURL);
if (iconDatabase().supportsAsynchronousMode()) {
- m_frame.loader().documentLoader()->getIconDataForIconURL(urlString);
+ m_frame.loader().documentLoader()->getIconDataForIconURL(iconURL.string());
return;
}
@@ -225,8 +218,8 @@ void IconController::continueLoadWithDecision(IconLoadDecision iconLoadDecision)
// 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());
+ if (!iconDatabase().synchronousIconDataKnownForIconURL(iconURL.string())) {
+ LOG(IconDatabase, "Told not to load icon %s but icon data is not yet available - registering for notification and requesting load from disk", iconURL.string().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));
@@ -242,45 +235,4 @@ void IconController::continueLoadWithDecision(IconLoadDecision iconLoadDecision)
m_iconLoader->startLoading();
}
-bool IconController::appendToIconURLs(IconType iconType, IconURLs* iconURLs)
-{
- IconURL faviconURL = iconURL(iconType);
- if (faviconURL.m_iconURL.isEmpty())
- return false;
-
- iconURLs->append(faviconURL);
- return true;
-}
-
-IconURL IconController::defaultURL(IconType iconType)
-{
- // Don't return a favicon iconURL unless we're http or https
- URL documentURL = m_frame.document()->url();
- if (!documentURL.protocolIsInHTTPFamily())
- return IconURL();
-
- URL 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::defaultIconURL(url, Favicon);
- }
-#if ENABLE(TOUCH_ICON_LOADING)
- if (iconType == TouchPrecomposedIcon) {
- url.setPath("/apple-touch-icon-precomposed.png");
- return IconURL::defaultIconURL(url, TouchPrecomposedIcon);
- }
- if (iconType == TouchIcon) {
- url.setPath("/apple-touch-icon.png");
- return IconURL::defaultIconURL(url, TouchIcon);
- }
-#endif
- return IconURL();
-}
-
}