Skip to content

Commit 6cb8e92

Browse files
committed
LibWeb/CSS: Stub out CSSNumericValue
Most of the methods on this rely on its subclasses existing, so for now it's very basic.
1 parent 5bdc298 commit 6cb8e92

File tree

9 files changed

+233
-0
lines changed

9 files changed

+233
-0
lines changed

Libraries/LibWeb/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ set(SOURCES
119119
CSS/CSSMediaRule.cpp
120120
CSS/CSSNamespaceRule.cpp
121121
CSS/CSSNestedDeclarations.cpp
122+
CSS/CSSNumericValue.cpp
122123
CSS/CSSPageRule.cpp
123124
CSS/CSSPageDescriptors.cpp
124125
CSS/CSSPropertyRule.cpp
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include "CSSNumericValue.h"
8+
#include <LibWeb/Bindings/CSSNumericValuePrototype.h>
9+
#include <LibWeb/Bindings/Intrinsics.h>
10+
#include <LibWeb/CSS/NumericType.h>
11+
#include <LibWeb/CSS/Serialize.h>
12+
13+
namespace Web::CSS {
14+
15+
GC_DEFINE_ALLOCATOR(CSSNumericValue);
16+
17+
static Bindings::CSSNumericBaseType to_om_numeric_base_type(NumericType::BaseType source)
18+
{
19+
switch (source) {
20+
case NumericType::BaseType::Length:
21+
return Bindings::CSSNumericBaseType::Length;
22+
case NumericType::BaseType::Angle:
23+
return Bindings::CSSNumericBaseType::Angle;
24+
case NumericType::BaseType::Time:
25+
return Bindings::CSSNumericBaseType::Time;
26+
case NumericType::BaseType::Frequency:
27+
return Bindings::CSSNumericBaseType::Frequency;
28+
case NumericType::BaseType::Resolution:
29+
return Bindings::CSSNumericBaseType::Resolution;
30+
case NumericType::BaseType::Flex:
31+
return Bindings::CSSNumericBaseType::Flex;
32+
case NumericType::BaseType::Percent:
33+
return Bindings::CSSNumericBaseType::Percent;
34+
case NumericType::BaseType::__Count:
35+
VERIFY_NOT_REACHED();
36+
}
37+
VERIFY_NOT_REACHED();
38+
}
39+
40+
CSSNumericValue::CSSNumericValue(JS::Realm& realm, NumericType type)
41+
: CSSStyleValue(realm)
42+
, m_type(move(type))
43+
{
44+
}
45+
46+
void CSSNumericValue::initialize(JS::Realm& realm)
47+
{
48+
WEB_SET_PROTOTYPE_FOR_INTERFACE(CSSNumericValue);
49+
Base::initialize(realm);
50+
}
51+
52+
// https://drafts.css-houdini.org/css-typed-om-1/#dom-cssnumericvalue-type
53+
CSSNumericType CSSNumericValue::type_for_bindings() const
54+
{
55+
// 1. Let result be a new CSSNumericType.
56+
CSSNumericType result {};
57+
58+
// 2. For each baseType → power in the type of this,
59+
m_type.for_each_type_and_exponent([&result](NumericType::BaseType base_type, auto power) {
60+
// 1. If power is not 0, set result[baseType] to power.
61+
if (power == 0)
62+
return;
63+
64+
switch (base_type) {
65+
case NumericType::BaseType::Length:
66+
result.length = power;
67+
break;
68+
case NumericType::BaseType::Angle:
69+
result.angle = power;
70+
break;
71+
case NumericType::BaseType::Time:
72+
result.time = power;
73+
break;
74+
case NumericType::BaseType::Frequency:
75+
result.frequency = power;
76+
break;
77+
case NumericType::BaseType::Resolution:
78+
result.resolution = power;
79+
break;
80+
case NumericType::BaseType::Flex:
81+
result.flex = power;
82+
break;
83+
case NumericType::BaseType::Percent:
84+
result.percent = power;
85+
break;
86+
case NumericType::BaseType::__Count:
87+
VERIFY_NOT_REACHED();
88+
}
89+
});
90+
91+
// 3. If the percent hint of this is not null,
92+
if (auto percent_hint = m_type.percent_hint(); percent_hint.has_value()) {
93+
// 1. Set result[percentHint] to the percent hint of this.
94+
result.percent_hint = to_om_numeric_base_type(percent_hint.value());
95+
}
96+
97+
// 4. Return result.
98+
return result;
99+
}
100+
101+
// https://drafts.css-houdini.org/css-typed-om-1/#serialize-a-cssnumericvalue
102+
String CSSNumericValue::to_string(SerializationParams const&) const
103+
{
104+
// To serialize a CSSNumericValue this, given an optional minimum, a numeric value, and optional maximum, a numeric value:
105+
// FIXME: 1. If this is a CSSUnitValue, serialize a CSSUnitValue from this, passing minimum and maximum. Return the result.
106+
// FIXME: 2. Otherwise, serialize a CSSMathValue from this, and return the result.
107+
108+
return {};
109+
}
110+
111+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#pragma once
8+
9+
#include <AK/FlyString.h>
10+
#include <LibWeb/Bindings/CSSNumericValuePrototype.h>
11+
#include <LibWeb/CSS/CSSStyleValue.h>
12+
#include <LibWeb/CSS/NumericType.h>
13+
#include <LibWeb/WebIDL/Types.h>
14+
15+
namespace Web::CSS {
16+
17+
struct CSSNumericType {
18+
WebIDL::Long length {};
19+
WebIDL::Long angle {};
20+
WebIDL::Long time {};
21+
WebIDL::Long frequency {};
22+
WebIDL::Long resolution {};
23+
WebIDL::Long flex {};
24+
WebIDL::Long percent {};
25+
Optional<Bindings::CSSNumericBaseType> percent_hint {};
26+
};
27+
28+
// https://drafts.css-houdini.org/css-typed-om-1/#cssnumericvalue
29+
class CSSNumericValue : public CSSStyleValue {
30+
WEB_PLATFORM_OBJECT(CSSNumericValue, CSSStyleValue);
31+
GC_DECLARE_ALLOCATOR(CSSNumericValue);
32+
33+
public:
34+
struct SerializationParams {
35+
Optional<double> minimum {};
36+
Optional<double> maximum {};
37+
bool nested { false };
38+
bool parenless { false };
39+
};
40+
virtual ~CSSNumericValue() override = default;
41+
42+
CSSNumericType type_for_bindings() const;
43+
NumericType const& type() const { return m_type; }
44+
45+
virtual String to_string() const final override { return to_string({}); }
46+
String to_string(SerializationParams const&) const;
47+
48+
protected:
49+
explicit CSSNumericValue(JS::Realm&, NumericType);
50+
51+
virtual void initialize(JS::Realm&) override;
52+
53+
NumericType m_type;
54+
};
55+
56+
// https://drafts.css-houdini.org/css-typed-om-1/#typedefdef-cssnumberish
57+
using CSSNumberish = Variant<double, GC::Root<CSSNumericValue>>;
58+
59+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#import <CSS/CSSStyleValue.idl>
2+
3+
// https://drafts.css-houdini.org/css-typed-om-1/#enumdef-cssnumericbasetype
4+
enum CSSNumericBaseType {
5+
"length",
6+
"angle",
7+
"time",
8+
"frequency",
9+
"resolution",
10+
"flex",
11+
"percent",
12+
};
13+
14+
// https://drafts.css-houdini.org/css-typed-om-1/#dictdef-cssnumerictype
15+
// AD-HOC: We give these default values and mark percentHint as nullable. https://github.com/w3c/css-houdini-drafts/issues/1149
16+
dictionary CSSNumericType {
17+
long length = 0;
18+
long angle = 0;
19+
long time = 0;
20+
long frequency = 0;
21+
long resolution = 0;
22+
long flex = 0;
23+
long percent = 0;
24+
CSSNumericBaseType? percentHint;
25+
};
26+
27+
// https://drafts.css-houdini.org/css-typed-om-1/#cssnumericvalue
28+
[Exposed=(Window, Worker, PaintWorklet, LayoutWorklet)]
29+
interface CSSNumericValue : CSSStyleValue {
30+
[FIXME] CSSNumericValue add(CSSNumberish... values);
31+
[FIXME] CSSNumericValue sub(CSSNumberish... values);
32+
[FIXME] CSSNumericValue mul(CSSNumberish... values);
33+
[FIXME] CSSNumericValue div(CSSNumberish... values);
34+
[FIXME] CSSNumericValue min(CSSNumberish... values);
35+
[FIXME] CSSNumericValue max(CSSNumberish... values);
36+
37+
[FIXME] boolean equals(CSSNumberish... value);
38+
39+
// FIXME: CSSUnitValue to(USVString unit);
40+
// FIXME: CSSMathSum toSum(USVString... units);
41+
[ImplementedAs=type_for_bindings] CSSNumericType type();
42+
43+
[FIXME, Exposed=Window] static CSSNumericValue parse(USVString cssText);
44+
};
45+
46+
// https://drafts.css-houdini.org/css-typed-om-1/#typedefdef-cssnumberish
47+
typedef (double or CSSNumericValue) CSSNumberish;

Libraries/LibWeb/CSS/NumericType.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,17 @@ class NumericType {
8484
Optional<i32> const& exponent(BaseType type) const { return m_type_exponents[to_underlying(type)]; }
8585
void set_exponent(BaseType type, i32 exponent) { m_type_exponents[to_underlying(type)] = exponent; }
8686

87+
template<typename Callback>
88+
void for_each_type_and_exponent(Callback callback) const
89+
{
90+
for (auto i = 0; i < to_underlying(BaseType::__Count); ++i) {
91+
if (!m_type_exponents[i].has_value())
92+
continue;
93+
auto base_type = static_cast<BaseType>(i);
94+
callback(base_type, m_type_exponents[i].value());
95+
}
96+
}
97+
8798
Optional<BaseType> const& percent_hint() const { return m_percent_hint; }
8899
void set_percent_hint(Optional<BaseType> hint) { m_percent_hint = hint; }
89100
void apply_percent_hint(BaseType hint);

Libraries/LibWeb/Forward.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ class CSSMarginRule;
245245
class CSSMediaRule;
246246
class CSSNamespaceRule;
247247
class CSSNestedDeclarations;
248+
class CSSNumericValue;
248249
class CSSPageRule;
249250
class CSSPageDescriptors;
250251
class CSSPropertyRule;

Libraries/LibWeb/idl_files.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ libweb_js_bindings(CSS/CSSMediaRule)
4040
libweb_js_bindings(CSS/CSS NAMESPACE)
4141
libweb_js_bindings(CSS/CSSNamespaceRule)
4242
libweb_js_bindings(CSS/CSSNestedDeclarations)
43+
libweb_js_bindings(CSS/CSSNumericValue)
4344
libweb_js_bindings(CSS/CSSPageRule)
4445
libweb_js_bindings(CSS/CSSPageDescriptors)
4546
libweb_js_bindings(CSS/CSSPropertyRule)

Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static bool is_platform_object(Type const& type)
5555
"CredentialsContainer"sv,
5656
"CryptoKey"sv,
5757
"CSSKeywordValue"sv,
58+
"CSSNumericValue"sv,
5859
"CSSStyleValue"sv,
5960
"CSSUnparsedValue"sv,
6061
"CSSVariableReferenceValue"sv,

Tests/LibWeb/Text/expected/all-window-properties.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ CSSMarginRule
5252
CSSMediaRule
5353
CSSNamespaceRule
5454
CSSNestedDeclarations
55+
CSSNumericValue
5556
CSSPageDescriptors
5657
CSSPageRule
5758
CSSPropertyRule

0 commit comments

Comments
 (0)