Browse Source

LibWeb: Invalidate element style after setting Element.style.foo

This makes us recompute style for the element so the change actually
takes effect. :^)
Andreas Kling 4 years ago
parent
commit
cad4cc9a2a

+ 8 - 0
Userland/Libraries/LibWeb/Bindings/CSSStyleDeclarationWrapperCustom.cpp

@@ -24,8 +24,10 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <AK/ScopeGuard.h>
 #include <LibWeb/Bindings/CSSStyleDeclarationWrapper.h>
 #include <LibWeb/CSS/Parser/DeprecatedCSSParser.h>
+#include <LibWeb/DOM/Element.h>
 
 namespace Web::Bindings {
 
@@ -58,6 +60,12 @@ bool CSSStyleDeclarationWrapper::put(const JS::PropertyName& name, JS::Value val
     if (!new_value)
         return false;
 
+    ScopeGuard style_invalidation_guard = [&] {
+        auto& declaration = downcast<CSS::ElementInlineCSSStyleDeclaration>(impl());
+        if (auto* element = declaration.element())
+            element->invalidate_style();
+    };
+
     // FIXME: I don't think '!important' is being handled correctly here..
 
     for (auto& property : impl().m_properties) {

+ 12 - 1
Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,6 +25,7 @@
  */
 
 #include <LibWeb/CSS/CSSStyleDeclaration.h>
+#include <LibWeb/DOM/Element.h>
 
 namespace Web::CSS {
 
@@ -44,4 +45,14 @@ String CSSStyleDeclaration::item(size_t index) const
     return CSS::string_from_property_id(m_properties[index].property_id);
 }
 
+ElementInlineCSSStyleDeclaration::ElementInlineCSSStyleDeclaration(DOM::Element& element)
+    : CSSStyleDeclaration({})
+    , m_element(element.make_weak_ptr<DOM::Element>())
+{
+}
+
+ElementInlineCSSStyleDeclaration::~ElementInlineCSSStyleDeclaration()
+{
+}
+
 }

+ 18 - 3
Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h

@@ -50,21 +50,36 @@ public:
         return adopt(*new CSSStyleDeclaration(move(properties)));
     }
 
-    ~CSSStyleDeclaration();
+    virtual ~CSSStyleDeclaration();
 
     const Vector<StyleProperty>& properties() const { return m_properties; }
 
     size_t length() const { return m_properties.size(); }
     String item(size_t index) const;
 
+protected:
+    explicit CSSStyleDeclaration(Vector<StyleProperty>&&);
+
 private:
     friend class Bindings::CSSStyleDeclarationWrapper;
 
-    explicit CSSStyleDeclaration(Vector<StyleProperty>&&);
-
     Vector<StyleProperty> m_properties;
 };
 
+class ElementInlineCSSStyleDeclaration final : public CSSStyleDeclaration {
+public:
+    static NonnullRefPtr<ElementInlineCSSStyleDeclaration> create(DOM::Element& element) { return adopt(*new ElementInlineCSSStyleDeclaration(element)); }
+    virtual ~ElementInlineCSSStyleDeclaration() override;
+
+    DOM::Element* element() { return m_element.ptr(); }
+    const DOM::Element* element() const { return m_element.ptr(); }
+
+private:
+    explicit ElementInlineCSSStyleDeclaration(DOM::Element&);
+
+    WeakPtr<DOM::Element> m_element;
+};
+
 }
 
 namespace Web::Bindings {

+ 1 - 1
Userland/Libraries/LibWeb/DOM/Element.cpp

@@ -383,7 +383,7 @@ void Element::set_shadow_root(RefPtr<ShadowRoot> shadow_root)
 NonnullRefPtr<CSS::CSSStyleDeclaration> Element::style_for_bindings()
 {
     if (!m_inline_style)
-        m_inline_style = CSS::CSSStyleDeclaration::create({});
+        m_inline_style = CSS::ElementInlineCSSStyleDeclaration::create(*this);
     return *m_inline_style;
 }
 

+ 1 - 0
Userland/Libraries/LibWeb/Forward.h

@@ -33,6 +33,7 @@ class CSSImportRule;
 class CSSStyleDeclaration;
 class CSSStyleRule;
 class CSSStyleSheet;
+class ElementInlineCSSStyleDeclaration;
 class Length;
 class Selector;
 class StyleProperties;