/* * Copyright (c) 2026, Callum Law . * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace Web::CSS { // https://drafts.csswg.org/css-counter-styles-3/#counter-styles class CounterStyle : public RefCounted { public: static NonnullRefPtr decimal(); static NonnullRefPtr disc(); static NonnullRefPtr from_counter_style_definition(CounterStyleDefinition const&, StyleScope const&); static NonnullRefPtr create(FlyString name, CounterStyleAlgorithm algorithm, CounterStyleNegativeSign negative_sign, FlyString prefix, FlyString suffix, Vector range, Optional fallback, CounterStylePad pad) { // NB: All counter styles apart from 'decimal' must have a fallback. VERIFY(fallback.has_value() || name == "decimal"_fly_string); return adopt_ref(*new (nothrow) CounterStyle(move(name), move(algorithm), move(negative_sign), move(prefix), move(suffix), move(range), move(fallback), move(pad))); } FlyString const& name() const { return m_name; } CounterStyleAlgorithm const& algorithm() const { return m_algorithm; } CounterStyleNegativeSign const& negative_sign() const { return m_negative_sign; } FlyString const& prefix() const { return m_prefix; } FlyString const& suffix() const { return m_suffix; } Vector const& range() const { return m_range; } Optional const& fallback() const { return m_fallback; } CounterStylePad const& pad() const { return m_pad; } Optional generate_an_initial_representation_for_the_counter_value(i64 value) const; bool uses_a_negative_sign() const; bool equals(CounterStyle const&) const; virtual ~CounterStyle() = default; private: CounterStyle(FlyString name, CounterStyleAlgorithm algorithm, CounterStyleNegativeSign negative_sign, FlyString prefix, FlyString suffix, Vector range, Optional fallback, CounterStylePad pad) : m_name(move(name)) , m_algorithm(move(algorithm)) , m_negative_sign(move(negative_sign)) , m_prefix(move(prefix)) , m_suffix(move(suffix)) , m_range(move(range)) , m_fallback(move(fallback)) , m_pad(move(pad)) { } // Counter styles are composed of: // a name, to identify the style FlyString m_name; // an algorithm, which transforms integer counter values into a basic string representation CounterStyleAlgorithm m_algorithm; // a negative sign, which is prepended or appended to the representation of a negative counter value. CounterStyleNegativeSign m_negative_sign; // a prefix, to prepend to the representation FlyString m_prefix; // a suffix to append to the representation FlyString m_suffix; // a range, which limits the values that a counter style handles Vector m_range; // FIXME: a spoken form, which describes how to read out the counter style in a speech synthesizer // and a fallback style, to render the representation with when the counter value is outside the counter style’s // range or the counter style otherwise can’t render the counter value Optional m_fallback; // AD-HOC: We store the `pad` descriptor here as well to have everything in one place CounterStylePad m_pad; }; String generate_a_counter_representation(RefPtr const& counter_style, StyleScope const& style_scope, i32 value); }