ladybird/Libraries/LibWeb/CSS/StyleValues/CSSKeywordValue.h
Callum Law 6a9c8d7767 LibWeb: Don't resolve colors with unresolved components
`CSSColorValue`s which have unresolved `calc` components should be able
to be resolved. Previously we would always resolve them but with
incorrect values.

This is useful as we will now be able to now whether we should serialize
colors in their normalized form or not.

Slight regression in that we now serialize (RGB, HSL and HWB) colors
with components that rely on compute-time information as an empty
string, but that will be fixed in the next commit.
2025-07-16 13:05:33 +01:00

76 lines
2.9 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
* Copyright (c) 2021-2024, Sam Atkins <sam@ladybird.org>
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/CSS/CSSStyleValue.h>
#include <LibWeb/CSS/Keyword.h>
namespace Web::CSS {
// https://drafts.css-houdini.org/css-typed-om-1/#csskeywordvalue
class CSSKeywordValue : public StyleValueWithDefaultOperators<CSSKeywordValue> {
public:
static ValueComparingNonnullRefPtr<CSSKeywordValue const> create(Keyword keyword)
{
// NOTE: We'll have to be much more careful with caching once we expose CSSKeywordValue to JS, as it's mutable.
switch (keyword) {
case Keyword::Inherit: {
static ValueComparingNonnullRefPtr<CSSKeywordValue const> const inherit_instance = adopt_ref(*new (nothrow) CSSKeywordValue(Keyword::Inherit));
return inherit_instance;
}
case Keyword::Initial: {
static ValueComparingNonnullRefPtr<CSSKeywordValue const> const initial_instance = adopt_ref(*new (nothrow) CSSKeywordValue(Keyword::Initial));
return initial_instance;
}
case Keyword::Revert: {
static ValueComparingNonnullRefPtr<CSSKeywordValue const> const revert_instance = adopt_ref(*new (nothrow) CSSKeywordValue(Keyword::Revert));
return revert_instance;
}
case Keyword::RevertLayer: {
static ValueComparingNonnullRefPtr<CSSKeywordValue const> const revert_layer_instance = adopt_ref(*new (nothrow) CSSKeywordValue(Keyword::RevertLayer));
return revert_layer_instance;
}
case Keyword::Unset: {
static ValueComparingNonnullRefPtr<CSSKeywordValue const> const unset_instance = adopt_ref(*new (nothrow) CSSKeywordValue(Keyword::Unset));
return unset_instance;
}
default:
return adopt_ref(*new (nothrow) CSSKeywordValue(keyword));
}
}
virtual ~CSSKeywordValue() override = default;
Keyword keyword() const { return m_keyword; }
static bool is_color(Keyword);
virtual bool has_color() const override;
virtual Optional<Color> to_color(Optional<Layout::NodeWithStyle const&> node, CalculationResolutionContext const&) const override;
virtual String to_string(SerializationMode) const override;
bool properties_equal(CSSKeywordValue const& other) const { return m_keyword == other.m_keyword; }
private:
explicit CSSKeywordValue(Keyword keyword)
: StyleValueWithDefaultOperators(Type::Keyword)
, m_keyword(keyword)
{
}
Keyword m_keyword { Keyword::Invalid };
};
inline Keyword CSSStyleValue::to_keyword() const
{
if (is_keyword())
return static_cast<CSSKeywordValue const&>(*this).keyword();
return Keyword::Invalid;
}
}