From 0925a32558f7bd4f167ea17a958fc8dd43fe4c75 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Wed, 7 May 2025 17:44:44 +0100 Subject: [PATCH] LibWeb/CSS: Extract a CSSDescriptors base class This holds the boilerplate that's needed by any CSSStyleDeclaration subclass that holds Descriptors. CSSFontFaceDescriptors now only has to worry about initialization and its own exposed properties. --- Libraries/LibWeb/CMakeLists.txt | 1 + Libraries/LibWeb/CSS/CSSDescriptors.cpp | 259 ++++++++++++++++++ Libraries/LibWeb/CSS/CSSDescriptors.h | 48 ++++ .../LibWeb/CSS/CSSFontFaceDescriptors.cpp | 243 +--------------- Libraries/LibWeb/CSS/CSSFontFaceDescriptors.h | 28 +- Libraries/LibWeb/Forward.h | 1 + 6 files changed, 313 insertions(+), 267 deletions(-) create mode 100644 Libraries/LibWeb/CSS/CSSDescriptors.cpp create mode 100644 Libraries/LibWeb/CSS/CSSDescriptors.h diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 17174724da6..5ab7fddfc9e 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -71,6 +71,7 @@ set(SOURCES CSS/CSS.cpp CSS/CSSAnimation.cpp CSS/CSSConditionRule.cpp + CSS/CSSDescriptors.cpp CSS/CSSFontFaceDescriptors.cpp CSS/CSSFontFaceRule.cpp CSS/CSSGroupingRule.cpp diff --git a/Libraries/LibWeb/CSS/CSSDescriptors.cpp b/Libraries/LibWeb/CSS/CSSDescriptors.cpp new file mode 100644 index 00000000000..1d77eaaf020 --- /dev/null +++ b/Libraries/LibWeb/CSS/CSSDescriptors.cpp @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2025, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Web::CSS { + +CSSDescriptors::CSSDescriptors(JS::Realm& realm, AtRuleID at_rule_id, Vector descriptors) + : CSSStyleDeclaration(realm, Computed::No, Readonly::No) + , m_at_rule_id(at_rule_id) + , m_descriptors(move(descriptors)) +{ +} + +CSSDescriptors::~CSSDescriptors() = default; + +// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-length +size_t CSSDescriptors::length() const +{ + // The length attribute must return the number of CSS declarations in the declarations. + return m_descriptors.size(); +} + +// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-item +String CSSDescriptors::item(size_t index) const +{ + // The item(index) method must return the property name of the CSS declaration at position index. + if (index >= length()) + return {}; + + return to_string(m_descriptors[index].descriptor_id).to_string(); +} + +// https://drafts.csswg.org/cssom/#set-a-css-declaration +bool CSSDescriptors::set_a_css_declaration(DescriptorID descriptor_id, NonnullRefPtr value, Important) +{ + VERIFY(!is_computed()); + + for (auto& descriptor : m_descriptors) { + if (descriptor.descriptor_id == descriptor_id) { + if (*descriptor.value == *value) + return false; + descriptor.value = move(value); + return true; + } + } + + m_descriptors.append(Descriptor { + .descriptor_id = descriptor_id, + .value = move(value), + }); + return true; +} + +// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-setproperty +WebIDL::ExceptionOr CSSDescriptors::set_property(StringView property, StringView value, StringView priority) +{ + // 1. If the readonly flag is set, then throw a NoModificationAllowedError exception. + if (is_readonly()) + return WebIDL::NoModificationAllowedError::create(realm(), "Cannot modify properties of readonly CSSStyleDeclaration"_string); + + // 2. If property is not a custom property, follow these substeps: + Optional descriptor_id; + { + // 1. Let property be property converted to ASCII lowercase. + // 2. If property is not a case-sensitive match for a supported CSS property, then return. + descriptor_id = descriptor_id_from_string(m_at_rule_id, property); + if (!descriptor_id.has_value()) + return {}; + } + + // 3. If value is the empty string, invoke removeProperty() with property as argument and return. + if (value.is_empty()) { + MUST(remove_property(property)); + return {}; + } + + // 4. If priority is not the empty string and is not an ASCII case-insensitive match for the string "important", then return. + if (!priority.is_empty() && !Infra::is_ascii_case_insensitive_match(priority, "important"sv)) + return {}; + + // 5. Let component value list be the result of parsing value for property property. + RefPtr component_value_list = parse_css_descriptor(Parser::ParsingParams {}, m_at_rule_id, *descriptor_id, value); + + // 6. If component value list is null, then return. + if (!component_value_list) + return {}; + + // 7. Let updated be false. + auto updated = false; + + // 8. If property is a shorthand property... + // NB: Descriptors can't be shorthands. + // 9. Otherwise, let updated be the result of set the CSS declaration property with value component value list, + // with the important flag set if priority is not the empty string, and unset otherwise, and with the list of + // declarations being the declarations. + updated = set_a_css_declaration(*descriptor_id, *component_value_list, !priority.is_empty() ? Important::Yes : Important::No); + + // 10. If updated is true, update style attribute for the CSS declaration block. + if (updated) + update_style_attribute(); + + return {}; +} + +// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty +WebIDL::ExceptionOr CSSDescriptors::remove_property(StringView property) +{ + // 1. If the readonly flag is set, then throw a NoModificationAllowedError exception. + if (is_readonly()) + return WebIDL::NoModificationAllowedError::create(realm(), "Cannot modify properties of readonly CSSStyleDeclaration"_string); + + // 2. If property is not a custom property, let property be property converted to ASCII lowercase. + // AD-HOC: We compare names case-insensitively instead. + + // 3. Let value be the return value of invoking getPropertyValue() with property as argument. + auto value = get_property_value(property); + + // 4. Let removed be false. + bool removed = false; + + // 5. If property is a shorthand property... + // NB: Descriptors can't be shorthands. + // 6. Otherwise, if property is a case-sensitive match for a property name of a CSS declaration in the + // declarations, remove that CSS declaration and let removed be true. + // auto descriptor_id = descriptor_from_string() + auto descriptor_id = descriptor_id_from_string(m_at_rule_id, property); + if (descriptor_id.has_value()) { + removed = m_descriptors.remove_first_matching([descriptor_id](auto& entry) { return entry.descriptor_id == *descriptor_id; }); + } + + // 7. If removed is true, Update style attribute for the CSS declaration block. + if (removed) + update_style_attribute(); + + // 8. Return value. + return value; +} + +// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertyvalue +String CSSDescriptors::get_property_value(StringView property) const +{ + // 1. If property is not a custom property, follow these substeps: ... + // NB: These substeps only apply to shorthands, and descriptors cannot be shorthands. + + // 2. If property is a case-sensitive match for a property name of a CSS declaration in the declarations, then + // return the result of invoking serialize a CSS value of that declaration. + auto descriptor_id = descriptor_id_from_string(m_at_rule_id, property); + if (descriptor_id.has_value()) { + auto match = m_descriptors.first_matching([descriptor_id](auto& entry) { return entry.descriptor_id == *descriptor_id; }); + if (match.has_value()) + return match->value->to_string(CSSStyleValue::SerializationMode::Normal); + } + + // 3. Return the empty string. + return {}; +} + +// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertypriority +StringView CSSDescriptors::get_property_priority(StringView) const +{ + // AD-HOC: It's not valid for descriptors to be !important. + return {}; +} + +// https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block +String CSSDescriptors::serialized() const +{ + // 1. Let list be an empty array. + Vector list; + list.ensure_capacity(m_descriptors.size()); + + // 2. Let already serialized be an empty array. + // AD-HOC: Not needed as we don't have shorthands. + + // 3. Declaration loop: For each CSS declaration declaration in declaration block’s declarations, follow these substeps: + for (auto const& descriptor : m_descriptors) { + // 1. Let property be declaration’s property name. + auto property = to_string(descriptor.descriptor_id); + + // 2. If property is in already serialized, continue with the steps labeled declaration loop. + // AD-HOC: Not needed as we don't have shorthands. + + // 3. If property maps to one or more shorthand properties, let shorthands be an array of those shorthand properties, in preferred order. + // 4. Shorthand loop: For each shorthand in shorthands, follow these substeps: ... + // NB: Descriptors can't be shorthands. + + // 5. Let value be the result of invoking serialize a CSS value of declaration. + auto value = descriptor.value->to_string(CSSStyleValue::SerializationMode::Normal); + + // 6. Let serialized declaration be the result of invoking serialize a CSS declaration with property name property, value value, and the important flag set if declaration has its important flag set. + auto serialized_declaration = serialize_a_css_declaration(property, value, Important::No); + + // 7. Append serialized declaration to list. + list.append(serialized_declaration); + + // 8. Append property to already serialized. + // AD-HOC: Not needed as we don't have shorthands. + } + + // 4. Return list joined with " " (U+0020). + return MUST(String::join(' ', list)); +} + +// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext +WebIDL::ExceptionOr CSSDescriptors::set_css_text(StringView value) +{ + // 1. If the readonly flag is set, then throw a NoModificationAllowedError exception. + if (is_readonly()) + return WebIDL::NoModificationAllowedError::create(realm(), "Cannot modify properties of readonly CSSStyleDeclaration"_string); + + // 2. Empty the declarations. + m_descriptors.clear(); + + // 3. Parse the given value and, if the return value is not the empty list, insert the items in the list into the + // declarations, in specified order. + auto descriptors = parse_css_descriptor_declaration_block(Parser::ParsingParams {}, m_at_rule_id, value); + if (!descriptors.is_empty()) + m_descriptors = move(descriptors); + + // 4. Update style attribute for the CSS declaration block. + update_style_attribute(); + + return {}; +} + +void CSSDescriptors::visit_edges(Visitor& visitor) +{ + Base::visit_edges(visitor); + for (auto& descriptor : m_descriptors) { + descriptor.value->visit_edges(visitor); + } +} + +RefPtr CSSDescriptors::descriptor(DescriptorID descriptor_id) const +{ + auto match = m_descriptors.first_matching([descriptor_id](Descriptor const& descriptor) { + return descriptor.descriptor_id == descriptor_id; + }); + if (match.has_value()) + return match->value; + return nullptr; +} + +RefPtr CSSDescriptors::descriptor_or_initial_value(DescriptorID descriptor_id) const +{ + if (auto value = descriptor(descriptor_id)) + return value.release_nonnull(); + + return descriptor_initial_value(m_at_rule_id, descriptor_id); +} + +} diff --git a/Libraries/LibWeb/CSS/CSSDescriptors.h b/Libraries/LibWeb/CSS/CSSDescriptors.h new file mode 100644 index 00000000000..bb9336d70b3 --- /dev/null +++ b/Libraries/LibWeb/CSS/CSSDescriptors.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Web::CSS { + +// A non-spec base class for descriptor-list classes +class CSSDescriptors : public CSSStyleDeclaration { + WEB_PLATFORM_OBJECT(CSSDescriptors, CSSStyleDeclaration); + +public: + virtual ~CSSDescriptors() override; + + virtual size_t length() const override; + virtual String item(size_t index) const override; + virtual WebIDL::ExceptionOr set_property(StringView property, StringView value, StringView priority) override; + virtual WebIDL::ExceptionOr remove_property(StringView property) override; + virtual String get_property_value(StringView property) const override; + virtual StringView get_property_priority(StringView property) const override; + + Vector const& descriptors() const { return m_descriptors; } + RefPtr descriptor(DescriptorID) const; + RefPtr descriptor_or_initial_value(DescriptorID) const; + virtual String serialized() const override; + + virtual WebIDL::ExceptionOr set_css_text(StringView) override; + +protected: + CSSDescriptors(JS::Realm&, AtRuleID, Vector); + +private: + bool set_a_css_declaration(DescriptorID, NonnullRefPtr, Important); + + virtual void visit_edges(Visitor&) override; + + AtRuleID m_at_rule_id; + Vector m_descriptors; +}; + +} diff --git a/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.cpp b/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.cpp index 2cb99d668b3..ccc8225f0a5 100644 --- a/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.cpp +++ b/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.cpp @@ -6,10 +6,6 @@ #include #include -#include -#include -#include -#include namespace Web::CSS { @@ -21,8 +17,7 @@ GC::Ref CSSFontFaceDescriptors::create(JS::Realm& realm, } CSSFontFaceDescriptors::CSSFontFaceDescriptors(JS::Realm& realm, Vector descriptors) - : CSSStyleDeclaration(realm, Computed::No, Readonly::No) - , m_descriptors(move(descriptors)) + : CSSDescriptors(realm, AtRuleID::FontFace, move(descriptors)) { } @@ -34,242 +29,6 @@ void CSSFontFaceDescriptors::initialize(JS::Realm& realm) Base::initialize(realm); } -// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-length -size_t CSSFontFaceDescriptors::length() const -{ - // The length attribute must return the number of CSS declarations in the declarations. - return m_descriptors.size(); -} - -// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-item -String CSSFontFaceDescriptors::item(size_t index) const -{ - // The item(index) method must return the property name of the CSS declaration at position index. - if (index >= length()) - return {}; - - return to_string(m_descriptors[index].descriptor_id).to_string(); -} - -// https://drafts.csswg.org/cssom/#set-a-css-declaration -bool CSSFontFaceDescriptors::set_a_css_declaration(DescriptorID descriptor_id, NonnullRefPtr value, Important) -{ - VERIFY(!is_computed()); - - for (auto& descriptor : m_descriptors) { - if (descriptor.descriptor_id == descriptor_id) { - if (*descriptor.value == *value) - return false; - descriptor.value = move(value); - return true; - } - } - - m_descriptors.append(Descriptor { - .descriptor_id = descriptor_id, - .value = move(value), - }); - return true; -} - -// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-setproperty -WebIDL::ExceptionOr CSSFontFaceDescriptors::set_property(StringView property, StringView value, StringView priority) -{ - // 1. If the readonly flag is set, then throw a NoModificationAllowedError exception. - if (is_readonly()) - return WebIDL::NoModificationAllowedError::create(realm(), "Cannot modify properties of readonly CSSFontFaceDescriptors"_string); - - // 2. If property is not a custom property, follow these substeps: - Optional descriptor_id; - { - // 1. Let property be property converted to ASCII lowercase. - // 2. If property is not a case-sensitive match for a supported CSS property, then return. - descriptor_id = descriptor_id_from_string(AtRuleID::FontFace, property); - if (!descriptor_id.has_value()) - return {}; - } - - // 3. If value is the empty string, invoke removeProperty() with property as argument and return. - if (value.is_empty()) { - MUST(remove_property(property)); - return {}; - } - - // 4. If priority is not the empty string and is not an ASCII case-insensitive match for the string "important", then return. - if (!priority.is_empty() && !Infra::is_ascii_case_insensitive_match(priority, "important"sv)) - return {}; - - // 5. Let component value list be the result of parsing value for property property. - RefPtr component_value_list = parse_css_descriptor(Parser::ParsingParams {}, AtRuleID::FontFace, *descriptor_id, value); - - // 6. If component value list is null, then return. - if (!component_value_list) - return {}; - - // 7. Let updated be false. - auto updated = false; - - // 8. If property is a shorthand property... - // NB: Descriptors can't be shorthands. - // 9. Otherwise, let updated be the result of set the CSS declaration property with value component value list, - // with the important flag set if priority is not the empty string, and unset otherwise, and with the list of - // declarations being the declarations. - updated = set_a_css_declaration(*descriptor_id, *component_value_list, !priority.is_empty() ? Important::Yes : Important::No); - - // 10. If updated is true, update style attribute for the CSS declaration block. - if (updated) - update_style_attribute(); - - return {}; -} - -// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty -WebIDL::ExceptionOr CSSFontFaceDescriptors::remove_property(StringView property) -{ - // 1. If the readonly flag is set, then throw a NoModificationAllowedError exception. - if (is_readonly()) - return WebIDL::NoModificationAllowedError::create(realm(), "Cannot modify properties of readonly CSSFontFaceDescriptors"_string); - - // 2. If property is not a custom property, let property be property converted to ASCII lowercase. - // AD-HOC: We compare names case-insensitively instead. - - // 3. Let value be the return value of invoking getPropertyValue() with property as argument. - auto value = get_property_value(property); - - // 4. Let removed be false. - bool removed = false; - - // 5. If property is a shorthand property... - // NB: Descriptors can't be shorthands. - // 6. Otherwise, if property is a case-sensitive match for a property name of a CSS declaration in the - // declarations, remove that CSS declaration and let removed be true. - // auto descriptor_id = descriptor_from_string() - auto descriptor_id = descriptor_id_from_string(AtRuleID::FontFace, property); - if (descriptor_id.has_value()) { - removed = m_descriptors.remove_first_matching([descriptor_id](auto& entry) { return entry.descriptor_id == *descriptor_id; }); - } - - // 7. If removed is true, Update style attribute for the CSS declaration block. - if (removed) - update_style_attribute(); - - // 8. Return value. - return value; -} - -// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertyvalue -String CSSFontFaceDescriptors::get_property_value(StringView property) const -{ - // 1. If property is not a custom property, follow these substeps: ... - // NB: These substeps only apply to shorthands, and descriptors cannot be shorthands. - - // 2. If property is a case-sensitive match for a property name of a CSS declaration in the declarations, then - // return the result of invoking serialize a CSS value of that declaration. - auto descriptor_id = descriptor_id_from_string(AtRuleID::FontFace, property); - if (descriptor_id.has_value()) { - auto match = m_descriptors.first_matching([descriptor_id](auto& entry) { return entry.descriptor_id == *descriptor_id; }); - if (match.has_value()) - return match->value->to_string(CSSStyleValue::SerializationMode::Normal); - } - - // 3. Return the empty string. - return {}; -} - -// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-getpropertypriority -StringView CSSFontFaceDescriptors::get_property_priority(StringView) const -{ - // AD-HOC: It's not valid for descriptors to be !important. - return {}; -} - -// https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block -String CSSFontFaceDescriptors::serialized() const -{ - // 1. Let list be an empty array. - Vector list; - list.ensure_capacity(m_descriptors.size()); - - // 2. Let already serialized be an empty array. - // AD-HOC: Not needed as we don't have shorthands. - - // 3. Declaration loop: For each CSS declaration declaration in declaration block’s declarations, follow these substeps: - for (auto const& descriptor : m_descriptors) { - // 1. Let property be declaration’s property name. - auto property = to_string(descriptor.descriptor_id); - - // 2. If property is in already serialized, continue with the steps labeled declaration loop. - // AD-HOC: Not needed as we don't have shorthands. - - // 3. If property maps to one or more shorthand properties, let shorthands be an array of those shorthand properties, in preferred order. - // 4. Shorthand loop: For each shorthand in shorthands, follow these substeps: ... - // NB: Descriptors can't be shorthands. - - // 5. Let value be the result of invoking serialize a CSS value of declaration. - auto value = descriptor.value->to_string(CSSStyleValue::SerializationMode::Normal); - - // 6. Let serialized declaration be the result of invoking serialize a CSS declaration with property name property, value value, and the important flag set if declaration has its important flag set. - auto serialized_declaration = serialize_a_css_declaration(property, value, Important::No); - - // 7. Append serialized declaration to list. - list.append(serialized_declaration); - - // 8. Append property to already serialized. - // AD-HOC: Not needed as we don't have shorthands. - } - - // 4. Return list joined with " " (U+0020). - return MUST(String::join(' ', list)); -} - -// https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-csstext -WebIDL::ExceptionOr CSSFontFaceDescriptors::set_css_text(StringView value) -{ - // 1. If the readonly flag is set, then throw a NoModificationAllowedError exception. - if (is_readonly()) - return WebIDL::NoModificationAllowedError::create(realm(), "Cannot modify properties of readonly CSSFontFaceDescriptors"_string); - - // 2. Empty the declarations. - m_descriptors.clear(); - - // 3. Parse the given value and, if the return value is not the empty list, insert the items in the list into the - // declarations, in specified order. - auto descriptors = parse_css_descriptor_declaration_block(Parser::ParsingParams {}, AtRuleID::FontFace, value); - if (!descriptors.is_empty()) - m_descriptors = move(descriptors); - - // 4. Update style attribute for the CSS declaration block. - update_style_attribute(); - - return {}; -} - -void CSSFontFaceDescriptors::visit_edges(Visitor& visitor) -{ - Base::visit_edges(visitor); - for (auto& descriptor : m_descriptors) { - descriptor.value->visit_edges(visitor); - } -} - -RefPtr CSSFontFaceDescriptors::descriptor(DescriptorID descriptor_id) const -{ - auto match = m_descriptors.first_matching([descriptor_id](Descriptor const& descriptor) { - return descriptor.descriptor_id == descriptor_id; - }); - if (match.has_value()) - return match->value; - return nullptr; -} - -RefPtr CSSFontFaceDescriptors::descriptor_or_initial_value(DescriptorID descriptor_id) const -{ - if (auto value = descriptor(descriptor_id)) - return value.release_nonnull(); - - return descriptor_initial_value(AtRuleID::FontFace, descriptor_id); -} - WebIDL::ExceptionOr CSSFontFaceDescriptors::set_ascent_override(StringView value) { return set_property("ascent-override"sv, value, ""sv); diff --git a/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.h b/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.h index 82ba82c5d04..05af255a6b1 100644 --- a/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.h +++ b/Libraries/LibWeb/CSS/CSSFontFaceDescriptors.h @@ -6,15 +6,14 @@ #pragma once -#include -#include +#include namespace Web::CSS { // https://drafts.csswg.org/css-fonts-4/#cssfontfacedescriptors class CSSFontFaceDescriptors final - : public CSSStyleDeclaration { - WEB_PLATFORM_OBJECT(CSSFontFaceDescriptors, CSSStyleDeclaration); + : public CSSDescriptors { + WEB_PLATFORM_OBJECT(CSSFontFaceDescriptors, CSSDescriptors); GC_DECLARE_ALLOCATOR(CSSFontFaceDescriptors); public: @@ -24,17 +23,6 @@ public: virtual void initialize(JS::Realm&) override; - virtual size_t length() const override; - virtual String item(size_t index) const override; - - virtual WebIDL::ExceptionOr set_property(StringView property, StringView value, StringView priority) override; - virtual WebIDL::ExceptionOr remove_property(StringView property) override; - virtual String get_property_value(StringView property) const override; - virtual StringView get_property_priority(StringView property) const override; - - RefPtr descriptor(DescriptorID) const; - RefPtr descriptor_or_initial_value(DescriptorID) const; - WebIDL::ExceptionOr set_ascent_override(StringView value); String ascent_override() const; @@ -77,18 +65,8 @@ public: WebIDL::ExceptionOr set_unicode_range(StringView value); String unicode_range() const; - virtual String serialized() const override; - - virtual WebIDL::ExceptionOr set_css_text(StringView) override; - private: CSSFontFaceDescriptors(JS::Realm&, Vector); - - bool set_a_css_declaration(DescriptorID, NonnullRefPtr, Important); - - virtual void visit_edges(Visitor&) override; - - Vector m_descriptors; }; } diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index fe8ff3d4638..6793b94da5e 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -163,6 +163,7 @@ class CounterStyleValue; class CSSAnimation; class CSSColorValue; class CSSConditionRule; +class CSSDescriptors; class CSSFontFaceDescriptors; class CSSFontFaceRule; class CSSGroupingRule;