Use auto for some of our lambda function parameters
[WebKit-https.git] / Source / WebCore / html / LinkIconCollector.cpp
1 /*
2  * Copyright (C) 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "LinkIconCollector.h"
28
29 #include "Document.h"
30 #include "ElementChildIterator.h"
31 #include "HTMLHeadElement.h"
32 #include "HTMLLinkElement.h"
33 #include "LinkIconType.h"
34
35 namespace WebCore {
36
37 const unsigned defaultTouchIconWidth = 60;
38
39 static unsigned iconSize(const LinkIconCollector::Icon& icon)
40 {
41     if (icon.size)
42         return *icon.size;
43
44     if (icon.type == LinkIconType::TouchIcon || icon.type == LinkIconType::TouchPrecomposedIcon)
45         return defaultTouchIconWidth;
46
47     return 0;
48 }
49
50 static int compareIcons(const LinkIconCollector::Icon& a, const LinkIconCollector::Icon& b)
51 {
52     // Apple Touch icons always come first.
53     if (a.type == LinkIconType::Favicon && b.type != LinkIconType::Favicon)
54         return 1;
55     if (a.type == LinkIconType::Favicon && b.type != LinkIconType::Favicon)
56         return -1;
57
58     unsigned aSize = iconSize(a);
59     unsigned bSize = iconSize(b);
60
61     if (bSize > aSize)
62         return 1;
63     if (bSize < aSize)
64         return -1;
65
66     // A Precomposed icon should come first if both icons have the same size.
67     if (a.type != LinkIconType::TouchPrecomposedIcon && b.type == LinkIconType::TouchPrecomposedIcon)
68         return 1;
69     if (b.type != LinkIconType::TouchPrecomposedIcon && a.type == LinkIconType::TouchPrecomposedIcon)
70         return -1;
71
72     return 0;
73 }
74
75 auto LinkIconCollector::iconsOfTypes(OptionSet<LinkIconType> iconTypes) -> Vector<Icon>
76 {
77     auto* head = m_document.head();
78     if (!head)
79         return { };
80
81     Vector<Icon> icons;
82
83     for (auto& linkElement : childrenOfType<HTMLLinkElement>(*head)) {
84         if (!linkElement.iconType())
85             continue;
86
87         auto iconType = *linkElement.iconType();
88         if (!iconTypes.contains(iconType))
89             continue;
90
91         auto url = linkElement.href();
92         if (!url.protocolIsInHTTPFamily())
93             continue;
94
95         // This icon size parsing is a little wonky - it only parses the first
96         // part of the size, "60x70" becomes "60". This is for compatibility reasons
97         // and is probably good enough for now.
98         Optional<unsigned> iconSize;
99
100         if (linkElement.sizes().length()) {
101             bool ok;
102             unsigned size = linkElement.sizes().item(0).string().stripWhiteSpace().toUInt(&ok);
103             if (ok)
104                 iconSize = size;
105         }
106
107         icons.append({ url, iconType, iconSize });
108     }
109
110     std::sort(icons.begin(), icons.end(), [](auto& a, auto& b) {
111         return compareIcons(a, b) < 0;
112     });
113
114     return icons;
115 }
116
117 }