diff --git a/Tests/LibWeb/Text/expected/css/revert-ignores-layers.txt b/Tests/LibWeb/Text/expected/css/revert-ignores-layers.txt
new file mode 100644
index 00000000000..26a017828be
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/css/revert-ignores-layers.txt
@@ -0,0 +1 @@
+ PASS, revert skipped the layers
diff --git a/Tests/LibWeb/Text/input/css/revert-ignores-layers.html b/Tests/LibWeb/Text/input/css/revert-ignores-layers.html
new file mode 100644
index 00000000000..35ad4720355
--- /dev/null
+++ b/Tests/LibWeb/Text/input/css/revert-ignores-layers.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+
diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
index d359e3f268f..e13658c75c1 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
@@ -896,18 +896,25 @@ void StyleComputer::for_each_property_expanding_shorthands(PropertyID property_i
set_longhand_property(property_id, value);
}
-void StyleComputer::set_property_expanding_shorthands(StyleProperties& style, CSS::PropertyID property_id, CSSStyleValue const& value, CSS::CSSStyleDeclaration const* declaration, StyleProperties const& style_for_revert, Important important)
+void StyleComputer::set_property_expanding_shorthands(StyleProperties& style, PropertyID property_id, CSSStyleValue const& value, CSSStyleDeclaration const* declaration, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer, Important important)
{
+ auto revert_shorthand = [&](PropertyID shorthand_id, StyleProperties const& style_for_revert) {
+ auto previous_value = style_for_revert.m_data->m_property_values[to_underlying(shorthand_id)];
+ if (!previous_value)
+ previous_value = CSSKeywordValue::create(Keyword::Initial);
+
+ style.set_property(shorthand_id, *previous_value, StyleProperties::Inherited::No, important);
+ if (shorthand_id == CSS::PropertyID::AnimationName)
+ style.set_animation_name_source(style_for_revert.animation_name_source());
+ if (shorthand_id == CSS::PropertyID::TransitionProperty)
+ style.set_transition_property_source(style_for_revert.transition_property_source());
+ };
+
for_each_property_expanding_shorthands(property_id, value, AllowUnresolved::No, [&](PropertyID shorthand_id, CSSStyleValue const& shorthand_value) {
- if (shorthand_value.is_revert() || shorthand_value.is_revert_layer()) {
- auto const& property_in_previous_cascade_origin = style_for_revert.m_data->m_property_values[to_underlying(shorthand_id)];
- if (property_in_previous_cascade_origin) {
- style.set_property(shorthand_id, *property_in_previous_cascade_origin, StyleProperties::Inherited::No, important);
- if (shorthand_id == CSS::PropertyID::AnimationName)
- style.set_animation_name_source(style_for_revert.animation_name_source());
- if (shorthand_id == CSS::PropertyID::TransitionProperty)
- style.set_transition_property_source(style_for_revert.transition_property_source());
- }
+ if (shorthand_value.is_revert()) {
+ revert_shorthand(shorthand_id, style_for_revert);
+ } else if (shorthand_value.is_revert_layer()) {
+ revert_shorthand(shorthand_id, style_for_revert_layer);
} else {
style.set_property(shorthand_id, shorthand_value, StyleProperties::Inherited::No, important);
if (shorthand_id == CSS::PropertyID::AnimationName)
@@ -918,16 +925,21 @@ void StyleComputer::set_property_expanding_shorthands(StyleProperties& style, CS
});
}
-void StyleComputer::set_all_properties(DOM::Element& element, Optional pseudo_element, StyleProperties& style, CSSStyleValue const& value, DOM::Document& document, CSS::CSSStyleDeclaration const* declaration, StyleProperties const& style_for_revert, Important important) const
+void StyleComputer::set_all_properties(DOM::Element& element, Optional pseudo_element, StyleProperties& style, CSSStyleValue const& value, DOM::Document& document, CSS::CSSStyleDeclaration const* declaration, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer, Important important) const
{
for (auto i = to_underlying(CSS::first_longhand_property_id); i <= to_underlying(CSS::last_longhand_property_id); ++i) {
auto property_id = (CSS::PropertyID)i;
- if (value.is_revert() || value.is_revert_layer()) {
+ if (value.is_revert()) {
style.revert_property(property_id, style_for_revert);
continue;
}
+ if (value.is_revert_layer()) {
+ style.revert_property(property_id, style_for_revert_layer);
+ continue;
+ }
+
if (value.is_unset()) {
if (is_inherited_property(property_id)) {
style.set_property(
@@ -949,25 +961,23 @@ void StyleComputer::set_all_properties(DOM::Element& element, Optionalis_unresolved())
property_value = Parser::Parser::resolve_unresolved_style_value(Parser::ParsingContext { document }, element, pseudo_element, property_id, property_value->as_unresolved());
if (!property_value->is_unresolved())
- set_property_expanding_shorthands(style, property_id, property_value, declaration, style_for_revert);
+ set_property_expanding_shorthands(style, property_id, property_value, declaration, style_for_revert, style_for_revert_layer);
style.set_property_important(property_id, important);
- set_property_expanding_shorthands(style, property_id, value, declaration, style_for_revert, important);
+ set_property_expanding_shorthands(style, property_id, value, declaration, style_for_revert, style_for_revert_layer, important);
}
}
-void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& element, Optional pseudo_element, Vector const& matching_rules, CascadeOrigin cascade_origin, Important important) const
+void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& element, Optional pseudo_element, Vector const& matching_rules, CascadeOrigin cascade_origin, Important important, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer) const
{
- auto style_for_revert = style.clone();
-
for (auto const& match : matching_rules) {
for (auto const& property : match.rule->declaration().properties()) {
if (important != property.important)
continue;
if (property.property_id == CSS::PropertyID::All) {
- set_all_properties(element, pseudo_element, style, property.value, m_document, &match.rule->declaration(), style_for_revert, important);
+ set_all_properties(element, pseudo_element, style, property.value, m_document, &match.rule->declaration(), style_for_revert, style_for_revert_layer, important);
continue;
}
@@ -975,7 +985,7 @@ void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& e
if (property.value->is_unresolved())
property_value = Parser::Parser::resolve_unresolved_style_value(Parser::ParsingContext { document() }, element, pseudo_element, property.property_id, property.value->as_unresolved());
if (!property_value->is_unresolved())
- set_property_expanding_shorthands(style, property.property_id, property_value, &match.rule->declaration(), style_for_revert, important);
+ set_property_expanding_shorthands(style, property.property_id, property_value, &match.rule->declaration(), style_for_revert, style_for_revert_layer, important);
}
}
@@ -986,7 +996,7 @@ void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& e
continue;
if (property.property_id == CSS::PropertyID::All) {
- set_all_properties(element, pseudo_element, style, property.value, m_document, inline_style, style_for_revert, important);
+ set_all_properties(element, pseudo_element, style, property.value, m_document, inline_style, style_for_revert, style_for_revert_layer, important);
continue;
}
@@ -994,7 +1004,7 @@ void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& e
if (property.value->is_unresolved())
property_value = Parser::Parser::resolve_unresolved_style_value(Parser::ParsingContext { document() }, element, pseudo_element, property.property_id, property.value->as_unresolved());
if (!property_value->is_unresolved())
- set_property_expanding_shorthands(style, property.property_id, property_value, inline_style, style_for_revert, important);
+ set_property_expanding_shorthands(style, property.property_id, property_value, inline_style, style_for_revert, style_for_revert_layer, important);
}
}
}
@@ -1532,12 +1542,17 @@ void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element
// Then we apply the declarations from the matched rules in cascade order:
// Normal user agent declarations
- cascade_declarations(style, element, pseudo_element, matching_rule_set.user_agent_rules, CascadeOrigin::UserAgent, Important::No);
+ auto previous_origin_style = style.clone();
+ auto previous_layer_style = style.clone();
+ cascade_declarations(style, element, pseudo_element, matching_rule_set.user_agent_rules, CascadeOrigin::UserAgent, Important::No, previous_origin_style, previous_layer_style);
// Normal user declarations
- cascade_declarations(style, element, pseudo_element, matching_rule_set.user_rules, CascadeOrigin::User, Important::No);
+ previous_origin_style = style.clone();
+ previous_layer_style = style.clone();
+ cascade_declarations(style, element, pseudo_element, matching_rule_set.user_rules, CascadeOrigin::User, Important::No, previous_origin_style, previous_layer_style);
// Author presentational hints (NOTE: The spec doesn't say exactly how to prioritize these.)
+ previous_origin_style = style.clone();
if (!pseudo_element.has_value()) {
element.apply_presentational_hints(style);
@@ -1560,7 +1575,8 @@ void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element
// Normal author declarations, ordered by @layer, with un-@layer-ed rules last
for (auto const& layer : matching_rule_set.author_rules) {
- cascade_declarations(style, element, pseudo_element, layer.rules, CascadeOrigin::Author, Important::No);
+ previous_layer_style = style.clone();
+ cascade_declarations(style, element, pseudo_element, layer.rules, CascadeOrigin::Author, Important::No, previous_origin_style, previous_layer_style);
}
// Animation declarations [css-animations-2]
@@ -1626,15 +1642,21 @@ void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element
}
// Important author declarations, with un-@layer-ed rules first, followed by each @layer in reverse order.
+ previous_origin_style = style.clone();
for (auto const& layer : matching_rule_set.author_rules.in_reverse()) {
- cascade_declarations(style, element, pseudo_element, layer.rules, CascadeOrigin::Author, Important::Yes);
+ previous_layer_style = style.clone();
+ cascade_declarations(style, element, pseudo_element, layer.rules, CascadeOrigin::Author, Important::Yes, previous_origin_style, previous_layer_style);
}
// Important user declarations
- cascade_declarations(style, element, pseudo_element, matching_rule_set.user_rules, CascadeOrigin::User, Important::Yes);
+ previous_origin_style = style.clone();
+ previous_layer_style = style.clone();
+ cascade_declarations(style, element, pseudo_element, matching_rule_set.user_rules, CascadeOrigin::User, Important::Yes, previous_origin_style, previous_layer_style);
// Important user agent declarations
- cascade_declarations(style, element, pseudo_element, matching_rule_set.user_agent_rules, CascadeOrigin::UserAgent, Important::Yes);
+ previous_origin_style = style.clone();
+ previous_layer_style = style.clone();
+ cascade_declarations(style, element, pseudo_element, matching_rule_set.user_agent_rules, CascadeOrigin::UserAgent, Important::Yes, previous_origin_style, previous_layer_style);
// Transition declarations [css-transitions-1]
// Note that we have to do these after finishing computing the style,
diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.h b/Userland/Libraries/LibWeb/CSS/StyleComputer.h
index a9bc777cef7..21c369afc9e 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleComputer.h
+++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.h
@@ -114,7 +114,7 @@ public:
No,
};
static void for_each_property_expanding_shorthands(PropertyID, CSSStyleValue const&, AllowUnresolved, Function const& set_longhand_property);
- static void set_property_expanding_shorthands(StyleProperties&, PropertyID, CSSStyleValue const&, CSS::CSSStyleDeclaration const*, StyleProperties const& style_for_revert, Important = Important::No);
+ static void set_property_expanding_shorthands(StyleProperties&, PropertyID, CSSStyleValue const&, CSS::CSSStyleDeclaration const*, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer, Important = Important::No);
static NonnullRefPtr get_inherit_value(JS::Realm& initial_value_context_realm, CSS::PropertyID, DOM::Element const*, Optional = {});
static Optional user_agent_style_sheet_source(StringView name);
@@ -184,7 +184,7 @@ private:
void compute_defaulted_property_value(StyleProperties&, DOM::Element const*, CSS::PropertyID, Optional) const;
- void set_all_properties(DOM::Element&, Optional, StyleProperties&, CSSStyleValue const&, DOM::Document&, CSS::CSSStyleDeclaration const*, StyleProperties const& style_for_revert, Important = Important::No) const;
+ void set_all_properties(DOM::Element&, Optional, StyleProperties&, CSSStyleValue const&, DOM::Document&, CSS::CSSStyleDeclaration const*, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer, Important = Important::No) const;
template
void for_each_stylesheet(CascadeOrigin, Callback) const;
@@ -207,7 +207,7 @@ private:
Vector author_rules;
};
- void cascade_declarations(StyleProperties&, DOM::Element&, Optional, Vector const&, CascadeOrigin, Important) const;
+ void cascade_declarations(StyleProperties&, DOM::Element&, Optional, Vector const&, CascadeOrigin, Important, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer) const;
void build_rule_cache();
void build_rule_cache_if_needed() const;