diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 50a5d6c18af..f08a162a08a 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -1569,7 +1569,7 @@ void IDL::ParameterizedType::generate_sequence_from_iterable(SourceGenerator& ge )~~~"); } else { sequence_generator.append(R"~~~( - @sequence.storage_type@ @cpp_name@ { vm.heap() }; + @sequence.storage_type@<@sequence.type@> @cpp_name@ { vm.heap() }; )~~~"); } diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 9557a37da84..be527836d81 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -55,6 +55,7 @@ set(SOURCES CSS/Display.cpp CSS/EdgeRect.cpp CSS/FontFace.cpp + CSS/FontFaceSet.cpp CSS/Flex.cpp CSS/Frequency.cpp CSS/GridTrackPlacement.cpp diff --git a/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp b/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp new file mode 100644 index 00000000000..2491ab25e65 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/FontFaceSet.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include + +namespace Web::CSS { + +JS_DEFINE_ALLOCATOR(FontFaceSet); + +JS::NonnullGCPtr FontFaceSet::construct_impl(JS::Realm& realm, Vector> initial_faces) +{ + return realm.heap().allocate(realm, realm, move(initial_faces)); +} + +JS::NonnullGCPtr FontFaceSet::create(JS::Realm& realm) +{ + return construct_impl(realm, {}); +} + +FontFaceSet::FontFaceSet(JS::Realm& realm, Vector>) + : Bindings::PlatformObject(realm) +{ +} + +void FontFaceSet::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + + WEB_SET_PROTOTYPE_FOR_INTERFACE(FontFaceSet); +} + +// https://drafts.csswg.org/css-font-loading/#dom-fontfaceset-add +JS::NonnullGCPtr FontFaceSet::add(JS::Handle) +{ + // FIXME: Do the steps + return *this; +} + +// https://drafts.csswg.org/css-font-loading/#dom-fontfaceset-load +JS::ThrowCompletionOr> FontFaceSet::load(String const&, String const&) +{ + // FIXME: Do the steps + auto promise = WebIDL::create_rejected_promise(realm(), WebIDL::NotSupportedError::create(realm(), "FontFaceSet::load is not yet implemented"_fly_string)); + return verify_cast(*promise->promise()); +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/FontFaceSet.h b/Userland/Libraries/LibWeb/CSS/FontFaceSet.h new file mode 100644 index 00000000000..fdeaaff7b38 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/FontFaceSet.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Web::CSS { + +class FontFaceSet final : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(FontFace, Bindings::PlatformObject); + JS_DECLARE_ALLOCATOR(FontFaceSet); + +public: + [[nodiscard]] static JS::NonnullGCPtr construct_impl(JS::Realm&, Vector> initial_faces); + [[nodiscard]] static JS::NonnullGCPtr create(JS::Realm&); + virtual ~FontFaceSet() override = default; + + JS::NonnullGCPtr add(JS::Handle face); + JS::ThrowCompletionOr> load(String const& font, String const& text); + +private: + FontFaceSet(JS::Realm&, Vector> initial_faces); + + virtual void initialize(JS::Realm&) override; +}; + +} diff --git a/Userland/Libraries/LibWeb/CSS/FontFaceSet.idl b/Userland/Libraries/LibWeb/CSS/FontFaceSet.idl new file mode 100644 index 00000000000..51f131e4331 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/FontFaceSet.idl @@ -0,0 +1,49 @@ +#import + +dictionary FontFaceSetLoadEventInit : EventInit { + sequence fontfaces = []; +}; + +// FIXME +// [Exposed=(Window,Worker)] +//interface FontFaceSetLoadEvent : Event { +// constructor(CSSOMString type, optional FontFaceSetLoadEventInit eventInitDict = {}); +// [SameObject] readonly attribute FrozenArray fontfaces; +//}; + +enum FontFaceSetLoadStatus { "loading", "loaded" }; + +// https://drafts.csswg.org/css-font-loading/#fontfaceset +[Exposed=(Window,Worker)] +interface FontFaceSet : EventTarget { + constructor(sequence initialFaces); + + // FIXME: setlike; + FontFaceSet add(FontFace font); + // FIXME: boolean delete(FontFace font); + // FIXME: clear(); + + // events for when loading state changes + // FIXME: attribute EventHandler onloading; + // FIXME: attribute EventHandler onloadingdone; + // FIXME: attribute EventHandler onloadingerror; + + // check and start loads if appropriate + // and fulfill promise when all loads complete + // FIXME: Promise> load(CSSOMString font, optional CSSOMString text = " "); + Promise> load(CSSOMString font, optional CSSOMString text = ""); + + // return whether all fonts in the fontlist are loaded + // (does not initiate load if not available) + // FIXME: boolean check(CSSOMString font, optional CSSOMString text = " "); + + // async notification that font loading and layout operations are done + // FIXME: readonly attribute Promise ready; + + // loading state, "loading" while one or more fonts loading, "loaded" otherwise + // FIXME: readonly attribute FontFaceSetLoadStatus status; +}; + +interface mixin FontFaceSource { + readonly attribute FontFaceSet fonts; +}; diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 72e22d44a51..ffaf8e607fa 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -440,6 +441,7 @@ void Document::visit_edges(Cell::Visitor& visitor) visitor.visit(m_forms); visitor.visit(m_scripts); visitor.visit(m_all); + visitor.visit(m_fonts); visitor.visit(m_selection); visitor.visit(m_first_base_element_with_href_in_tree_order); visitor.visit(m_parser); @@ -1452,6 +1454,14 @@ JS::NonnullGCPtr Document::all() return *m_all; } +// https://drafts.csswg.org/css-font-loading/#font-source +JS::NonnullGCPtr Document::fonts() +{ + if (!m_fonts) + m_fonts = CSS::FontFaceSet::create(realm()); + return *m_fonts; +} + // https://html.spec.whatwg.org/multipage/obsolete.html#dom-document-clear void Document::clear() { diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index 3a384386f73..842da349eba 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -256,6 +256,9 @@ public: JS::NonnullGCPtr scripts(); JS::NonnullGCPtr all(); + // https://drafts.csswg.org/css-font-loading/#font-source + JS::NonnullGCPtr fonts(); + void clear(); void capture_events(); void release_events(); @@ -810,6 +813,9 @@ private: JS::GCPtr m_scripts; JS::GCPtr m_all; + // https://drafts.csswg.org/css-font-loading/#font-source + JS::GCPtr m_fonts; + // https://html.spec.whatwg.org/#completely-loaded-time Optional m_completely_loaded_time; diff --git a/Userland/Libraries/LibWeb/DOM/Document.idl b/Userland/Libraries/LibWeb/DOM/Document.idl index db18fc3d355..dcc07f2590c 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.idl +++ b/Userland/Libraries/LibWeb/DOM/Document.idl @@ -1,4 +1,5 @@ #import +#import #import #import #import @@ -152,3 +153,4 @@ dictionary ElementCreationOptions { Document includes ParentNode; Document includes GlobalEventHandlers; Document includes DocumentOrShadowRoot; +Document includes FontFaceSource; diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 29480d029ec..48c64a9d5df 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -125,6 +125,7 @@ class Flex; class FlexOrCalculated; class FlexStyleValue; class FontFace; +class FontFaceSet; class Frequency; class FrequencyOrCalculated; class FrequencyPercentage; diff --git a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp index 3267c6ccaac..157424f4314 100644 --- a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp +++ b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,7 @@ void WorkerGlobalScope::visit_edges(Cell::Visitor& visitor) visitor.visit(m_navigator); visitor.visit(m_internal_port); visitor.visit(m_page); + visitor.visit(m_fonts); } void WorkerGlobalScope::finalize() @@ -127,4 +129,11 @@ WebIDL::ExceptionOr WorkerGlobalScope::post_message(JS::Value message, Str ENUMERATE_WORKER_GLOBAL_SCOPE_EVENT_HANDLERS(__ENUMERATE) #undef __ENUMERATE +JS::NonnullGCPtr WorkerGlobalScope::fonts() +{ + if (!m_fonts) + m_fonts = CSS::FontFaceSet::create(realm()); + return *m_fonts; +} + } diff --git a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h index cac99a4a35f..c7cb0e9989c 100644 --- a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h +++ b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h @@ -77,6 +77,8 @@ public: WebIDL::ExceptionOr post_message(JS::Value message, StructuredSerializeOptions const&); + JS::NonnullGCPtr fonts(); + // Non-IDL public methods URL::URL const& url() const { return m_url.value(); } @@ -136,6 +138,9 @@ private: // https://html.spec.whatwg.org/multipage/workers.html#concept-workerglobalscope-cross-origin-isolated-capability bool m_cross_origin_isolated_capability { false }; + + // https://drafts.csswg.org/css-font-loading/#font-source + JS::GCPtr m_fonts; }; } diff --git a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.idl b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.idl index 58d25184d99..b29e0e3e057 100644 --- a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.idl +++ b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.idl @@ -1,3 +1,4 @@ +#import #import #import #import @@ -28,3 +29,4 @@ interface WorkerGlobalScope : EventTarget { }; WorkerGlobalScope includes WindowOrWorkerGlobalScope; +WorkerGlobalScope includes FontFaceSource; diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 34cc390d310..3c070787d31 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -30,6 +30,7 @@ libweb_js_bindings(CSS/CSSStyleSheet) libweb_js_bindings(CSS/CSSSupportsRule) libweb_js_bindings(CSS/CSSTransition) libweb_js_bindings(CSS/FontFace) +libweb_js_bindings(CSS/FontFaceSet) libweb_js_bindings(CSS/MediaList) libweb_js_bindings(CSS/MediaQueryList) libweb_js_bindings(CSS/MediaQueryListEvent)