Coverage Report

Created: 2026-09-26 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibWeb/CSS/CalculatedOr.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/Variant.h>
10
#include <LibWeb/CSS/Angle.h>
11
#include <LibWeb/CSS/Flex.h>
12
#include <LibWeb/CSS/Frequency.h>
13
#include <LibWeb/CSS/Length.h>
14
#include <LibWeb/CSS/Percentage.h>
15
#include <LibWeb/CSS/Resolution.h>
16
#include <LibWeb/CSS/StyleValues/CSSMathValue.h>
17
#include <LibWeb/CSS/Time.h>
18
19
namespace Web::CSS {
20
21
template<typename T>
22
class CalculatedOr {
23
public:
24
    CalculatedOr(T t)
25
0
        : m_value(move(t))
26
0
    {
27
0
    }
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Angle>::CalculatedOr(Web::CSS::Angle)
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Flex>::CalculatedOr(Web::CSS::Flex)
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Frequency>::CalculatedOr(Web::CSS::Frequency)
Unexecuted instantiation: Web::CSS::CalculatedOr<long>::CalculatedOr(long)
Unexecuted instantiation: Web::CSS::CalculatedOr<double>::CalculatedOr(double)
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Resolution>::CalculatedOr(Web::CSS::Resolution)
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Time>::CalculatedOr(Web::CSS::Time)
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Length>::CalculatedOr(Web::CSS::Length)
28
29
    CalculatedOr(NonnullRefPtr<CSSMathValue> calculated)
30
0
        : m_value(move(calculated))
31
0
    {
32
0
    }
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Angle>::CalculatedOr(AK::NonnullRefPtr<Web::CSS::CSSMathValue>)
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Flex>::CalculatedOr(AK::NonnullRefPtr<Web::CSS::CSSMathValue>)
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Frequency>::CalculatedOr(AK::NonnullRefPtr<Web::CSS::CSSMathValue>)
Unexecuted instantiation: Web::CSS::CalculatedOr<long>::CalculatedOr(AK::NonnullRefPtr<Web::CSS::CSSMathValue>)
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Length>::CalculatedOr(AK::NonnullRefPtr<Web::CSS::CSSMathValue>)
Unexecuted instantiation: Web::CSS::CalculatedOr<double>::CalculatedOr(AK::NonnullRefPtr<Web::CSS::CSSMathValue>)
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Resolution>::CalculatedOr(AK::NonnullRefPtr<Web::CSS::CSSMathValue>)
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Time>::CalculatedOr(AK::NonnullRefPtr<Web::CSS::CSSMathValue>)
33
34
0
    virtual ~CalculatedOr() = default;
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Angle>::~CalculatedOr()
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Flex>::~CalculatedOr()
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Frequency>::~CalculatedOr()
Unexecuted instantiation: Web::CSS::CalculatedOr<long>::~CalculatedOr()
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Length>::~CalculatedOr()
Unexecuted instantiation: Web::CSS::CalculatedOr<double>::~CalculatedOr()
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Resolution>::~CalculatedOr()
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Time>::~CalculatedOr()
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Percentage>::~CalculatedOr()
35
36
0
    bool is_calculated() const { return m_value.template has<NonnullRefPtr<CSSMathValue>>(); }
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Angle>::is_calculated() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Frequency>::is_calculated() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Length>::is_calculated() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Percentage>::is_calculated() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Time>::is_calculated() const
Unexecuted instantiation: Web::CSS::CalculatedOr<long>::is_calculated() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Resolution>::is_calculated() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Flex>::is_calculated() const
Unexecuted instantiation: Web::CSS::CalculatedOr<double>::is_calculated() const
37
38
    T const& value() const
39
0
    {
40
0
        VERIFY(!is_calculated());
41
0
        return m_value.template get<T>();
42
0
    }
Unexecuted instantiation: Web::CSS::CalculatedOr<long>::value() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Length>::value() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Resolution>::value() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Angle>::value() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Flex>::value() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Frequency>::value() const
Unexecuted instantiation: Web::CSS::CalculatedOr<double>::value() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Percentage>::value() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Time>::value() const
43
44
    NonnullRefPtr<CSSStyleValue> as_style_value() const
45
0
    {
46
0
        if (is_calculated())
47
0
            return calculated();
48
0
        return create_style_value();
49
0
    }
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Length>::as_style_value() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Time>::as_style_value() const
50
51
    NonnullRefPtr<CSSMathValue> const& calculated() const
52
0
    {
53
0
        VERIFY(is_calculated());
54
0
        return m_value.template get<NonnullRefPtr<CSSMathValue>>();
55
0
    }
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Length>::calculated() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Time>::calculated() const
56
57
    T resolved(Layout::Node const& layout_node) const
58
0
    {
59
0
        return m_value.visit(
60
0
            [&](T const& t) {
61
0
                return t;
62
0
            },
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Angle>::resolved(Web::Layout::Node const&) const::{lambda(Web::CSS::Angle const&)#1}::operator()(Web::CSS::Angle const&) const
Unexecuted instantiation: Web::CSS::CalculatedOr<double>::resolved(Web::Layout::Node const&) const::{lambda(double const&)#1}::operator()(double const&) const
63
0
            [&](NonnullRefPtr<CSSMathValue> const& calculated) {
64
0
                return resolve_calculated(calculated, layout_node);
65
0
            });
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Angle>::resolved(Web::Layout::Node const&) const::{lambda(AK::NonnullRefPtr<Web::CSS::CSSMathValue> const&)#1}::operator()(AK::NonnullRefPtr<Web::CSS::CSSMathValue> const&) const
Unexecuted instantiation: Web::CSS::CalculatedOr<double>::resolved(Web::Layout::Node const&) const::{lambda(AK::NonnullRefPtr<Web::CSS::CSSMathValue> const&)#1}::operator()(AK::NonnullRefPtr<Web::CSS::CSSMathValue> const&) const
66
0
    }
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Angle>::resolved(Web::Layout::Node const&) const
Unexecuted instantiation: Web::CSS::CalculatedOr<double>::resolved(Web::Layout::Node const&) const
67
68
    String to_string() const
69
0
    {
70
0
        if (is_calculated())
71
0
            return m_value.template get<NonnullRefPtr<CSSMathValue>>()->to_string();
72
73
0
        return m_value.template get<T>().to_string();
74
0
    }
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Angle>::to_string() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Frequency>::to_string() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Length>::to_string() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Percentage>::to_string() const
Unexecuted instantiation: Web::CSS::CalculatedOr<Web::CSS::Time>::to_string() const
75
76
    bool operator==(CalculatedOr<T> const& other) const
77
0
    {
78
0
        if (is_calculated() || other.is_calculated())
79
0
            return false;
80
0
        return (m_value.template get<T>() == other.m_value.template get<T>());
81
0
    }
82
83
protected:
84
    virtual T resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const = 0;
85
    virtual NonnullRefPtr<CSSStyleValue> create_style_value() const = 0;
86
87
private:
88
    Variant<T, NonnullRefPtr<CSSMathValue>> m_value;
89
};
90
91
class AngleOrCalculated : public CalculatedOr<Angle> {
92
public:
93
    using CalculatedOr<Angle>::CalculatedOr;
94
95
private:
96
    virtual Angle resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override;
97
    virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override;
98
};
99
100
class FlexOrCalculated : public CalculatedOr<Flex> {
101
public:
102
    using CalculatedOr<Flex>::CalculatedOr;
103
104
private:
105
    virtual Flex resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override;
106
    virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override;
107
};
108
109
class FrequencyOrCalculated : public CalculatedOr<Frequency> {
110
public:
111
    using CalculatedOr<Frequency>::CalculatedOr;
112
113
private:
114
    virtual Frequency resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override;
115
    virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override;
116
};
117
118
class IntegerOrCalculated : public CalculatedOr<i64> {
119
public:
120
    using CalculatedOr<i64>::CalculatedOr;
121
122
private:
123
    virtual i64 resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override;
124
    virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override;
125
};
126
127
class LengthOrCalculated : public CalculatedOr<Length> {
128
public:
129
    using CalculatedOr<Length>::CalculatedOr;
130
131
    [[nodiscard]] Length resolved(Length::ResolutionContext const&) const;
132
133
private:
134
    virtual Length resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override;
135
    virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override;
136
};
137
138
class NumberOrCalculated : public CalculatedOr<double> {
139
public:
140
    using CalculatedOr<double>::CalculatedOr;
141
142
private:
143
    virtual double resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override;
144
    virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override;
145
};
146
147
class PercentageOrCalculated : public CalculatedOr<Percentage> {
148
public:
149
    using CalculatedOr<Percentage>::CalculatedOr;
150
151
private:
152
    virtual Percentage resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override;
153
    virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override;
154
};
155
156
class ResolutionOrCalculated : public CalculatedOr<Resolution> {
157
public:
158
    using CalculatedOr<Resolution>::CalculatedOr;
159
160
private:
161
    virtual Resolution resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override;
162
    virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override;
163
};
164
165
class TimeOrCalculated : public CalculatedOr<Time> {
166
public:
167
    using CalculatedOr<Time>::CalculatedOr;
168
169
private:
170
    virtual Time resolve_calculated(NonnullRefPtr<CSSMathValue> const&, Layout::Node const&) const override;
171
    virtual NonnullRefPtr<CSSStyleValue> create_style_value() const override;
172
};
173
174
}
175
176
template<>
177
struct AK::Formatter<Web::CSS::AngleOrCalculated> : Formatter<StringView> {
178
    ErrorOr<void> format(FormatBuilder& builder, Web::CSS::AngleOrCalculated const& calculated_or)
179
0
    {
180
0
        return Formatter<StringView>::format(builder, calculated_or.to_string());
181
0
    }
182
};
183
184
template<>
185
struct AK::Formatter<Web::CSS::FrequencyOrCalculated> : Formatter<StringView> {
186
    ErrorOr<void> format(FormatBuilder& builder, Web::CSS::FrequencyOrCalculated const& calculated_or)
187
0
    {
188
0
        return Formatter<StringView>::format(builder, calculated_or.to_string());
189
0
    }
190
};
191
192
template<>
193
struct AK::Formatter<Web::CSS::LengthOrCalculated> : Formatter<StringView> {
194
    ErrorOr<void> format(FormatBuilder& builder, Web::CSS::LengthOrCalculated const& calculated_or)
195
0
    {
196
0
        return Formatter<StringView>::format(builder, calculated_or.to_string());
197
0
    }
198
};
199
200
template<>
201
struct AK::Formatter<Web::CSS::PercentageOrCalculated> : Formatter<StringView> {
202
    ErrorOr<void> format(FormatBuilder& builder, Web::CSS::PercentageOrCalculated const& calculated_or)
203
0
    {
204
0
        return Formatter<StringView>::format(builder, calculated_or.to_string());
205
0
    }
206
};
207
208
template<>
209
struct AK::Formatter<Web::CSS::TimeOrCalculated> : Formatter<StringView> {
210
    ErrorOr<void> format(FormatBuilder& builder, Web::CSS::TimeOrCalculated const& calculated_or)
211
0
    {
212
0
        return Formatter<StringView>::format(builder, calculated_or.to_string());
213
0
    }
214
};