Title: [95593] trunk/Source/WebCore
Revision
95593
Author
commit-qu...@webkit.org
Date
2011-09-20 18:49:03 -0700 (Tue, 20 Sep 2011)

Log Message

Support for multiple <link rel="icon"> favicon elements.
https://bugs.webkit.org/show_bug.cgi?id=65564

Patch by Rachel Blum <gr...@chromium.org> on 2011-09-20
Reviewed by Darin Fisher.

No tests - purely an API change. (And API is not exposed to LayoutTests)

* dom/Document.cpp:
(WebCore::Document::iconURLs):
(WebCore::Document::addIconURL):
* dom/Document.h:
* dom/IconURL.cpp:
(WebCore::toIconIndex):
* dom/IconURL.h:
(WebCore::IconURL::IconURL):
* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::process):
* loader/LinkLoader.cpp:
(WebCore::LinkLoader::loadLink):
* loader/LinkLoader.h:
* loader/icon/IconController.cpp:
(WebCore::IconController::urlsForTypes):
(WebCore::IconController::appendToIconURLs):
(WebCore::IconController::defaultURL):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (95592 => 95593)


--- trunk/Source/WebCore/ChangeLog	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/ChangeLog	2011-09-21 01:49:03 UTC (rev 95593)
@@ -1,3 +1,30 @@
+2011-09-20  Rachel Blum  <gr...@chromium.org>
+
+        Support for multiple <link rel="icon"> favicon elements.
+        https://bugs.webkit.org/show_bug.cgi?id=65564
+
+        Reviewed by Darin Fisher.
+
+        No tests - purely an API change. (And API is not exposed to LayoutTests)
+
+        * dom/Document.cpp:
+        (WebCore::Document::iconURLs):
+        (WebCore::Document::addIconURL):
+        * dom/Document.h:
+        * dom/IconURL.cpp:
+        (WebCore::toIconIndex):
+        * dom/IconURL.h:
+        (WebCore::IconURL::IconURL):
+        * html/HTMLLinkElement.cpp:
+        (WebCore::HTMLLinkElement::process):
+        * loader/LinkLoader.cpp:
+        (WebCore::LinkLoader::loadLink):
+        * loader/LinkLoader.h:
+        * loader/icon/IconController.cpp:
+        (WebCore::IconController::urlsForTypes):
+        (WebCore::IconController::appendToIconURLs):
+        (WebCore::IconController::defaultURL):
+
 2011-09-20  Ojan Vafai  <o...@chromium.org>
 
         [css3-flexbox] cleanup padding width calculations

Modified: trunk/Source/WebCore/dom/Document.cpp (95592 => 95593)


--- trunk/Source/WebCore/dom/Document.cpp	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/dom/Document.cpp	2011-09-21 01:49:03 UTC (rev 95593)
@@ -5,7 +5,7 @@
  *           (C) 2006 Alexey Proskuryakov (a...@webkit.org)
  * Copyright (C) 2004, 2005, 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) 2008, 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved.
  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
  *
  * This library is free software; you can redistribute it and/or
@@ -4430,26 +4430,25 @@
     return StringHasher::hashMemory<sizeof(FormElementKey)>(&key);
 }
 
-IconURL Document::iconURL(IconType iconType) const
+const Vector<IconURL>& Document::iconURLs() const
 {
-    return m_iconURLs[toIconIndex(iconType)];
+    return m_iconURLs;
 }
 
-void Document::setIconURL(const String& url, const String& mimeType, IconType iconType)
+void Document::addIconURL(const String& url, const String& mimeType, const String& sizes, IconType iconType)
 {
+    if (url.isEmpty())
+        return;
+
     // FIXME - <rdar://problem/4727645> - At some point in the future, we might actually honor the "mimeType"
-    IconURL newURL(KURL(ParsedURLString, url), iconType);
-    if (iconURL(iconType).m_iconURL.isEmpty())
-        setIconURL(newURL);
-    else if (!mimeType.isEmpty())
-        setIconURL(newURL);
-    if (Frame* f = frame())
-        f->loader()->icon()->setURL(newURL);
-}
+    IconURL newURL(KURL(ParsedURLString, url), sizes, mimeType, iconType);
+    m_iconURLs.append(newURL);
 
-void Document::setIconURL(const IconURL& iconURL)
-{
-    m_iconURLs[toIconIndex(iconURL.m_iconType)] = iconURL;
+    if (Frame* f = frame()) {
+        IconURL iconURL = f->loader()->icon()->iconURL(iconType);
+        if (iconURL == newURL)
+            f->loader()->didChangeIcons(iconType);
+    }
 }
 
 void Document::registerFormElementWithFormAttribute(FormAssociatedElement* element)

Modified: trunk/Source/WebCore/dom/Document.h (95592 => 95593)


--- trunk/Source/WebCore/dom/Document.h	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/dom/Document.h	2011-09-21 01:49:03 UTC (rev 95593)
@@ -6,6 +6,7 @@
  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011 Google Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -917,9 +918,8 @@
     
     void setHasNodesWithPlaceholderStyle() { m_hasNodesWithPlaceholderStyle = true; }
 
-    IconURL iconURL(IconType) const;
-    void setIconURL(const String&, const String&, IconType);
-    void setIconURL(const IconURL&);
+    const Vector<IconURL>& iconURLs() const;
+    void addIconURL(const String& url, const String& mimeType, const String& size, IconType);
 
     void setUseSecureKeyboardEntryWhenActive(bool);
     bool useSecureKeyboardEntryWhenActive() const;
@@ -1349,7 +1349,7 @@
 
     bool m_createRenderers;
     bool m_inPageCache;
-    IconURL m_iconURLs[ICON_COUNT];
+    Vector<IconURL> m_iconURLs;
 
     HashSet<Element*> m_documentActivationCallbackElements;
     HashSet<Element*> m_mediaVolumeCallbackElements;

Modified: trunk/Source/WebCore/dom/IconURL.cpp (95592 => 95593)


--- trunk/Source/WebCore/dom/IconURL.cpp	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/dom/IconURL.cpp	2011-09-21 01:49:03 UTC (rev 95593)
@@ -54,5 +54,21 @@
     return index;
 }
 
+IconURL IconURL::defaultIconURL(const KURL& url, IconType type)
+{
+    IconURL result(url, emptyString(), emptyString(), type);
+    result.m_isDefaultIcon = true;
+    return result;
 }
 
+bool operator==(const IconURL& lhs, const IconURL& rhs)
+{
+    return lhs.m_iconType == rhs.m_iconType
+           && lhs.m_isDefaultIcon == rhs.m_isDefaultIcon
+           && lhs.m_iconURL == rhs.m_iconURL
+           && lhs.m_sizes == rhs.m_sizes
+           && lhs.m_mimeType == rhs.m_mimeType;
+}
+
+}
+

Modified: trunk/Source/WebCore/dom/IconURL.h (95592 => 95593)


--- trunk/Source/WebCore/dom/IconURL.h	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/dom/IconURL.h	2011-09-21 01:49:03 UTC (rev 95593)
@@ -45,25 +45,36 @@
     InvalidIcon = 0,
     Favicon = 1,
     TouchIcon = 1 << 1,
-    TouchPrecomposedIcon = 1 << 2
+    TouchPrecomposedIcon = 1 << 2,
 };
 
 struct IconURL {
     IconType m_iconType;
+    String m_sizes;
+    String m_mimeType;
     KURL m_iconURL;
+    bool m_isDefaultIcon;
 
     IconURL()
         : m_iconType(InvalidIcon)
+        , m_isDefaultIcon(false)
     {
     }
 
-    IconURL(const KURL& url, IconType type)
+    IconURL(const KURL& url, const String& sizes, const String& mimeType, IconType type)
         : m_iconType(type)
+        , m_sizes(sizes)
+        , m_mimeType(mimeType)
         , m_iconURL(url)
+        , m_isDefaultIcon(false)
     {
     }
+    
+    static IconURL defaultIconURL(const KURL&, IconType);
 };
 
+bool operator==(const IconURL&, const IconURL&);
+
 typedef Vector<IconURL, ICON_COUNT> IconURLs;
 
 // Returns the index of the given type, 0 is returned if the type is invalid.

Modified: trunk/Source/WebCore/html/HTMLLinkElement.cpp (95592 => 95593)


--- trunk/Source/WebCore/html/HTMLLinkElement.cpp	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/html/HTMLLinkElement.cpp	2011-09-21 01:49:03 UTC (rev 95593)
@@ -179,7 +179,7 @@
 
     String type = m_type.lower();
 
-    if (!m_linkLoader.loadLink(m_relAttribute, type, m_url, document()))
+    if (!m_linkLoader.loadLink(m_relAttribute, type, m_sizes->toString(), m_url, document()))
         return;
 
     bool acceptIfTypeContainsTextCSS = document()->page() && document()->page()->settings() && document()->page()->settings()->treatsAnyTextCSSLinkAsStylesheet();

Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (95592 => 95593)


--- trunk/Source/WebCore/loader/DocumentLoader.cpp	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp	2011-09-21 01:49:03 UTC (rev 95593)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -682,22 +683,6 @@
     }
 }
 
-IconURL DocumentLoader::iconURL(IconType iconType) const
-{
-    return m_iconURLs[toIconIndex(iconType)];
-}
-
-void DocumentLoader::setIconURL(const IconURL& url)
-{
-    if (url.m_iconURL.isEmpty())
-        return;
-
-    if (iconURL(url.m_iconType).m_iconURL != url.m_iconURL) {
-        m_iconURLs[toIconIndex(url.m_iconType)] = url;
-        frameLoader()->didChangeIcons(this, url.m_iconType);
-    }
-}
-
 KURL DocumentLoader::urlForHistory() const
 {
     // Return the URL to be used for history and B/F list.

Modified: trunk/Source/WebCore/loader/DocumentLoader.h (95592 => 95593)


--- trunk/Source/WebCore/loader/DocumentLoader.h	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/loader/DocumentLoader.h	2011-09-21 01:49:03 UTC (rev 95593)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,7 +33,6 @@
 #include "DocumentLoadTiming.h"
 #include "DocumentWriter.h"
 #include "IconDatabaseBase.h"
-#include "IconURL.h"
 #include "NavigationAction.h"
 #include "ResourceError.h"
 #include "ResourceRequest.h"
@@ -128,7 +128,6 @@
         bool isLoadingInAPISense() const;
         void setPrimaryLoadComplete(bool);
         void setTitle(const StringWithDirection&);
-        void setIconURL(const IconURL&);
         const String& overrideEncoding() const { return m_overrideEncoding; }
 
 #if PLATFORM(MAC)
@@ -175,7 +174,6 @@
 
         void stopRecordingResponses();
         const StringWithDirection& title() const { return m_pageTitle; }
-        IconURL iconURL(IconType) const;
 
         KURL urlForHistory() const;
         bool urlForHistoryReflectsFailure() const;
@@ -314,7 +312,6 @@
         bool m_wasOnloadHandled;
 
         StringWithDirection m_pageTitle;
-        IconURL m_iconURLs[ICON_COUNT];
 
         String m_overrideEncoding;
 

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (95592 => 95593)


--- trunk/Source/WebCore/loader/FrameLoader.cpp	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp	2011-09-21 01:49:03 UTC (rev 95593)
@@ -5,6 +5,7 @@
  * Copyright (C) 2008 Alp Toker <a...@atoker.com>
  * Copyright (C) Research In Motion Limited 2009. All rights reserved.
  * Copyright (C) 2011 Kris Jordan <krisjor...@gmail.com>
+ * Copyright (C) 2011 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -3228,10 +3229,9 @@
     }
 }
 
-void FrameLoader::didChangeIcons(DocumentLoader* loader, IconType type)
+void FrameLoader::didChangeIcons(IconType type)
 {
-    if (loader == m_documentLoader)
-        m_client->dispatchDidChangeIcons(type);
+    m_client->dispatchDidChangeIcons(type);
 }
 
 void FrameLoader::dispatchDidCommitLoad()

Modified: trunk/Source/WebCore/loader/FrameLoader.h (95592 => 95593)


--- trunk/Source/WebCore/loader/FrameLoader.h	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/loader/FrameLoader.h	2011-09-21 01:49:03 UTC (rev 95593)
@@ -2,6 +2,7 @@
  * 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.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -169,7 +170,7 @@
     bool subframeIsLoading() const;
     void willChangeTitle(DocumentLoader*);
     void didChangeTitle(DocumentLoader*);
-    void didChangeIcons(DocumentLoader*, IconType);
+    void didChangeIcons(IconType);
 
     FrameLoadType loadType() const;
 

Modified: trunk/Source/WebCore/loader/LinkLoader.cpp (95592 => 95593)


--- trunk/Source/WebCore/loader/LinkLoader.cpp	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/loader/LinkLoader.cpp	2011-09-21 01:49:03 UTC (rev 95593)
@@ -85,13 +85,13 @@
 }
 
 bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, const String& type,
-                          const KURL& href, Document* document)
+                          const String& sizes, const KURL& href, Document* document)
 {
     // We'll record this URL per document, even if we later only use it in top level frames
     if (relAttribute.m_iconType != InvalidIcon && href.isValid() && !href.isEmpty()) {
         if (!m_client->shouldLoadLink()) 
             return false;
-        document->setIconURL(href.string(), type, relAttribute.m_iconType);
+        document->addIconURL(href.string(), type, sizes, relAttribute.m_iconType);
     }
 
     if (relAttribute.m_isDNSPrefetch) {

Modified: trunk/Source/WebCore/loader/LinkLoader.h (95592 => 95593)


--- trunk/Source/WebCore/loader/LinkLoader.h	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/loader/LinkLoader.h	2011-09-21 01:49:03 UTC (rev 95593)
@@ -50,7 +50,7 @@
     // from CachedResourceClient
     virtual void notifyFinished(CachedResource*);
     
-    bool loadLink(const LinkRelAttribute&, const String& type, const KURL&, Document*);
+    bool loadLink(const LinkRelAttribute&, const String& type, const String& sizes, const KURL&, Document*);
 
 private:
     void linkLoadTimerFired(Timer<LinkLoader>*);

Modified: trunk/Source/WebCore/loader/icon/IconController.cpp (95592 => 95593)


--- trunk/Source/WebCore/loader/icon/IconController.cpp	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/loader/icon/IconController.cpp	2011-09-21 01:49:03 UTC (rev 95593)
@@ -5,6 +5,7 @@
  * Copyright (C) 2008 Alp Toker <a...@atoker.com>
  * Copyright (C) Research In Motion Limited 2009. All rights reserved.
  * Copyright (C) 2011 Kris Jordan <krisjor...@gmail.com>
+ * Copyright (C) 2011 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -64,30 +65,61 @@
     return iconURLs.isEmpty() ? KURL() : iconURLs[0].m_iconURL;
 }
 
+IconURL IconController::iconURL(IconType iconType) const
+{
+    IconURL result;
+    const Vector<IconURL>& iconURLs = m_frame->document()->iconURLs();
+    Vector<IconURL>::const_iterator iter(iconURLs.begin());
+    for (; iter != iconURLs.end(); ++iter) {
+        if (iter->m_iconType == iconType) {
+            if (result.m_iconURL.isEmpty() || !iter->m_mimeType.isEmpty())
+                result = *iter;
+        }
+    }
+
+    return result;
+}
+
 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;
+    int missedIcons = 0;
     if (iconTypes & TouchPrecomposedIcon)
-        havePrecomposedIcon = appendToIconURLs(TouchPrecomposedIcon, &iconURLs);
+        missedIcons += appendToIconURLs(TouchPrecomposedIcon, &iconURLs) ? 0:1;
 
-    bool haveTouchIcon = false;
     if (iconTypes & TouchIcon)
-        haveTouchIcon = appendToIconURLs(TouchIcon, &iconURLs);
+      missedIcons += appendToIconURLs(TouchIcon, &iconURLs) ? 0:1;
 
     // Only return the default touch icons when the both were required and neither was gotten.
-    if (iconTypes & TouchPrecomposedIcon && iconTypes & TouchIcon && !havePrecomposedIcon && !haveTouchIcon) {
+    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();
+    for (Vector<IconURL>::const_iterator iter = allIconURLs.begin(); iter != allIconURLs.end(); ++iter) {
+        if (!(iter->m_iconType & iconTypes))
+            continue;
+
+        int i;
+        int iconCount = iconURLs.size();
+        for (i = 0; i < iconCount; ++i) {
+            if (*iter == iconURLs.at(i))
+                break;
+        }
+        if (i == iconCount)
+            iconURLs.append(*iter);
+    }
+
     return iconURLs;
 }
 
@@ -98,11 +130,6 @@
     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.
@@ -218,11 +245,11 @@
 
 bool IconController::appendToIconURLs(IconType iconType, IconURLs* iconURLs)
 {
-    IconURL url = ""
-    if (url.m_iconURL.isEmpty())
+    IconURL faviconURL = iconURL(iconType);
+    if (faviconURL.m_iconURL.isEmpty())
         return false;
 
-    iconURLs->append(url);
+    iconURLs->append(faviconURL);
     return true;
 }
 
@@ -239,18 +266,19 @@
     url.setHost(documentURL.host());
     if (documentURL.hasPort())
         url.setPort(documentURL.port());
+
     if (iconType == Favicon) {
         url.setPath("/favicon.ico");
-        return IconURL(url, Favicon);
+        return IconURL::defaultIconURL(url, Favicon);
     }
 #if ENABLE(TOUCH_ICON_LOADING)
     if (iconType == TouchPrecomposedIcon) {
         url.setPath("/apple-touch-icon-precomposed.png");
-        return IconURL(url, TouchPrecomposedIcon);
+        return IconURL::defaultIconURL(url, TouchPrecomposedIcon);
     }
     if (iconType == TouchIcon) {
         url.setPath("/apple-touch-icon.png");
-        return IconURL(url, TouchIcon);
+        return IconURL::defaultIconURL(url, TouchIcon);
     }
 #endif
     return IconURL();

Modified: trunk/Source/WebCore/loader/icon/IconController.h (95592 => 95593)


--- trunk/Source/WebCore/loader/icon/IconController.h	2011-09-21 01:48:50 UTC (rev 95592)
+++ trunk/Source/WebCore/loader/icon/IconController.h	2011-09-21 01:49:03 UTC (rev 95593)
@@ -49,10 +49,8 @@
 
     KURL url();
     IconURLs urlsForTypes(int iconTypes);
+    IconURL iconURL(IconType) const;
 
-    // FIXME: We should inline this function into its one caller!
-    void setURL(const IconURL&);
-
     void startLoader();
     void stopLoader();
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to