| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_COUNTER_STYLE_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_COUNTER_STYLE_H_ |
| |
| #include "third_party/blink/renderer/core/core_export.h" |
| #include "third_party/blink/renderer/platform/heap/handle.h" |
| #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" |
| |
| namespace blink { |
| |
| class StyleRuleCounterStyle; |
| class CSSValue; |
| |
| enum class CounterStyleSystem { |
| kCyclic, |
| kFixed, |
| kSymbolic, |
| kAlphabetic, |
| kNumeric, |
| kAdditive, |
| kHebrew, |
| kSimpChineseInformal, |
| kSimpChineseFormal, |
| kTradChineseInformal, |
| kTradChineseFormal, |
| kKoreanHangulFormal, |
| kKoreanHanjaInformal, |
| kKoreanHanjaFormal, |
| kLowerArmenian, |
| kUpperArmenian, |
| kEthiopicNumeric, |
| kUnresolvedExtends, |
| }; |
| |
| // Represents a valid counter style defined in a tree scope. |
| class CORE_EXPORT CounterStyle final : public GarbageCollected<CounterStyle> { |
| public: |
| static CounterStyle& GetDecimal(); |
| |
| static CounterStyleSystem ToCounterStyleSystemEnum(const CSSValue* value); |
| |
| // Returns nullptr if the @counter-style rule is invalid. |
| static CounterStyle* Create(const StyleRuleCounterStyle&); |
| |
| const StyleRuleCounterStyle& GetStyleRule() const { return *style_rule_; } |
| |
| AtomicString GetName() const; |
| CounterStyleSystem GetSystem() const { return system_; } |
| |
| bool IsPredefined() const { return is_predefined_; } |
| void SetIsPredefined() { is_predefined_ = true; } |
| |
| // Returns true for the predefined symbolic counter styles 'disc', 'circle', |
| // 'square', 'disclosure-open' and 'disclosure-closed'. |
| bool IsPredefinedSymbolMarker() const { return is_predefined_symbol_marker_; } |
| void SetIsPredefinedSymbolMarker() { is_predefined_symbol_marker_ = true; } |
| |
| // A CounterStyle object is dirtied when the information it holds becomes |
| // stale, e.g., when the style rule mutated or the 'extends' or 'fallback' |
| // counter styles mutated, etc. Once dirtied, it will never be reused, and |
| // will be removed or replaced by a newly created clean CounterStyle. |
| // Elements using dirty CounterStyles should update style and layout. |
| bool IsDirty() const { return is_dirty_; } |
| void SetIsDirty() { is_dirty_ = true; } |
| |
| void TraverseAndMarkDirtyIfNeeded(HeapHashSet<Member<CounterStyle>>& visited); |
| |
| // Set to true when there's no counter style matching 'extends' or 'fallback', |
| // and therefore we are resorting to 'decimal'. |
| void SetHasInexistentReferences() { has_inexistent_references_ = true; } |
| |
| // https://drafts.csswg.org/css-counter-styles/#generate-a-counter |
| String GenerateRepresentation(int value) const; |
| |
| String GetPrefix() const { return prefix_; } |
| String GetSuffix() const { return suffix_; } |
| |
| AtomicString GetExtendsName() const { return extends_name_; } |
| const CounterStyle& GetExtendedStyle() const { return *extended_style_; } |
| bool HasUnresolvedExtends() const { |
| return system_ == CounterStyleSystem::kUnresolvedExtends; |
| } |
| void ResolveExtends(CounterStyle& extended); |
| |
| AtomicString GetFallbackName() const { return fallback_name_; } |
| const CounterStyle& GetFallbackStyle() const { return *fallback_style_; } |
| bool HasUnresolvedFallback() const { return !fallback_style_; } |
| void ResolveFallback(CounterStyle& fallback) { fallback_style_ = &fallback; } |
| |
| void Trace(Visitor*) const; |
| |
| explicit CounterStyle(const StyleRuleCounterStyle& rule); |
| ~CounterStyle(); |
| |
| private: |
| // https://drafts.csswg.org/css-counter-styles/#counter-style-range |
| bool RangeContains(int value) const; |
| |
| // Returns true if a negative sign is needed for the value. |
| // https://drafts.csswg.org/css-counter-styles/#counter-style-negative |
| bool NeedsNegativeSign(int value) const; |
| |
| // https://drafts.csswg.org/css-counter-styles/#initial-representation-for-the-counter-value |
| // Returns nullptr if the counter value cannot be represented with the given |
| // 'system', 'range' and 'symbols'/'additive-symbols' descriptor values. |
| String GenerateInitialRepresentation(int value) const; |
| |
| // Uses the fallback counter style to generate a representation for the value. |
| // It may recurse, and if it enters a loop, it uses 'decimal' instead. |
| String GenerateFallbackRepresentation(int value) const; |
| |
| String IndexesToString(const Vector<wtf_size_t>& symbol_indexes) const; |
| |
| // The corresponding style rule in CSS. |
| Member<const StyleRuleCounterStyle> style_rule_; |
| |
| // Tracks mutations of |style_rule_|. |
| int style_rule_version_; |
| |
| // The actual system of the counter style with 'extends' resolved. The value |
| // is kUnresolvedExtends temporarily before the resolution. |
| CounterStyleSystem system_ = CounterStyleSystem::kSymbolic; |
| |
| AtomicString extends_name_; |
| Member<CounterStyle> extended_style_; |
| |
| AtomicString fallback_name_ = "decimal"; |
| Member<CounterStyle> fallback_style_; |
| |
| // True if we are looking for a fallback counter style to generate a counter |
| // value. Supports cycle detection in fallback. |
| mutable bool is_in_fallback_ = false; |
| |
| // Value of 'symbols' for non-additive systems; Or symbol values in |
| // 'additive-symbols' for the 'additive' system. |
| Vector<String> symbols_; |
| |
| // Additive weights, for the 'additive' system only. |
| Vector<unsigned> additive_weights_; |
| |
| // Value of 'range' descriptor. Empty vector means 'auto'. |
| Vector<std::pair<int, int>> range_; |
| |
| String prefix_; |
| String suffix_ = ". "; |
| |
| String negative_prefix_ = "-"; |
| String negative_suffix_; |
| |
| String pad_symbol_; |
| wtf_size_t pad_length_ = 0; |
| |
| // First symbol value, for 'fixed' system only. |
| wtf_size_t first_symbol_value_ = 1; |
| |
| bool is_predefined_ = false; |
| bool is_predefined_symbol_marker_ = false; |
| bool has_inexistent_references_ = false; |
| bool is_dirty_ = false; |
| |
| friend class CounterStyleMapTest; |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_COUNTER_STYLE_H_ |