LinkIconCollector.cpp [plain text]
#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 LinkIcon& icon)
{
if (icon.size)
return *icon.size;
if (icon.type == LinkIconType::TouchIcon || icon.type == LinkIconType::TouchPrecomposedIcon)
return defaultTouchIconWidth;
return 0;
}
static int compareIcons(const LinkIcon& a, const LinkIcon& b)
{
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;
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<LinkIcon>
{
auto* head = m_document.head();
if (!head)
return { };
Vector<LinkIcon> 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;
std::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, linkElement.type(), iconSize });
}
std::sort(icons.begin(), icons.end(), [](auto& a, auto& b) {
return compareIcons(a, b) < 0;
});
return icons;
}
}