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 "nsStringFwd.h"
10 #include "nsRefPtrHashtable.h"
11 #include "nsHashKeys.h"
12 
13 #include "nsStyleConsts.h"
14 
15 #include "mozilla/Attributes.h"
16 
17 #include "nsCSSValue.h"
18 
19 class nsPresContext;
20 
21 namespace mozilla {
22 
23 class WritingMode;
24 
25 typedef int32_t CounterValue;
26 
27 class CounterStyleManager;
28 class AnonymousCounterStyle;
29 
30 struct NegativeType;
31 struct PadType;
32 
33 class CounterStyle
34 {
35 protected:
CounterStyle(int32_t aStyle)36   explicit constexpr CounterStyle(int32_t aStyle)
37     : mStyle(aStyle)
38   {
39   }
40 
41 private:
42   CounterStyle(const CounterStyle& aOther) = delete;
43   void operator=(const CounterStyle& other) = delete;
44 
45 public:
GetStyle()46   int32_t GetStyle() const { return mStyle; }
IsNone()47   bool IsNone() const { return mStyle == NS_STYLE_LIST_STYLE_NONE; }
IsCustomStyle()48   bool IsCustomStyle() const { return mStyle == NS_STYLE_LIST_STYLE_CUSTOM; }
49   // A style is dependent if it depends on the counter style manager.
50   // Custom styles are certainly dependent. In addition, some builtin
51   // styles are dependent for fallback.
52   bool IsDependentStyle() const;
53 
54   virtual void GetStyleName(nsSubstring& aResult) = 0;
55   virtual void GetPrefix(nsSubstring& aResult) = 0;
56   virtual void GetSuffix(nsSubstring& aResult) = 0;
57   void GetCounterText(CounterValue aOrdinal,
58                       WritingMode aWritingMode,
59                       nsSubstring& aResult,
60                       bool& aIsRTL);
61   virtual void GetSpokenCounterText(CounterValue aOrdinal,
62                                     WritingMode aWritingMode,
63                                     nsSubstring& aResult,
64                                     bool& aIsBullet);
65 
66   // XXX This method could be removed once ::-moz-list-bullet and
67   //     ::-moz-list-number are completely merged into ::marker.
68   virtual bool IsBullet() = 0;
69 
70   virtual void GetNegative(NegativeType& aResult) = 0;
71   /**
72    * This method returns whether an ordinal is in the range of this
73    * counter style. Note that, it is possible that an ordinal in range
74    * is rejected by the generating algorithm.
75    */
76   virtual bool IsOrdinalInRange(CounterValue aOrdinal) = 0;
77   /**
78    * This method returns whether an ordinal is in the default range of
79    * this counter style. This is the effective range when no 'range'
80    * descriptor is specified.
81    */
82   virtual bool IsOrdinalInAutoRange(CounterValue aOrdinal) = 0;
83   virtual void GetPad(PadType& aResult) = 0;
84   virtual CounterStyle* GetFallback() = 0;
85   virtual uint8_t GetSpeakAs() = 0;
86   virtual bool UseNegativeSign() = 0;
87 
88   virtual void CallFallbackStyle(CounterValue aOrdinal,
89                                  WritingMode aWritingMode,
90                                  nsSubstring& aResult,
91                                  bool& aIsRTL);
92   virtual bool GetInitialCounterText(CounterValue aOrdinal,
93                                      WritingMode aWritingMode,
94                                      nsSubstring& aResult,
95                                      bool& aIsRTL) = 0;
96 
AsAnonymous()97   virtual AnonymousCounterStyle* AsAnonymous() { return nullptr; }
98 
99   NS_IMETHOD_(MozExternalRefCountType) AddRef() = 0;
100   NS_IMETHOD_(MozExternalRefCountType) Release() = 0;
101 
102 protected:
103   int32_t mStyle;
104 };
105 
106 class AnonymousCounterStyle final : public CounterStyle
107 {
108 public:
109   explicit AnonymousCounterStyle(const nsSubstring& aContent);
110   explicit AnonymousCounterStyle(const nsCSSValue::Array* aValue);
111 
112   virtual void GetStyleName(nsAString& aResult) override;
113   virtual void GetPrefix(nsAString& aResult) override;
114   virtual void GetSuffix(nsAString& aResult) override;
115   virtual bool IsBullet() override;
116 
117   virtual void GetNegative(NegativeType& aResult) override;
118   virtual bool IsOrdinalInRange(CounterValue aOrdinal) override;
119   virtual bool IsOrdinalInAutoRange(CounterValue aOrdinal) override;
120   virtual void GetPad(PadType& aResult) override;
121   virtual CounterStyle* GetFallback() override;
122   virtual uint8_t GetSpeakAs() override;
123   virtual bool UseNegativeSign() override;
124 
125   virtual bool GetInitialCounterText(CounterValue aOrdinal,
126                                      WritingMode aWritingMode,
127                                      nsSubstring& aResult,
128                                      bool& aIsRTL) override;
129 
AsAnonymous()130   virtual AnonymousCounterStyle* AsAnonymous() override { return this; }
131 
IsSingleString()132   bool IsSingleString() const { return mSingleString; }
GetSystem()133   uint8_t GetSystem() const { return mSystem; }
GetSymbols()134   const nsTArray<nsString>& GetSymbols() const { return mSymbols; }
135 
NS_INLINE_DECL_REFCOUNTING(AnonymousCounterStyle,override)136   NS_INLINE_DECL_REFCOUNTING(AnonymousCounterStyle, override)
137 
138 private:
139   ~AnonymousCounterStyle() {}
140 
141   bool mSingleString;
142   uint8_t mSystem;
143   nsTArray<nsString> mSymbols;
144 };
145 
146 class CounterStyleManager final
147 {
148 private:
149   ~CounterStyleManager();
150 public:
151   explicit CounterStyleManager(nsPresContext* aPresContext);
152 
153   static void InitializeBuiltinCounterStyles();
154 
155   void Disconnect();
156 
IsInitial()157   bool IsInitial() const
158   {
159     // only 'none' and 'decimal'
160     return mCacheTable.Count() == 2;
161   }
162 
163   CounterStyle* BuildCounterStyle(const nsSubstring& aName);
164 
165   static CounterStyle* GetBuiltinStyle(int32_t aStyle);
GetNoneStyle()166   static CounterStyle* GetNoneStyle()
167   {
168     return GetBuiltinStyle(NS_STYLE_LIST_STYLE_NONE);
169   }
GetDecimalStyle()170   static CounterStyle* GetDecimalStyle()
171   {
172     return GetBuiltinStyle(NS_STYLE_LIST_STYLE_DECIMAL);
173   }
174 
175   // This method will scan all existing counter styles generated by this
176   // manager, and remove or mark data dirty accordingly. It returns true
177   // if any counter style is changed, false elsewise. This method should
178   // be called when any counter style may be affected.
179   bool NotifyRuleChanged();
180 
PresContext()181   nsPresContext* PresContext() const { return mPresContext; }
182 
183   NS_INLINE_DECL_REFCOUNTING(CounterStyleManager)
184 
185 private:
186   nsPresContext* mPresContext;
187   nsRefPtrHashtable<nsStringHashKey, CounterStyle> mCacheTable;
188 };
189 
190 } // namespace mozilla
191 
192 #endif /* !defined(mozilla_CounterStyleManager_h_) */
193