From 14d62d7f31e49e021332f3e64e6ea4b285dcdd15 Mon Sep 17 00:00:00 2001 From: Kostya Farber Date: Thu, 26 Sep 2024 10:52:54 +0100 Subject: [PATCH] LibWeb/CSS: Implement add for FontFaceSet There is still some work to do with some of the underying methods called inside this method (e.g is_css_connected) but this is a start. --- Userland/Libraries/LibWeb/CSS/FontFace.h | 2 ++ Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp | 33 +++++++++++++++++-- Userland/Libraries/LibWeb/CSS/FontFaceSet.h | 6 +++- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibWeb/CSS/FontFace.h b/Userland/Libraries/LibWeb/CSS/FontFace.h index ef1871e4ece..b2fed616cbf 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFace.h +++ b/Userland/Libraries/LibWeb/CSS/FontFace.h @@ -70,6 +70,8 @@ public: String line_gap_override() const { return m_line_gap_override; } WebIDL::ExceptionOr set_line_gap_override(String const&); + bool is_css_connected() const { return m_is_css_connected; } + Bindings::FontFaceLoadStatus status() const { return m_status; } JS::NonnullGCPtr load(); diff --git a/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp b/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp index 4e6ee21f5db..767b25f94d8 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp +++ b/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp @@ -61,14 +61,41 @@ void FontFaceSet::visit_edges(Cell::Visitor& visitor) Base::visit_edges(visitor); visitor.visit(m_set_entries); visitor.visit(m_ready_promise); + visitor.visit(m_loading_fonts); + visitor.visit(m_loaded_fonts); + visitor.visit(m_failed_fonts); } // https://drafts.csswg.org/css-font-loading/#dom-fontfaceset-add -JS::NonnullGCPtr FontFaceSet::add(JS::Handle face) +WebIDL::ExceptionOr> +FontFaceSet::add(JS::Handle face) { - // FIXME: Do the actual spec steps + // 1. If font is already in the FontFaceSet’s set entries, skip to the last step of this algorithm immediately. + if (m_set_entries->set_has(face)) + return JS::NonnullGCPtr(*this); + + // 2. If font is CSS-connected, throw an InvalidModificationError exception and exit this algorithm immediately. + if (face->is_css_connected()) { + return WebIDL::InvalidModificationError::create(realm(), "Cannot add a CSS-connected FontFace to a FontFaceSet"_fly_string); + } + + // 3. Add the font argument to the FontFaceSet’s set entries. m_set_entries->set_add(face); - return *this; + + // 4. If font’s status attribute is "loading" + if (face->status() == Bindings::FontFaceLoadStatus::Loading) { + + // 1. If the FontFaceSet’s [[LoadingFonts]] list is empty, switch the FontFaceSet to loading. + if (m_loading_fonts.is_empty()) { + m_status = Bindings::FontFaceSetLoadStatus::Loading; + } + + // 2. Append font to the FontFaceSet’s [[LoadingFonts]] list. + m_loading_fonts.append(*face); + } + + // 5. Return the FontFaceSet. + return JS::NonnullGCPtr(*this); } // https://drafts.csswg.org/css-font-loading/#dom-fontfaceset-delete diff --git a/Userland/Libraries/LibWeb/CSS/FontFaceSet.h b/Userland/Libraries/LibWeb/CSS/FontFaceSet.h index 0916c96e81d..f365a128d1a 100644 --- a/Userland/Libraries/LibWeb/CSS/FontFaceSet.h +++ b/Userland/Libraries/LibWeb/CSS/FontFaceSet.h @@ -27,7 +27,7 @@ public: JS::NonnullGCPtr set_entries() const { return m_set_entries; } - JS::NonnullGCPtr add(JS::Handle); + WebIDL::ExceptionOr> add(JS::Handle); bool delete_(JS::Handle); void clear(); @@ -52,6 +52,10 @@ private: JS::NonnullGCPtr m_set_entries; JS::GCPtr m_ready_promise; // [[ReadyPromise]] + Vector> m_loading_fonts {}; // [[LoadingFonts]] + Vector> m_loaded_fonts {}; // [[LoadedFonts]] + Vector> m_failed_fonts {}; // [[FailedFonts]] + Bindings::FontFaceSetLoadStatus m_status { Bindings::FontFaceSetLoadStatus::Loading }; };