LibWeb: Start implementing render-blocking mechanism from HTML spec

This change implements enough spec steps to block rendering until
execution of sync scripts inserted from HTML parser is complete.
This commit is contained in:
Aliaksandr Kalenik 2025-02-04 19:09:14 +01:00 committed by Andreas Kling
commit da579e11b0
Notes: github-actions[bot] 2025-02-05 17:29:43 +00:00
7 changed files with 99 additions and 3 deletions

View file

@ -577,6 +577,7 @@ void Document::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_editing_host_manager);
visitor.visit(m_local_storage_holder);
visitor.visit(m_session_storage_holder);
visitor.visit(m_render_blocking_elements);
}
// https://w3c.github.io/selection-api/#dom-document-getselection
@ -5971,6 +5972,32 @@ bool Document::allow_declarative_shadow_roots() const
return m_allow_declarative_shadow_roots;
}
// https://html.spec.whatwg.org/multipage/dom.html#render-blocked
bool Document::is_render_blocked() const
{
// A Document document is render-blocked if both of the following are true:
// - document's render-blocking element set is non-empty, or document allows adding render-blocking elements.
// - FIXME: The current high resolution time given document's relevant global object has not exceeded an implementation-defined timeout value.
return !m_render_blocking_elements.is_empty() || allows_adding_render_blocking_elements();
}
// https://html.spec.whatwg.org/multipage/dom.html#allows-adding-render-blocking-elements
bool Document::allows_adding_render_blocking_elements() const
{
// A document allows adding render-blocking elements if document's content type is "text/html" and the body element of document is null.
return content_type() == "text/html" && !body();
}
void Document::add_render_blocking_element(GC::Ref<Element> element)
{
m_render_blocking_elements.set(element);
}
void Document::remove_render_blocking_element(GC::Ref<Element> element)
{
m_render_blocking_elements.remove(element);
}
// https://dom.spec.whatwg.org/#document-allow-declarative-shadow-roots
void Document::set_allow_declarative_shadow_roots(bool allow)
{

View file

@ -797,6 +797,14 @@ public:
GC::Ptr<HTML::Storage> local_storage_holder() { return m_local_storage_holder; }
void set_local_storage_holder(GC::Ptr<HTML::Storage> storage) { m_local_storage_holder = storage; }
// https:// html.spec.whatwg.org/multipage/dom.html#render-blocked
[[nodiscard]] bool is_render_blocked() const;
// https://html.spec.whatwg.org/multipage/dom.html#allows-adding-render-blocking-elements
[[nodiscard]] bool allows_adding_render_blocking_elements() const;
void add_render_blocking_element(GC::Ref<Element>);
void remove_render_blocking_element(GC::Ref<Element>);
protected:
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
@ -1131,6 +1139,9 @@ private:
// https://html.spec.whatwg.org/multipage/webstorage.html#local-storage-holder
// A Document object has an associated local storage holder, which is null or a Storage object. It is initially null.
GC::Ptr<HTML::Storage> m_local_storage_holder;
// https://html.spec.whatwg.org/multipage/dom.html#render-blocking-element-set
HashTable<GC::Ref<Element>> m_render_blocking_elements;
};
template<>