diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 0edc57b971..128a991fcf 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -3282,7 +3282,7 @@ void Document::start_intersection_observing_a_lazy_loading_element(Element& elem auto& entry = verify_cast(entries.get_without_side_effects(property_key).as_object()); // 1. Let resumptionSteps be null. - JS::SafeFunction resumption_steps; + JS::GCPtr> resumption_steps; // 2. If entry.isIntersecting is true, then set resumptionSteps to entry.target's lazy load resumption steps. if (entry.is_intersecting()) { @@ -3306,7 +3306,7 @@ void Document::start_intersection_observing_a_lazy_loading_element(Element& elem m_lazy_load_intersection_observer->unobserve(entry.target()); // 6. Invoke resumptionSteps. - resumption_steps(); + resumption_steps->function()(); } return JS::js_undefined(); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp index 9a9310465a..ecb97145a5 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp @@ -69,6 +69,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_lazy_load_resumption_steps); } void HTMLImageElement::apply_presentational_hints(CSS::StyleProperties& style) const @@ -159,6 +160,11 @@ void HTMLImageElement::set_visible_in_viewport(bool) // FIXME: Loosen grip on image data when it's not visible, e.g via volatile memory. } +void HTMLImageElement::set_lazy_load_resumption_steps(Function steps) +{ + m_lazy_load_resumption_steps = JS::create_heap_function(vm().heap(), move(steps)); +} + // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-width unsigned HTMLImageElement::width() const { @@ -549,9 +555,9 @@ after_step_7: // 24. If the will lazy load element steps given the img return true, then: if (will_lazy_load()) { // 1. Set the img's lazy load resumption steps to the rest of this algorithm starting with the step labeled fetch the image. - m_lazy_load_resumption_steps = [this, request, image_request]() { + set_lazy_load_resumption_steps([this, request, image_request]() { image_request->fetch_image(realm(), request); - }; + }); // 2. Start intersection-observing a lazy loading element for the img element. document().start_intersection_observing_a_lazy_loading_element(*this); @@ -1022,9 +1028,11 @@ bool HTMLImageElement::will_lazy_load() const return lazy_loading() == LazyLoading::Lazy; } -JS::SafeFunction HTMLImageElement::take_lazy_load_resumption_steps(Badge) +JS::GCPtr> HTMLImageElement::take_lazy_load_resumption_steps(Badge) { - return move(m_lazy_load_resumption_steps); + auto lazy_load_resumption_steps = m_lazy_load_resumption_steps; + m_lazy_load_resumption_steps = nullptr; + return lazy_load_resumption_steps; } } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h index c8acab6441..5e6710f0b8 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -90,7 +91,8 @@ public: virtual RefPtr current_image_bitmap(Gfx::IntSize = {}) const override; virtual void set_visible_in_viewport(bool) override; - JS::SafeFunction take_lazy_load_resumption_steps(Badge); + void set_lazy_load_resumption_steps(Function); + JS::GCPtr> take_lazy_load_resumption_steps(Badge); virtual void visit_edges(Cell::Visitor&) override; @@ -136,7 +138,7 @@ private: // https://html.spec.whatwg.org/multipage/urls-and-fetching.html#lazy-load-resumption-steps // Each img and iframe element has associated lazy load resumption steps, initially null. - JS::SafeFunction m_lazy_load_resumption_steps; + JS::GCPtr> m_lazy_load_resumption_steps; CSSPixelSize m_last_seen_viewport_size; };