diff --git a/Tests/LibWeb/Text/expected/css/style-declaration-parent-rule.txt b/Tests/LibWeb/Text/expected/css/style-declaration-parent-rule.txt new file mode 100644 index 00000000000..4bce08e27ca --- /dev/null +++ b/Tests/LibWeb/Text/expected/css/style-declaration-parent-rule.txt @@ -0,0 +1,4 @@ +spanRule: [object CSSStyleRule] ~ span { color: rgb(128, 0, 128); } +spanRule.style: [object CSSStyleDeclaration] ~ span { color: rgb(128, 0, 128); } +spanRule.style.parentRule: [object CSSStyleRule] ~ span { color: rgb(128, 0, 128); } +spanRule.style.parentRule === spanRule: true diff --git a/Tests/LibWeb/Text/input/css/style-declaration-parent-rule.html b/Tests/LibWeb/Text/input/css/style-declaration-parent-rule.html new file mode 100644 index 00000000000..36c9bdef673 --- /dev/null +++ b/Tests/LibWeb/Text/input/css/style-declaration-parent-rule.html @@ -0,0 +1,15 @@ + + + diff --git a/Userland/Libraries/LibWeb/CSS/CSSKeyframeRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSKeyframeRule.cpp index 31583fe7003..fb0f666a770 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSKeyframeRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSKeyframeRule.cpp @@ -13,11 +13,19 @@ namespace Web::CSS { JS_DEFINE_ALLOCATOR(CSSKeyframeRule); -JS::NonnullGCPtr CSSKeyframeRule::create(JS::Realm& realm, CSS::Percentage key, Web::CSS::CSSStyleDeclaration& declarations) +JS::NonnullGCPtr CSSKeyframeRule::create(JS::Realm& realm, CSS::Percentage key, Web::CSS::PropertyOwningCSSStyleDeclaration& declarations) { return realm.heap().allocate(realm, realm, key, declarations); } +CSSKeyframeRule::CSSKeyframeRule(JS::Realm& realm, CSS::Percentage key, PropertyOwningCSSStyleDeclaration& declarations) + : CSSRule(realm) + , m_key(key) + , m_declarations(declarations) +{ + m_declarations->set_parent_rule(*this); +} + void CSSKeyframeRule::visit_edges(Visitor& visitor) { Base::visit_edges(visitor); diff --git a/Userland/Libraries/LibWeb/CSS/CSSKeyframeRule.h b/Userland/Libraries/LibWeb/CSS/CSSKeyframeRule.h index 90017913b20..bac207ead9d 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSKeyframeRule.h +++ b/Userland/Libraries/LibWeb/CSS/CSSKeyframeRule.h @@ -21,7 +21,7 @@ class CSSKeyframeRule final : public CSSRule { JS_DECLARE_ALLOCATOR(CSSKeyframeRule); public: - static JS::NonnullGCPtr create(JS::Realm&, CSS::Percentage key, CSSStyleDeclaration&); + static JS::NonnullGCPtr create(JS::Realm&, CSS::Percentage key, PropertyOwningCSSStyleDeclaration&); virtual ~CSSKeyframeRule() = default; @@ -41,19 +41,14 @@ public: } private: - CSSKeyframeRule(JS::Realm& realm, CSS::Percentage key, CSSStyleDeclaration& declarations) - : CSSRule(realm) - , m_key(key) - , m_declarations(declarations) - { - } + CSSKeyframeRule(JS::Realm&, CSS::Percentage, PropertyOwningCSSStyleDeclaration&); virtual void visit_edges(Visitor&) override; virtual void initialize(JS::Realm&) override; virtual String serialized() const override; CSS::Percentage m_key; - JS::NonnullGCPtr m_declarations; + JS::NonnullGCPtr m_declarations; }; template<> diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp index a05ec01a000..8529d76c5f3 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp @@ -31,6 +31,11 @@ void CSSStyleDeclaration::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(CSSStyleDeclaration); } +JS::GCPtr CSSStyleDeclaration::parent_rule() const +{ + return nullptr; +} + JS::NonnullGCPtr PropertyOwningCSSStyleDeclaration::create(JS::Realm& realm, Vector properties, HashMap custom_properties) { return realm.heap().allocate(realm, realm, move(properties), move(custom_properties)); @@ -46,6 +51,7 @@ PropertyOwningCSSStyleDeclaration::PropertyOwningCSSStyleDeclaration(JS::Realm& void PropertyOwningCSSStyleDeclaration::visit_edges(Cell::Visitor& visitor) { Base::visit_edges(visitor); + visitor.visit(m_parent_rule); for (auto& property : m_properties) { if (property.value->is_image()) property.value->as_image().visit_edges(visitor); @@ -482,4 +488,14 @@ WebIDL::ExceptionOr ElementInlineCSSStyleDeclaration::set_css_text(StringV return {}; } +JS::GCPtr PropertyOwningCSSStyleDeclaration::parent_rule() const +{ + return m_parent_rule; +} + +void PropertyOwningCSSStyleDeclaration::set_parent_rule(JS::NonnullGCPtr rule) +{ + m_parent_rule = rule; +} + } diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h index 0eee4969e86..79a81877889 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h @@ -45,6 +45,8 @@ public: virtual JS::ThrowCompletionOr internal_get(JS::PropertyKey const&, JS::Value receiver, JS::CacheablePropertyMetadata*, PropertyLookupPhase) const override; virtual JS::ThrowCompletionOr internal_set(JS::PropertyKey const&, JS::Value value, JS::Value receiver, JS::CacheablePropertyMetadata*) override; + virtual JS::GCPtr parent_rule() const; + protected: explicit CSSStyleDeclaration(JS::Realm&); }; @@ -77,6 +79,9 @@ public: virtual String serialized() const final override; virtual WebIDL::ExceptionOr set_css_text(StringView) override; + virtual JS::GCPtr parent_rule() const override; + void set_parent_rule(JS::NonnullGCPtr); + protected: PropertyOwningCSSStyleDeclaration(JS::Realm&, Vector, HashMap); @@ -90,6 +95,7 @@ private: virtual void visit_edges(Cell::Visitor&) override; + JS::GCPtr m_parent_rule; Vector m_properties; HashMap m_custom_properties; }; diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.idl b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.idl index 2501475d735..9440fbbfa3c 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.idl +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.idl @@ -13,7 +13,7 @@ interface CSSStyleDeclaration { [CEReactions] undefined setProperty(CSSOMString property, [LegacyNullToEmptyString] CSSOMString value, optional [LegacyNullToEmptyString] CSSOMString priority = ""); [CEReactions] CSSOMString removeProperty(CSSOMString property); - [FIXME] readonly attribute CSSRule? parentRule; + readonly attribute CSSRule? parentRule; [FIXME, CEReactions, LegacyNullToEmptyString] attribute CSSOMString cssFloat; }; diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp index 97ce852febd..87b0ca12eb7 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp @@ -25,6 +25,7 @@ CSSStyleRule::CSSStyleRule(JS::Realm& realm, Vector>&& s , m_selectors(move(selectors)) , m_declaration(declaration) { + m_declaration->set_parent_rule(*this); } void CSSStyleRule::initialize(JS::Realm& realm)