tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CounterStyleManager.h (6941B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 #ifndef mozilla_CounterStyleManager_h_
      7 #define mozilla_CounterStyleManager_h_
      8 
      9 #include "mozilla/Attributes.h"
     10 #include "nsGkAtoms.h"
     11 #include "nsHashKeys.h"
     12 #include "nsStringFwd.h"
     13 #include "nsStyleConsts.h"
     14 #include "nsTHashMap.h"
     15 
     16 class nsPresContext;
     17 
     18 namespace mozilla {
     19 
     20 enum class SpeakAs : uint8_t {
     21  Bullets = 0,
     22  Numbers = 1,
     23  Words = 2,
     24  Spellout = 3,
     25  Other = 255
     26 };
     27 
     28 class WritingMode;
     29 
     30 typedef int32_t CounterValue;
     31 
     32 class CounterStyleManager;
     33 class AnonymousCounterStyle;
     34 
     35 struct NegativeType;
     36 struct PadType;
     37 
     38 class CounterStyle {
     39 protected:
     40  explicit constexpr CounterStyle(ListStyle aStyle) : mStyle(aStyle) {}
     41 
     42 private:
     43  CounterStyle(const CounterStyle& aOther) = delete;
     44  void operator=(const CounterStyle& other) = delete;
     45 
     46 public:
     47  constexpr ListStyle GetStyle() const { return mStyle; }
     48  bool IsNone() const { return mStyle == ListStyle::None; }
     49  bool IsCustomStyle() const { return mStyle == ListStyle::Custom; }
     50  // A style is dependent if it depends on the counter style manager.
     51  // Custom styles are certainly dependent. In addition, some builtin
     52  // styles are dependent for fallback.
     53  bool IsDependentStyle() const;
     54 
     55  virtual void GetPrefix(nsAString& aResult) = 0;
     56  virtual void GetSuffix(nsAString& aResult) = 0;
     57  void GetCounterText(CounterValue aOrdinal, WritingMode aWritingMode,
     58                      nsAString& aResult, bool& aIsRTL);
     59  virtual void GetSpokenCounterText(CounterValue aOrdinal,
     60                                    WritingMode aWritingMode,
     61                                    nsAString& aResult, bool& aIsBullet);
     62 
     63  // XXX This method could be removed once ::-moz-list-bullet and
     64  //     ::-moz-list-number are completely merged into ::marker.
     65  virtual bool IsBullet() = 0;
     66 
     67  virtual void GetNegative(NegativeType& aResult) = 0;
     68  /**
     69   * This method returns whether an ordinal is in the range of this
     70   * counter style. Note that, it is possible that an ordinal in range
     71   * is rejected by the generating algorithm.
     72   */
     73  virtual bool IsOrdinalInRange(CounterValue aOrdinal) = 0;
     74  /**
     75   * This method returns whether an ordinal is in the default range of
     76   * this counter style. This is the effective range when no 'range'
     77   * descriptor is specified.
     78   */
     79  virtual bool IsOrdinalInAutoRange(CounterValue aOrdinal) = 0;
     80  virtual void GetPad(PadType& aResult) = 0;
     81  virtual CounterStyle* GetFallback() = 0;
     82  virtual SpeakAs GetSpeakAs() = 0;
     83  virtual bool UseNegativeSign() = 0;
     84 
     85  virtual void CallFallbackStyle(CounterValue aOrdinal,
     86                                 WritingMode aWritingMode, nsAString& aResult,
     87                                 bool& aIsRTL);
     88  virtual bool GetInitialCounterText(CounterValue aOrdinal,
     89                                     WritingMode aWritingMode,
     90                                     nsAString& aResult, bool& aIsRTL) = 0;
     91 
     92  virtual AnonymousCounterStyle* AsAnonymous() { return nullptr; }
     93 
     94 protected:
     95  const ListStyle mStyle;
     96 };
     97 
     98 class MOZ_STACK_CLASS AnonymousCounterStyle final : public CounterStyle {
     99 public:
    100  explicit AnonymousCounterStyle(const nsAString& aContent);
    101  AnonymousCounterStyle(StyleSymbolsType, Span<const StyleSymbol> aSymbols);
    102 
    103  void GetPrefix(nsAString& aResult) override;
    104  void GetSuffix(nsAString& aResult) override;
    105  bool IsBullet() override;
    106 
    107  void GetNegative(NegativeType& aResult) override;
    108  bool IsOrdinalInRange(CounterValue aOrdinal) override;
    109  bool IsOrdinalInAutoRange(CounterValue aOrdinal) override;
    110  void GetPad(PadType& aResult) override;
    111  CounterStyle* GetFallback() override;
    112  SpeakAs GetSpeakAs() override;
    113  bool UseNegativeSign() override;
    114 
    115  bool GetInitialCounterText(CounterValue aOrdinal, WritingMode aWritingMode,
    116                             nsAString& aResult, bool& aIsRTL) override;
    117 
    118  AnonymousCounterStyle* AsAnonymous() override { return this; }
    119 
    120  auto GetSymbols() const { return mSymbols; }
    121 
    122  StyleCounterSystem GetSystem() const;
    123 
    124  ~AnonymousCounterStyle() = default;
    125 
    126  StyleSymbolsType mSymbolsType;
    127  Span<const StyleSymbol> mSymbols;
    128 };
    129 
    130 class CounterStyleManager final {
    131 private:
    132  ~CounterStyleManager();
    133 
    134 public:
    135  explicit CounterStyleManager(nsPresContext* aPresContext);
    136 
    137  void Disconnect();
    138 
    139  bool IsInitial() const {
    140    // only 'none', 'decimal', and 'disc'
    141    return mStyles.Count() == 3;
    142  }
    143 
    144  // Returns the counter style object for the given name from the style
    145  // table if it is already built, and nullptr otherwise.
    146  CounterStyle* GetCounterStyle(nsAtom* aName) const {
    147    return mStyles.Get(aName);
    148  }
    149  // Same as GetCounterStyle but try to build the counter style object
    150  // rather than returning nullptr if that hasn't been built.
    151  CounterStyle* ResolveCounterStyle(nsAtom* aName);
    152  template <typename F>
    153  void WithCounterStyleNameOrSymbols(const StyleCounterStyle& aStyle,
    154                                     F&& aCallback) {
    155    using Tag = StyleCounterStyle::Tag;
    156    switch (aStyle.tag) {
    157      case Tag::None:
    158      case Tag::String:
    159        MOZ_CRASH("Unexpected counter style");
    160      case Tag::Symbols: {
    161        AnonymousCounterStyle s(aStyle.AsSymbols().ty,
    162                                aStyle.AsSymbols().symbols._0.AsSpan());
    163        return aCallback(&s);
    164      }
    165      case Tag::Name: {
    166        return aCallback(ResolveCounterStyle(aStyle.AsName().AsAtom()));
    167      }
    168    }
    169  }
    170 
    171  static CounterStyle* GetBuiltinStyle(ListStyle aStyle);
    172  static CounterStyle* GetNoneStyle() {
    173    return GetBuiltinStyle(ListStyle::None);
    174  }
    175  static CounterStyle* GetDecimalStyle() {
    176    return GetBuiltinStyle(ListStyle::Decimal);
    177  }
    178  static CounterStyle* GetDiscStyle() {
    179    return GetBuiltinStyle(ListStyle::Disc);
    180  }
    181 
    182  // This method will scan all existing counter styles generated by this
    183  // manager, and remove or mark data dirty accordingly. It returns true
    184  // if any counter style is changed, false elsewise. This method should
    185  // be called when any counter style may be affected.
    186  bool NotifyRuleChanged();
    187  // NotifyRuleChanged will evict no longer needed counter styles into
    188  // mRetiredStyles, and this function destroys all objects listed there.
    189  // It should be called only after no one may ever use those objects.
    190  void CleanRetiredStyles();
    191 
    192  nsPresContext* PresContext() const { return mPresContext; }
    193 
    194  NS_INLINE_DECL_REFCOUNTING(CounterStyleManager)
    195 
    196 private:
    197  void DestroyCounterStyle(CounterStyle* aCounterStyle);
    198 
    199  nsPresContext* mPresContext;
    200  nsTHashMap<RefPtr<nsAtom>, CounterStyle*> mStyles;
    201  nsTArray<CounterStyle*> mRetiredStyles;
    202 };
    203 
    204 }  // namespace mozilla
    205 
    206 #endif /* !defined(mozilla_CounterStyleManager_h_) */