From 0bdcaf02d35d12359b35cf97a0a7029556ddba9a Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sat, 21 Jun 2025 15:31:29 +1200 Subject: [PATCH] LibWeb/HTML: Only update the image data on fully loaded document Documents created by DOMParser and fragment documents do not have an origin set on the document by the spec. These documents also happen to never become fully active. By properly implementing the steps for the element to only update the image data for documents which are fully active, this fixes a crash for img elements in these types of documents. Unfortunately, this is not a full fix for the microtask queue case. This is because it seems possible for node document for an element to be changed during the microtask queue for that document. It is not clear to me how this can be fixed in a nice way. --- Libraries/LibWeb/HTML/HTMLImageElement.cpp | 47 ++- Libraries/LibWeb/HTML/HTMLImageElement.h | 4 + ...date-the-image-data-temporary-document.txt | 19 + ...ate-the-image-data-temporary-document.html | 8 + ...h-naturalHeight-width-height.tentative.txt | 234 +++++++++++ ...-naturalHeight-width-height.tentative.html | 377 ++++++++++++++++++ .../the-img-element/resources/cat.jpg | Bin 0 -> 21474 bytes 7 files changed, 684 insertions(+), 5 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/HTMLImageElement-update-the-image-data-temporary-document.txt create mode 100644 Tests/LibWeb/Layout/input/HTMLImageElement-update-the-image-data-temporary-document.html create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-width-height.tentative.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-width-height.tentative.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/semantics/embedded-content/the-img-element/resources/cat.jpg diff --git a/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Libraries/LibWeb/HTML/HTMLImageElement.cpp index f0d11890ac8..032f668ca74 100644 --- a/Libraries/LibWeb/HTML/HTMLImageElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLImageElement.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,12 @@ void HTMLImageElement::adopted_from(DOM::Document& old_document) { old_document.unregister_viewport_client(*this); document().register_viewport_client(*this); + + if (m_document_observer) { + m_document_observer->set_document(document()); + if (!old_document.is_fully_active() && document().is_fully_active()) + m_document_observer->document_became_active()->function()(); + } } void HTMLImageElement::visit_edges(Cell::Visitor& visitor) @@ -81,6 +88,7 @@ void HTMLImageElement::visit_edges(Cell::Visitor& visitor) Base::visit_edges(visitor); visitor.visit(m_current_request); visitor.visit(m_pending_request); + visitor.visit(m_document_observer); visit_lazy_loading_element(visitor); } @@ -482,13 +490,42 @@ static BatchingDispatcher& batching_dispatcher() // https://html.spec.whatwg.org/multipage/images.html#update-the-image-data void HTMLImageElement::update_the_image_data(bool restart_animations, bool maybe_omit_events) { + auto& realm = this->realm(); + // 1. If the element's node document is not fully active, then: if (!document().is_fully_active()) { - // FIXME: 1. Continue running this algorithm in parallel. - // FIXME: 2. Wait until the element's node document is fully active. - // FIXME: 3. If another instance of this algorithm for this img element was started after this instance - // (even if it aborted and is no longer running), then return. - // FIXME: 4. Queue a microtask to continue this algorithm. + // 1. Continue running this algorithm in parallel. + // 2. Wait until the element's node document is fully active. + // 3. If another instance of this algorithm for this img element was started after this instance + // (even if it aborted and is no longer running), then return. + if (m_document_observer) + return; + + m_document_observer = realm.create(realm, document()); + m_document_observer->set_document_became_active([this, restart_animations, maybe_omit_events]() { + // 4. Queue a microtask to continue this algorithm. + queue_a_microtask(&document(), GC::create_function(this->heap(), [this, restart_animations, maybe_omit_events]() { + update_the_image_data_impl(restart_animations, maybe_omit_events); + })); + }); + + return; + } + + update_the_image_data_impl(restart_animations, maybe_omit_events); +} + +// https://html.spec.whatwg.org/multipage/images.html#update-the-image-data +void HTMLImageElement::update_the_image_data_impl(bool restart_animations, bool maybe_omit_events) +{ + // 1. If the element's node document is not fully active, then: + // FIXME: This step and it's substeps is implemented by the calling `update_the_image_data` function. + // By the time that we reach here, the document should be fully active. However, it is possible + // that the node document is swapped out again during the queue of the microtask to run this + // algorithm. + if (!document().is_fully_active()) { + dbgln("FIXME: Node document is not fully active running 'update the image data'"); + return; } // 2. FIXME: If the user agent cannot support images, or its support for images has been disabled, diff --git a/Libraries/LibWeb/HTML/HTMLImageElement.h b/Libraries/LibWeb/HTML/HTMLImageElement.h index d4e547efa66..f9aa3660390 100644 --- a/Libraries/LibWeb/HTML/HTMLImageElement.h +++ b/Libraries/LibWeb/HTML/HTMLImageElement.h @@ -114,6 +114,8 @@ public: private: HTMLImageElement(DOM::Document&, DOM::QualifiedName); + void update_the_image_data_impl(bool restart_the_animations = false, bool maybe_omit_events = false); + virtual bool is_html_image_element() const override { return true; } virtual void initialize(JS::Realm&) override; @@ -144,6 +146,8 @@ private: Optional m_load_event_delayer; + GC::Ptr m_document_observer; + CORSSettingAttribute m_cors_setting { CORSSettingAttribute::NoCORS }; // https://html.spec.whatwg.org/multipage/images.html#last-selected-source diff --git a/Tests/LibWeb/Layout/expected/HTMLImageElement-update-the-image-data-temporary-document.txt b/Tests/LibWeb/Layout/expected/HTMLImageElement-update-the-image-data-temporary-document.txt new file mode 100644 index 00000000000..a8520c1ab91 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/HTMLImageElement-update-the-image-data-temporary-document.txt @@ -0,0 +1,19 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x166 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x150 children: not-inline + BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline + TextNode <#text> + BlockContainer at (8,8) content-size 784x150 children: inline + frag 0 from ImageBox start: 0, length: 0, rect: [8,8 150x150] baseline: 150 + ImageBox at (8,8) content-size 150x150 children: not-inline + BlockContainer <(anonymous)> at (8,158) content-size 784x0 children: inline + TextNode <#text> + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x166] + PaintableWithLines (BlockContainer) [8,8 784x150] + PaintableWithLines (BlockContainer(anonymous)) [8,8 784x0] + PaintableWithLines (BlockContainer
#image-container) [8,8 784x150] + ImagePaintable (ImageBox) [8,8 150x150] + PaintableWithLines (BlockContainer(anonymous)) [8,158 784x0] diff --git a/Tests/LibWeb/Layout/input/HTMLImageElement-update-the-image-data-temporary-document.html b/Tests/LibWeb/Layout/input/HTMLImageElement-update-the-image-data-temporary-document.html new file mode 100644 index 00000000000..6e8f26ac88b --- /dev/null +++ b/Tests/LibWeb/Layout/input/HTMLImageElement-update-the-image-data-temporary-document.html @@ -0,0 +1,8 @@ + + +
Original content
+ + + diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-width-height.tentative.txt b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-width-height.tentative.txt new file mode 100644 index 00000000000..b95e914d6e7 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-width-height.tentative.txt @@ -0,0 +1,234 @@ +Harness status: OK + +Found 228 tests + +44 Pass +184 Fail +Pass raster image +Pass raster image (when not rendered) +Pass raster image with width/height attributes +Pass raster image with width/height attributes (when not rendered) +Pass non existent image, no natural dimensions +Pass non existent image, no natural dimensions (when not rendered) +Pass non existent image with width/height attributes, no natural dimensions +Pass non existent image with width/height attributes, no natural dimensions (when not rendered) +Fail SVG image, no natural dimensions +Fail SVG image, no natural dimensions (when not rendered) +Fail SVG image with width/height attrs, no natural dimensions +Fail SVG image with width/height attrs, no natural dimensions (when not rendered) +Fail SVG image with width attr, no natural dimensions +Fail SVG image with width attr, no natural dimensions (when not rendered) +Fail SVG image with height attr, no natural dimensions +Fail SVG image with height attr, no natural dimensions (when not rendered) +Fail SVG image, percengage natural dimensions +Fail SVG image, percengage natural dimensions (when not rendered) +Fail SVG image, negative percengage natural dimensions +Fail SVG image, negative percengage natural dimensions (when not rendered) +Fail SVG image, with natural width +Fail SVG image, with natural width (when not rendered) +Fail SVG image, with natural height +Fail SVG image, with natural height (when not rendered) +Fail SVG image, with natural width of 0 +Fail SVG image, with natural width of 0 (when not rendered) +Fail SVG image, with natural height of 0 +Fail SVG image, with natural height of 0 (when not rendered) +Fail SVG image, with natural width being negative +Fail SVG image, with natural width being negative (when not rendered) +Fail SVG image, with natural height being negative +Fail SVG image, with natural height being negative (when not rendered) +Fail SVG image, no natural dimensions, and aspect ratio from viewBox +Fail SVG image, no natural dimensions, and aspect ratio from viewBox (when not rendered) +Fail SVG image, percengage natural dimensions, and aspect ratio from viewBox +Fail SVG image, percengage natural dimensions, and aspect ratio from viewBox (when not rendered) +Fail SVG image, negative percengage natural dimensions, and aspect ratio from viewBox +Fail SVG image, negative percengage natural dimensions, and aspect ratio from viewBox (when not rendered) +Fail SVG image, with natural width, and aspect ratio from viewBox +Fail SVG image, with natural width, and aspect ratio from viewBox (when not rendered) +Fail SVG image, with natural height, and aspect ratio from viewBox +Fail SVG image, with natural height, and aspect ratio from viewBox (when not rendered) +Pass SVG image, with natural width of 0, and aspect ratio from viewBox +Pass SVG image, with natural width of 0, and aspect ratio from viewBox (when not rendered) +Fail SVG image, with natural height of 0, and aspect ratio from viewBox +Pass SVG image, with natural height of 0, and aspect ratio from viewBox (when not rendered) +Fail SVG image, with natural width being negative, and aspect ratio from viewBox +Pass SVG image, with natural width being negative, and aspect ratio from viewBox (when not rendered) +Fail SVG image, with natural height being negative, and aspect ratio from viewBox +Pass SVG image, with natural height being negative, and aspect ratio from viewBox (when not rendered) +Fail SVG image, no natural dimensions, viewBox with 0 width/height +Fail SVG image, no natural dimensions, viewBox with 0 width/height (when not rendered) +Fail SVG image, no natural dimensions, viewBox with 0 width +Fail SVG image, no natural dimensions, viewBox with 0 width (when not rendered) +Fail SVG image, no natural dimensions, viewBox with 0 height +Fail SVG image, no natural dimensions, viewBox with 0 height (when not rendered) +Fail SVG image, with natural width, viewBox with 0 width/height +Fail SVG image, with natural width, viewBox with 0 width/height (when not rendered) +Fail SVG image, with natural width, viewBox with 0 width +Fail SVG image, with natural width, viewBox with 0 width (when not rendered) +Fail SVG image, with natural width, viewBox with 0 height +Fail SVG image, with natural width, viewBox with 0 height (when not rendered) +Fail SVG image, with natural height, viewBox with 0 width/height +Fail SVG image, with natural height, viewBox with 0 width/height (when not rendered) +Fail SVG image, with natural height, viewBox with 0 width +Fail SVG image, with natural height, viewBox with 0 width (when not rendered) +Fail SVG image, with natural height, viewBox with 0 height +Fail SVG image, with natural height, viewBox with 0 height (when not rendered) +Fail SVG image, with natural width and height +Fail SVG image, with natural width and height (when not rendered) +Fail SVG image, with natural width and height, and aspect ratio from viewBox +Fail SVG image, with natural width and height, and aspect ratio from viewBox (when not rendered) +Pass SVG image, with natural width and height of 0, and aspect ratio from viewBox +Pass SVG image, with natural width and height of 0, and aspect ratio from viewBox (when not rendered) +Fail SVG image, with natural width and height being negative, and aspect ratio from viewBox +Pass SVG image, with natural width and height being negative, and aspect ratio from viewBox (when not rendered) +Pass raster image (with srcset/1x) +Pass raster image (with srcset/1x) (when not rendered) +Pass raster image with width/height attributes (with srcset/1x) +Pass raster image with width/height attributes (with srcset/1x) (when not rendered) +Pass non existent image, no natural dimensions (with srcset/1x) +Pass non existent image, no natural dimensions (with srcset/1x) (when not rendered) +Pass non existent image with width/height attributes, no natural dimensions (with srcset/1x) +Pass non existent image with width/height attributes, no natural dimensions (with srcset/1x) (when not rendered) +Fail SVG image, no natural dimensions (with srcset/1x) +Fail SVG image, no natural dimensions (with srcset/1x) (when not rendered) +Fail SVG image with width/height attrs, no natural dimensions (with srcset/1x) +Fail SVG image with width/height attrs, no natural dimensions (with srcset/1x) (when not rendered) +Fail SVG image with width attr, no natural dimensions (with srcset/1x) +Fail SVG image with width attr, no natural dimensions (with srcset/1x) (when not rendered) +Fail SVG image with height attr, no natural dimensions (with srcset/1x) +Fail SVG image with height attr, no natural dimensions (with srcset/1x) (when not rendered) +Fail SVG image, percengage natural dimensions (with srcset/1x) +Fail SVG image, percengage natural dimensions (with srcset/1x) (when not rendered) +Fail SVG image, negative percengage natural dimensions (with srcset/1x) +Fail SVG image, negative percengage natural dimensions (with srcset/1x) (when not rendered) +Fail SVG image, with natural width (with srcset/1x) +Fail SVG image, with natural width (with srcset/1x) (when not rendered) +Fail SVG image, with natural height (with srcset/1x) +Fail SVG image, with natural height (with srcset/1x) (when not rendered) +Fail SVG image, with natural width of 0 (with srcset/1x) +Fail SVG image, with natural width of 0 (with srcset/1x) (when not rendered) +Fail SVG image, with natural height of 0 (with srcset/1x) +Fail SVG image, with natural height of 0 (with srcset/1x) (when not rendered) +Fail SVG image, with natural width being negative (with srcset/1x) +Fail SVG image, with natural width being negative (with srcset/1x) (when not rendered) +Fail SVG image, with natural height being negative (with srcset/1x) +Fail SVG image, with natural height being negative (with srcset/1x) (when not rendered) +Fail SVG image, no natural dimensions, and aspect ratio from viewBox (with srcset/1x) +Fail SVG image, no natural dimensions, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Fail SVG image, percengage natural dimensions, and aspect ratio from viewBox (with srcset/1x) +Fail SVG image, percengage natural dimensions, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Fail SVG image, negative percengage natural dimensions, and aspect ratio from viewBox (with srcset/1x) +Fail SVG image, negative percengage natural dimensions, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Fail SVG image, with natural width, and aspect ratio from viewBox (with srcset/1x) +Fail SVG image, with natural width, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Fail SVG image, with natural height, and aspect ratio from viewBox (with srcset/1x) +Fail SVG image, with natural height, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Pass SVG image, with natural width of 0, and aspect ratio from viewBox (with srcset/1x) +Pass SVG image, with natural width of 0, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Fail SVG image, with natural height of 0, and aspect ratio from viewBox (with srcset/1x) +Pass SVG image, with natural height of 0, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Fail SVG image, with natural width being negative, and aspect ratio from viewBox (with srcset/1x) +Pass SVG image, with natural width being negative, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Fail SVG image, with natural height being negative, and aspect ratio from viewBox (with srcset/1x) +Pass SVG image, with natural height being negative, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Fail SVG image, no natural dimensions, viewBox with 0 width/height (with srcset/1x) +Fail SVG image, no natural dimensions, viewBox with 0 width/height (with srcset/1x) (when not rendered) +Fail SVG image, no natural dimensions, viewBox with 0 width (with srcset/1x) +Fail SVG image, no natural dimensions, viewBox with 0 width (with srcset/1x) (when not rendered) +Fail SVG image, no natural dimensions, viewBox with 0 height (with srcset/1x) +Fail SVG image, no natural dimensions, viewBox with 0 height (with srcset/1x) (when not rendered) +Fail SVG image, with natural width, viewBox with 0 width/height (with srcset/1x) +Fail SVG image, with natural width, viewBox with 0 width/height (with srcset/1x) (when not rendered) +Fail SVG image, with natural width, viewBox with 0 width (with srcset/1x) +Fail SVG image, with natural width, viewBox with 0 width (with srcset/1x) (when not rendered) +Fail SVG image, with natural width, viewBox with 0 height (with srcset/1x) +Fail SVG image, with natural width, viewBox with 0 height (with srcset/1x) (when not rendered) +Fail SVG image, with natural height, viewBox with 0 width/height (with srcset/1x) +Fail SVG image, with natural height, viewBox with 0 width/height (with srcset/1x) (when not rendered) +Fail SVG image, with natural height, viewBox with 0 width (with srcset/1x) +Fail SVG image, with natural height, viewBox with 0 width (with srcset/1x) (when not rendered) +Fail SVG image, with natural height, viewBox with 0 height (with srcset/1x) +Fail SVG image, with natural height, viewBox with 0 height (with srcset/1x) (when not rendered) +Fail SVG image, with natural width and height (with srcset/1x) +Fail SVG image, with natural width and height (with srcset/1x) (when not rendered) +Fail SVG image, with natural width and height, and aspect ratio from viewBox (with srcset/1x) +Fail SVG image, with natural width and height, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Pass SVG image, with natural width and height of 0, and aspect ratio from viewBox (with srcset/1x) +Pass SVG image, with natural width and height of 0, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Fail SVG image, with natural width and height being negative, and aspect ratio from viewBox (with srcset/1x) +Pass SVG image, with natural width and height being negative, and aspect ratio from viewBox (with srcset/1x) (when not rendered) +Fail raster image (with srcset/2x) +Fail raster image (with srcset/2x) (when not rendered) +Fail raster image with width/height attributes (with srcset/2x) +Fail raster image with width/height attributes (with srcset/2x) (when not rendered) +Pass non existent image, no natural dimensions (with srcset/2x) +Pass non existent image, no natural dimensions (with srcset/2x) (when not rendered) +Pass non existent image with width/height attributes, no natural dimensions (with srcset/2x) +Pass non existent image with width/height attributes, no natural dimensions (with srcset/2x) (when not rendered) +Fail SVG image, no natural dimensions (with srcset/2x) +Fail SVG image, no natural dimensions (with srcset/2x) (when not rendered) +Fail SVG image with width/height attrs, no natural dimensions (with srcset/2x) +Fail SVG image with width/height attrs, no natural dimensions (with srcset/2x) (when not rendered) +Fail SVG image with width attr, no natural dimensions (with srcset/2x) +Fail SVG image with width attr, no natural dimensions (with srcset/2x) (when not rendered) +Fail SVG image with height attr, no natural dimensions (with srcset/2x) +Fail SVG image with height attr, no natural dimensions (with srcset/2x) (when not rendered) +Fail SVG image, percengage natural dimensions (with srcset/2x) +Fail SVG image, percengage natural dimensions (with srcset/2x) (when not rendered) +Fail SVG image, negative percengage natural dimensions (with srcset/2x) +Fail SVG image, negative percengage natural dimensions (with srcset/2x) (when not rendered) +Fail SVG image, with natural width (with srcset/2x) +Fail SVG image, with natural width (with srcset/2x) (when not rendered) +Fail SVG image, with natural height (with srcset/2x) +Fail SVG image, with natural height (with srcset/2x) (when not rendered) +Fail SVG image, with natural width of 0 (with srcset/2x) +Fail SVG image, with natural width of 0 (with srcset/2x) (when not rendered) +Fail SVG image, with natural height of 0 (with srcset/2x) +Fail SVG image, with natural height of 0 (with srcset/2x) (when not rendered) +Fail SVG image, with natural width being negative (with srcset/2x) +Fail SVG image, with natural width being negative (with srcset/2x) (when not rendered) +Fail SVG image, with natural height being negative (with srcset/2x) +Fail SVG image, with natural height being negative (with srcset/2x) (when not rendered) +Fail SVG image, no natural dimensions, and aspect ratio from viewBox (with srcset/2x) +Fail SVG image, no natural dimensions, and aspect ratio from viewBox (with srcset/2x) (when not rendered) +Fail SVG image, percengage natural dimensions, and aspect ratio from viewBox (with srcset/2x) +Fail SVG image, percengage natural dimensions, and aspect ratio from viewBox (with srcset/2x) (when not rendered) +Fail SVG image, negative percengage natural dimensions, and aspect ratio from viewBox (with srcset/2x) +Fail SVG image, negative percengage natural dimensions, and aspect ratio from viewBox (with srcset/2x) (when not rendered) +Fail SVG image, with natural width, and aspect ratio from viewBox (with srcset/2x) +Fail SVG image, with natural width, and aspect ratio from viewBox (with srcset/2x) (when not rendered) +Fail SVG image, with natural height, and aspect ratio from viewBox (with srcset/2x) +Fail SVG image, with natural height, and aspect ratio from viewBox (with srcset/2x) (when not rendered) +Pass SVG image, with natural width of 0, and aspect ratio from viewBox (with srcset/2x) +Pass SVG image, with natural width of 0, and aspect ratio from viewBox (with srcset/2x) (when not rendered) +Fail SVG image, with natural height of 0, and aspect ratio from viewBox (with srcset/2x) +Pass SVG image, with natural height of 0, and aspect ratio from viewBox (with srcset/2x) (when not rendered) +Fail SVG image, with natural width being negative, and aspect ratio from viewBox (with srcset/2x) +Pass SVG image, with natural width being negative, and aspect ratio from viewBox (with srcset/2x) (when not rendered) +Fail SVG image, with natural height being negative, and aspect ratio from viewBox (with srcset/2x) +Pass SVG image, with natural height being negative, and aspect ratio from viewBox (with srcset/2x) (when not rendered) +Fail SVG image, no natural dimensions, viewBox with 0 width/height (with srcset/2x) +Fail SVG image, no natural dimensions, viewBox with 0 width/height (with srcset/2x) (when not rendered) +Fail SVG image, no natural dimensions, viewBox with 0 width (with srcset/2x) +Fail SVG image, no natural dimensions, viewBox with 0 width (with srcset/2x) (when not rendered) +Fail SVG image, no natural dimensions, viewBox with 0 height (with srcset/2x) +Fail SVG image, no natural dimensions, viewBox with 0 height (with srcset/2x) (when not rendered) +Fail SVG image, with natural width, viewBox with 0 width/height (with srcset/2x) +Fail SVG image, with natural width, viewBox with 0 width/height (with srcset/2x) (when not rendered) +Fail SVG image, with natural width, viewBox with 0 width (with srcset/2x) +Fail SVG image, with natural width, viewBox with 0 width (with srcset/2x) (when not rendered) +Fail SVG image, with natural width, viewBox with 0 height (with srcset/2x) +Fail SVG image, with natural width, viewBox with 0 height (with srcset/2x) (when not rendered) +Fail SVG image, with natural height, viewBox with 0 width/height (with srcset/2x) +Fail SVG image, with natural height, viewBox with 0 width/height (with srcset/2x) (when not rendered) +Fail SVG image, with natural height, viewBox with 0 width (with srcset/2x) +Fail SVG image, with natural height, viewBox with 0 width (with srcset/2x) (when not rendered) +Fail SVG image, with natural height, viewBox with 0 height (with srcset/2x) +Fail SVG image, with natural height, viewBox with 0 height (with srcset/2x) (when not rendered) +Fail SVG image, with natural width and height (with srcset/2x) +Fail SVG image, with natural width and height (with srcset/2x) (when not rendered) +Fail SVG image, with natural width and height, and aspect ratio from viewBox (with srcset/2x) +Fail SVG image, with natural width and height, and aspect ratio from viewBox (with srcset/2x) (when not rendered) +Pass SVG image, with natural width and height of 0, and aspect ratio from viewBox (with srcset/2x) +Pass SVG image, with natural width and height of 0, and aspect ratio from viewBox (with srcset/2x) (when not rendered) +Fail SVG image, with natural width and height being negative, and aspect ratio from viewBox (with srcset/2x) +Pass SVG image, with natural width and height being negative, and aspect ratio from viewBox (with srcset/2x) (when not rendered) \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-width-height.tentative.html b/Tests/LibWeb/Text/input/wpt-import/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-width-height.tentative.html new file mode 100644 index 00000000000..d89d92ffd3c --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-width-height.tentative.html @@ -0,0 +1,377 @@ + + + +HTMLImageElement attributes naturalWidth, naturalHeight, width, height + + + + + + + + + + + + + +
+
+
+
+ + + diff --git a/Tests/LibWeb/Text/input/wpt-import/html/semantics/embedded-content/the-img-element/resources/cat.jpg b/Tests/LibWeb/Text/input/wpt-import/html/semantics/embedded-content/the-img-element/resources/cat.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a4f14f54d60e592f3ca8b44360931898602ba6fe GIT binary patch literal 21474 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 No(B{}v