ladybird/Libraries/LibWeb/CSS/CountersSet.h
Sam Atkins a57595faf5 LibWeb: Make [resolve,inherit]_counters() take AbstractElement
This is one of those cases where the spec says "element" and
means "element or pseudo-element". The easiest way to handle both is to
make these be free functions that take an AbstractElement, and then
give AbstractElement some helper methods so that the caller doesn't
have to care which it's dealing with.

There are some FIXMEs here because PseudoElement doesn't have a
CountersSet yet, and because the CountersSet currently uses a
UniqueNodeID to identify counter sources, which doesn't support
pseudo-elements.
2025-06-19 12:35:31 +01:00

54 lines
1.8 KiB
C++

/*
* Copyright (c) 2024-2025, Sam Atkins <sam@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Checked.h>
#include <AK/FlyString.h>
#include <AK/Optional.h>
#include <LibWeb/Forward.h>
namespace Web::CSS {
// "UAs may have implementation-specific limits on the maximum or minimum value of a counter.
// If a counter reset, set, or increment would push the value outside of that range, the value
// must be clamped to that range." - https://drafts.csswg.org/css-lists-3/#auto-numbering
// So, we use a Checked<i32> and saturating addition/subtraction.
using CounterValue = Checked<i32>;
// https://drafts.csswg.org/css-lists-3/#counter
struct Counter {
FlyString name;
UniqueNodeID originating_element_id; // "creator"
bool reversed { false };
Optional<CounterValue> value;
};
// https://drafts.csswg.org/css-lists-3/#css-counters-set
class CountersSet {
public:
CountersSet() = default;
~CountersSet() = default;
Counter& instantiate_a_counter(FlyString name, UniqueNodeID originating_element_id, bool reversed, Optional<CounterValue>);
void set_a_counter(FlyString name, UniqueNodeID originating_element_id, CounterValue value);
void increment_a_counter(FlyString name, UniqueNodeID originating_element_id, CounterValue amount);
void append_copy(Counter const&);
Optional<Counter&> last_counter_with_name(FlyString const& name);
Optional<Counter&> counter_with_same_name_and_creator(FlyString const& name, UniqueNodeID originating_element_id);
Vector<Counter> const& counters() const { return m_counters; }
bool is_empty() const { return m_counters.is_empty(); }
private:
Vector<Counter> m_counters;
};
void resolve_counters(DOM::AbstractElement&);
void inherit_counters(DOM::AbstractElement&);
}