LibWeb/CSS: Allow converting CSSMathValues to StyleValues

Because we store calculations as a tree of CalculationNodes inside a
CalculatedStyleValue, instead of a tree of StyleValues directly, this
implements a create_calculation_node() method on CSSNumericValue.
CSSMathValue::create_an_internal_representation() then calls
create_calculation_node() on itself, and wraps it in a
CalculatedStyleValue.

Lots of WPT passes again! Some regressions, which are expected: `cursor`
fails a test for the same reason it fails other that set it to some
kind of numeric value: We don't distinguish between "can contain a
number" and "can accept a number by itself". This will affect any
similar properties, but overall this is a big improvement.
This commit is contained in:
Sam Atkins 2025-10-10 17:29:54 +01:00
commit 078bc1a471
Notes: github-actions[bot] 2025-10-13 09:01:05 +00:00
24 changed files with 172 additions and 36 deletions

View file

@ -9,6 +9,7 @@
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/CSSMathNegate.h>
#include <LibWeb/CSS/CSSNumericArray.h>
#include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
#include <LibWeb/WebIDL/DOMException.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
@ -146,4 +147,12 @@ Optional<SumValue> CSSMathClamp::create_a_sum_value() const
};
}
WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> CSSMathClamp::create_calculation_node(CalculationContext const& context) const
{
auto lower = TRY(m_lower->create_calculation_node(context));
auto value = TRY(m_value->create_calculation_node(context));
auto upper = TRY(m_upper->create_calculation_node(context));
return ClampCalculationNode::create(move(lower), move(value), move(upper));
}
}

View file

@ -32,6 +32,8 @@ public:
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
virtual Optional<SumValue> create_a_sum_value() const override;
virtual WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> create_calculation_node(CalculationContext const&) const override;
private:
CSSMathClamp(JS::Realm&, NumericType, GC::Ref<CSSNumericValue> lower, GC::Ref<CSSNumericValue> value, GC::Ref<CSSNumericValue> upper);
GC::Ref<CSSNumericValue> m_lower;

View file

@ -7,6 +7,7 @@
#include "CSSMathInvert.h"
#include <LibWeb/Bindings/CSSMathInvertPrototype.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
namespace Web::CSS {
@ -131,4 +132,9 @@ Optional<SumValue> CSSMathInvert::create_a_sum_value() const
return values;
}
WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> CSSMathInvert::create_calculation_node(CalculationContext const& context) const
{
return InvertCalculationNode::create(TRY(m_value->create_calculation_node(context)));
}
}

View file

@ -30,6 +30,8 @@ public:
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
virtual Optional<SumValue> create_a_sum_value() const override;
virtual WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> create_calculation_node(CalculationContext const&) const override;
private:
CSSMathInvert(JS::Realm&, NumericType, GC::Ref<CSSNumericValue>);
GC::Ref<CSSNumericValue> m_value;

View file

@ -9,6 +9,7 @@
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/CSSMathNegate.h>
#include <LibWeb/CSS/CSSNumericArray.h>
#include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
#include <LibWeb/WebIDL/DOMException.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
@ -157,4 +158,14 @@ Optional<SumValue> CSSMathMax::create_a_sum_value() const
return item_with_largest_value;
}
WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> CSSMathMax::create_calculation_node(CalculationContext const& context) const
{
Vector<NonnullRefPtr<CalculationNode const>> child_nodes;
for (auto const& child_value : m_values->values()) {
child_nodes.append(TRY(child_value->create_calculation_node(context)));
}
return MaxCalculationNode::create(move(child_nodes));
}
}

View file

@ -30,6 +30,8 @@ public:
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
virtual Optional<SumValue> create_a_sum_value() const override;
virtual WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> create_calculation_node(CalculationContext const&) const override;
private:
CSSMathMax(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
GC::Ref<CSSNumericArray> m_values;

View file

@ -10,6 +10,7 @@
#include <LibWeb/CSS/CSSMathNegate.h>
#include <LibWeb/CSS/CSSNumericArray.h>
#include <LibWeb/CSS/CSSNumericValue.h>
#include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
#include <LibWeb/WebIDL/DOMException.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
@ -158,4 +159,14 @@ Optional<SumValue> CSSMathMin::create_a_sum_value() const
return item_with_smallest_value;
}
WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> CSSMathMin::create_calculation_node(CalculationContext const& context) const
{
Vector<NonnullRefPtr<CalculationNode const>> child_nodes;
for (auto const& child_value : m_values->values()) {
child_nodes.append(TRY(child_value->create_calculation_node(context)));
}
return MinCalculationNode::create(move(child_nodes));
}
}

View file

@ -30,6 +30,8 @@ public:
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
virtual Optional<SumValue> create_a_sum_value() const override;
virtual WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> create_calculation_node(CalculationContext const&) const override;
private:
CSSMathMin(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
GC::Ref<CSSNumericArray> m_values;

View file

@ -7,6 +7,7 @@
#include "CSSMathNegate.h"
#include <LibWeb/Bindings/CSSMathNegatePrototype.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
namespace Web::CSS {
@ -121,4 +122,9 @@ Optional<SumValue> CSSMathNegate::create_a_sum_value() const
return values;
}
WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> CSSMathNegate::create_calculation_node(CalculationContext const& context) const
{
return NegateCalculationNode::create(TRY(m_value->create_calculation_node(context)));
}
}

View file

@ -30,6 +30,8 @@ public:
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
virtual Optional<SumValue> create_a_sum_value() const override;
virtual WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> create_calculation_node(CalculationContext const&) const override;
private:
CSSMathNegate(JS::Realm&, NumericType, GC::Ref<CSSNumericValue>);
GC::Ref<CSSNumericValue> m_value;

View file

@ -9,6 +9,7 @@
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/CSSMathInvert.h>
#include <LibWeb/CSS/CSSNumericArray.h>
#include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
#include <LibWeb/WebIDL/DOMException.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
@ -194,4 +195,14 @@ Optional<SumValue> CSSMathProduct::create_a_sum_value() const
return values;
}
WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> CSSMathProduct::create_calculation_node(CalculationContext const& context) const
{
Vector<NonnullRefPtr<CalculationNode const>> child_nodes;
for (auto const& child_value : m_values->values()) {
child_nodes.append(TRY(child_value->create_calculation_node(context)));
}
return ProductCalculationNode::create(move(child_nodes));
}
}

View file

@ -30,6 +30,8 @@ public:
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
virtual Optional<SumValue> create_a_sum_value() const override;
virtual WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> create_calculation_node(CalculationContext const&) const override;
private:
CSSMathProduct(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
GC::Ref<CSSNumericArray> m_values;

View file

@ -9,6 +9,7 @@
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/CSSMathNegate.h>
#include <LibWeb/CSS/CSSNumericArray.h>
#include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
#include <LibWeb/WebIDL/DOMException.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
@ -206,4 +207,14 @@ Optional<SumValue> CSSMathSum::create_a_sum_value() const
return values;
}
WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> CSSMathSum::create_calculation_node(CalculationContext const& context) const
{
Vector<NonnullRefPtr<CalculationNode const>> child_nodes;
for (auto const& child_value : m_values->values()) {
child_nodes.append(TRY(child_value->create_calculation_node(context)));
}
return SumCalculationNode::create(move(child_nodes));
}
}

View file

@ -30,6 +30,8 @@ public:
virtual bool is_equal_numeric_value(GC::Ref<CSSNumericValue> other) const override;
virtual Optional<SumValue> create_a_sum_value() const override;
virtual WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> create_calculation_node(CalculationContext const&) const override;
private:
CSSMathSum(JS::Realm&, NumericType, GC::Ref<CSSNumericArray>);
GC::Ref<CSSNumericArray> m_values;

View file

@ -6,6 +6,8 @@
#include "CSSMathValue.h"
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/PropertyNameAndID.h>
#include <LibWeb/CSS/StyleValues/CalculatedStyleValue.h>
namespace Web::CSS {
@ -23,4 +25,44 @@ void CSSMathValue::initialize(JS::Realm& realm)
Base::initialize(realm);
}
// https://drafts.css-houdini.org/css-typed-om-1/#create-an-internal-representation
WebIDL::ExceptionOr<NonnullRefPtr<StyleValue const>> CSSMathValue::create_an_internal_representation(PropertyNameAndID const& property) const
{
// If value is a CSSStyleValue subclass,
// If value does not match the grammar of a list-valued property iteration of property, throw a TypeError.
//
// If any component of propertys CSS grammar has a limited numeric range, and the corresponding part of value
// is a CSSUnitValue that is outside of that range, replace that value with the result of wrapping it in a
// fresh CSSMathSum whose values internal slot contains only that part of value.
//
// Return the value.
// FIXME: Check types allowed by registered custom properties.
auto context = CalculationContext::for_property(property);
auto matches = [&] {
if (type().matches_angle(context.percentages_resolve_as))
return property_accepts_type(property.id(), ValueType::Angle);
if (type().matches_flex(context.percentages_resolve_as))
return property_accepts_type(property.id(), ValueType::Flex);
if (type().matches_frequency(context.percentages_resolve_as))
return property_accepts_type(property.id(), ValueType::Frequency);
if (type().matches_length(context.percentages_resolve_as))
return property_accepts_type(property.id(), ValueType::Length);
if (type().matches_number(context.percentages_resolve_as))
return property_accepts_type(property.id(), ValueType::Number);
if (type().matches_percentage())
return property_accepts_type(property.id(), ValueType::Percentage);
if (type().matches_resolution(context.percentages_resolve_as))
return property_accepts_type(property.id(), ValueType::Resolution);
if (type().matches_time(context.percentages_resolve_as))
return property_accepts_type(property.id(), ValueType::Time);
return false;
}();
if (!matches)
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Property does not accept values of this type."sv };
return CalculatedStyleValue::create(TRY(create_calculation_node(context)), type(), move(context));
}
}

View file

@ -8,6 +8,7 @@
#include <LibWeb/Bindings/CSSMathValuePrototype.h>
#include <LibWeb/CSS/CSSNumericValue.h>
#include <LibWeb/Forward.h>
namespace Web::CSS {
@ -31,6 +32,8 @@ public:
};
virtual String serialize_math_value(Nested, Parens) const = 0;
virtual WebIDL::ExceptionOr<NonnullRefPtr<StyleValue const>> create_an_internal_representation(PropertyNameAndID const&) const final override;
protected:
explicit CSSMathValue(JS::Realm&, Bindings::CSSMathOperator, NumericType);

View file

@ -65,6 +65,8 @@ public:
static WebIDL::ExceptionOr<GC::Ref<CSSNumericValue>> parse(JS::VM&, String const& css_text);
virtual WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> create_calculation_node(CalculationContext const&) const = 0;
protected:
explicit CSSNumericValue(JS::Realm&, NumericType);

View file

@ -444,4 +444,13 @@ WebIDL::ExceptionOr<NonnullRefPtr<StyleValue const>> CSSUnitValue::create_an_int
return style_value.release_nonnull();
}
WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> CSSUnitValue::create_calculation_node(CalculationContext const& context) const
{
auto value = create_numeric_value(m_value, m_unit);
if (!value.has_value())
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, MUST(String::formatted("Unable to create calculation node from `{}{}`.", m_value, m_unit)) };
return NumericCalculationNode::create(value.release_value(), context);
}
}

View file

@ -36,6 +36,7 @@ public:
virtual Optional<SumValue> create_a_sum_value() const override;
virtual WebIDL::ExceptionOr<NonnullRefPtr<StyleValue const>> create_an_internal_representation(PropertyNameAndID const&) const override;
virtual WebIDL::ExceptionOr<NonnullRefPtr<CalculationNode const>> create_calculation_node(CalculationContext const&) const override;
private:
explicit CSSUnitValue(JS::Realm&, double value, FlyString unit, NumericType type);

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 69 tests
65 Pass
4 Fail
64 Pass
5 Fail
Pass Can set 'cursor' to CSS-wide keywords: initial
Pass Can set 'cursor' to CSS-wide keywords: inherit
Pass Can set 'cursor' to CSS-wide keywords: unset
@ -67,7 +67,7 @@ Pass Setting 'cursor' to a flexible length: -3.14fr throws TypeError
Fail Setting 'cursor' to a number: 0 throws TypeError
Fail Setting 'cursor' to a number: -3.14 throws TypeError
Fail Setting 'cursor' to a number: 3.14 throws TypeError
Pass Setting 'cursor' to a number: calc(2 + 3) throws TypeError
Fail Setting 'cursor' to a number: calc(2 + 3) throws TypeError
Pass Setting 'cursor' to a transform: translate(50%, 50%) throws TypeError
Pass Setting 'cursor' to a transform: perspective(10em) throws TypeError
Pass Setting 'cursor' to a transform: translate3d(0px, 1px, 2px) translate(0px, 1px) rotate3d(1, 2, 3, 45deg) rotate(45deg) scale3d(1, 2, 3) scale(1, 2) skew(1deg, 1deg) skewX(1deg) skewY(45deg) perspective(1px) matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) matrix(1, 2, 3, 4, 5, 6) throws TypeError

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 32 tests
26 Pass
6 Fail
29 Pass
3 Fail
Pass Can set 'line-height' to CSS-wide keywords: initial
Pass Can set 'line-height' to CSS-wide keywords: inherit
Pass Can set 'line-height' to CSS-wide keywords: unset
@ -13,15 +13,15 @@ Pass Can set 'line-height' to the 'normal' keyword: normal
Pass Can set 'line-height' to a length: 0px
Pass Can set 'line-height' to a length: -3.14em
Pass Can set 'line-height' to a length: 3.14cm
Fail Can set 'line-height' to a length: calc(0px + 0em)
Pass Can set 'line-height' to a length: calc(0px + 0em)
Fail Can set 'line-height' to a number: 0
Fail Can set 'line-height' to a number: -3.14
Pass Can set 'line-height' to a number: 3.14
Fail Can set 'line-height' to a number: calc(2 + 3)
Pass Can set 'line-height' to a number: calc(2 + 3)
Pass Can set 'line-height' to a percent: 0%
Pass Can set 'line-height' to a percent: -3.14%
Pass Can set 'line-height' to a percent: 3.14%
Fail Can set 'line-height' to a percent: calc(0% + 0%)
Pass Can set 'line-height' to a percent: calc(0% + 0%)
Pass Setting 'line-height' to a time: 0s throws TypeError
Pass Setting 'line-height' to a time: -3.14ms throws TypeError
Pass Setting 'line-height' to a time: 3.14s throws TypeError

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 161 tests
144 Pass
17 Fail
152 Pass
9 Fail
Pass Can set 'margin-top' to CSS-wide keywords: initial
Pass Can set 'margin-top' to CSS-wide keywords: inherit
Pass Can set 'margin-top' to CSS-wide keywords: unset
@ -13,11 +13,11 @@ Pass Can set 'margin-top' to the 'auto' keyword: auto
Pass Can set 'margin-top' to a percent: 0%
Pass Can set 'margin-top' to a percent: -3.14%
Pass Can set 'margin-top' to a percent: 3.14%
Fail Can set 'margin-top' to a percent: calc(0% + 0%)
Pass Can set 'margin-top' to a percent: calc(0% + 0%)
Pass Can set 'margin-top' to a length: 0px
Pass Can set 'margin-top' to a length: -3.14em
Pass Can set 'margin-top' to a length: 3.14cm
Fail Can set 'margin-top' to a length: calc(0px + 0em)
Pass Can set 'margin-top' to a length: calc(0px + 0em)
Pass Setting 'margin-top' to a time: 0s throws TypeError
Pass Setting 'margin-top' to a time: -3.14ms throws TypeError
Pass Setting 'margin-top' to a time: 3.14s throws TypeError
@ -45,11 +45,11 @@ Pass Can set 'margin-left' to the 'auto' keyword: auto
Pass Can set 'margin-left' to a percent: 0%
Pass Can set 'margin-left' to a percent: -3.14%
Pass Can set 'margin-left' to a percent: 3.14%
Fail Can set 'margin-left' to a percent: calc(0% + 0%)
Pass Can set 'margin-left' to a percent: calc(0% + 0%)
Pass Can set 'margin-left' to a length: 0px
Pass Can set 'margin-left' to a length: -3.14em
Pass Can set 'margin-left' to a length: 3.14cm
Fail Can set 'margin-left' to a length: calc(0px + 0em)
Pass Can set 'margin-left' to a length: calc(0px + 0em)
Pass Setting 'margin-left' to a time: 0s throws TypeError
Pass Setting 'margin-left' to a time: -3.14ms throws TypeError
Pass Setting 'margin-left' to a time: 3.14s throws TypeError
@ -77,11 +77,11 @@ Pass Can set 'margin-right' to the 'auto' keyword: auto
Pass Can set 'margin-right' to a percent: 0%
Pass Can set 'margin-right' to a percent: -3.14%
Pass Can set 'margin-right' to a percent: 3.14%
Fail Can set 'margin-right' to a percent: calc(0% + 0%)
Pass Can set 'margin-right' to a percent: calc(0% + 0%)
Pass Can set 'margin-right' to a length: 0px
Pass Can set 'margin-right' to a length: -3.14em
Pass Can set 'margin-right' to a length: 3.14cm
Fail Can set 'margin-right' to a length: calc(0px + 0em)
Pass Can set 'margin-right' to a length: calc(0px + 0em)
Pass Setting 'margin-right' to a time: 0s throws TypeError
Pass Setting 'margin-right' to a time: -3.14ms throws TypeError
Pass Setting 'margin-right' to a time: 3.14s throws TypeError
@ -109,11 +109,11 @@ Pass Can set 'margin-bottom' to the 'auto' keyword: auto
Pass Can set 'margin-bottom' to a percent: 0%
Pass Can set 'margin-bottom' to a percent: -3.14%
Pass Can set 'margin-bottom' to a percent: 3.14%
Fail Can set 'margin-bottom' to a percent: calc(0% + 0%)
Pass Can set 'margin-bottom' to a percent: calc(0% + 0%)
Pass Can set 'margin-bottom' to a length: 0px
Pass Can set 'margin-bottom' to a length: -3.14em
Pass Can set 'margin-bottom' to a length: 3.14cm
Fail Can set 'margin-bottom' to a length: calc(0px + 0em)
Pass Can set 'margin-bottom' to a length: calc(0px + 0em)
Pass Setting 'margin-bottom' to a time: 0s throws TypeError
Pass Setting 'margin-bottom' to a time: -3.14ms throws TypeError
Pass Setting 'margin-bottom' to a time: 3.14s throws TypeError

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 124 tests
108 Pass
16 Fail
116 Pass
8 Fail
Pass Can set 'padding-top' to CSS-wide keywords: initial
Pass Can set 'padding-top' to CSS-wide keywords: inherit
Pass Can set 'padding-top' to CSS-wide keywords: unset
@ -12,11 +12,11 @@ Fail Can set 'padding-top' to var() references: var(--A)
Pass Can set 'padding-top' to a percent: 0%
Fail Can set 'padding-top' to a percent: -3.14%
Pass Can set 'padding-top' to a percent: 3.14%
Fail Can set 'padding-top' to a percent: calc(0% + 0%)
Pass Can set 'padding-top' to a percent: calc(0% + 0%)
Pass Can set 'padding-top' to a length: 0px
Pass Can set 'padding-top' to a length: -3.14em
Pass Can set 'padding-top' to a length: 3.14cm
Fail Can set 'padding-top' to a length: calc(0px + 0em)
Pass Can set 'padding-top' to a length: calc(0px + 0em)
Pass Setting 'padding-top' to a time: 0s throws TypeError
Pass Setting 'padding-top' to a time: -3.14ms throws TypeError
Pass Setting 'padding-top' to a time: 3.14s throws TypeError
@ -43,11 +43,11 @@ Fail Can set 'padding-left' to var() references: var(--A)
Pass Can set 'padding-left' to a percent: 0%
Fail Can set 'padding-left' to a percent: -3.14%
Pass Can set 'padding-left' to a percent: 3.14%
Fail Can set 'padding-left' to a percent: calc(0% + 0%)
Pass Can set 'padding-left' to a percent: calc(0% + 0%)
Pass Can set 'padding-left' to a length: 0px
Pass Can set 'padding-left' to a length: -3.14em
Pass Can set 'padding-left' to a length: 3.14cm
Fail Can set 'padding-left' to a length: calc(0px + 0em)
Pass Can set 'padding-left' to a length: calc(0px + 0em)
Pass Setting 'padding-left' to a time: 0s throws TypeError
Pass Setting 'padding-left' to a time: -3.14ms throws TypeError
Pass Setting 'padding-left' to a time: 3.14s throws TypeError
@ -74,11 +74,11 @@ Fail Can set 'padding-right' to var() references: var(--A)
Pass Can set 'padding-right' to a percent: 0%
Fail Can set 'padding-right' to a percent: -3.14%
Pass Can set 'padding-right' to a percent: 3.14%
Fail Can set 'padding-right' to a percent: calc(0% + 0%)
Pass Can set 'padding-right' to a percent: calc(0% + 0%)
Pass Can set 'padding-right' to a length: 0px
Pass Can set 'padding-right' to a length: -3.14em
Pass Can set 'padding-right' to a length: 3.14cm
Fail Can set 'padding-right' to a length: calc(0px + 0em)
Pass Can set 'padding-right' to a length: calc(0px + 0em)
Pass Setting 'padding-right' to a time: 0s throws TypeError
Pass Setting 'padding-right' to a time: -3.14ms throws TypeError
Pass Setting 'padding-right' to a time: 3.14s throws TypeError
@ -105,11 +105,11 @@ Fail Can set 'padding-bottom' to var() references: var(--A)
Pass Can set 'padding-bottom' to a percent: 0%
Fail Can set 'padding-bottom' to a percent: -3.14%
Pass Can set 'padding-bottom' to a percent: 3.14%
Fail Can set 'padding-bottom' to a percent: calc(0% + 0%)
Pass Can set 'padding-bottom' to a percent: calc(0% + 0%)
Pass Can set 'padding-bottom' to a length: 0px
Pass Can set 'padding-bottom' to a length: -3.14em
Pass Can set 'padding-bottom' to a length: 3.14cm
Fail Can set 'padding-bottom' to a length: calc(0px + 0em)
Pass Can set 'padding-bottom' to a length: calc(0px + 0em)
Pass Setting 'padding-bottom' to a time: 0s throws TypeError
Pass Setting 'padding-bottom' to a time: -3.14ms throws TypeError
Pass Setting 'padding-bottom' to a time: 3.14s throws TypeError

View file

@ -2,8 +2,8 @@ Harness status: OK
Found 95 tests
83 Pass
12 Fail
89 Pass
6 Fail
Pass Can set 'width' to CSS-wide keywords: initial
Pass Can set 'width' to CSS-wide keywords: inherit
Pass Can set 'width' to CSS-wide keywords: unset
@ -13,11 +13,11 @@ Pass Can set 'width' to the 'auto' keyword: auto
Pass Can set 'width' to a percent: 0%
Fail Can set 'width' to a percent: -3.14%
Pass Can set 'width' to a percent: 3.14%
Fail Can set 'width' to a percent: calc(0% + 0%)
Pass Can set 'width' to a percent: calc(0% + 0%)
Pass Can set 'width' to a length: 0px
Pass Can set 'width' to a length: -3.14em
Pass Can set 'width' to a length: 3.14cm
Fail Can set 'width' to a length: calc(0px + 0em)
Pass Can set 'width' to a length: calc(0px + 0em)
Pass Setting 'width' to a time: 0s throws TypeError
Pass Setting 'width' to a time: -3.14ms throws TypeError
Pass Setting 'width' to a time: 3.14s throws TypeError
@ -44,11 +44,11 @@ Fail Can set 'min-width' to var() references: var(--A)
Pass Can set 'min-width' to a percent: 0%
Fail Can set 'min-width' to a percent: -3.14%
Pass Can set 'min-width' to a percent: 3.14%
Fail Can set 'min-width' to a percent: calc(0% + 0%)
Pass Can set 'min-width' to a percent: calc(0% + 0%)
Pass Can set 'min-width' to a length: 0px
Pass Can set 'min-width' to a length: -3.14em
Pass Can set 'min-width' to a length: 3.14cm
Fail Can set 'min-width' to a length: calc(0px + 0em)
Pass Can set 'min-width' to a length: calc(0px + 0em)
Pass Setting 'min-width' to a time: 0s throws TypeError
Pass Setting 'min-width' to a time: -3.14ms throws TypeError
Pass Setting 'min-width' to a time: 3.14s throws TypeError
@ -76,11 +76,11 @@ Pass Can set 'max-width' to the 'none' keyword: none
Pass Can set 'max-width' to a percent: 0%
Fail Can set 'max-width' to a percent: -3.14%
Pass Can set 'max-width' to a percent: 3.14%
Fail Can set 'max-width' to a percent: calc(0% + 0%)
Pass Can set 'max-width' to a percent: calc(0% + 0%)
Pass Can set 'max-width' to a length: 0px
Pass Can set 'max-width' to a length: -3.14em
Pass Can set 'max-width' to a length: 3.14cm
Fail Can set 'max-width' to a length: calc(0px + 0em)
Pass Can set 'max-width' to a length: calc(0px + 0em)
Pass Setting 'max-width' to a time: 0s throws TypeError
Pass Setting 'max-width' to a time: -3.14ms throws TypeError
Pass Setting 'max-width' to a time: 3.14s throws TypeError