1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:27:45 +00:00

LibWeb: Update displayed favicon when a favicon is loaded

When a favicon has been loaded, trigger a favicon update on
document level. Of all the link tags in the header, the last
favicon that is load should be shown.

When the favicon could not be loaded, load the next icon in reverse tree
order.
This commit is contained in:
Anthony Van de Gejuchte 2022-04-03 19:49:38 +02:00 committed by Andreas Kling
parent 13847aa7e8
commit 06d9853a8b
4 changed files with 116 additions and 0 deletions

View file

@ -51,6 +51,7 @@
#include <LibWeb/HTML/HTMLHtmlElement.h>
#include <LibWeb/HTML/HTMLIFrameElement.h>
#include <LibWeb/HTML/HTMLImageElement.h>
#include <LibWeb/HTML/HTMLLinkElement.h>
#include <LibWeb/HTML/HTMLScriptElement.h>
#include <LibWeb/HTML/HTMLTitleElement.h>
#include <LibWeb/HTML/MessageEvent.h>
@ -1560,4 +1561,48 @@ void Document::invalidate_stacking_context_tree()
const_cast<Painting::PaintableBox*>(paint_box)->invalidate_stacking_context();
}
void Document::check_favicon_after_loading_link_resource()
{
// https://html.spec.whatwg.org/multipage/links.html#rel-icon
// NOTE: firefox also load favicons outside the head tag, which is against spec (see table 4.6.7)
auto head_element = head();
auto favicon_link_elements = HTMLCollection::create(*head_element, [](Element const& element) {
if (!is<HTML::HTMLLinkElement>(element))
return false;
return static_cast<HTML::HTMLLinkElement const&>(element).has_loaded_icon();
});
if (favicon_link_elements->length() == 0) {
dbgln_if(SPAM_DEBUG, "No favicon found to be used");
return;
}
// 4.6.7.8 Link type "icon"
//
// If there are multiple equally appropriate icons, user agents must use the last one declared
// in tree order at the time that the user agent collected the list of icons.
//
// If multiple icons are provided, the user agent must select the most appropriate icon
// according to the type, media, and sizes attributes.
//
// FIXME: There is no selective behavior yet for favicons.
for (auto i = favicon_link_elements->length(); i-- > 0;) {
auto favicon_element = favicon_link_elements->item(i);
if (favicon_element == m_active_element)
return;
// If the user agent tries to use an icon but that icon is determined, upon closer examination,
// to in fact be inappropriate (...), then the user agent must try the next-most-appropriate icon
// as determined by the attributes.
if (static_cast<HTML::HTMLLinkElement*>(favicon_element)->load_favicon_and_use_if_window_is_active()) {
m_active_favicon = favicon_element;
return;
}
}
dbgln_if(SPAM_DEBUG, "No favicon found to be used");
}
}