1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 04:07:34 +00:00

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

This makes us recompute style for the element so the change actually
takes effect. :^)
This commit is contained in:
Andreas Kling 2021-03-16 18:55:53 +01:00
parent 6c8185151e
commit cad4cc9a2a
5 changed files with 40 additions and 5 deletions

View file

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

View file

@ -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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -25,6 +25,7 @@
*/ */
#include <LibWeb/CSS/CSSStyleDeclaration.h> #include <LibWeb/CSS/CSSStyleDeclaration.h>
#include <LibWeb/DOM/Element.h>
namespace Web::CSS { 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); 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()
{
}
} }

View file

@ -50,21 +50,36 @@ public:
return adopt(*new CSSStyleDeclaration(move(properties))); return adopt(*new CSSStyleDeclaration(move(properties)));
} }
~CSSStyleDeclaration(); virtual ~CSSStyleDeclaration();
const Vector<StyleProperty>& properties() const { return m_properties; } const Vector<StyleProperty>& properties() const { return m_properties; }
size_t length() const { return m_properties.size(); } size_t length() const { return m_properties.size(); }
String item(size_t index) const; String item(size_t index) const;
protected:
explicit CSSStyleDeclaration(Vector<StyleProperty>&&);
private: private:
friend class Bindings::CSSStyleDeclarationWrapper; friend class Bindings::CSSStyleDeclarationWrapper;
explicit CSSStyleDeclaration(Vector<StyleProperty>&&);
Vector<StyleProperty> m_properties; 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 { namespace Web::Bindings {

View file

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

View file

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