LibWeb: Use a separate class for shared image requests

As it turns out, making everyone piggyback on HTML::ImageRequest had
some major flaws, as HTMLImageElement may decide to abort an ongoing
fetch or wipe out image data, even when someone else is using the same
image request.

To avoid this issue, this patch introduces SharedImageRequest, and then
implements ImageRequest on top of that.

Other clients of the ImageRequest API are moved to SharedImageRequest
as well, and ImageRequest is now only used by HTMLImageElement.

This fixes an issue with image data disappearing and leading to asserts
and/or visually absent images.
This commit is contained in:
Andreas Kling 2023-06-14 12:45:56 +02:00
parent cdec23a68c
commit 34591ff3d9
Notes: sideshowbarker 2024-07-16 20:31:50 +09:00
11 changed files with 287 additions and 174 deletions

View file

@ -318,7 +318,7 @@ void HTMLObjectElement::load_image()
// NOTE: This currently reloads the image instead of reusing the resource we've already downloaded.
auto data = attribute(HTML::AttributeNames::data);
auto url = document().parse_url(data);
m_image_request = HTML::ImageRequest::get_shareable_or_create(*document().page(), url).release_value_but_fixme_should_propagate_errors();
m_image_request = HTML::SharedImageRequest::get_or_create(*document().page(), url).release_value_but_fixme_should_propagate_errors();
m_image_request->add_callbacks(
[this] {
run_object_representation_completed_steps(Representation::Image);
@ -327,13 +327,11 @@ void HTMLObjectElement::load_image()
run_object_representation_fallback_steps();
});
// If the image request is already available or fetching, no need to start another fetch.
if (m_image_request->is_available() || m_image_request->fetch_controller())
return;
auto request = HTML::create_potential_CORS_request(vm(), url, Fetch::Infrastructure::Request::Destination::Image, HTML::CORSSettingAttribute::NoCORS);
request->set_client(&document().relevant_settings_object());
m_image_request->fetch_image(realm(), request);
if (m_image_request->needs_fetching()) {
auto request = HTML::create_potential_CORS_request(vm(), url, Fetch::Infrastructure::Request::Destination::Image, HTML::CORSSettingAttribute::NoCORS);
request->set_client(&document().relevant_settings_object());
m_image_request->fetch_image(realm(), request);
}
}
void HTMLObjectElement::update_layout_and_child_objects(Representation representation)