diff --git a/Userland/Libraries/LibWeb/CSS/FontFace.h b/Userland/Libraries/LibWeb/CSS/FontFace.h index ef1871e4ec..b2fed616cb 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 4e6ee21f5d..767b25f94d 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 0916c96e81..f365a128d1 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 }; };