Browse Source

LibWeb: Fire "load" and "error" events for rel=preload link loads

Andreas Kling 2 years ago
parent
commit
b97004ea4a

+ 2 - 0
Tests/LibWeb/Text/expected/link-element-rel-preload-load-event.txt

@@ -0,0 +1,2 @@
+Got load event
+Got error event

+ 20 - 0
Tests/LibWeb/Text/input/link-element-rel-preload-load-event.html

@@ -0,0 +1,20 @@
+<script src="include.js"></script>
+<script>
+    let goodLink = document.createElement("link");
+    goodLink.setAttribute("rel", "preload");
+    goodLink.setAttribute("href", "valid.css");
+    goodLink.setAttribute("as", "style");
+    goodLink.addEventListener("load", function() {
+        println("Got load event");
+    });
+    document.head.appendChild(goodLink);
+
+    let badLink = document.createElement("link");
+    badLink.setAttribute("rel", "preload");
+    badLink.setAttribute("href", "this-file-does-not-exist-and-so-is-invalid.css");
+    badLink.setAttribute("as", "style");
+    badLink.addEventListener("error", function() {
+        println("Got error event");
+    });
+    document.head.appendChild(badLink);
+</script>

+ 1 - 0
Tests/LibWeb/Text/input/valid.css

@@ -0,0 +1 @@
+* { }

+ 10 - 3
Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org>
  * Copyright (c) 2021, the SerenityOS developers.
  * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
  * Copyright (c) 2023, Srikavin Ramkumar <me@srikavin.me>
@@ -60,7 +60,7 @@ void HTMLLinkElement::inserted()
         // FIXME: Respect the "as" attribute.
         LoadRequest request;
         request.set_url(document().parse_url(attribute(HTML::AttributeNames::href)));
-        m_preload_resource = ResourceLoader::the().load_resource(Resource::Type::Generic, request);
+        set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, request));
     } else if (m_relationship & Relationship::DNSPrefetch) {
         ResourceLoader::the().prefetch_dns(document().parse_url(attribute(HTML::AttributeNames::href)));
     } else if (m_relationship & Relationship::Preconnect) {
@@ -111,6 +111,8 @@ void HTMLLinkElement::parse_attribute(DeprecatedFlyString const& name, Deprecate
         // https://html.spec.whatwg.org/multipage/links.html#link-type-stylesheet:fetch-and-process-the-linked-resource
         // The appropriate times to fetch and process this type of link are:
         if (
+            // AD-HOC: When the rel attribute changes
+            name == AttributeNames::rel ||
             // - When the href attribute of the link element of an external resource link that is already browsing-context connected is changed.
             name == AttributeNames::href ||
             // - When the disabled attribute of the link element of an external resource link that is already browsing-context connected is set, changed, or removed.
@@ -128,16 +130,21 @@ void HTMLLinkElement::parse_attribute(DeprecatedFlyString const& name, Deprecate
 void HTMLLinkElement::resource_did_fail()
 {
     dbgln_if(CSS_LOADER_DEBUG, "HTMLLinkElement: Resource did fail. URL: {}", resource()->url());
+    if (m_relationship & Relationship::Preload) {
+        dispatch_event(*DOM::Event::create(realm(), HTML::EventNames::error).release_value_but_fixme_should_propagate_errors());
+    }
 }
 
 void HTMLLinkElement::resource_did_load()
 {
     VERIFY(resource());
-    VERIFY(m_relationship & (Relationship::Icon));
     if (m_relationship & Relationship::Icon) {
         resource_did_load_favicon();
         m_document_load_event_delayer.clear();
     }
+    if (m_relationship & Relationship::Preload) {
+        dispatch_event(*DOM::Event::create(realm(), HTML::EventNames::load).release_value_but_fixme_should_propagate_errors());
+    }
 }
 
 void HTMLLinkElement::did_remove_attribute(DeprecatedFlyString const& attr)

+ 1 - 2
Userland/Libraries/LibWeb/HTML/HTMLLinkElement.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org>
  * Copyright (c) 2021, the SerenityOS developers.
  * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
  * Copyright (c) 2023, Srikavin Ramkumar <me@srikavin.me>
@@ -127,7 +127,6 @@ private:
         };
     };
 
-    RefPtr<Resource> m_preload_resource;
     JS::GCPtr<CSS::CSSStyleSheet> m_loaded_style_sheet;
 
     Optional<DOM::DocumentLoadEventDelayer> m_document_load_event_delayer;