summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/HTML
diff options
context:
space:
mode:
authorAnthony Van de Gejuchte <anthonyvdg@yahoo.com>2022-04-03 19:49:38 +0200
committerAndreas Kling <kling@serenityos.org>2022-04-10 12:10:59 +0200
commit06d9853a8b172f0fd452040299f5c6db9436f928 (patch)
tree09793e8c4a683d4f67dace7a774d027a6ad80e44 /Userland/Libraries/LibWeb/HTML
parent13847aa7e8a78c0ce943ecf50875cc25ba015ac2 (diff)
downloadserenity-06d9853a8b172f0fd452040299f5c6db9436f928.zip
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.
Diffstat (limited to 'Userland/Libraries/LibWeb/HTML')
-rw-r--r--Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp62
-rw-r--r--Userland/Libraries/LibWeb/HTML/HTMLLinkElement.h6
2 files changed, 68 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp
index 722e2b2508..f6b601f9c3 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp
@@ -12,7 +12,9 @@
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/HTMLLinkElement.h>
+#include <LibWeb/ImageDecoding.h>
#include <LibWeb/Loader/ResourceLoader.h>
+#include <LibWeb/Page/Page.h>
namespace Web::HTML {
@@ -50,9 +52,18 @@ void HTMLLinkElement::inserted()
ResourceLoader::the().prefetch_dns(document().parse_url(attribute(HTML::AttributeNames::href)));
} else if (m_relationship & Relationship::Preconnect) {
ResourceLoader::the().preconnect(document().parse_url(attribute(HTML::AttributeNames::href)));
+ } else if (m_relationship & Relationship::Icon) {
+ auto favicon_url = document().parse_url(href());
+ auto favicon_request = LoadRequest::create_for_url_on_page(favicon_url, document().page());
+ set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, favicon_request));
}
}
+bool HTMLLinkElement::has_loaded_icon() const
+{
+ return m_relationship & Relationship::Icon && resource() && resource()->is_loaded() && resource()->has_encoded_data();
+}
+
void HTMLLinkElement::parse_attribute(FlyString const& name, String const& value)
{
// 4.6.7 Link types - https://html.spec.whatwg.org/multipage/links.html#linkTypes
@@ -91,7 +102,17 @@ void HTMLLinkElement::resource_did_fail()
void HTMLLinkElement::resource_did_load()
{
VERIFY(resource());
+ VERIFY(m_relationship & (Relationship::Stylesheet | Relationship::Icon));
+ if (m_relationship & Relationship::Stylesheet)
+ resource_did_load_stylesheet();
+ if (m_relationship & Relationship::Icon)
+ resource_did_load_favicon();
+}
+
+void HTMLLinkElement::resource_did_load_stylesheet()
+{
+ VERIFY(m_relationship & Relationship::Stylesheet);
m_document_load_event_delayer.clear();
if (!resource()->has_encoded_data()) {
@@ -115,4 +136,45 @@ void HTMLLinkElement::resource_did_load()
document().style_sheets().add_sheet(sheet.release_nonnull());
}
+void HTMLLinkElement::resource_did_load_favicon()
+{
+ VERIFY(m_relationship & (Relationship::Icon));
+ if (!resource()->has_encoded_data()) {
+ dbgln_if(SPAM_DEBUG, "Favicon downloaded, no encoded data");
+ return;
+ }
+
+ dbgln_if(SPAM_DEBUG, "Favicon downloaded, {} bytes from {}", resource()->encoded_data().size(), resource()->url());
+
+ document().check_favicon_after_loading_link_resource();
+}
+
+bool HTMLLinkElement::load_favicon_and_use_if_window_is_active()
+{
+ if (!has_loaded_icon())
+ return false;
+
+ RefPtr<Gfx::Bitmap> favicon_bitmap;
+ auto decoded_image = Web::image_decoder_client().decode_image(resource()->encoded_data());
+ if (!decoded_image.has_value() || decoded_image->frames.is_empty()) {
+ dbgln("Could not decode favicon {}", resource()->url());
+ return false;
+ }
+
+ favicon_bitmap = decoded_image->frames[0].bitmap;
+ dbgln_if(IMAGE_DECODER_DEBUG, "Decoded favicon, {}", favicon_bitmap->size());
+
+ auto* page = document().page();
+ if (!page)
+ return favicon_bitmap;
+
+ if (document().browsing_context() == &page->top_level_browsing_context())
+ if (favicon_bitmap) {
+ page->client().page_did_change_favicon(*favicon_bitmap);
+ return true;
+ }
+
+ return false;
+}
+
}
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.h b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.h
index eab494ad09..844bba4149 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.h
@@ -28,6 +28,9 @@ public:
String type() const { return attribute(HTML::AttributeNames::type); }
String href() const { return attribute(HTML::AttributeNames::href); }
+ bool has_loaded_icon() const;
+ bool load_favicon_and_use_if_window_is_active();
+
private:
void parse_attribute(FlyString const&, String const&) override;
@@ -35,6 +38,9 @@ private:
virtual void resource_did_fail() override;
virtual void resource_did_load() override;
+ void resource_did_load_stylesheet();
+ void resource_did_load_favicon();
+
struct Relationship {
enum {
Alternate = 1 << 0,