diff --git a/Userland/Libraries/LibWeb/HTML/AttributeNames.h b/Userland/Libraries/LibWeb/HTML/AttributeNames.h
index 08838deee0..083375ebd4 100644
--- a/Userland/Libraries/LibWeb/HTML/AttributeNames.h
+++ b/Userland/Libraries/LibWeb/HTML/AttributeNames.h
@@ -90,6 +90,7 @@ namespace AttributeNames {
__ENUMERATE_HTML_ATTRIBUTE(lang) \
__ENUMERATE_HTML_ATTRIBUTE(language) \
__ENUMERATE_HTML_ATTRIBUTE(link) \
+ __ENUMERATE_HTML_ATTRIBUTE(loading) \
__ENUMERATE_HTML_ATTRIBUTE(longdesc) \
__ENUMERATE_HTML_ATTRIBUTE(loop) \
__ENUMERATE_HTML_ATTRIBUTE(marginheight) \
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp
index d53d72c9fa..bc3e87b63b 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp
@@ -455,7 +455,8 @@ after_step_6:
// FIXME: 21. Set request's priority to the current state of the element's fetchpriority attribute.
- // FIXME: 22. Let delay load event be true if the img's lazy loading attribute is in the Eager state, or if scripting is disabled for the img, and false otherwise.
+ // 22. Let delay load event be true if the img's lazy loading attribute is in the Eager state, or if scripting is disabled for the img, and false otherwise.
+ auto delay_load_event = lazy_loading() == LazyLoading::Eager;
// FIXME: 23. If the will lazy load element steps given the img return true, then:
// FIXME: 1. Set the img's lazy load resumption steps to the rest of this algorithm starting with the step labeled fetch the image.
@@ -492,6 +493,12 @@ after_step_6:
// 24. Fetch the image: Fetch request.
// Return from this algorithm, and run the remaining steps as part of the fetch's processResponse for the response response.
+
+ // When delay load event is true, fetching the image must delay the load event of the element's node document
+ // until the task that is queued by the networking task source once the resource has been fetched (defined below) has been run.
+ if (delay_load_event)
+ m_load_event_delayer.emplace(document());
+
auto fetch_controller = Fetch::Fetching::fetch(
realm(),
request,
@@ -508,6 +515,10 @@ void HTMLImageElement::handle_successful_fetch(AK::URL const& url_string, ImageR
// AD-HOC: At this point, things gets very ad-hoc.
// FIXME: Bring this closer to spec.
+ ScopeGuard undelay_load_event_guard = [this] {
+ m_load_event_delayer.clear();
+ };
+
auto result = Web::Platform::ImageCodecPlugin::the().decode_image(data.bytes());
if (!result.has_value()) {
dispatch_event(DOM::Event::create(realm(), HTML::EventNames::error).release_value_but_fixme_should_propagate_errors());
@@ -748,4 +759,13 @@ void HTMLImageElement::animate()
layout_node()->set_needs_display();
}
+// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#lazy-loading-attributes
+HTMLImageElement::LazyLoading HTMLImageElement::lazy_loading() const
+{
+ auto value = attribute(HTML::AttributeNames::loading);
+ if (value.equals_ignoring_ascii_case("lazy"sv))
+ return LazyLoading::Lazy;
+ return LazyLoading::Eager;
+}
+
}
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h
index 9f408c080d..8f35409906 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling
+ * Copyright (c) 2018-2023, Andreas Kling
*
* SPDX-License-Identifier: BSD-2-Clause
*/