diff --git a/Libraries/LibHTML/DOM/HTMLImageElement.cpp b/Libraries/LibHTML/DOM/HTMLImageElement.cpp
index da4afde0848..7bb8f8cd38d 100644
--- a/Libraries/LibHTML/DOM/HTMLImageElement.cpp
+++ b/Libraries/LibHTML/DOM/HTMLImageElement.cpp
@@ -80,3 +80,17 @@ const GraphicsBitmap* HTMLImageElement::bitmap() const
return nullptr;
return m_image_decoder->bitmap();
}
+
+void HTMLImageElement::set_volatile(Badge, bool v)
+{
+ if (!m_image_decoder)
+ return;
+ if (v) {
+ m_image_decoder->set_volatile();
+ return;
+ }
+ bool has_image = m_image_decoder->set_nonvolatile();
+ if (has_image)
+ return;
+ m_image_decoder = ImageDecoder::create(m_encoded_data.data(), m_encoded_data.size());
+}
diff --git a/Libraries/LibHTML/DOM/HTMLImageElement.h b/Libraries/LibHTML/DOM/HTMLImageElement.h
index 2cc8587c30e..e2677e9651d 100644
--- a/Libraries/LibHTML/DOM/HTMLImageElement.h
+++ b/Libraries/LibHTML/DOM/HTMLImageElement.h
@@ -4,6 +4,8 @@
#include
#include
+class LayoutDocument;
+
class HTMLImageElement : public HTMLElement {
public:
HTMLImageElement(Document&, const String& tag_name);
@@ -19,12 +21,13 @@ public:
const GraphicsBitmap* bitmap() const;
const ImageDecoder* image_decoder() const { return m_image_decoder; }
+ void set_volatile(Badge, bool);
+
private:
void load_image(const String& src);
virtual RefPtr create_layout_node(const StyleProperties* parent_style) const override;
RefPtr m_image_decoder;
- mutable RefPtr m_bitmap;
ByteBuffer m_encoded_data;
};
diff --git a/Libraries/LibHTML/Frame.cpp b/Libraries/LibHTML/Frame.cpp
index 3f1894763d3..b87fd356ccf 100644
--- a/Libraries/LibHTML/Frame.cpp
+++ b/Libraries/LibHTML/Frame.cpp
@@ -1,6 +1,7 @@
#include
#include
#include
+#include
Frame::Frame(HtmlView& html_view)
: m_html_view(html_view.make_weak_ptr())
@@ -37,6 +38,9 @@ void Frame::set_viewport_rect(const Rect& rect)
if (m_viewport_rect == rect)
return;
m_viewport_rect = rect;
+
+ if (m_document && m_document->layout_node())
+ m_document->layout_node()->did_set_viewport_rect({}, rect);
}
void Frame::set_needs_display(const Rect& rect)
diff --git a/Libraries/LibHTML/Layout/LayoutDocument.cpp b/Libraries/LibHTML/Layout/LayoutDocument.cpp
index 97768039029..279fb810cbf 100644
--- a/Libraries/LibHTML/Layout/LayoutDocument.cpp
+++ b/Libraries/LibHTML/Layout/LayoutDocument.cpp
@@ -1,6 +1,7 @@
-#include
#include
+#include
#include
+#include
LayoutDocument::LayoutDocument(const Document& document, NonnullRefPtr style)
: LayoutBlock(&document, move(style))
@@ -29,3 +30,15 @@ void LayoutDocument::layout()
});
rect().set_bottom(lowest_bottom);
}
+
+void LayoutDocument::did_set_viewport_rect(Badge, const Rect& a_viewport_rect)
+{
+ FloatRect viewport_rect(a_viewport_rect.x(), a_viewport_rect.y(), a_viewport_rect.width(), a_viewport_rect.height());
+ for_each_in_subtree([&](auto& layout_node) {
+ if (is(layout_node)) {
+ auto& image = to(layout_node);
+ const_cast(image.node()).set_volatile({}, !viewport_rect.intersects(image.rect()));
+ }
+ return IterationDecision::Continue;
+ });
+}
diff --git a/Libraries/LibHTML/Layout/LayoutDocument.h b/Libraries/LibHTML/Layout/LayoutDocument.h
index 18b44c21bed..5f2e51c09b6 100644
--- a/Libraries/LibHTML/Layout/LayoutDocument.h
+++ b/Libraries/LibHTML/Layout/LayoutDocument.h
@@ -15,6 +15,8 @@ public:
const LayoutRange& selection() const { return m_selection; }
LayoutRange& selection() { return m_selection; }
+ void did_set_viewport_rect(Badge, const Rect&);
+
private:
LayoutRange m_selection;
};