mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 11:49:44 +00:00
LibWeb/CSS: Implement revert-layer
With the introduction of the cascade layer, the 5th CSS-wide keyword, `revert-layer`, has been added.
This commit is contained in:
parent
71d977b791
commit
bea7eec518
Notes:
github-actions[bot]
2024-09-11 21:31:19 +00:00
Author: https://github.com/An-n-ya 🔰
Commit: bea7eec518
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1371
Reviewed-by: https://github.com/AtkinsSJ ✅
8 changed files with 70 additions and 5 deletions
|
@ -77,6 +77,7 @@ inline bool is_css_wide_keyword(StringView name)
|
|||
return name.equals_ignoring_ascii_case("inherit"sv)
|
||||
|| name.equals_ignoring_ascii_case("initial"sv)
|
||||
|| name.equals_ignoring_ascii_case("revert"sv)
|
||||
|| name.equals_ignoring_ascii_case("revert-layer"sv)
|
||||
|| name.equals_ignoring_ascii_case("unset"sv);
|
||||
}
|
||||
|
||||
|
|
4
Tests/LibWeb/Text/expected/css/revert-layer.txt
Normal file
4
Tests/LibWeb/Text/expected/css/revert-layer.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
PASS: revert to base (first target)
|
||||
PASS: revert to base (second target)
|
||||
PASS: double revert (first target)
|
||||
PASS: double revert (second target)
|
47
Tests/LibWeb/Text/input/css/revert-layer.html
Normal file
47
Tests/LibWeb/Text/input/css/revert-layer.html
Normal file
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<target class="first"></target>
|
||||
<target class="second"></target>
|
||||
<script src="../include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
// In all test cases, the rule specified as "color: green" should win.
|
||||
var testCases = [
|
||||
{
|
||||
title: 'revert to base',
|
||||
style: `
|
||||
@layer base, special;
|
||||
@layer special { target { color: revert-layer; } target.second { color: green; } }
|
||||
@layer base { target { color: green; } target.second { color: red; } }
|
||||
`,
|
||||
},
|
||||
{
|
||||
title: 'double revert',
|
||||
style: `
|
||||
@layer layer1, layer2, layer3;
|
||||
@layer layer3 { target { color: revert-layer; } target.second { color: revert-layer; } }
|
||||
@layer layer2 { target { color: revert-layer; } target.second { color: green; } }
|
||||
@layer layer1 { target { color: green; } target.second { color: revert-layer; } }
|
||||
`,
|
||||
},
|
||||
];
|
||||
|
||||
for (let testCase of testCases) {
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.textContent = testCase['style'];
|
||||
document.head.append(styleElement);
|
||||
|
||||
var targets = document.querySelectorAll('target');
|
||||
for (let target of targets) {
|
||||
let actual = window.getComputedStyle(target).color;
|
||||
if (actual === 'rgb(0, 128, 0)') {
|
||||
println(`PASS: ${testCase['title']} (${target.classList[0]} target)`);
|
||||
} else {
|
||||
println(`FAIL: ${testCase['title']} (${target.classList[0]} target) - Expected 'rgb(0, 128, 0)', got '${actual}'`);
|
||||
}
|
||||
}
|
||||
|
||||
styleElement.remove();
|
||||
}
|
||||
|
||||
});
|
||||
</script>
|
|
@ -326,10 +326,11 @@ public:
|
|||
|
||||
// https://www.w3.org/TR/css-values-4/#common-keywords
|
||||
// https://drafts.csswg.org/css-cascade-4/#valdef-all-revert
|
||||
bool is_css_wide_keyword() const { return is_inherit() || is_initial() || is_revert() || is_unset(); }
|
||||
bool is_css_wide_keyword() const { return is_inherit() || is_initial() || is_revert() || is_unset() || is_revert_layer(); }
|
||||
bool is_inherit() const { return to_keyword() == Keyword::Inherit; }
|
||||
bool is_initial() const { return to_keyword() == Keyword::Initial; }
|
||||
bool is_revert() const { return to_keyword() == Keyword::Revert; }
|
||||
bool is_revert_layer() const { return to_keyword() == Keyword::RevertLayer; }
|
||||
bool is_unset() const { return to_keyword() == Keyword::Unset; }
|
||||
|
||||
bool has_auto() const;
|
||||
|
|
|
@ -293,6 +293,7 @@
|
|||
"repeat-y",
|
||||
"reverse",
|
||||
"revert",
|
||||
"revert-layer",
|
||||
"ridge",
|
||||
"right",
|
||||
"round",
|
||||
|
|
|
@ -1755,7 +1755,10 @@ RefPtr<CSSStyleValue> Parser::parse_builtin_value(TokenStream<ComponentValue>& t
|
|||
transaction.commit();
|
||||
return CSSKeywordValue::create(Keyword::Revert);
|
||||
}
|
||||
// FIXME: Implement `revert-layer` from CSS-CASCADE-5.
|
||||
if (ident.equals_ignoring_ascii_case("revert-layer"sv)) {
|
||||
transaction.commit();
|
||||
return CSSKeywordValue::create(Keyword::RevertLayer);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -886,7 +886,7 @@ void StyleComputer::for_each_property_expanding_shorthands(PropertyID property_i
|
|||
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)
|
||||
{
|
||||
for_each_property_expanding_shorthands(property_id, value, AllowUnresolved::No, [&](PropertyID shorthand_id, CSSStyleValue const& shorthand_value) {
|
||||
if (shorthand_value.is_revert()) {
|
||||
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);
|
||||
|
@ -906,7 +906,7 @@ void StyleComputer::set_all_properties(DOM::Element& element, Optional<CSS::Sele
|
|||
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()) {
|
||||
if (value.is_revert() || value.is_revert_layer()) {
|
||||
style.revert_property(property_id, style_for_revert);
|
||||
continue;
|
||||
}
|
||||
|
@ -997,8 +997,12 @@ static void cascade_custom_properties(DOM::Element& element, Optional<CSS::Selec
|
|||
custom_properties.ensure_capacity(custom_properties.size() + needed_capacity);
|
||||
|
||||
for (auto const& matching_rule : matching_rules) {
|
||||
for (auto const& it : matching_rule.rule->declaration().custom_properties())
|
||||
for (auto const& it : matching_rule.rule->declaration().custom_properties()) {
|
||||
auto style_value = it.value.value;
|
||||
if (style_value->is_revert_layer())
|
||||
continue;
|
||||
custom_properties.set(it.key, it.value);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pseudo_element.has_value()) {
|
||||
|
|
|
@ -33,6 +33,10 @@ public:
|
|||
static ValueComparingNonnullRefPtr<CSSKeywordValue> const revert_instance = adopt_ref(*new (nothrow) CSSKeywordValue(Keyword::Revert));
|
||||
return revert_instance;
|
||||
}
|
||||
case Keyword::RevertLayer: {
|
||||
static ValueComparingNonnullRefPtr<CSSKeywordValue> const revert_layer_instance = adopt_ref(*new (nothrow) CSSKeywordValue(Keyword::RevertLayer));
|
||||
return revert_layer_instance;
|
||||
}
|
||||
case Keyword::Unset: {
|
||||
static ValueComparingNonnullRefPtr<CSSKeywordValue> const unset_instance = adopt_ref(*new (nothrow) CSSKeywordValue(Keyword::Unset));
|
||||
return unset_instance;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue