Quellcode durchsuchen

LibWeb: Implement CSSStyleDeclaration.parentRule

This readonly attribute returns the containing CSS rule, or null (in the
case of element inline style).
Andreas Kling vor 1 Jahr
Ursprung
Commit
a12d28fd30

+ 4 - 0
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

+ 15 - 0
Tests/LibWeb/Text/input/css/style-declaration-parent-rule.html

@@ -0,0 +1,15 @@
+<style>
+span {
+    color: purple;
+}
+</style>
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        const spanRule = document.styleSheets[0].cssRules[0];
+        println("spanRule: " + spanRule + " ~ " + spanRule.cssText);
+        println("spanRule.style: " + spanRule.style + " ~ " + spanRule.cssText);
+        println("spanRule.style.parentRule: " + spanRule.style.parentRule + " ~ " + spanRule.cssText);
+        println("spanRule.style.parentRule === spanRule: " + (spanRule.style.parentRule === spanRule));
+    });
+</script>

+ 9 - 1
Userland/Libraries/LibWeb/CSS/CSSKeyframeRule.cpp

@@ -13,11 +13,19 @@ namespace Web::CSS {
 
 JS_DEFINE_ALLOCATOR(CSSKeyframeRule);
 
-JS::NonnullGCPtr<CSSKeyframeRule> CSSKeyframeRule::create(JS::Realm& realm, CSS::Percentage key, Web::CSS::CSSStyleDeclaration& declarations)
+JS::NonnullGCPtr<CSSKeyframeRule> CSSKeyframeRule::create(JS::Realm& realm, CSS::Percentage key, Web::CSS::PropertyOwningCSSStyleDeclaration& declarations)
 {
     return realm.heap().allocate<CSSKeyframeRule>(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);

+ 3 - 8
Userland/Libraries/LibWeb/CSS/CSSKeyframeRule.h

@@ -21,7 +21,7 @@ class CSSKeyframeRule final : public CSSRule {
     JS_DECLARE_ALLOCATOR(CSSKeyframeRule);
 
 public:
-    static JS::NonnullGCPtr<CSSKeyframeRule> create(JS::Realm&, CSS::Percentage key, CSSStyleDeclaration&);
+    static JS::NonnullGCPtr<CSSKeyframeRule> 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<CSSStyleDeclaration> m_declarations;
+    JS::NonnullGCPtr<PropertyOwningCSSStyleDeclaration> m_declarations;
 };
 
 template<>

+ 16 - 0
Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp

@@ -31,6 +31,11 @@ void CSSStyleDeclaration::initialize(JS::Realm& realm)
     WEB_SET_PROTOTYPE_FOR_INTERFACE(CSSStyleDeclaration);
 }
 
+JS::GCPtr<CSSRule> CSSStyleDeclaration::parent_rule() const
+{
+    return nullptr;
+}
+
 JS::NonnullGCPtr<PropertyOwningCSSStyleDeclaration> PropertyOwningCSSStyleDeclaration::create(JS::Realm& realm, Vector<StyleProperty> properties, HashMap<FlyString, StyleProperty> custom_properties)
 {
     return realm.heap().allocate<PropertyOwningCSSStyleDeclaration>(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<void> ElementInlineCSSStyleDeclaration::set_css_text(StringV
     return {};
 }
 
+JS::GCPtr<CSSRule> PropertyOwningCSSStyleDeclaration::parent_rule() const
+{
+    return m_parent_rule;
+}
+
+void PropertyOwningCSSStyleDeclaration::set_parent_rule(JS::NonnullGCPtr<CSSRule> rule)
+{
+    m_parent_rule = rule;
+}
+
 }

+ 6 - 0
Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h

@@ -45,6 +45,8 @@ public:
     virtual JS::ThrowCompletionOr<JS::Value> internal_get(JS::PropertyKey const&, JS::Value receiver, JS::CacheablePropertyMetadata*, PropertyLookupPhase) const override;
     virtual JS::ThrowCompletionOr<bool> internal_set(JS::PropertyKey const&, JS::Value value, JS::Value receiver, JS::CacheablePropertyMetadata*) override;
 
+    virtual JS::GCPtr<CSSRule> parent_rule() const;
+
 protected:
     explicit CSSStyleDeclaration(JS::Realm&);
 };
@@ -77,6 +79,9 @@ public:
     virtual String serialized() const final override;
     virtual WebIDL::ExceptionOr<void> set_css_text(StringView) override;
 
+    virtual JS::GCPtr<CSSRule> parent_rule() const override;
+    void set_parent_rule(JS::NonnullGCPtr<CSSRule>);
+
 protected:
     PropertyOwningCSSStyleDeclaration(JS::Realm&, Vector<StyleProperty>, HashMap<FlyString, StyleProperty>);
 
@@ -90,6 +95,7 @@ private:
 
     virtual void visit_edges(Cell::Visitor&) override;
 
+    JS::GCPtr<CSSRule> m_parent_rule;
     Vector<StyleProperty> m_properties;
     HashMap<FlyString, StyleProperty> m_custom_properties;
 };

+ 1 - 1
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;
 
 };

+ 1 - 0
Userland/Libraries/LibWeb/CSS/CSSStyleRule.cpp

@@ -25,6 +25,7 @@ CSSStyleRule::CSSStyleRule(JS::Realm& realm, Vector<NonnullRefPtr<Selector>>&& s
     , m_selectors(move(selectors))
     , m_declaration(declaration)
 {
+    m_declaration->set_parent_rule(*this);
 }
 
 void CSSStyleRule::initialize(JS::Realm& realm)