diff --git a/Libraries/LibWeb/HTML/HTMLLinkElement.cpp b/Libraries/LibWeb/HTML/HTMLLinkElement.cpp
index 3085ff9fbd3..f559ad528ce 100644
--- a/Libraries/LibWeb/HTML/HTMLLinkElement.cpp
+++ b/Libraries/LibWeb/HTML/HTMLLinkElement.cpp
@@ -9,6 +9,7 @@
#include
#include
+#include
#include
#include
#include
@@ -34,6 +35,7 @@
#include
#include
#include
+#include
namespace Web::HTML {
@@ -596,8 +598,31 @@ void HTMLLinkElement::resource_did_load_favicon()
document().check_favicon_after_loading_link_resource();
}
-static NonnullRefPtr> decode_favicon(ReadonlyBytes favicon_data, URL::URL const& favicon_url, GC::Ref document)
+static NonnullRefPtr> decode_favicon(ReadonlyBytes favicon_data, URL::URL const& favicon_url, GC::Ref document)
{
+ if (favicon_url.basename().ends_with(".svg"sv)) {
+ auto result = SVG::SVGDecodedImageData::create(document->realm(), document->page(), favicon_url, favicon_data);
+ auto promise = Core::Promise::construct();
+ if (result.is_error()) {
+ promise->reject(Error::from_string_view("Failed to decode SVG favicon"sv));
+ return promise;
+ }
+
+ // FIXME: Calculate size based on device pixel ratio
+ Gfx::IntSize size { 32, 32 };
+ auto immutable_bitmap = result.release_value()->bitmap(0, size);
+ auto bitmap = immutable_bitmap->bitmap();
+ if (!bitmap) {
+ promise->reject(Error::from_string_view("Failed to get bitmap from SVG favicon"sv));
+ return promise;
+ }
+ auto navigable = document->navigable();
+ if (navigable && navigable->is_traversable())
+ navigable->traversable_navigable()->page().client().page_did_change_favicon(*bitmap);
+ promise->resolve(true);
+ return promise;
+ }
+
auto on_failed_decode = [favicon_url]([[maybe_unused]] Error& error) {
dbgln_if(IMAGE_DECODER_DEBUG, "Failed to decode favicon {}: {}", favicon_url, error);
};
@@ -614,8 +639,7 @@ static NonnullRefPtr> decode_favicon(
};
auto promise = Platform::ImageCodecPlugin::the().decode_image(favicon_data, move(on_successful_decode), move(on_failed_decode));
-
- return promise;
+ return promise->map([](auto const&) { return true; });
}
bool HTMLLinkElement::load_favicon_and_use_if_window_is_active()
diff --git a/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp b/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp
index a7ce09e9ade..f72f49bc8f9 100644
--- a/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp
+++ b/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp
@@ -30,7 +30,7 @@ namespace Web::SVG {
GC_DEFINE_ALLOCATOR(SVGDecodedImageData);
GC_DEFINE_ALLOCATOR(SVGDecodedImageData::SVGPageClient);
-ErrorOr> SVGDecodedImageData::create(JS::Realm& realm, GC::Ref host_page, URL::URL const& url, ByteBuffer data)
+ErrorOr> SVGDecodedImageData::create(JS::Realm& realm, GC::Ref host_page, URL::URL const& url, ReadonlyBytes data)
{
auto page_client = SVGPageClient::create(Bindings::main_thread_vm(), host_page);
auto page = Page::create(Bindings::main_thread_vm(), *page_client);
diff --git a/Libraries/LibWeb/SVG/SVGDecodedImageData.h b/Libraries/LibWeb/SVG/SVGDecodedImageData.h
index 11a72f7d79d..e941ca0bcb6 100644
--- a/Libraries/LibWeb/SVG/SVGDecodedImageData.h
+++ b/Libraries/LibWeb/SVG/SVGDecodedImageData.h
@@ -18,7 +18,7 @@ class SVGDecodedImageData final : public HTML::DecodedImageData {
public:
class SVGPageClient;
- static ErrorOr> create(JS::Realm&, GC::Ref, URL::URL const&, ByteBuffer encoded_svg);
+ static ErrorOr> create(JS::Realm&, GC::Ref, URL::URL const&, ReadonlyBytes encoded_svg);
virtual ~SVGDecodedImageData() override;
virtual RefPtr bitmap(size_t frame_index, Gfx::IntSize) const override;