1
1
/*
2
- * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
2
+ * Copyright (c) 2020-2023 , Andreas Kling <kling@serenityos.org>
3
3
*
4
4
* SPDX-License-Identifier: BSD-2-Clause
5
5
*/
8
8
#include < LibWeb/CSS/StyleComputer.h>
9
9
#include < LibWeb/DOM/Document.h>
10
10
#include < LibWeb/DOM/Event.h>
11
+ #include < LibWeb/HTML/DecodedImageData.h>
11
12
#include < LibWeb/HTML/HTMLMediaElement.h>
12
13
#include < LibWeb/HTML/HTMLObjectElement.h>
14
+ #include < LibWeb/HTML/ImageRequest.h>
15
+ #include < LibWeb/HTML/PotentialCORSRequest.h>
13
16
#include < LibWeb/Layout/ImageBox.h>
14
17
#include < LibWeb/Loader/ResourceLoader.h>
15
18
#include < LibWeb/MimeSniff/MimeType.h>
@@ -75,7 +78,7 @@ JS::GCPtr<Layout::Node> HTMLObjectElement::create_layout_node(NonnullRefPtr<CSS:
75
78
// FIXME: Actually paint the nested browsing context's document, similar to how iframes are painted with FrameBox and NestedBrowsingContextPaintable.
76
79
return nullptr ;
77
80
case Representation::Image:
78
- if (m_image_loader. has_value () && m_image_loader-> has_image ())
81
+ if (image_data ())
79
82
return heap ().allocate_without_realm <Layout::ImageBox>(document (), *this , move (style), *this );
80
83
break ;
81
84
default :
@@ -272,7 +275,7 @@ void HTMLObjectElement::run_object_representation_handler_steps(Optional<Depreca
272
275
if (!resource ()->has_encoded_data ())
273
276
return run_object_representation_fallback_steps ();
274
277
275
- convert_resource_to_image ();
278
+ load_image ();
276
279
}
277
280
278
281
// * Otherwise
@@ -310,22 +313,27 @@ void HTMLObjectElement::run_object_representation_fallback_steps()
310
313
update_layout_and_child_objects (Representation::Children);
311
314
}
312
315
313
- void HTMLObjectElement::convert_resource_to_image ()
316
+ void HTMLObjectElement::load_image ()
314
317
{
315
- // FIXME: This is a bit awkward. We convert the Resource to an ImageResource here because we do not know
316
- // until now that the resource is an image. ImageLoader then becomes responsible for handling
317
- // encoding failures, animations, etc. It would be clearer if those features were split from
318
- // ImageLoader into a purpose build class to be shared between here and ImageBox.
319
- m_image_loader.emplace (*this );
320
-
321
- m_image_loader->on_load = [this ] {
322
- run_object_representation_completed_steps (Representation::Image);
323
- };
324
- m_image_loader->on_fail = [this ] {
325
- run_object_representation_fallback_steps ();
326
- };
318
+ // NOTE: This currently reloads the image instead of reusing the resource we've already downloaded.
319
+ auto data = attribute (HTML::AttributeNames::data);
320
+ auto url = document ().parse_url (data);
321
+ m_image_request = HTML::ImageRequest::get_shareable_or_create (*document ().page (), url).release_value_but_fixme_should_propagate_errors ();
322
+ m_image_request->add_callbacks (
323
+ [this ] {
324
+ run_object_representation_completed_steps (Representation::Image);
325
+ },
326
+ [this ] {
327
+ run_object_representation_fallback_steps ();
328
+ });
329
+
330
+ // If the image request is already available or fetching, no need to start another fetch.
331
+ if (m_image_request->is_available () || m_image_request->fetch_controller ())
332
+ return ;
327
333
328
- m_image_loader->adopt_object_resource ({}, *resource ());
334
+ auto request = HTML::create_potential_CORS_request (vm (), url, Fetch::Infrastructure::Request::Destination::Image, HTML::CORSSettingAttribute::NoCORS);
335
+ request->set_client (&document ().relevant_settings_object ());
336
+ m_image_request->fetch_image (realm (), request);
329
337
}
330
338
331
339
void HTMLObjectElement::update_layout_and_child_objects (Representation representation)
@@ -350,31 +358,38 @@ i32 HTMLObjectElement::default_tab_index_value() const
350
358
return 0 ;
351
359
}
352
360
361
+ RefPtr<DecodedImageData const > HTMLObjectElement::image_data () const
362
+ {
363
+ if (!m_image_request)
364
+ return nullptr ;
365
+ return m_image_request->image_data ();
366
+ }
367
+
353
368
Optional<CSSPixels> HTMLObjectElement::intrinsic_width () const
354
369
{
355
- if (m_image_loader. has_value ())
356
- return m_image_loader-> bitmap ( 0 )-> width ();
370
+ if (auto image_data = this -> image_data ())
371
+ return image_data-> intrinsic_width ();
357
372
return {};
358
373
}
359
374
360
375
Optional<CSSPixels> HTMLObjectElement::intrinsic_height () const
361
376
{
362
- if (m_image_loader. has_value ())
363
- return m_image_loader-> bitmap ( 0 )-> height ();
377
+ if (auto image_data = this -> image_data ())
378
+ return image_data-> intrinsic_height ();
364
379
return {};
365
380
}
366
381
367
382
Optional<float > HTMLObjectElement::intrinsic_aspect_ratio () const
368
383
{
369
- if (m_image_loader. has_value ())
370
- return static_cast < float >(m_image_loader-> bitmap ( 0 )-> width ()) / static_cast < float >(m_image_loader-> bitmap ( 0 )-> height () );
384
+ if (auto image_data = this -> image_data ())
385
+ return image_data-> intrinsic_aspect_ratio ( );
371
386
return {};
372
387
}
373
388
374
- RefPtr<Gfx::Bitmap const > HTMLObjectElement::current_image_bitmap (Gfx::IntSize) const
389
+ RefPtr<Gfx::Bitmap const > HTMLObjectElement::current_image_bitmap (Gfx::IntSize size ) const
375
390
{
376
- if (m_image_loader. has_value ())
377
- return m_image_loader ->bitmap (m_image_loader-> current_frame_index () );
391
+ if (auto image_data = this -> image_data ())
392
+ return image_data ->bitmap (0 , size );
378
393
return nullptr ;
379
394
}
380
395
0 commit comments