mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-22 09:18:55 +00:00
LibWeb: Support decoding SVG favicons
Adds a path that checks if blob contains SVG image before reaching for image decoder. Fixes logged image decoding errors on https://chatgpt.com/
This commit is contained in:
parent
f9888b0641
commit
77f6edaf71
Notes:
github-actions[bot]
2025-08-27 06:42:04 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 77f6edaf71
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5988
Reviewed-by: https://github.com/gmta ✅
Reviewed-by: https://github.com/konradekk
3 changed files with 29 additions and 5 deletions
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
|
#include <LibGfx/ImmutableBitmap.h>
|
||||||
#include <LibTextCodec/Decoder.h>
|
#include <LibTextCodec/Decoder.h>
|
||||||
#include <LibURL/URL.h>
|
#include <LibURL/URL.h>
|
||||||
#include <LibWeb/Bindings/HTMLLinkElementPrototype.h>
|
#include <LibWeb/Bindings/HTMLLinkElementPrototype.h>
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
#include <LibWeb/Loader/ResourceLoader.h>
|
#include <LibWeb/Loader/ResourceLoader.h>
|
||||||
#include <LibWeb/Page/Page.h>
|
#include <LibWeb/Page/Page.h>
|
||||||
#include <LibWeb/Platform/ImageCodecPlugin.h>
|
#include <LibWeb/Platform/ImageCodecPlugin.h>
|
||||||
|
#include <LibWeb/SVG/SVGDecodedImageData.h>
|
||||||
|
|
||||||
namespace Web::HTML {
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
@ -596,8 +598,31 @@ void HTMLLinkElement::resource_did_load_favicon()
|
||||||
document().check_favicon_after_loading_link_resource();
|
document().check_favicon_after_loading_link_resource();
|
||||||
}
|
}
|
||||||
|
|
||||||
static NonnullRefPtr<Core::Promise<Web::Platform::DecodedImage>> decode_favicon(ReadonlyBytes favicon_data, URL::URL const& favicon_url, GC::Ref<DOM::Document> document)
|
static NonnullRefPtr<Core::Promise<bool>> decode_favicon(ReadonlyBytes favicon_data, URL::URL const& favicon_url, GC::Ref<DOM::Document> 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<bool>::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) {
|
auto on_failed_decode = [favicon_url]([[maybe_unused]] Error& error) {
|
||||||
dbgln_if(IMAGE_DECODER_DEBUG, "Failed to decode favicon {}: {}", favicon_url, error);
|
dbgln_if(IMAGE_DECODER_DEBUG, "Failed to decode favicon {}: {}", favicon_url, error);
|
||||||
};
|
};
|
||||||
|
@ -614,8 +639,7 @@ static NonnullRefPtr<Core::Promise<Web::Platform::DecodedImage>> decode_favicon(
|
||||||
};
|
};
|
||||||
|
|
||||||
auto promise = Platform::ImageCodecPlugin::the().decode_image(favicon_data, move(on_successful_decode), move(on_failed_decode));
|
auto promise = Platform::ImageCodecPlugin::the().decode_image(favicon_data, move(on_successful_decode), move(on_failed_decode));
|
||||||
|
return promise->map<bool>([](auto const&) { return true; });
|
||||||
return promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HTMLLinkElement::load_favicon_and_use_if_window_is_active()
|
bool HTMLLinkElement::load_favicon_and_use_if_window_is_active()
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace Web::SVG {
|
||||||
GC_DEFINE_ALLOCATOR(SVGDecodedImageData);
|
GC_DEFINE_ALLOCATOR(SVGDecodedImageData);
|
||||||
GC_DEFINE_ALLOCATOR(SVGDecodedImageData::SVGPageClient);
|
GC_DEFINE_ALLOCATOR(SVGDecodedImageData::SVGPageClient);
|
||||||
|
|
||||||
ErrorOr<GC::Ref<SVGDecodedImageData>> SVGDecodedImageData::create(JS::Realm& realm, GC::Ref<Page> host_page, URL::URL const& url, ByteBuffer data)
|
ErrorOr<GC::Ref<SVGDecodedImageData>> SVGDecodedImageData::create(JS::Realm& realm, GC::Ref<Page> host_page, URL::URL const& url, ReadonlyBytes data)
|
||||||
{
|
{
|
||||||
auto page_client = SVGPageClient::create(Bindings::main_thread_vm(), host_page);
|
auto page_client = SVGPageClient::create(Bindings::main_thread_vm(), host_page);
|
||||||
auto page = Page::create(Bindings::main_thread_vm(), *page_client);
|
auto page = Page::create(Bindings::main_thread_vm(), *page_client);
|
||||||
|
|
|
@ -18,7 +18,7 @@ class SVGDecodedImageData final : public HTML::DecodedImageData {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class SVGPageClient;
|
class SVGPageClient;
|
||||||
static ErrorOr<GC::Ref<SVGDecodedImageData>> create(JS::Realm&, GC::Ref<Page>, URL::URL const&, ByteBuffer encoded_svg);
|
static ErrorOr<GC::Ref<SVGDecodedImageData>> create(JS::Realm&, GC::Ref<Page>, URL::URL const&, ReadonlyBytes encoded_svg);
|
||||||
virtual ~SVGDecodedImageData() override;
|
virtual ~SVGDecodedImageData() override;
|
||||||
|
|
||||||
virtual RefPtr<Gfx::ImmutableBitmap> bitmap(size_t frame_index, Gfx::IntSize) const override;
|
virtual RefPtr<Gfx::ImmutableBitmap> bitmap(size_t frame_index, Gfx::IntSize) const override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue