Add injected bundle SPI for getting favicon and touch icon URLs
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 9 May 2016 20:41:31 +0000 (20:41 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 9 May 2016 20:41:31 +0000 (20:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=157435

Reviewed by Darin Adler.

Source/WebCore:

* CMakeLists.txt:
Add new files.

* WebCore.xcodeproj/project.pbxproj:
Add new files.

* html/HTMLLinkElement.cpp:
(WebCore::HTMLLinkElement::iconType):
* html/HTMLLinkElement.h:
Rename LinkRelAttribute::IconType to LinkIconType.

* html/LinkIconCollector.cpp: Added.
(WebCore::iconSize):
New helper function that returns the icon size for an icon.

(WebCore::compareIcons):
Icon comparison function, to be used by for sorting.

(LinkIconCollector::iconsOfTypes):
Gather the right icons, sort them (descending by size) and return them.

* html/LinkIconCollector.h:
Added.

* html/LinkIconType.h:
Move icon type declarations here and arrange them so we can use them in an OptionSet.

* html/LinkRelAttribute.cpp:
(WebCore::LinkRelAttribute::LinkRelAttribute):
* html/LinkRelAttribute.h:
* loader/icon/IconController.cpp:
(WebCore::iconFromLinkElements):
Rename IconType to LinkIconType.

Source/WebKit2:

* WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInFrame.h:
* WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInFrame.mm:
(collectIcons):
New helper function that calls into the WebCore LinkCollector.

(-[WKWebProcessPlugInFrame appleTouchIconURLs]):
Call collectIcons.

(-[WKWebProcessPlugInFrame faviconURLs]):
Ditto.

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

14 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/HTMLLinkElement.cpp
Source/WebCore/html/HTMLLinkElement.h
Source/WebCore/html/LinkIconCollector.cpp [new file with mode: 0644]
Source/WebCore/html/LinkIconCollector.h [new file with mode: 0644]
Source/WebCore/html/LinkIconType.h [new file with mode: 0644]
Source/WebCore/html/LinkRelAttribute.cpp
Source/WebCore/html/LinkRelAttribute.h
Source/WebCore/loader/icon/IconController.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInFrame.h
Source/WebKit2/WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInFrame.mm

index f05b70e..a984ae0 100644 (file)
@@ -1736,6 +1736,7 @@ set(WebCore_SOURCES
     html/InputTypeNames.cpp
     html/LabelableElement.cpp
     html/LabelsNodeList.cpp
+    html/LinkIconCollector.cpp
     html/LinkRelAttribute.cpp
     html/MediaController.cpp
     html/MediaDocument.cpp
index af3bcaf..f57c401 100644 (file)
@@ -1,3 +1,44 @@
+2016-05-09  Anders Carlsson  <andersca@apple.com>
+
+        Add injected bundle SPI for getting favicon and touch icon URLs
+        https://bugs.webkit.org/show_bug.cgi?id=157435
+
+        Reviewed by Darin Adler.
+
+        * CMakeLists.txt:
+        Add new files.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        Add new files.
+
+        * html/HTMLLinkElement.cpp:
+        (WebCore::HTMLLinkElement::iconType):
+        * html/HTMLLinkElement.h:
+        Rename LinkRelAttribute::IconType to LinkIconType.
+
+        * html/LinkIconCollector.cpp: Added.
+        (WebCore::iconSize):
+        New helper function that returns the icon size for an icon.
+
+        (WebCore::compareIcons):
+        Icon comparison function, to be used by for sorting.
+
+        (LinkIconCollector::iconsOfTypes):
+        Gather the right icons, sort them (descending by size) and return them.
+
+        * html/LinkIconCollector.h:
+        Added.
+
+        * html/LinkIconType.h:
+        Move icon type declarations here and arrange them so we can use them in an OptionSet.
+
+        * html/LinkRelAttribute.cpp:
+        (WebCore::LinkRelAttribute::LinkRelAttribute):
+        * html/LinkRelAttribute.h:
+        * loader/icon/IconController.cpp:
+        (WebCore::iconFromLinkElements):
+        Rename IconType to LinkIconType.
+
 2016-05-06  Simon Fraser  <simon.fraser@apple.com>
 
         [iOS WK2] Font size increases on some pages after navigating then going back
index cac7247..a96e0e6 100644 (file)
                1A22464C0CC98DDB00C05240 /* SQLiteStatement.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2246460CC98DDB00C05240 /* SQLiteStatement.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1A22464D0CC98DDB00C05240 /* SQLiteTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2246470CC98DDB00C05240 /* SQLiteTransaction.cpp */; };
                1A22464E0CC98DDB00C05240 /* SQLiteTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2246480CC98DDB00C05240 /* SQLiteTransaction.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               1A250E0D1CDD632000D0BE63 /* LinkIconType.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A250E0C1CDD632000D0BE63 /* LinkIconType.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1A2A68230B5BEDE70002A480 /* ProgressTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A68210B5BEDE70002A480 /* ProgressTracker.cpp */; };
                1A2A68240B5BEDE70002A480 /* ProgressTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2A68220B5BEDE70002A480 /* ProgressTracker.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1A2AAC580DC2A3B100A20D9A /* ApplicationCacheStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2AAC560DC2A3B100A20D9A /* ApplicationCacheStorage.cpp */; };
                1A4A954D0B4EDCCB002D8C3C /* SharedBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A4A954B0B4EDCCB002D8C3C /* SharedBuffer.cpp */; };
                1A4A954E0B4EDCCB002D8C3C /* SharedBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A4A954C0B4EDCCB002D8C3C /* SharedBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1A4A95520B4EDCFF002D8C3C /* SharedBufferMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A4A95510B4EDCFF002D8C3C /* SharedBufferMac.mm */; };
+               1A4DA4211CDD3A8300F4473C /* LinkIconCollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A4DA41F1CDD3A8300F4473C /* LinkIconCollector.cpp */; };
+               1A4DA4221CDD3A8300F4473C /* LinkIconCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A4DA4201CDD3A8300F4473C /* LinkIconCollector.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1A569CF70D7E2B82007C3983 /* c_class.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A569CC60D7E2B82007C3983 /* c_class.cpp */; };
                1A569CF80D7E2B82007C3983 /* c_class.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A569CC70D7E2B82007C3983 /* c_class.h */; };
                1A569CF90D7E2B82007C3983 /* c_instance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A569CC80D7E2B82007C3983 /* c_instance.cpp */; };
                1A2246460CC98DDB00C05240 /* SQLiteStatement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLiteStatement.h; sourceTree = "<group>"; };
                1A2246470CC98DDB00C05240 /* SQLiteTransaction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLiteTransaction.cpp; sourceTree = "<group>"; };
                1A2246480CC98DDB00C05240 /* SQLiteTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLiteTransaction.h; sourceTree = "<group>"; };
+               1A250E0C1CDD632000D0BE63 /* LinkIconType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkIconType.h; sourceTree = "<group>"; };
                1A2A68210B5BEDE70002A480 /* ProgressTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ProgressTracker.cpp; sourceTree = "<group>"; };
                1A2A68220B5BEDE70002A480 /* ProgressTracker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ProgressTracker.h; sourceTree = "<group>"; };
                1A2AAC560DC2A3B100A20D9A /* ApplicationCacheStorage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ApplicationCacheStorage.cpp; sourceTree = "<group>"; };
                1A4A954B0B4EDCCB002D8C3C /* SharedBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SharedBuffer.cpp; sourceTree = "<group>"; };
                1A4A954C0B4EDCCB002D8C3C /* SharedBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SharedBuffer.h; sourceTree = "<group>"; };
                1A4A95510B4EDCFF002D8C3C /* SharedBufferMac.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = SharedBufferMac.mm; sourceTree = "<group>"; };
+               1A4DA41F1CDD3A8300F4473C /* LinkIconCollector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinkIconCollector.cpp; sourceTree = "<group>"; };
+               1A4DA4201CDD3A8300F4473C /* LinkIconCollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkIconCollector.h; sourceTree = "<group>"; };
                1A569CC60D7E2B82007C3983 /* c_class.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = c_class.cpp; sourceTree = "<group>"; };
                1A569CC70D7E2B82007C3983 /* c_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = c_class.h; sourceTree = "<group>"; };
                1A569CC80D7E2B82007C3983 /* c_instance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = c_instance.cpp; sourceTree = "<group>"; };
                                450CEBEF15073BBE002BB149 /* LabelableElement.h */,
                                A456FA2411AD4A830020B420 /* LabelsNodeList.cpp */,
                                A456FA2511AD4A830020B420 /* LabelsNodeList.h */,
+                               1A4DA41F1CDD3A8300F4473C /* LinkIconCollector.cpp */,
+                               1A4DA4201CDD3A8300F4473C /* LinkIconCollector.h */,
+                               1A250E0C1CDD632000D0BE63 /* LinkIconType.h */,
                                985BB96B13A94058007A0B69 /* LinkRelAttribute.cpp */,
                                985BB96C13A94058007A0B69 /* LinkRelAttribute.h */,
                                CD27F6E6145770D30078207D /* MediaController.cpp */,
                                A8CFF7AB0A156978000A4234 /* HTMLAnchorElement.h in Headers */,
                                A871D45D0A127CBC00B12A68 /* HTMLAppletElement.h in Headers */,
                                A8EA7D2E0A19385500A8EF5F /* HTMLAreaElement.h in Headers */,
+                               1A4DA4221CDD3A8300F4473C /* LinkIconCollector.h in Headers */,
                                7C5F28FC1A827D8400C0F31F /* HTMLAttachmentElement.h in Headers */,
                                E44613A20CD6331000FADA75 /* HTMLAudioElement.h in Headers */,
                                A871DC1F0A15205700B12A68 /* HTMLBaseElement.h in Headers */,
                                B22279D40D00BF220071B782 /* SVGFEDiffuseLightingElement.h in Headers */,
                                B22279D70D00BF220071B782 /* SVGFEDisplacementMapElement.h in Headers */,
                                B22279DA0D00BF220071B782 /* SVGFEDistantLightElement.h in Headers */,
+                               1A250E0D1CDD632000D0BE63 /* LinkIconType.h in Headers */,
                                4358E8861360A33B00E4748C /* SVGFEDropShadowElement.h in Headers */,
                                B22279DD0D00BF220071B782 /* SVGFEFloodElement.h in Headers */,
                                B22279E00D00BF220071B782 /* SVGFEFuncAElement.h in Headers */,
                                4331AC7813B6870000A9E5AE /* SVGAnimatedNumberList.cpp in Sources */,
                                431A2F9D13B6F2B0007791E4 /* SVGAnimatedNumberOptionalNumber.cpp in Sources */,
                                08B5F25513B5FFF2002959EC /* SVGAnimatedPath.cpp in Sources */,
+                               1A4DA4211CDD3A8300F4473C /* LinkIconCollector.cpp in Sources */,
                                43B9336A13B261B1004584BF /* SVGAnimatedPointList.cpp in Sources */,
                                431A302113B89DCC007791E4 /* SVGAnimatedPreserveAspectRatio.cpp in Sources */,
                                836FBCEC178C117F00B21A15 /* SVGAnimatedProperty.cpp in Sources */,
index 3cabdec..587cb05 100644 (file)
@@ -495,7 +495,7 @@ const AtomicString& HTMLLinkElement::type() const
     return getAttribute(typeAttr);
 }
 
-Optional<LinkRelAttribute::IconType> HTMLLinkElement::iconType() const
+Optional<LinkIconType> HTMLLinkElement::iconType() const
 {
     return m_relAttribute.iconType;
 }
index fd6cb82..1b1b1ce 100644 (file)
@@ -54,7 +54,7 @@ public:
 
     const AtomicString& type() const;
 
-    Optional<LinkRelAttribute::IconType> iconType() const;
+    Optional<LinkIconType> iconType() const;
 
     // the icon size string as parsed from the HTML attribute
     String iconSizes();
diff --git a/Source/WebCore/html/LinkIconCollector.cpp b/Source/WebCore/html/LinkIconCollector.cpp
new file mode 100644 (file)
index 0000000..9d2c02e
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2016 Apple Inc. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "LinkIconCollector.h"
+
+#include "Document.h"
+#include "ElementChildIterator.h"
+#include "HTMLHeadElement.h"
+#include "HTMLLinkElement.h"
+#include "LinkIconType.h"
+
+namespace WebCore {
+
+const unsigned defaultTouchIconWidth = 60;
+
+static unsigned iconSize(const LinkIconCollector::Icon& icon)
+{
+    if (icon.size)
+        return *icon.size;
+
+    if (icon.type == LinkIconType::TouchIcon || icon.type == LinkIconType::TouchPrecomposedIcon)
+        return defaultTouchIconWidth;
+
+    return 0;
+}
+
+static int compareIcons(const LinkIconCollector::Icon& a, const LinkIconCollector::Icon& b)
+{
+    // Apple Touch icons always come first.
+    if (a.type == LinkIconType::Favicon && b.type != LinkIconType::Favicon)
+        return 1;
+    if (a.type == LinkIconType::Favicon && b.type != LinkIconType::Favicon)
+        return -1;
+
+    unsigned aSize = iconSize(a);
+    unsigned bSize = iconSize(b);
+
+    if (bSize > aSize)
+        return 1;
+    if (bSize < aSize)
+        return -1;
+
+    // A Precomposed icon should come first if both icons have the same size.
+    if (a.type != LinkIconType::TouchPrecomposedIcon && b.type == LinkIconType::TouchPrecomposedIcon)
+        return 1;
+    if (b.type != LinkIconType::TouchPrecomposedIcon && a.type == LinkIconType::TouchPrecomposedIcon)
+        return -1;
+
+    return 0;
+}
+
+auto LinkIconCollector::iconsOfTypes(OptionSet<LinkIconType> iconTypes) -> Vector<Icon>
+{
+    auto* head = m_document.head();
+    if (!head)
+        return { };
+
+    Vector<Icon> icons;
+
+    for (auto& linkElement : childrenOfType<HTMLLinkElement>(*head)) {
+        if (!linkElement.iconType())
+            continue;
+
+        auto iconType = *linkElement.iconType();
+        if (!iconTypes.contains(iconType))
+            continue;
+
+        auto url = linkElement.href();
+        if (!url.protocolIsInHTTPFamily())
+            continue;
+
+        // This icon size parsing is a little wonky - it only parses the first
+        // part of the size, "60x70" becomes "60". This is for compatibility reasons
+        // and is probably good enough for now.
+        Optional<unsigned> iconSize;
+
+        if (linkElement.sizes().length()) {
+            bool ok;
+            unsigned size = linkElement.sizes().item(0).string().stripWhiteSpace().toUInt(&ok);
+            if (ok)
+                iconSize = size;
+        }
+
+        icons.append({ url, iconType, iconSize });
+    }
+
+    std::sort(icons.begin(), icons.end(), [](const LinkIconCollector::Icon& a, const LinkIconCollector::Icon& b) {
+        return compareIcons(a, b) < 0;
+    });
+
+    return icons;
+}
+
+}
diff --git a/Source/WebCore/html/LinkIconCollector.h b/Source/WebCore/html/LinkIconCollector.h
new file mode 100644 (file)
index 0000000..6f11495
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 Apple Inc. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
+ */
+
+#pragma once
+
+#include "URL.h"
+#include <wtf/OptionSet.h>
+#include <wtf/Optional.h>
+
+namespace WebCore {
+
+class Document;
+enum class LinkIconType;
+
+class LinkIconCollector {
+public:
+    explicit LinkIconCollector(Document& document)
+        : m_document(document)
+    {
+    }
+
+    struct Icon {
+        URL url;
+
+        LinkIconType type;
+        Optional<unsigned> size;
+    };
+
+    WEBCORE_EXPORT Vector<Icon> iconsOfTypes(OptionSet<LinkIconType>);
+
+private:
+    Document& m_document;
+};
+
+}
diff --git a/Source/WebCore/html/LinkIconType.h b/Source/WebCore/html/LinkIconType.h
new file mode 100644 (file)
index 0000000..e74fd8d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 Apple Inc. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
+ */
+
+#pragma once
+
+namespace WebCore {
+
+// These values are arranged so that they can be used with WTF::OptionSet.
+
+enum class LinkIconType {
+    Favicon = 1 << 0,
+    TouchIcon = 1 << 1,
+    TouchPrecomposedIcon = 1 <<2
+};
+
+}
index e6931e4..6e50b18 100644 (file)
@@ -32,6 +32,7 @@
 #include "config.h"
 #include "LinkRelAttribute.h"
 
+#include "LinkIconType.h"
 #include "RuntimeEnabledFeatures.h"
 #include <wtf/text/WTFString.h>
 
@@ -46,11 +47,11 @@ LinkRelAttribute::LinkRelAttribute(const String& rel)
     if (equalLettersIgnoringASCIICase(rel, "stylesheet"))
         isStyleSheet = true;
     else if (equalLettersIgnoringASCIICase(rel, "icon") || equalLettersIgnoringASCIICase(rel, "shortcut icon"))
-        iconType = IconType::Favicon;
+        iconType = LinkIconType::Favicon;
     else if (equalLettersIgnoringASCIICase(rel, "apple-touch-icon"))
-        iconType = IconType::TouchIcon;
+        iconType = LinkIconType::TouchIcon;
     else if (equalLettersIgnoringASCIICase(rel, "apple-touch-icon-precomposed"))
-        iconType = IconType::TouchPrecomposedIcon;
+        iconType = LinkIconType::TouchPrecomposedIcon;
     else if (equalLettersIgnoringASCIICase(rel, "dns-prefetch"))
         isDNSPrefetch = true;
     else if (RuntimeEnabledFeatures::sharedFeatures().linkPreloadEnabled() && equalLettersIgnoringASCIICase(rel, "preload"))
@@ -70,11 +71,11 @@ LinkRelAttribute::LinkRelAttribute(const String& rel)
             else if (equalLettersIgnoringASCIICase(word, "alternate"))
                 isAlternate = true;
             else if (equalLettersIgnoringASCIICase(word, "icon"))
-                iconType = IconType::Favicon;
+                iconType = LinkIconType::Favicon;
             else if (equalLettersIgnoringASCIICase(word, "apple-touch-icon"))
-                iconType = IconType::TouchIcon;
+                iconType = LinkIconType::TouchIcon;
             else if (equalLettersIgnoringASCIICase(word, "apple-touch-icon-precomposed"))
-                iconType = IconType::TouchPrecomposedIcon;
+                iconType = LinkIconType::TouchPrecomposedIcon;
 #if ENABLE(LINK_PREFETCH)
             else if (equalLettersIgnoringASCIICase(word, "prefetch"))
                 isLinkPrefetch = true;
index 7d4fddc..2009575 100644 (file)
 
 namespace WebCore {
 
-struct LinkRelAttribute {
-    enum class IconType {
-        Favicon,
-        TouchIcon,
-        TouchPrecomposedIcon,
-    };
+enum class LinkIconType;
 
+struct LinkRelAttribute {
     bool isStyleSheet { false };
-    Optional<IconType> iconType;
+    Optional<LinkIconType> iconType;
     bool isAlternate { false };
     bool isDNSPrefetch { false };
     bool isLinkPreload { false };
index f0692cf..9a1a931 100644 (file)
@@ -44,6 +44,7 @@
 #include "HTMLLinkElement.h"
 #include "IconDatabase.h"
 #include "IconLoader.h"
+#include "LinkIconType.h"
 #include "Logging.h"
 #include "MainFrame.h"
 #include "Page.h"
@@ -81,7 +82,7 @@ static URL iconFromLinkElements(Frame& frame)
     for (auto& linkElement : childrenOfType<HTMLLinkElement>(*head)) {
         if (!linkElement.iconType())
             continue;
-        if (*linkElement.iconType() != LinkRelAttribute::IconType::Favicon)
+        if (*linkElement.iconType() != LinkIconType::Favicon)
             continue;
         if (linkElement.href().isEmpty())
             continue;
index 7f56805..9103f7d 100644 (file)
@@ -1,3 +1,21 @@
+2016-05-09  Anders Carlsson  <andersca@apple.com>
+
+        Add injected bundle SPI for getting favicon and touch icon URLs
+        https://bugs.webkit.org/show_bug.cgi?id=157435
+
+        Reviewed by Darin Adler.
+
+        * WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInFrame.h:
+        * WebProcess/InjectedBundle/API/Cocoa/WKWebProcessPlugInFrame.mm:
+        (collectIcons):
+        New helper function that calls into the WebCore LinkCollector.
+
+        (-[WKWebProcessPlugInFrame appleTouchIconURLs]):
+        Call collectIcons.
+
+        (-[WKWebProcessPlugInFrame faviconURLs]):
+        Ditto.
+
 2016-05-06  Simon Fraser  <simon.fraser@apple.com>
 
         [iOS WK2] Font size increases on some pages after navigating then going back
index 3604aac..a82bafd 100644 (file)
@@ -45,6 +45,11 @@ WK_CLASS_AVAILABLE(10_10, 8_0)
 
 @property (nonatomic, readonly) _WKFrameHandle *handle;
 
+// Returns URLs ordered by resolution in descending order.
+// FIXME: These should be tagged nonnull.
+@property (nonatomic, readonly) WK_ARRAY(NSURL *) *appleTouchIconURLs WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
+@property (nonatomic, readonly) WK_ARRAY(NSURL *) *faviconURLs WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
+
 - (JSContext *)jsContextForWorld:(WKWebProcessPlugInScriptWorld *)world;
 - (WKWebProcessPlugInHitTestResult *)hitTest:(CGPoint)point;
 - (JSValue *)jsNodeForNodeHandle:(WKWebProcessPlugInNodeHandle *)nodeHandle inWorld:(WKWebProcessPlugInScriptWorld *)world;
index fc0c9ad..4ddc099 100644 (file)
 #import "_WKFrameHandleInternal.h"
 #import <JavaScriptCore/JSValue.h>
 #import <WebCore/CertificateInfo.h>
+#import <WebCore/Frame.h>
 #import <WebCore/IntPoint.h>
+#import <WebCore/LinkIconCollector.h>
+#import <WebCore/LinkIconType.h>
 
 using namespace WebKit;
 
@@ -103,6 +106,30 @@ using namespace WebKit;
     return [wrapper(API::FrameHandle::create(_frame->frameID()).leakRef()) autorelease];
 }
 
+static RetainPtr<NSArray> collectIcons(WebCore::Frame* frame, OptionSet<WebCore::LinkIconType> iconTypes)
+{
+    auto result = adoptNS([[NSMutableArray alloc] init]);
+
+    if (frame) {
+        if (auto* document = frame->document()) {
+            for (auto& icon : WebCore::LinkIconCollector(*document).iconsOfTypes(iconTypes))
+                [result addObject:(NSURL *)icon.url];
+        }
+    }
+
+    return result.autorelease();
+}
+
+- (NSArray *)appleTouchIconURLs
+{
+    return collectIcons(_frame->coreFrame(), { WebCore::LinkIconType::TouchIcon, WebCore::LinkIconType::TouchPrecomposedIcon }).autorelease();
+}
+
+- (NSArray *)faviconURLs
+{
+    return collectIcons(_frame->coreFrame(), WebCore::LinkIconType::Favicon).autorelease();
+}
+
 - (WKWebProcessPlugInFrame *)_parentFrame
 {
     WebFrame *parentFrame = _frame->parentFrame();