2026-02-05 06:37:32 -03:00
|
|
|
|
/*
|
|
|
|
|
|
* Copyright (c) 2026, Callum Law <callumlaw1709@outlook.com>
|
|
|
|
|
|
*
|
|
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
#include <LibWeb/CSS/StyleValues/CounterStyleSystemStyleValue.h>
|
|
|
|
|
|
|
|
|
|
|
|
namespace Web::CSS {
|
|
|
|
|
|
|
|
|
|
|
|
struct CounterStyleRangeEntry {
|
2026-03-26 05:33:07 -03:00
|
|
|
|
i32 start;
|
|
|
|
|
|
i32 end;
|
2026-04-07 01:18:17 -03:00
|
|
|
|
|
|
|
|
|
|
bool operator==(CounterStyleRangeEntry const&) const = default;
|
2026-02-05 06:37:32 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// https://drafts.csswg.org/css-counter-styles-3/#counter-style-symbols
|
|
|
|
|
|
// <symbol> = <string> | <image> | <custom-ident>
|
|
|
|
|
|
// Note: The <image> syntax in <symbol> is currently at-risk. No implementations have plans to implement it currently,
|
|
|
|
|
|
// and it complicates some usages of counter() in ways that haven’t been fully handled.
|
|
|
|
|
|
// FIXME: Given the above note we don't currently support <image> here - we may need to revisit this if other browsers
|
|
|
|
|
|
// implement it.
|
|
|
|
|
|
using CounterStyleSymbol = FlyString;
|
|
|
|
|
|
|
|
|
|
|
|
struct CounterStyleNegativeSign {
|
|
|
|
|
|
CounterStyleSymbol prefix;
|
|
|
|
|
|
CounterStyleSymbol suffix;
|
2026-04-07 01:18:17 -03:00
|
|
|
|
|
|
|
|
|
|
bool operator==(CounterStyleNegativeSign const&) const = default;
|
2026-02-05 06:37:32 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct CounterStylePad {
|
|
|
|
|
|
i32 minimum_length;
|
|
|
|
|
|
CounterStyleSymbol symbol;
|
2026-04-07 01:18:17 -03:00
|
|
|
|
|
|
|
|
|
|
bool operator==(CounterStylePad const&) const = default;
|
2026-02-05 06:37:32 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct AdditiveCounterStyleAlgorithm {
|
|
|
|
|
|
struct AdditiveTuple {
|
|
|
|
|
|
i32 weight;
|
|
|
|
|
|
CounterStyleSymbol symbol;
|
2026-04-07 01:18:17 -03:00
|
|
|
|
|
|
|
|
|
|
bool operator==(AdditiveTuple const&) const = default;
|
2026-02-05 06:37:32 -03:00
|
|
|
|
};
|
|
|
|
|
|
Vector<AdditiveTuple> symbol_list;
|
2026-04-07 01:18:17 -03:00
|
|
|
|
|
|
|
|
|
|
bool operator==(AdditiveCounterStyleAlgorithm const&) const = default;
|
2026-02-05 06:37:32 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct FixedCounterStyleAlgorithm {
|
2026-03-26 05:33:07 -03:00
|
|
|
|
i32 first_symbol;
|
2026-02-05 06:37:32 -03:00
|
|
|
|
Vector<CounterStyleSymbol> symbol_list;
|
2026-04-07 01:18:17 -03:00
|
|
|
|
|
|
|
|
|
|
bool operator==(FixedCounterStyleAlgorithm const&) const = default;
|
2026-02-05 06:37:32 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct GenericCounterStyleAlgorithm {
|
|
|
|
|
|
CounterStyleSystem type;
|
|
|
|
|
|
Vector<CounterStyleSymbol> symbol_list;
|
2026-04-07 01:18:17 -03:00
|
|
|
|
|
|
|
|
|
|
bool operator==(GenericCounterStyleAlgorithm const&) const = default;
|
2026-02-05 06:37:32 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
2026-04-07 01:18:17 -03:00
|
|
|
|
struct EthiopicNumericCounterStyleAlgorithm {
|
|
|
|
|
|
bool operator==(EthiopicNumericCounterStyleAlgorithm const&) const = default;
|
|
|
|
|
|
};
|
2026-02-24 06:26:07 -03:00
|
|
|
|
|
2026-02-25 19:57:54 -03:00
|
|
|
|
struct ExtendedCJKCounterStyleAlgorithm {
|
|
|
|
|
|
enum class Type : u8 {
|
|
|
|
|
|
SimpChineseInformal,
|
|
|
|
|
|
SimpChineseFormal,
|
|
|
|
|
|
TradChineseInformal,
|
|
|
|
|
|
TradChineseFormal,
|
2026-02-25 21:05:29 -03:00
|
|
|
|
JapaneseInformal,
|
2026-02-25 23:25:33 -03:00
|
|
|
|
JapaneseFormal,
|
|
|
|
|
|
KoreanHangulFormal,
|
|
|
|
|
|
KoreanHanjaInformal,
|
|
|
|
|
|
KoreanHanjaFormal,
|
2026-02-25 19:57:54 -03:00
|
|
|
|
} type;
|
2026-04-07 01:18:17 -03:00
|
|
|
|
|
|
|
|
|
|
bool operator==(ExtendedCJKCounterStyleAlgorithm const&) const = default;
|
2026-02-25 19:57:54 -03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
using CounterStyleAlgorithm = Variant<AdditiveCounterStyleAlgorithm, FixedCounterStyleAlgorithm, GenericCounterStyleAlgorithm, EthiopicNumericCounterStyleAlgorithm, ExtendedCJKCounterStyleAlgorithm>;
|
2026-02-23 18:11:05 -03:00
|
|
|
|
using CounterStyleAlgorithmOrExtends = Variant<CounterStyleAlgorithm, CounterStyleSystemStyleValue::Extends>;
|
2026-02-05 06:37:32 -03:00
|
|
|
|
|
|
|
|
|
|
struct AutoRange {
|
|
|
|
|
|
static Vector<CounterStyleRangeEntry> resolve(CounterStyleAlgorithm const&);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class CounterStyleDefinition {
|
|
|
|
|
|
public:
|
2026-02-23 18:11:05 -03:00
|
|
|
|
static CounterStyleDefinition create(FlyString name, CounterStyleAlgorithmOrExtends algorithm, Optional<CounterStyleNegativeSign> negative_sign, Optional<CounterStyleSymbol> prefix, Optional<CounterStyleSymbol> suffix, Variant<Empty, AutoRange, Vector<CounterStyleRangeEntry>> range, Optional<FlyString> fallback, Optional<CounterStylePad> pad)
|
2026-02-05 06:37:32 -03:00
|
|
|
|
{
|
|
|
|
|
|
return CounterStyleDefinition(move(name), move(algorithm), move(negative_sign), move(prefix), move(suffix), move(range), move(fallback), move(pad));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Optional<CounterStyleDefinition> from_counter_style_rule(CSSCounterStyleRule const&, ComputationContext const&);
|
|
|
|
|
|
|
|
|
|
|
|
FlyString const& name() const { return m_name; }
|
|
|
|
|
|
|
2026-02-23 18:11:05 -03:00
|
|
|
|
CounterStyleAlgorithmOrExtends const& algorithm() const { return m_algorithm; }
|
|
|
|
|
|
void set_algorithm(CounterStyleAlgorithmOrExtends algorithm) { m_algorithm = move(algorithm); }
|
2026-02-05 06:37:32 -03:00
|
|
|
|
|
|
|
|
|
|
Optional<CounterStyleNegativeSign> const& negative_sign() const { return m_negative_sign; }
|
|
|
|
|
|
|
|
|
|
|
|
Optional<CounterStyleSymbol> const& prefix() const { return m_prefix; }
|
|
|
|
|
|
|
|
|
|
|
|
Optional<CounterStyleSymbol> const& suffix() const { return m_suffix; }
|
|
|
|
|
|
|
|
|
|
|
|
Variant<Empty, AutoRange, Vector<CounterStyleRangeEntry>> const& range() const { return m_range; }
|
|
|
|
|
|
|
|
|
|
|
|
Optional<FlyString> const& fallback() const { return m_fallback; }
|
|
|
|
|
|
|
|
|
|
|
|
Optional<CounterStylePad> const& pad() const { return m_pad; }
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
static Variant<Empty, CounterStyleAlgorithm, CounterStyleSystemStyleValue::Extends> resolve_algorithm(NonnullRefPtr<StyleValue const> const& system_style_value, RefPtr<StyleValue const> const& symbols_style_value, RefPtr<StyleValue const> const& additive_symbols_style_value, ComputationContext const&);
|
|
|
|
|
|
static Vector<CounterStyleSymbol> resolve_symbols(NonnullRefPtr<StyleValue const> const& symbols_style_value);
|
|
|
|
|
|
static Vector<AdditiveCounterStyleAlgorithm::AdditiveTuple> resolve_additive_symbols(NonnullRefPtr<StyleValue const> const& additive_symbols_style_value, ComputationContext const&);
|
|
|
|
|
|
static CounterStyleNegativeSign resolve_negative_sign(NonnullRefPtr<StyleValue const> const&);
|
|
|
|
|
|
static Variant<AutoRange, Vector<CounterStyleRangeEntry>> resolve_range(NonnullRefPtr<StyleValue const> const&, ComputationContext const&);
|
|
|
|
|
|
static CounterStylePad resolve_pad(NonnullRefPtr<StyleValue const> const&, ComputationContext const&);
|
|
|
|
|
|
|
2026-02-23 18:11:05 -03:00
|
|
|
|
CounterStyleDefinition(FlyString name, CounterStyleAlgorithmOrExtends algorithm, Optional<CounterStyleNegativeSign> negative_sign, Optional<CounterStyleSymbol> prefix, Optional<CounterStyleSymbol> suffix, Variant<Empty, AutoRange, Vector<CounterStyleRangeEntry>> range, Optional<FlyString> fallback, Optional<CounterStylePad> pad)
|
2026-02-05 06:37:32 -03:00
|
|
|
|
: 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))
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FlyString m_name;
|
2026-02-23 18:11:05 -03:00
|
|
|
|
CounterStyleAlgorithmOrExtends m_algorithm;
|
2026-02-05 06:37:32 -03:00
|
|
|
|
Optional<CounterStyleNegativeSign> m_negative_sign;
|
|
|
|
|
|
Optional<CounterStyleSymbol> m_prefix;
|
|
|
|
|
|
Optional<CounterStyleSymbol> m_suffix;
|
|
|
|
|
|
Variant<Empty, AutoRange, Vector<CounterStyleRangeEntry>> m_range;
|
|
|
|
|
|
Optional<FlyString> m_fallback;
|
|
|
|
|
|
Optional<CounterStylePad> m_pad;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
}
|