diff --git a/Userland/Libraries/LibWeb/Bindings/CSSRuleWrapperFactory.cpp b/Userland/Libraries/LibWeb/Bindings/CSSRuleWrapperFactory.cpp index e20db17db7..bafaea3772 100644 --- a/Userland/Libraries/LibWeb/Bindings/CSSRuleWrapperFactory.cpp +++ b/Userland/Libraries/LibWeb/Bindings/CSSRuleWrapperFactory.cpp @@ -5,9 +5,11 @@ */ #include +#include #include #include #include +#include #include namespace Web::Bindings { @@ -19,6 +21,8 @@ CSSRuleWrapper* wrap(JS::GlobalObject& global_object, CSS::CSSRule& rule) if (is(rule)) return static_cast(wrap_impl(global_object, verify_cast(rule))); + if (is(rule)) + return static_cast(wrap_impl(global_object, verify_cast(rule))); return static_cast(wrap_impl(global_object, rule)); } diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h index 805a6f6663..53dd04c7b8 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h +++ b/Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include #include @@ -340,6 +342,7 @@ ADD_WINDOW_OBJECT_INTERFACE(AbortSignal) \ ADD_WINDOW_OBJECT_INTERFACE(AbstractRange) \ ADD_WINDOW_OBJECT_INTERFACE(Crypto) \ + ADD_WINDOW_OBJECT_INTERFACE(CSSFontFaceRule) \ ADD_WINDOW_OBJECT_INTERFACE(CSSRule) \ ADD_WINDOW_OBJECT_INTERFACE(CSSRuleList) \ ADD_WINDOW_OBJECT_INTERFACE(CSSStyleDeclaration) \ diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index c036e24801..24486e80b1 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -22,6 +22,7 @@ set(SOURCES CSS/CSSConditionRule.cpp CSS/CSSGroupingRule.cpp CSS/CSSImportRule.cpp + CSS/CSSFontFaceRule.cpp CSS/CSSMediaRule.cpp CSS/CSSRule.cpp CSS/CSSRuleList.cpp @@ -31,6 +32,7 @@ set(SOURCES CSS/CSSSupportsRule.cpp CSS/DefaultStyleSheetSource.cpp CSS/Display.cpp + CSS/FontFace.cpp CSS/Frequency.cpp CSS/Length.cpp CSS/MediaFeatureID.cpp @@ -433,6 +435,7 @@ endfunction() libweb_js_wrapper(Crypto/Crypto) libweb_js_wrapper(Crypto/SubtleCrypto) +libweb_js_wrapper(CSS/CSSFontFaceRule) libweb_js_wrapper(CSS/CSSRule) libweb_js_wrapper(CSS/CSSRuleList) libweb_js_wrapper(CSS/CSSStyleDeclaration) diff --git a/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp new file mode 100644 index 0000000000..f001068142 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace Web::CSS { + +CSSFontFaceRule::CSSFontFaceRule(FontFace&& font_face) + : m_font_face(move(font_face)) +{ +} + +CSSStyleDeclaration* CSSFontFaceRule::style() +{ + // FIXME: Return a CSSStyleDeclaration subclass that directs changes to the FontFace. + return nullptr; +} + +// https://www.w3.org/TR/cssom/#ref-for-cssfontfacerule +String CSSFontFaceRule::serialized() const +{ + // FIXME: Implement this! + return "@font-face { /* FIXME: Implement CSSFontFaceRule::serialized()! */ }"; +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.h b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.h new file mode 100644 index 0000000000..7eb1b487e8 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Web::CSS { + +class CSSFontFaceRule final : public CSSRule { + AK_MAKE_NONCOPYABLE(CSSFontFaceRule); + AK_MAKE_NONMOVABLE(CSSFontFaceRule); + +public: + using WrapperType = Bindings::CSSFontFaceRuleWrapper; + + static NonnullRefPtr create(FontFace&& font_face) + { + return adopt_ref(*new CSSFontFaceRule(move(font_face))); + } + + virtual ~CSSFontFaceRule() override = default; + + virtual StringView class_name() const override { return "CSSFontFaceRule"; } + virtual Type type() const override { return Type::FontFace; } + + FontFace const& font_face() const { return m_font_face; } + CSSStyleDeclaration* style(); + +private: + explicit CSSFontFaceRule(FontFace&&); + + virtual String serialized() const override; + + FontFace m_font_face; +}; + +template<> +inline bool CSSRule::fast_is() const { return type() == CSSRule::Type::FontFace; } + +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.idl b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.idl new file mode 100644 index 0000000000..cf5701a19b --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSFontFaceRule.idl @@ -0,0 +1,7 @@ +#import +#import + +[Exposed=Window] +interface CSSFontFaceRule : CSSRule { + readonly attribute CSSStyleDeclaration style; +}; diff --git a/Userland/Libraries/LibWeb/CSS/CSSRule.h b/Userland/Libraries/LibWeb/CSS/CSSRule.h index 125f38d63d..ec7f9f29d9 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSRule.h @@ -29,6 +29,7 @@ public: Import, Media, Supports, + FontFace, __Count, }; diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp index 0ee0b1fd43..650dac3765 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp @@ -78,8 +78,7 @@ void CSSRuleList::for_each_effective_style_rule(Function(rule)); + case CSSRule::Type::FontFace: break; case CSSRule::Type::Import: { auto const& import_rule = static_cast(rule); @@ -90,6 +89,9 @@ void CSSRuleList::for_each_effective_style_rule(Function(rule).for_each_effective_style_rule(callback); break; + case CSSRule::Type::Style: + callback(static_cast(rule)); + break; case CSSRule::Type::Supports: static_cast(rule).for_each_effective_style_rule(callback); break; @@ -105,7 +107,7 @@ bool CSSRuleList::evaluate_media_queries(HTML::Window const& window) for (auto& rule : m_rules) { switch (rule.type()) { - case CSSRule::Type::Style: + case CSSRule::Type::FontFace: break; case CSSRule::Type::Import: { auto& import_rule = verify_cast(rule); @@ -123,6 +125,8 @@ bool CSSRuleList::evaluate_media_queries(HTML::Window const& window) any_media_queries_changed_match_state = true; break; } + case CSSRule::Type::Style: + break; case CSSRule::Type::Supports: { auto& supports_rule = verify_cast(rule); if (supports_rule.condition_matches() && supports_rule.css_rules().evaluate_media_queries(window)) diff --git a/Userland/Libraries/LibWeb/CSS/FontFace.cpp b/Userland/Libraries/LibWeb/CSS/FontFace.cpp new file mode 100644 index 0000000000..b0401996cd --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/FontFace.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2022, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace Web::CSS { + +FontFace::FontFace(FlyString font_family, Vector sources) + : m_font_family(move(font_family)) + , m_sources(move(sources)) +{ +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/FontFace.h b/Userland/Libraries/LibWeb/CSS/FontFace.h new file mode 100644 index 0000000000..e90aa75b19 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/FontFace.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Web::CSS { + +class FontFace { +public: + struct Source { + AK::URL url; + }; + + FontFace(FlyString font_family, Vector sources); + ~FontFace() = default; + + FlyString font_family() const { return m_font_family; } + Vector const& sources() const { return m_sources; } + // FIXME: font-style, font-weight, font-stretch, unicode-range, font-feature-settings + +private: + FlyString m_font_family; + Vector m_sources; +}; + +} diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index 7fda549794..850f3796c4 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -547,8 +548,8 @@ void dump_rule(StringBuilder& builder, CSS::CSSRule const& rule, int indent_leve builder.appendff("{}:\n", rule.class_name()); switch (rule.type()) { - case CSS::CSSRule::Type::Style: - dump_style_rule(builder, verify_cast(rule), indent_levels); + case CSS::CSSRule::Type::FontFace: + dump_font_face_rule(builder, verify_cast(rule), indent_levels); break; case CSS::CSSRule::Type::Import: dump_import_rule(builder, verify_cast(rule), indent_levels); @@ -556,6 +557,9 @@ void dump_rule(StringBuilder& builder, CSS::CSSRule const& rule, int indent_leve case CSS::CSSRule::Type::Media: dump_media_rule(builder, verify_cast(rule), indent_levels); break; + case CSS::CSSRule::Type::Style: + dump_style_rule(builder, verify_cast(rule), indent_levels); + break; case CSS::CSSRule::Type::Supports: dump_supports_rule(builder, verify_cast(rule), indent_levels); break; @@ -564,6 +568,20 @@ void dump_rule(StringBuilder& builder, CSS::CSSRule const& rule, int indent_leve } } +void dump_font_face_rule(StringBuilder& builder, CSS::CSSFontFaceRule const& rule, int indent_levels) +{ + auto& font_face = rule.font_face(); + indent(builder, indent_levels + 1); + builder.appendff("font-family: {}\n", font_face.font_family()); + + indent(builder, indent_levels + 1); + builder.append("sources:\n"); + for (auto const& source : font_face.sources()) { + indent(builder, indent_levels + 2); + builder.appendff("{}\n", source.url); + } +} + void dump_import_rule(StringBuilder& builder, CSS::CSSImportRule const& rule, int indent_levels) { indent(builder, indent_levels); diff --git a/Userland/Libraries/LibWeb/Dump.h b/Userland/Libraries/LibWeb/Dump.h index aa12e4ba2f..a76b104a2a 100644 --- a/Userland/Libraries/LibWeb/Dump.h +++ b/Userland/Libraries/LibWeb/Dump.h @@ -20,9 +20,10 @@ void dump_sheet(StringBuilder&, CSS::StyleSheet const&); void dump_sheet(CSS::StyleSheet const&); void dump_rule(StringBuilder&, CSS::CSSRule const&, int indent_levels = 0); void dump_rule(CSS::CSSRule const&); -void dump_style_rule(StringBuilder&, CSS::CSSStyleRule const&, int indent_levels = 0); +void dump_font_face_rule(StringBuilder&, CSS::CSSFontFaceRule const&, int indent_levels = 0); void dump_import_rule(StringBuilder&, CSS::CSSImportRule const&, int indent_levels = 0); void dump_media_rule(StringBuilder&, CSS::CSSMediaRule const&, int indent_levels = 0); +void dump_style_rule(StringBuilder&, CSS::CSSStyleRule const&, int indent_levels = 0); void dump_supports_rule(StringBuilder&, CSS::CSSSupportsRule const&, int indent_levels = 0); void dump_selector(StringBuilder&, CSS::Selector const&); void dump_selector(CSS::Selector const&); diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 215d28635a..cbba73e767 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -31,6 +31,7 @@ class CalculatedStyleValue; class ColorStyleValue; class ContentStyleValue; class CSSImportRule; +class CSSFontFaceRule; class CSSMediaRule; class CSSRule; class CSSRuleList; @@ -42,6 +43,7 @@ class Display; class ElementInlineCSSStyleDeclaration; class FlexFlowStyleValue; class FlexStyleValue; +class FontFace; class FontStyleValue; class Frequency; class FrequencyPercentage; @@ -381,6 +383,7 @@ class CharacterDataWrapper; class CloseEventWrapper; class CommentWrapper; class CryptoWrapper; +class CSSFontFaceRuleWrapper; class CSSRuleListWrapper; class CSSRuleWrapper; class CSSStyleDeclarationWrapper;