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;