mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibWeb: Support tree counting functions within calc()
This commit is contained in:
parent
55bcdcf824
commit
e9036c7c75
Notes:
github-actions[bot]
2025-10-20 15:13:31 +00:00
Author: https://github.com/Calme1709
Commit: e9036c7c75
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6426
Reviewed-by: https://github.com/AtkinsSJ ✅
15 changed files with 62 additions and 44 deletions
|
|
@ -4314,6 +4314,10 @@ RefPtr<CalculationNode const> Parser::convert_to_calculation_node(CalcParsing::N
|
||||||
if (component_value->is(Token::Type::Percentage))
|
if (component_value->is(Token::Type::Percentage))
|
||||||
return NumericCalculationNode::create(Percentage { component_value->token().percentage() }, context);
|
return NumericCalculationNode::create(Percentage { component_value->token().percentage() }, context);
|
||||||
|
|
||||||
|
auto tree_counting_function_tokens = TokenStream<ComponentValue>::of_single_token(component_value);
|
||||||
|
if (auto tree_counting_function = parse_tree_counting_function(tree_counting_function_tokens, TreeCountingFunctionStyleValue::ComputedType::Number))
|
||||||
|
return NonMathFunctionCalculationNode::create(tree_counting_function.release_nonnull(), NumericType {});
|
||||||
|
|
||||||
// NOTE: If we get here, then we have a ComponentValue that didn't get replaced with something else,
|
// NOTE: If we get here, then we have a ComponentValue that didn't get replaced with something else,
|
||||||
// so the calc() is invalid.
|
// so the calc() is invalid.
|
||||||
ErrorReporter::the().report(InvalidValueError {
|
ErrorReporter::the().report(InvalidValueError {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TreeCountingFunctionStyleValue.h"
|
#include "TreeCountingFunctionStyleValue.h"
|
||||||
|
#include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/IntegerStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/IntegerStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
|
||||||
|
|
||||||
|
|
@ -34,6 +35,14 @@ size_t TreeCountingFunctionStyleValue::resolve(TreeCountingFunctionResolutionCon
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefPtr<CalculationNode const> TreeCountingFunctionStyleValue::resolve_to_calculation_node(CalculationContext const& calculation_context, CalculationResolutionContext const& calculation_resolution_context) const
|
||||||
|
{
|
||||||
|
if (!calculation_resolution_context.tree_counting_function_resolution_context.has_value())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return NumericCalculationNode::create(Number { Number::Type::Number, static_cast<double>(resolve(calculation_resolution_context.tree_counting_function_resolution_context.value())) }, calculation_context);
|
||||||
|
}
|
||||||
|
|
||||||
ValueComparingNonnullRefPtr<StyleValue const> TreeCountingFunctionStyleValue::absolutized(ComputationContext const& computation_context) const
|
ValueComparingNonnullRefPtr<StyleValue const> TreeCountingFunctionStyleValue::absolutized(ComputationContext const& computation_context) const
|
||||||
{
|
{
|
||||||
// FIXME: We should clamp this value in case it falls outside the valid range for the context it is in
|
// FIXME: We should clamp this value in case it falls outside the valid range for the context it is in
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <LibWeb/CSS/StyleValues/StyleValue.h>
|
#include <LibWeb/CSS/StyleValues/AbstractNonMathCalcFunctionStyleValue.h>
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
class TreeCountingFunctionStyleValue final : public StyleValue {
|
class TreeCountingFunctionStyleValue final : public AbstractNonMathCalcFunctionStyleValue {
|
||||||
public:
|
public:
|
||||||
enum class TreeCountingFunction : u8 {
|
enum class TreeCountingFunction : u8 {
|
||||||
SiblingCount,
|
SiblingCount,
|
||||||
|
|
@ -32,13 +32,14 @@ public:
|
||||||
|
|
||||||
size_t resolve(TreeCountingFunctionResolutionContext const&) const;
|
size_t resolve(TreeCountingFunctionResolutionContext const&) const;
|
||||||
|
|
||||||
|
virtual RefPtr<CalculationNode const> resolve_to_calculation_node(CalculationContext const&, CalculationResolutionContext const&) const override;
|
||||||
virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(ComputationContext const&) const override;
|
virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(ComputationContext const&) const override;
|
||||||
|
|
||||||
virtual bool equals(StyleValue const& other) const override;
|
virtual bool equals(StyleValue const& other) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TreeCountingFunctionStyleValue(TreeCountingFunction function, ComputedType computed_type)
|
TreeCountingFunctionStyleValue(TreeCountingFunction function, ComputedType computed_type)
|
||||||
: StyleValue(Type::TreeCountingFunction)
|
: AbstractNonMathCalcFunctionStyleValue(Type::TreeCountingFunction)
|
||||||
, m_function(function)
|
, m_function(function)
|
||||||
, m_computed_type(computed_type)
|
, m_computed_type(computed_type)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ Harness status: OK
|
||||||
|
|
||||||
Found 22 tests
|
Found 22 tests
|
||||||
|
|
||||||
20 Pass
|
21 Pass
|
||||||
2 Fail
|
1 Fail
|
||||||
Pass Property transition-timing-function value 'linear'
|
Pass Property transition-timing-function value 'linear'
|
||||||
Pass Property transition-timing-function value 'ease'
|
Pass Property transition-timing-function value 'ease'
|
||||||
Pass Property transition-timing-function value 'ease-in'
|
Pass Property transition-timing-function value 'ease-in'
|
||||||
|
|
@ -21,7 +21,7 @@ Pass Property transition-timing-function value 'steps(2, jump-start)'
|
||||||
Pass Property transition-timing-function value 'steps(2, jump-end)'
|
Pass Property transition-timing-function value 'steps(2, jump-end)'
|
||||||
Pass Property transition-timing-function value 'steps(2, jump-both)'
|
Pass Property transition-timing-function value 'steps(2, jump-both)'
|
||||||
Pass Property transition-timing-function value 'steps(2, jump-none)'
|
Pass Property transition-timing-function value 'steps(2, jump-none)'
|
||||||
Fail Property transition-timing-function value 'steps(calc(2 * sibling-index()), jump-none)'
|
Pass Property transition-timing-function value 'steps(calc(2 * sibling-index()), jump-none)'
|
||||||
Fail Property transition-timing-function value 'steps(sibling-index(), jump-none)'
|
Fail Property transition-timing-function value 'steps(sibling-index(), jump-none)'
|
||||||
Pass Property transition-timing-function value 'steps(calc(2 * sign(1em - 1000px)), jump-none)'
|
Pass Property transition-timing-function value 'steps(calc(2 * sign(1em - 1000px)), jump-none)'
|
||||||
Pass Property transition-timing-function value 'steps(calc(2 * sign(1em - 1000px)), start)'
|
Pass Property transition-timing-function value 'steps(calc(2 * sign(1em - 1000px)), start)'
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ Harness status: OK
|
||||||
|
|
||||||
Found 45 tests
|
Found 45 tests
|
||||||
|
|
||||||
36 Pass
|
39 Pass
|
||||||
9 Fail
|
6 Fail
|
||||||
Pass acos(1) should be used-value-equivalent to 0deg
|
Pass acos(1) should be used-value-equivalent to 0deg
|
||||||
Pass atan(0) should be used-value-equivalent to 0deg
|
Pass atan(0) should be used-value-equivalent to 0deg
|
||||||
Pass asin(0) should be used-value-equivalent to 0deg
|
Pass asin(0) should be used-value-equivalent to 0deg
|
||||||
|
|
@ -24,9 +24,9 @@ Pass calc(atan2(0,1)) should be used-value-equivalent to 0deg
|
||||||
Pass calc(atan2(0,-1) / 4) should be used-value-equivalent to 45deg
|
Pass calc(atan2(0,-1) / 4) should be used-value-equivalent to 45deg
|
||||||
Pass calc(atan2(1,-1)) should be used-value-equivalent to 135deg
|
Pass calc(atan2(1,-1)) should be used-value-equivalent to 135deg
|
||||||
Pass calc(atan2(-1,1)) should be used-value-equivalent to -45deg
|
Pass calc(atan2(-1,1)) should be used-value-equivalent to -45deg
|
||||||
Fail calc(asin(sin(180deg * sibling-index()))) should be used-value-equivalent to 0deg
|
Pass calc(asin(sin(180deg * sibling-index()))) should be used-value-equivalent to 0deg
|
||||||
Fail calc(acos(cos(180deg * sibling-index()))) should be used-value-equivalent to 180deg
|
Pass calc(acos(cos(180deg * sibling-index()))) should be used-value-equivalent to 180deg
|
||||||
Fail calc(atan(tan(180deg * sibling-index()))) should be used-value-equivalent to 0deg
|
Pass calc(atan(tan(180deg * sibling-index()))) should be used-value-equivalent to 0deg
|
||||||
Pass calc(cos(sin(acos(cos(pi))))) should be used-value-equivalent to 1
|
Pass calc(cos(sin(acos(cos(pi))))) should be used-value-equivalent to 1
|
||||||
Pass atan2(1px, -1px) should be used-value-equivalent to 135deg
|
Pass atan2(1px, -1px) should be used-value-equivalent to 135deg
|
||||||
Pass atan2(1cm, -1cm) should be used-value-equivalent to 135deg
|
Pass atan2(1cm, -1cm) should be used-value-equivalent to 135deg
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@ Harness status: OK
|
||||||
|
|
||||||
Found 47 tests
|
Found 47 tests
|
||||||
|
|
||||||
44 Pass
|
47 Pass
|
||||||
3 Fail
|
|
||||||
Pass pow(1,1) should be used-value-equivalent to 1
|
Pass pow(1,1) should be used-value-equivalent to 1
|
||||||
Pass sqrt(1) should be used-value-equivalent to 1
|
Pass sqrt(1) should be used-value-equivalent to 1
|
||||||
Pass hypot(1) should be used-value-equivalent to 1
|
Pass hypot(1) should be used-value-equivalent to 1
|
||||||
|
|
@ -27,9 +26,9 @@ Pass hypot(0% + 3px, 0% + 4px) should be used-value-equivalent to 5px
|
||||||
Pass hypot(0% + 772.333px) should be used-value-equivalent to calc(0% + 772.333px)
|
Pass hypot(0% + 772.333px) should be used-value-equivalent to calc(0% + 772.333px)
|
||||||
Pass hypot(0% + 772.35px) should be used-value-equivalent to calc(0% + 772.35px)
|
Pass hypot(0% + 772.35px) should be used-value-equivalent to calc(0% + 772.35px)
|
||||||
Pass hypot(0% + 600px, 0% + 800px) should be used-value-equivalent to 1000px
|
Pass hypot(0% + 600px, 0% + 800px) should be used-value-equivalent to 1000px
|
||||||
Fail sqrt(sibling-index()) should be used-value-equivalent to 2
|
Pass sqrt(sibling-index()) should be used-value-equivalent to 2
|
||||||
Fail calc(1px * sqrt(sibling-index())) should be used-value-equivalent to 2px
|
Pass calc(1px * sqrt(sibling-index())) should be used-value-equivalent to 2px
|
||||||
Fail sqrt(pow(sibling-index(), 2)) should be used-value-equivalent to 4
|
Pass sqrt(pow(sibling-index(), 2)) should be used-value-equivalent to 4
|
||||||
Pass hypot(1px) should be used-value-equivalent to 1px
|
Pass hypot(1px) should be used-value-equivalent to 1px
|
||||||
Pass hypot(1cm) should be used-value-equivalent to 1cm
|
Pass hypot(1cm) should be used-value-equivalent to 1cm
|
||||||
Pass hypot(1mm) should be used-value-equivalent to 1mm
|
Pass hypot(1mm) should be used-value-equivalent to 1mm
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,14 @@ Harness status: OK
|
||||||
|
|
||||||
Found 10 tests
|
Found 10 tests
|
||||||
|
|
||||||
6 Pass
|
10 Pass
|
||||||
4 Fail
|
Pass e.style['left'] = "calc(1px * sibling-index())" should set the property value
|
||||||
Fail e.style['left'] = "calc(1px * sibling-index())" should set the property value
|
Pass e.style['left'] = "calc(1px * sibling-index( ))" should set the property value
|
||||||
Fail e.style['left'] = "calc(1px * sibling-index( ))" should set the property value
|
|
||||||
Pass e.style['z-index'] = "sibling-index()" should set the property value
|
Pass e.style['z-index'] = "sibling-index()" should set the property value
|
||||||
Pass e.style['left'] = "calc(1px * sibling-index(100px))" should not set the property value
|
Pass e.style['left'] = "calc(1px * sibling-index(100px))" should not set the property value
|
||||||
Pass e.style['left'] = "calc(1px * sibling-index(1))" should not set the property value
|
Pass e.style['left'] = "calc(1px * sibling-index(1))" should not set the property value
|
||||||
Fail e.style['left'] = "calc(1px * sibling-count())" should set the property value
|
Pass e.style['left'] = "calc(1px * sibling-count())" should set the property value
|
||||||
Fail e.style['left'] = "calc(1px * sibling-count( ))" should set the property value
|
Pass e.style['left'] = "calc(1px * sibling-count( ))" should set the property value
|
||||||
Pass e.style['z-index'] = "sibling-count()" should set the property value
|
Pass e.style['z-index'] = "sibling-count()" should set the property value
|
||||||
Pass e.style['left'] = "calc(1px * sibling-count(100px))" should not set the property value
|
Pass e.style['left'] = "calc(1px * sibling-count(100px))" should not set the property value
|
||||||
Pass e.style['left'] = "calc(1px * sibling-count(1))" should not set the property value
|
Pass e.style['left'] = "calc(1px * sibling-count(1))" should not set the property value
|
||||||
|
|
@ -2,11 +2,10 @@ Harness status: OK
|
||||||
|
|
||||||
Found 6 tests
|
Found 6 tests
|
||||||
|
|
||||||
1 Pass
|
6 Pass
|
||||||
5 Fail
|
Pass basic sibling-index() test
|
||||||
Fail basic sibling-index() test
|
Pass basic sibling-count() test
|
||||||
Fail basic sibling-count() test
|
Pass sibling-index() in calc() with percentage
|
||||||
Fail sibling-index() in calc() with percentage
|
Pass sibling-count() on pseudo-element
|
||||||
Fail sibling-count() on pseudo-element
|
Pass sibling-index() on root
|
||||||
Fail sibling-index() on root
|
|
||||||
Pass sibling-count() on root
|
Pass sibling-count() on root
|
||||||
|
|
@ -2,8 +2,9 @@ Harness status: OK
|
||||||
|
|
||||||
Found 4 tests
|
Found 4 tests
|
||||||
|
|
||||||
4 Fail
|
2 Pass
|
||||||
Fail Initially 6th sibling
|
2 Fail
|
||||||
|
Pass Initially 6th sibling
|
||||||
Fail 5th sibling after removal
|
Fail 5th sibling after removal
|
||||||
Fail Initially 6 siblings
|
Pass Initially 6 siblings
|
||||||
Fail 5 siblings after removal
|
Fail 5 siblings after removal
|
||||||
|
|
@ -2,6 +2,7 @@ Harness status: OK
|
||||||
|
|
||||||
Found 2 tests
|
Found 2 tests
|
||||||
|
|
||||||
2 Fail
|
1 Pass
|
||||||
Fail Initially, the sibling-index() is 3 for #target
|
1 Fail
|
||||||
|
Pass Initially, the sibling-index() is 3 for #target
|
||||||
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
||||||
|
|
@ -2,6 +2,7 @@ Harness status: OK
|
||||||
|
|
||||||
Found 2 tests
|
Found 2 tests
|
||||||
|
|
||||||
2 Fail
|
1 Pass
|
||||||
Fail Initially, the sibling-index() is 3 for #target
|
1 Fail
|
||||||
|
Pass Initially, the sibling-index() is 3 for #target
|
||||||
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
||||||
|
|
@ -2,6 +2,7 @@ Harness status: OK
|
||||||
|
|
||||||
Found 2 tests
|
Found 2 tests
|
||||||
|
|
||||||
2 Fail
|
1 Pass
|
||||||
Fail Initially, the sibling-index() is 2 for #target
|
1 Fail
|
||||||
|
Pass Initially, the sibling-index() is 2 for #target
|
||||||
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
||||||
|
|
@ -2,6 +2,7 @@ Harness status: OK
|
||||||
|
|
||||||
Found 2 tests
|
Found 2 tests
|
||||||
|
|
||||||
2 Fail
|
1 Pass
|
||||||
Fail Initially, the sibling-index() is 3 for #target
|
1 Fail
|
||||||
|
Pass Initially, the sibling-index() is 3 for #target
|
||||||
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
||||||
|
|
@ -2,6 +2,7 @@ Harness status: OK
|
||||||
|
|
||||||
Found 2 tests
|
Found 2 tests
|
||||||
|
|
||||||
2 Fail
|
1 Pass
|
||||||
Fail Initially, the sibling-index() is 3 for #target
|
1 Fail
|
||||||
|
Pass Initially, the sibling-index() is 3 for #target
|
||||||
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
||||||
|
|
@ -2,6 +2,7 @@ Harness status: OK
|
||||||
|
|
||||||
Found 2 tests
|
Found 2 tests
|
||||||
|
|
||||||
2 Fail
|
1 Pass
|
||||||
Fail Initially, the sibling-index() is 3 for #target
|
1 Fail
|
||||||
|
Pass Initially, the sibling-index() is 3 for #target
|
||||||
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
Fail Removing a preceding sibling of #target reduces the sibling-index()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue