From 90829fe8801ef0f27cdd67d5ce88faf0c34509c4 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 23 Mar 2022 08:20:41 -0400 Subject: [PATCH] LibWeb: Allow HTMLObjectElement to convert a Resource to ImageResource HTMLObjectElement, when implemented according to the spec, does not know the resource type specified by the 'data' attribute until after it has actually loaded (i.e. it may be an image, XML document, etc.). Currently we always use ImageLoader within HTMLObjectElement to load the object, but will need to use ResourceLoader instead to generically load data. However, ImageLoader / ImageResource have image-specific functionality that HTMLObjectElement still needs if the resource turns out to be an image. This patch will allow (only) HTMLObjectElement to convert the generic Resource to an ImageResource as needed. --- Userland/Libraries/LibWeb/Loader/ImageLoader.cpp | 6 ++++++ Userland/Libraries/LibWeb/Loader/ImageLoader.h | 2 ++ Userland/Libraries/LibWeb/Loader/ImageResource.cpp | 10 ++++++++++ Userland/Libraries/LibWeb/Loader/ImageResource.h | 3 +++ Userland/Libraries/LibWeb/Loader/Resource.cpp | 14 ++++++++++++++ Userland/Libraries/LibWeb/Loader/Resource.h | 1 + 6 files changed, 36 insertions(+) diff --git a/Userland/Libraries/LibWeb/Loader/ImageLoader.cpp b/Userland/Libraries/LibWeb/Loader/ImageLoader.cpp index d777e2da1c..3b1cd1d48f 100644 --- a/Userland/Libraries/LibWeb/Loader/ImageLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/ImageLoader.cpp @@ -20,6 +20,12 @@ ImageLoader::ImageLoader(DOM::Element& owner_element) { } +void ImageLoader::adopt_object_resource(Badge, Resource& resource) +{ + auto image_resource = ImageResource::convert_from_resource(resource); + set_resource(image_resource); +} + void ImageLoader::load(const AK::URL& url) { m_redirects_count = 0; diff --git a/Userland/Libraries/LibWeb/Loader/ImageLoader.h b/Userland/Libraries/LibWeb/Loader/ImageLoader.h index 43fa0da297..ad6ece9c71 100644 --- a/Userland/Libraries/LibWeb/Loader/ImageLoader.h +++ b/Userland/Libraries/LibWeb/Loader/ImageLoader.h @@ -16,6 +16,8 @@ class ImageLoader : public ImageResourceClient { public: ImageLoader(DOM::Element& owner_element); + void adopt_object_resource(Badge, Resource&); + void load(const AK::URL&); const Gfx::Bitmap* bitmap(size_t index) const; diff --git a/Userland/Libraries/LibWeb/Loader/ImageResource.cpp b/Userland/Libraries/LibWeb/Loader/ImageResource.cpp index ce9a37d3d5..76769c7828 100644 --- a/Userland/Libraries/LibWeb/Loader/ImageResource.cpp +++ b/Userland/Libraries/LibWeb/Loader/ImageResource.cpp @@ -10,11 +10,21 @@ namespace Web { +NonnullRefPtr ImageResource::convert_from_resource(Resource& resource) +{ + return adopt_ref(*new ImageResource(resource)); +} + ImageResource::ImageResource(const LoadRequest& request) : Resource(Type::Image, request) { } +ImageResource::ImageResource(Resource& resource) + : Resource(Type::Image, resource) +{ +} + ImageResource::~ImageResource() = default; int ImageResource::frame_duration(size_t frame_index) const diff --git a/Userland/Libraries/LibWeb/Loader/ImageResource.h b/Userland/Libraries/LibWeb/Loader/ImageResource.h index 48aa89ea39..c740010a87 100644 --- a/Userland/Libraries/LibWeb/Loader/ImageResource.h +++ b/Userland/Libraries/LibWeb/Loader/ImageResource.h @@ -14,6 +14,8 @@ class ImageResource final : public Resource { friend class Resource; public: + static NonnullRefPtr convert_from_resource(Resource&); + virtual ~ImageResource() override; struct Frame { @@ -43,6 +45,7 @@ public: private: explicit ImageResource(const LoadRequest&); + explicit ImageResource(Resource&); void decode_if_needed() const; diff --git a/Userland/Libraries/LibWeb/Loader/Resource.cpp b/Userland/Libraries/LibWeb/Loader/Resource.cpp index 0ccf8b49df..d922546e88 100644 --- a/Userland/Libraries/LibWeb/Loader/Resource.cpp +++ b/Userland/Libraries/LibWeb/Loader/Resource.cpp @@ -27,6 +27,20 @@ Resource::Resource(Type type, const LoadRequest& request) { } +Resource::Resource(Type type, Resource& resource) + : m_request(resource.m_request) + , m_encoded_data(move(resource.m_encoded_data)) + , m_type(type) + , m_loaded(resource.m_loaded) + , m_failed(resource.m_failed) + , m_error(move(resource.m_error)) + , m_encoding(move(resource.m_encoding)) + , m_mime_type(move(resource.m_mime_type)) + , m_response_headers(move(resource.m_response_headers)) + , m_status_code(move(resource.m_status_code)) +{ +} + Resource::~Resource() = default; void Resource::for_each_client(Function callback) diff --git a/Userland/Libraries/LibWeb/Loader/Resource.h b/Userland/Libraries/LibWeb/Loader/Resource.h index c138da0af4..ad77e9e611 100644 --- a/Userland/Libraries/LibWeb/Loader/Resource.h +++ b/Userland/Libraries/LibWeb/Loader/Resource.h @@ -65,6 +65,7 @@ public: protected: explicit Resource(Type, const LoadRequest&); + Resource(Type, Resource&); private: LoadRequest m_request;