mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-05 01:10:24 +00:00
LibWeb: Favour !important property values over animated values
This commit is contained in:
Notes:
github-actions[bot]
2025-10-27 09:52:58 +00:00
Author: https://github.com/Calme1709 Commit: https://github.com/LadybirdBrowser/ladybird/commit/76dadd45d6e Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6590 Reviewed-by: https://github.com/AtkinsSJ ✅
@@ -169,7 +169,8 @@ StyleValue const& ComputedProperties::property(PropertyID property_id, WithAnima
|
||||
{
|
||||
VERIFY(property_id >= first_longhand_property_id && property_id <= last_longhand_property_id);
|
||||
|
||||
if (return_animated_value == WithAnimationsApplied::Yes) {
|
||||
// Important properties override animated properties
|
||||
if (!is_property_important(property_id) && return_animated_value == WithAnimationsApplied::Yes) {
|
||||
if (auto animated_value = m_animated_property_values.get(property_id); animated_value.has_value())
|
||||
return *animated_value.value();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
Harness status: OK
|
||||
|
||||
Found 7 tests
|
||||
|
||||
5 Pass
|
||||
2 Fail
|
||||
Pass Interpolated value is observable
|
||||
Pass Important rules override animations
|
||||
Pass Non-overriden interpolations are observable
|
||||
Pass Important rules override animations (::before)
|
||||
Pass Important rules do not override animations on :visited as seen from JS
|
||||
Fail Standard property animations appearing via setKeyframes do not override important declarations
|
||||
Fail Custom property animations appearing via setKeyframes do not override important declarations
|
||||
@@ -0,0 +1,144 @@
|
||||
<!DOCTYPE html>
|
||||
<title>Test !important declarations vs. animation effects</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-cascade/#cascade-origin">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
CSS.registerProperty({
|
||||
name: "--length-1",
|
||||
syntax: "<length>",
|
||||
initialValue: "0px",
|
||||
inherits: false
|
||||
});
|
||||
CSS.registerProperty({
|
||||
name: "--length-2",
|
||||
syntax: "<length>",
|
||||
initialValue: "0px",
|
||||
inherits: false
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
@keyframes bgcolor_animation {
|
||||
from { background-color: rgb(10, 10, 10); }
|
||||
to { background-color: rgb(20, 20, 20); }
|
||||
}
|
||||
@keyframes color_and_bg_animation {
|
||||
from { background-color: rgb(10, 10, 10); color: rgb(10, 10, 10); }
|
||||
to { background-color: rgb(20, 20, 20); color: rgb(20, 20, 20); }
|
||||
}
|
||||
a, div, ::before{
|
||||
animation-duration: 1000s;
|
||||
animation-delay: -500s;
|
||||
animation-timing-function: steps(2, end);
|
||||
}
|
||||
#target1 {
|
||||
animation-name: bgcolor_animation;
|
||||
}
|
||||
#target2 {
|
||||
background-color: rgb(0, 128, 0) !important;
|
||||
animation-name: bgcolor_animation;
|
||||
}
|
||||
#target3 {
|
||||
color: rgb(0, 128, 0) !important;
|
||||
animation-name: color_and_bg_animation;
|
||||
}
|
||||
#target4::before {
|
||||
color: rgb(0, 128, 0) !important;
|
||||
animation-name: color_and_bg_animation;
|
||||
content: " ";
|
||||
}
|
||||
#target5 {
|
||||
animation-name: color_and_bg_animation;
|
||||
}
|
||||
#target5:visited {
|
||||
color: rgb(0, 128, 0) !important;
|
||||
}
|
||||
#target6 {
|
||||
background-color: white;
|
||||
color: white !important;
|
||||
}
|
||||
#target7 {
|
||||
--length-1: 10px;
|
||||
--length-2: 10px !important;
|
||||
}
|
||||
</style>
|
||||
<div id="target1"></div>
|
||||
<div id="target2"></div>
|
||||
<div id="target3"></div>
|
||||
<div id="target4"></div>
|
||||
<a href="" id="target5"></a>
|
||||
<span id="target6"></span>
|
||||
<span id="target7"></span>
|
||||
<script>
|
||||
test(() => {
|
||||
assert_equals(getComputedStyle(target1).backgroundColor, 'rgb(15, 15, 15)');
|
||||
}, 'Interpolated value is observable');
|
||||
|
||||
test(() => {
|
||||
assert_equals(getComputedStyle(target2).backgroundColor, 'rgb(0, 128, 0)');
|
||||
}, 'Important rules override animations');
|
||||
|
||||
test(() => {
|
||||
assert_equals(getComputedStyle(target3).color, 'rgb(0, 128, 0)');
|
||||
assert_equals(getComputedStyle(target3).backgroundColor, 'rgb(15, 15, 15)');
|
||||
}, 'Non-overriden interpolations are observable');
|
||||
|
||||
test(() => {
|
||||
assert_equals(getComputedStyle(target4, '::before').color, 'rgb(0, 128, 0)');
|
||||
assert_equals(getComputedStyle(target4, '::before').backgroundColor, 'rgb(15, 15, 15)');
|
||||
}, 'Important rules override animations (::before)');
|
||||
|
||||
test(() => {
|
||||
assert_equals(getComputedStyle(target5).color, 'rgb(15, 15, 15)');
|
||||
assert_equals(getComputedStyle(target5).backgroundColor, 'rgb(15, 15, 15)');
|
||||
}, 'Important rules do not override animations on :visited as seen from JS');
|
||||
|
||||
test(() => {
|
||||
getComputedStyle(target6).backgroundColor;
|
||||
|
||||
let animation = target6.animate([
|
||||
{ backgroundColor: 'rgb(10, 10, 10)' },
|
||||
{ backgroundColor: 'rgb(20, 20, 20)' },
|
||||
], {
|
||||
duration: 1000000,
|
||||
delay: -500000,
|
||||
easing: 'steps(2, end)'
|
||||
});
|
||||
|
||||
assert_equals(getComputedStyle(target6).backgroundColor, 'rgb(15, 15, 15)');
|
||||
assert_equals(getComputedStyle(target6).color, 'rgb(255, 255, 255)');
|
||||
|
||||
animation.effect.setKeyframes([
|
||||
{ color: 'rgb(10, 10, 10)' },
|
||||
{ color: 'rgb(20, 20, 20)' },
|
||||
]);
|
||||
|
||||
assert_equals(getComputedStyle(target6).backgroundColor, 'rgb(255, 255, 255)');
|
||||
assert_equals(getComputedStyle(target6).color, 'rgb(255, 255, 255)');
|
||||
}, 'Standard property animations appearing via setKeyframes do not override important declarations');
|
||||
|
||||
test(() => {
|
||||
getComputedStyle(target7).getPropertyValue('--length-1');
|
||||
|
||||
let animation = target7.animate([
|
||||
{ '--length-1': '100px' },
|
||||
{ '--length-1': '200px' },
|
||||
], {
|
||||
duration: 1000000,
|
||||
delay: -500000,
|
||||
easing: 'steps(2, end)'
|
||||
});
|
||||
|
||||
assert_equals(getComputedStyle(target7).getPropertyValue('--length-1'), '150px');
|
||||
assert_equals(getComputedStyle(target7).getPropertyValue('--length-2'), '10px');
|
||||
|
||||
animation.effect.setKeyframes([
|
||||
{ '--length-2': '100px' },
|
||||
{ '--length-2': '200px' },
|
||||
]);
|
||||
|
||||
assert_equals(getComputedStyle(target7).getPropertyValue('--length-1'), '10px');
|
||||
assert_equals(getComputedStyle(target7).getPropertyValue('--length-2'), '10px');
|
||||
}, 'Custom property animations appearing via setKeyframes do not override important declarations');
|
||||
|
||||
</script>
|
||||
Reference in New Issue
Block a user