diff --git a/Base/res/html/misc/attr-invalidate-style.html b/Base/res/html/misc/attr-invalidate-style.html
new file mode 100644
index 0000000000..eed7e51c0f
--- /dev/null
+++ b/Base/res/html/misc/attr-invalidate-style.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ GREEN
+
+ BLUE
+
+
+
diff --git a/Base/res/html/misc/welcome.html b/Base/res/html/misc/welcome.html
index b23ef984fa..cb581f2e86 100644
--- a/Base/res/html/misc/welcome.html
+++ b/Base/res/html/misc/welcome.html
@@ -76,6 +76,7 @@
CSS
CSSOM
+ - Style invalidation on attribute changes
- Computed style
- CSS.supports() and @supports
- Attributes
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt
index f8d7d10cf3..7451212877 100644
--- a/Userland/Libraries/LibWeb/CMakeLists.txt
+++ b/Userland/Libraries/LibWeb/CMakeLists.txt
@@ -46,7 +46,6 @@ set(SOURCES
CSS/Selector.cpp
CSS/SelectorEngine.cpp
CSS/StyleComputer.cpp
- CSS/StyleInvalidator.cpp
CSS/StyleProperties.cpp
CSS/StyleSheet.cpp
CSS/StyleSheetList.cpp
diff --git a/Userland/Libraries/LibWeb/CSS/StyleInvalidator.cpp b/Userland/Libraries/LibWeb/CSS/StyleInvalidator.cpp
deleted file mode 100644
index 0d0bd93137..0000000000
--- a/Userland/Libraries/LibWeb/CSS/StyleInvalidator.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2020, Linus Groh
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include
-#include
-#include
-#include
-
-namespace Web::CSS {
-
-StyleInvalidator::StyleInvalidator(DOM::Document& document)
- : m_document(document)
-{
- if (!m_document.should_invalidate_styles_on_attribute_changes())
- return;
- auto& style_computer = m_document.style_computer();
- m_document.for_each_in_inclusive_subtree_of_type([&](auto& element) {
- m_elements_and_matching_rules_before.set(&element, style_computer.collect_matching_rules(element));
- return IterationDecision::Continue;
- });
-}
-
-StyleInvalidator::~StyleInvalidator()
-{
- if (!m_document.should_invalidate_styles_on_attribute_changes())
- return;
- auto& style_computer = m_document.style_computer();
- m_document.for_each_in_inclusive_subtree_of_type([&](auto& element) {
- auto matching_rules_before_iter = m_elements_and_matching_rules_before.find(&element);
- if (matching_rules_before_iter == m_elements_and_matching_rules_before.end()) {
- element.set_needs_style_update(true);
- return IterationDecision::Continue;
- }
- auto& matching_rules_before = matching_rules_before_iter->value;
- auto matching_rules_after = style_computer.collect_matching_rules(element);
- if (matching_rules_before.size() != matching_rules_after.size()) {
- element.set_needs_style_update(true);
- return IterationDecision::Continue;
- }
- style_computer.sort_matching_rules(matching_rules_before);
- style_computer.sort_matching_rules(matching_rules_after);
- for (size_t i = 0; i < matching_rules_before.size(); ++i) {
- if (matching_rules_before[i].rule != matching_rules_after[i].rule) {
- element.set_needs_style_update(true);
- break;
- }
- }
- return IterationDecision::Continue;
- });
-}
-
-}
diff --git a/Userland/Libraries/LibWeb/CSS/StyleInvalidator.h b/Userland/Libraries/LibWeb/CSS/StyleInvalidator.h
deleted file mode 100644
index c213d39813..0000000000
--- a/Userland/Libraries/LibWeb/CSS/StyleInvalidator.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2020, Linus Groh
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include
-#include
-#include
-#include
-
-namespace Web::CSS {
-
-class StyleInvalidator {
-public:
- explicit StyleInvalidator(DOM::Document&);
- ~StyleInvalidator();
-
-private:
- DOM::Document& m_document;
- HashMap> m_elements_and_matching_rules_before;
-};
-
-}
diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp
index 85cb637806..0df7eb3fd0 100644
--- a/Userland/Libraries/LibWeb/DOM/Element.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Element.cpp
@@ -10,7 +10,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -70,8 +69,6 @@ ExceptionOr Element::set_attribute(const FlyString& name, const String& va
if (name.is_empty())
return InvalidCharacterError::create("Attribute name must not be empty");
- CSS::StyleInvalidator style_invalidator(document());
-
// 2. If this is in the HTML namespace and its node document is an HTML document, then set qualifiedName to qualifiedName in ASCII lowercase.
// FIXME: Handle the second condition, assume it is an HTML document for now.
bool insert_as_lowercase = namespace_uri() == Namespace::HTML;
@@ -93,14 +90,20 @@ ExceptionOr Element::set_attribute(const FlyString& name, const String& va
}
parse_attribute(attribute->local_name(), value);
+
+ // FIXME: Invalidate less.
+ document().invalidate_style();
+
return {};
}
// https://dom.spec.whatwg.org/#dom-element-removeattribute
void Element::remove_attribute(const FlyString& name)
{
- CSS::StyleInvalidator style_invalidator(document());
m_attributes->remove_attribute(name);
+
+ // FIXME: Invalidate less.
+ document().invalidate_style();
}
// https://dom.spec.whatwg.org/#dom-element-hasattribute