diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2022-04-22 19:56:22 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-05-11 20:16:10 +0200 |
commit | c718ba59478e63a46542c66f0fb241d1fa9f4b2b (patch) | |
tree | f6f4340f67577405731cd18d1242069086504576 /Userland | |
parent | 6e6607a92f3e00a1e349556f6a211507d26774ab (diff) | |
download | serenity-c718ba59478e63a46542c66f0fb241d1fa9f4b2b.zip |
LibWeb: Implement CSSRule.parentRule and .parentStyleSheet
Both of these are supposed to be set when the CSSRule is created. The
spec is silent on setting it when a CSSRule is added to a parent. So,
this is a bit ad-hoc.
The parent rule gets set whenever a rule is added to a new parent. The
parent stylesheet gets set whenever the rule or one of its ancestors is
added to a different stylesheet. There may be some nuance there that
I'm missing, but I'm sure we'll find out quickly once we have WPT
running!
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp | 24 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSRule.cpp | 18 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSRule.h | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSRule.idl | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp | 9 |
7 files changed, 65 insertions, 11 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp index 66eb4e1dae..725a2f09d6 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org> + * Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -12,18 +12,21 @@ namespace Web::CSS { CSSGroupingRule::CSSGroupingRule(NonnullRefPtrVector<CSSRule>&& rules) : m_rules(CSSRuleList::create(move(rules))) { + for (auto& rule : *m_rules) + rule.set_parent_rule(this); } -size_t CSSGroupingRule::insert_rule(StringView, size_t) +DOM::ExceptionOr<u32> CSSGroupingRule::insert_rule(StringView rule, u32 index) { - // https://www.w3.org/TR/cssom-1/#insert-a-css-rule - TODO(); + TRY(m_rules->insert_a_css_rule(rule, index)); + // NOTE: The spec doesn't say where to set the parent rule, so we'll do it here. + m_rules->item(index)->set_parent_rule(this); + return index; } -void CSSGroupingRule::delete_rule(size_t) +DOM::ExceptionOr<void> CSSGroupingRule::delete_rule(u32 index) { - // https://www.w3.org/TR/cssom-1/#remove-a-css-rule - TODO(); + return m_rules->remove_a_css_rule(index); } void CSSGroupingRule::for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const @@ -31,4 +34,11 @@ void CSSGroupingRule::for_each_effective_style_rule(Function<void(CSSStyleRule c m_rules->for_each_effective_style_rule(callback); } +void CSSGroupingRule::set_parent_style_sheet(CSSStyleSheet* parent_style_sheet) +{ + CSSRule::set_parent_style_sheet(parent_style_sheet); + for (auto& rule : *m_rules) + rule.set_parent_style_sheet(parent_style_sheet); +} + } diff --git a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h index 4d28f42ee7..0f533b6c50 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSGroupingRule.h @@ -26,11 +26,13 @@ public: CSSRuleList const& css_rules() const { return m_rules; } CSSRuleList& css_rules() { return m_rules; } NonnullRefPtr<CSSRuleList> css_rules_for_bindings() { return m_rules; } - size_t insert_rule(StringView rule, size_t index = 0); - void delete_rule(size_t index); + DOM::ExceptionOr<u32> insert_rule(StringView rule, u32 index = 0); + DOM::ExceptionOr<void> delete_rule(u32 index); virtual void for_each_effective_style_rule(Function<void(CSSStyleRule const&)> const& callback) const; + virtual void set_parent_style_sheet(CSSStyleSheet*) override; + protected: explicit CSSGroupingRule(NonnullRefPtrVector<CSSRule>&&); diff --git a/Userland/Libraries/LibWeb/CSS/CSSRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSRule.cpp index e6a2aac960..aeeec6b7fb 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRule.cpp @@ -1,10 +1,12 @@ /* * Copyright (c) 2021, the SerenityOS developers. + * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #include <LibWeb/CSS/CSSRule.h> +#include <LibWeb/CSS/CSSStyleSheet.h> namespace Web::CSS { @@ -21,4 +23,20 @@ void CSSRule::set_css_text(StringView) // On setting the cssText attribute must do nothing. } +void CSSRule::set_parent_rule(CSSRule* parent_rule) +{ + if (parent_rule) + m_parent_rule = parent_rule->make_weak_ptr(); + else + m_parent_rule = nullptr; +} + +void CSSRule::set_parent_style_sheet(CSSStyleSheet* parent_style_sheet) +{ + if (parent_style_sheet) + m_parent_style_sheet = parent_style_sheet->make_weak_ptr(); + else + m_parent_style_sheet = nullptr; +} + } diff --git a/Userland/Libraries/LibWeb/CSS/CSSRule.h b/Userland/Libraries/LibWeb/CSS/CSSRule.h index ece51f8f14..986dc3a6e6 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSRule.h @@ -39,11 +39,20 @@ public: String css_text() const; void set_css_text(StringView); + CSSRule* parent_rule() { return m_parent_rule; } + void set_parent_rule(CSSRule*); + + CSSStyleSheet* parent_style_sheet() { return m_parent_style_sheet; } + virtual void set_parent_style_sheet(CSSStyleSheet*); + template<typename T> bool fast_is() const = delete; protected: virtual String serialized() const = 0; + + WeakPtr<CSSRule> m_parent_rule; + WeakPtr<CSSStyleSheet> m_parent_style_sheet; }; } diff --git a/Userland/Libraries/LibWeb/CSS/CSSRule.idl b/Userland/Libraries/LibWeb/CSS/CSSRule.idl index b2d416c6f8..bd40b41bd6 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRule.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSRule.idl @@ -1,7 +1,13 @@ +#import <CSS/CSSStyleSheet.idl> + +[Exposed=Window] interface CSSRule { attribute CSSOMString cssText; + readonly attribute CSSRule? parentRule; + readonly attribute CSSStyleSheet? parentStyleSheet; + readonly attribute unsigned short type; const unsigned short STYLE_RULE = 1; diff --git a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp index 1a04ef0311..d92f9d72eb 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSRuleList.cpp @@ -80,7 +80,9 @@ DOM::ExceptionOr<void> CSSRuleList::remove_a_css_rule(u32 index) // 5. Remove rule old rule from list at the zero-indexed position index. m_rules.remove(index); - // FIXME: 6. Set old rule’s parent CSS rule and parent CSS style sheet to null. + // 6. Set old rule’s parent CSS rule and parent CSS style sheet to null. + old_rule.set_parent_rule(nullptr); + old_rule.set_parent_style_sheet(nullptr); return {}; } diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp index f3ce3b9135..cecdb9ebe5 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleSheet.cpp @@ -17,6 +17,9 @@ CSSStyleSheet::CSSStyleSheet(NonnullRefPtrVector<CSSRule> rules, Optional<AK::UR { if (location.has_value()) set_location(location->to_string()); + + for (auto& rule : *m_rules) + rule.set_parent_style_sheet(this); } // https://www.w3.org/TR/cssom/#dom-cssstylesheet-insertrule @@ -36,9 +39,13 @@ DOM::ExceptionOr<unsigned> CSSStyleSheet::insert_rule(StringView rule, unsigned // FIXME: 5. If parsed rule is an @import rule, and the constructed flag is set, throw a SyntaxError DOMException. // 6. Return the result of invoking insert a CSS rule rule in the CSS rules at index. - auto result = m_rules->insert_a_css_rule(parsed_rule.release_nonnull(), index); + auto parsed_rule_nonnull = parsed_rule.release_nonnull(); + auto result = m_rules->insert_a_css_rule(parsed_rule_nonnull, index); if (!result.is_exception()) { + // NOTE: The spec doesn't say where to set the parent style sheet, so we'll do it here. + parsed_rule_nonnull->set_parent_style_sheet(this); + if (m_style_sheet_list) { m_style_sheet_list->document().style_computer().invalidate_rule_cache(); m_style_sheet_list->document().invalidate_style(); |