Jelajahi Sumber

LibWeb: Add SVGImageElement load and error events

This resolves all WPT timeouts in html/canvas/element/manual/imagebitmap
We can now run an additional 6 tests and 126 subtests :)

This also adds regression tests for this behavior.
Benjamin Bjerken 9 bulan lalu
induk
melakukan
0c04bd6676

+ 3 - 0
Tests/LibWeb/Text/expected/HTML/SVGImageElement-load-and-error-events.txt

@@ -0,0 +1,3 @@
+SUCCESS: "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
+FAIL: "file:///i-do-not-exist"
+FAIL: "https://something.invalid"

+ 41 - 0
Tests/LibWeb/Text/input/HTML/SVGImageElement-load-and-error-events.html

@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<script src="../include.js"></script>
+<script type="text/javascript">
+    const SOURCES = [
+        "data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==", // Valid
+        "file:///i-do-not-exist",  // invalid
+        "https://something.invalid", // invalid
+    ];
+
+    const runTest = (source) => {
+        const svgNamespace = "http://www.w3.org/2000/svg";
+        const image = document.createElementNS(svgNamespace, "image");
+        const svg = document.createElementNS(svgNamespace, "svg");
+        svg.appendChild(image);
+        document.body.appendChild(svg);
+
+        return new Promise((resolve) => {
+            image.addEventListener("load", () => {
+                resolve(`SUCCESS: "${source}"`);
+                document.body.removeChild(svg);
+            });
+
+            image.addEventListener("error", () => {
+                resolve(`FAIL: "${source}"`);
+                document.body.removeChild(svg);
+            });
+
+            image.setAttributeNS("http://www.w3.org/1999/xlink", "href", source);
+        });
+    };
+
+    asyncTest(done => {
+        const promises = SOURCES.map(source => runTest(source));
+
+        Promise.allSettled(promises)
+            .then(results => {
+                results.forEach(result => println(result.value));
+            })
+            .finally(done);
+    });
+</script>

+ 5 - 0
Userland/Libraries/LibWeb/SVG/SVGImageElement.cpp

@@ -9,6 +9,7 @@
 #include <LibJS/Heap/Heap.h>
 #include <LibWeb/Bindings/SVGImageElementPrototype.h>
 #include <LibWeb/DOM/DocumentObserver.h>
+#include <LibWeb/DOM/Event.h>
 #include <LibWeb/HTML/PotentialCORSRequest.h>
 #include <LibWeb/HTML/SharedResourceRequest.h>
 #include <LibWeb/Layout/SVGImageBox.h>
@@ -161,9 +162,13 @@ void SVGImageElement::fetch_the_document(URL::URL const& url)
             }
             set_needs_style_update(true);
             document().set_needs_layout();
+
+            dispatch_event(DOM::Event::create(realm(), HTML::EventNames::load));
         },
         [this] {
             m_load_event_delayer.clear();
+
+            dispatch_event(DOM::Event::create(realm(), HTML::EventNames::error));
         });
 
     if (m_resource_request->needs_fetching()) {