1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef nsTextAttrs_h_
7 #define nsTextAttrs_h_
8 
9 #include "nsCOMPtr.h"
10 #include "nsColor.h"
11 #include "nsStyleConsts.h"
12 
13 class nsIFrame;
14 class nsIPersistentProperties;
15 class nsIContent;
16 class nsDeviceContext;
17 
18 namespace mozilla {
19 namespace a11y {
20 
21 class Accessible;
22 class HyperTextAccessible;
23 
24 /**
25  * Used to expose text attributes for the hyper text accessible (see
26  * HyperTextAccessible class).
27  *
28  * @note "invalid: spelling" text attribute is implemented entirely in
29  *       HyperTextAccessible class.
30  */
31 class TextAttrsMgr
32 {
33 public:
34   /**
35    * Constructor. Used to expose default text attributes.
36    */
TextAttrsMgr(HyperTextAccessible * aHyperTextAcc)37   explicit TextAttrsMgr(HyperTextAccessible* aHyperTextAcc) :
38     mOffsetAcc(nullptr),  mHyperTextAcc(aHyperTextAcc),
39     mOffsetAccIdx(-1), mIncludeDefAttrs(true) { }
40 
41   /**
42    * Constructor. Used to expose text attributes at the given offset.
43    *
44    * @param aHyperTextAcc    [in] hyper text accessible text attributes are
45    *                          calculated for
46    * @param aIncludeDefAttrs [optional] indicates whether default text
47    *                          attributes should be included into list of exposed
48    *                          text attributes
49    * @param oOffsetAcc       [optional] offset an accessible the text attributes
50    *                          should be calculated for
51    * @param oOffsetAccIdx    [optional] index in parent of offset accessible
52    */
TextAttrsMgr(HyperTextAccessible * aHyperTextAcc,bool aIncludeDefAttrs,Accessible * aOffsetAcc,int32_t aOffsetAccIdx)53   TextAttrsMgr(HyperTextAccessible* aHyperTextAcc,
54                bool aIncludeDefAttrs,
55                Accessible* aOffsetAcc,
56                int32_t aOffsetAccIdx) :
57     mOffsetAcc(aOffsetAcc), mHyperTextAcc(aHyperTextAcc),
58     mOffsetAccIdx(aOffsetAccIdx), mIncludeDefAttrs(aIncludeDefAttrs) { }
59 
60   /*
61    * Return text attributes and hyper text offsets where these attributes are
62    * applied. Offsets are calculated in the case of non default attributes.
63    *
64    * @note In the case of default attributes pointers on hyper text offsets
65    *       must be skipped.
66    *
67    * @param aAttributes    [in, out] text attributes list
68    * @param aStartHTOffset [out, optional] start hyper text offset
69    * @param aEndHTOffset   [out, optional] end hyper text offset
70    */
71   void GetAttributes(nsIPersistentProperties* aAttributes,
72                      uint32_t* aStartHTOffset = nullptr,
73                      uint32_t* aEndHTOffset = nullptr);
74 
75 protected:
76   /**
77    * Calculates range (start and end offsets) of text where the text attributes
78    * are stretched. New offsets may be smaller if one of text attributes changes
79    * its value before or after the given offsets.
80    *
81    * @param aTextAttrArray  [in] text attributes array
82    * @param aAttrArrayLen   [in] text attributes array length
83    * @param aStartHTOffset  [in, out] the start offset
84    * @param aEndHTOffset    [in, out] the end offset
85    */
86   class TextAttr;
87   void GetRange(TextAttr* aAttrArray[], uint32_t aAttrArrayLen,
88                 uint32_t* aStartOffset, uint32_t* aEndOffset);
89 
90 private:
91   Accessible* mOffsetAcc;
92   HyperTextAccessible* mHyperTextAcc;
93   int32_t mOffsetAccIdx;
94   bool mIncludeDefAttrs;
95 
96 protected:
97 
98   /**
99    * Interface class of text attribute class implementations.
100    */
101   class TextAttr
102   {
103   public:
104     /**
105      * Expose the text attribute to the given attribute set.
106      *
107      * @param aAttributes           [in] the given attribute set
108      * @param aIncludeDefAttrValue  [in] if true then attribute is exposed even
109      *                               if its value is the same as default one
110      */
111     virtual void Expose(nsIPersistentProperties* aAttributes,
112                         bool aIncludeDefAttrValue) = 0;
113 
114     /**
115      * Return true if the text attribute value on the given element equals with
116      * predefined attribute value.
117      */
118     virtual bool Equal(Accessible* aAccessible) = 0;
119   };
120 
121 
122   /**
123    * Base class to work with text attributes. See derived classes below.
124    */
125   template<class T>
126   class TTextAttr : public TextAttr
127   {
128   public:
TTextAttr(bool aGetRootValue)129     explicit TTextAttr(bool aGetRootValue) : mGetRootValue(aGetRootValue) {}
130 
131     // TextAttr
Expose(nsIPersistentProperties * aAttributes,bool aIncludeDefAttrValue)132     virtual void Expose(nsIPersistentProperties* aAttributes,
133                         bool aIncludeDefAttrValue) override
134     {
135       if (mGetRootValue) {
136         if (mIsRootDefined)
137           ExposeValue(aAttributes, mRootNativeValue);
138         return;
139       }
140 
141       if (mIsDefined) {
142         if (aIncludeDefAttrValue || mRootNativeValue != mNativeValue)
143           ExposeValue(aAttributes, mNativeValue);
144         return;
145       }
146 
147       if (aIncludeDefAttrValue && mIsRootDefined)
148         ExposeValue(aAttributes, mRootNativeValue);
149     }
150 
Equal(Accessible * aAccessible)151     virtual bool Equal(Accessible* aAccessible) override
152     {
153       T nativeValue;
154       bool isDefined = GetValueFor(aAccessible, &nativeValue);
155 
156       if (!mIsDefined && !isDefined)
157         return true;
158 
159       if (mIsDefined && isDefined)
160         return nativeValue == mNativeValue;
161 
162       if (mIsDefined)
163         return mNativeValue == mRootNativeValue;
164 
165       return nativeValue == mRootNativeValue;
166     }
167 
168   protected:
169 
170     // Expose the text attribute with the given value to attribute set.
171     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
172                              const T& aValue) = 0;
173 
174     // Return native value for the given DOM element.
175     virtual bool GetValueFor(Accessible* aAccessible, T* aValue) = 0;
176 
177     // Indicates if root value should be exposed.
178     bool mGetRootValue;
179 
180     // Native value and flag indicating if the value is defined (initialized in
181     // derived classes). Note, undefined native value means it is inherited
182     // from root.
183     MOZ_INIT_OUTSIDE_CTOR T mNativeValue;
184     MOZ_INIT_OUTSIDE_CTOR bool mIsDefined;
185 
186     // Native root value and flag indicating if the value is defined  (initialized
187     // in derived classes).
188     MOZ_INIT_OUTSIDE_CTOR T mRootNativeValue;
189     MOZ_INIT_OUTSIDE_CTOR bool mIsRootDefined;
190   };
191 
192 
193   /**
194    * Class is used for the work with 'language' text attribute.
195    */
196   class LangTextAttr : public TTextAttr<nsString>
197   {
198   public:
199     LangTextAttr(HyperTextAccessible* aRoot, nsIContent* aRootElm,
200                  nsIContent* aElm);
201     virtual ~LangTextAttr();
202 
203   protected:
204 
205     // TextAttr
206     virtual bool GetValueFor(Accessible* aAccessible, nsString* aValue) override;
207     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
208                              const nsString& aValue) override;
209 
210   private:
211     nsCOMPtr<nsIContent> mRootContent;
212   };
213 
214 
215   /**
216    * Class is used for the 'invalid' text attribute. Note, it calculated
217    * the attribute from aria-invalid attribute only; invalid:spelling attribute
218    * calculated from misspelled text in the editor is managed by
219    * HyperTextAccessible and applied on top of the value from aria-invalid.
220    */
221   class InvalidTextAttr : public TTextAttr<uint32_t>
222   {
223   public:
224     InvalidTextAttr(nsIContent* aRootElm, nsIContent* aElm);
~InvalidTextAttr()225     virtual ~InvalidTextAttr() { };
226 
227   protected:
228 
229     enum {
230       eFalse,
231       eGrammar,
232       eSpelling,
233       eTrue
234     };
235 
236     // TextAttr
237     virtual bool GetValueFor(Accessible* aAccessible, uint32_t* aValue) override;
238     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
239                              const uint32_t& aValue) override;
240 
241   private:
242     bool GetValue(nsIContent* aElm, uint32_t* aValue);
243     nsIContent* mRootElm;
244   };
245 
246 
247   /**
248    * Class is used for the work with 'background-color' text attribute.
249    */
250   class BGColorTextAttr : public TTextAttr<nscolor>
251   {
252   public:
253     BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
~BGColorTextAttr()254     virtual ~BGColorTextAttr() { }
255 
256   protected:
257 
258     // TextAttr
259     virtual bool GetValueFor(Accessible* aAccessible, nscolor* aValue)
260       override;
261     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
262                              const nscolor& aValue) override;
263 
264   private:
265     bool GetColor(nsIFrame* aFrame, nscolor* aColor);
266     nsIFrame* mRootFrame;
267   };
268 
269 
270   /**
271    * Class is used for the work with 'color' text attribute.
272    */
273   class ColorTextAttr : public TTextAttr<nscolor>
274   {
275   public:
276     ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
~ColorTextAttr()277     virtual ~ColorTextAttr() { }
278 
279   protected:
280 
281     // TTextAttr
282     virtual bool GetValueFor(Accessible* aAccessible, nscolor* aValue)
283       override;
284     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
285                              const nscolor& aValue) override;
286   };
287 
288 
289   /**
290    * Class is used for the work with "font-family" text attribute.
291    */
292   class FontFamilyTextAttr : public TTextAttr<nsString>
293   {
294   public:
295     FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
~FontFamilyTextAttr()296     virtual ~FontFamilyTextAttr() { }
297 
298   protected:
299 
300     // TTextAttr
301     virtual bool GetValueFor(Accessible* aAccessible, nsString* aValue)
302       override;
303     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
304                              const nsString& aValue) override;
305 
306   private:
307 
308     bool GetFontFamily(nsIFrame* aFrame, nsString& aFamily);
309   };
310 
311 
312   /**
313    * Class is used for the work with "font-size" text attribute.
314    */
315   class FontSizeTextAttr : public TTextAttr<nscoord>
316   {
317   public:
318     FontSizeTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
~FontSizeTextAttr()319     virtual ~FontSizeTextAttr() { }
320 
321   protected:
322 
323     // TTextAttr
324     virtual bool GetValueFor(Accessible* aAccessible, nscoord* aValue)
325       override;
326     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
327                              const nscoord& aValue) override;
328 
329   private:
330     nsDeviceContext* mDC;
331   };
332 
333 
334   /**
335    * Class is used for the work with "font-style" text attribute.
336    */
337   class FontStyleTextAttr : public TTextAttr<nscoord>
338   {
339   public:
340     FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
~FontStyleTextAttr()341     virtual ~FontStyleTextAttr() { }
342 
343   protected:
344 
345     // TTextAttr
346     virtual bool GetValueFor(Accessible* aContent, nscoord* aValue)
347       override;
348     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
349                              const nscoord& aValue) override;
350   };
351 
352 
353   /**
354    * Class is used for the work with "font-weight" text attribute.
355    */
356   class FontWeightTextAttr : public TTextAttr<int32_t>
357   {
358   public:
359     FontWeightTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
~FontWeightTextAttr()360     virtual ~FontWeightTextAttr() { }
361 
362   protected:
363 
364     // TTextAttr
365     virtual bool GetValueFor(Accessible* aAccessible, int32_t* aValue)
366       override;
367     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
368                              const int32_t& aValue) override;
369 
370   private:
371     int32_t GetFontWeight(nsIFrame* aFrame);
372   };
373 
374   /**
375    * Class is used for the work with 'auto-generated' text attribute.
376    */
377   class AutoGeneratedTextAttr : public TTextAttr<bool>
378   {
379   public:
380     AutoGeneratedTextAttr(HyperTextAccessible* aHyperTextAcc,
381                           Accessible* aAccessible);
~AutoGeneratedTextAttr()382     virtual ~AutoGeneratedTextAttr() { }
383 
384   protected:
385     // TextAttr
386     virtual bool GetValueFor(Accessible* aAccessible, bool* aValue)
387       override;
388     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
389                              const bool& aValue) override;
390   };
391 
392 
393   /**
394    * TextDecorTextAttr class is used for the work with
395    * "text-line-through-style", "text-line-through-color",
396    * "text-underline-style" and "text-underline-color" text attributes.
397    */
398 
399   class TextDecorValue
400   {
401   public:
TextDecorValue()402     TextDecorValue() { }
403     explicit TextDecorValue(nsIFrame* aFrame);
404 
Color()405     nscolor Color() const { return mColor; }
Style()406     uint8_t Style() const { return mStyle; }
407 
IsDefined()408     bool IsDefined() const
409       { return IsUnderline() || IsLineThrough(); }
IsUnderline()410     bool IsUnderline() const
411       { return mLine & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE; }
IsLineThrough()412     bool IsLineThrough() const
413       { return mLine & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH; }
414 
415     bool operator ==(const TextDecorValue& aValue)
416     {
417       return mColor == aValue.mColor && mLine == aValue.mLine &&
418         mStyle == aValue.mStyle;
419     }
420     bool operator !=(const TextDecorValue& aValue)
421       { return !(*this == aValue); }
422 
423   private:
424     nscolor mColor;
425     uint8_t mLine;
426     uint8_t mStyle;
427   };
428 
429   class TextDecorTextAttr : public TTextAttr<TextDecorValue>
430   {
431   public:
432     TextDecorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
~TextDecorTextAttr()433     virtual ~TextDecorTextAttr() { }
434 
435   protected:
436 
437     // TextAttr
438     virtual bool GetValueFor(Accessible* aAccessible, TextDecorValue* aValue)
439       override;
440     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
441                              const TextDecorValue& aValue) override;
442   };
443 
444   /**
445    * Class is used for the work with "text-position" text attribute.
446    */
447 
448   enum TextPosValue {
449     eTextPosNone = 0,
450     eTextPosBaseline,
451     eTextPosSub,
452     eTextPosSuper
453   };
454 
455   class TextPosTextAttr : public TTextAttr<TextPosValue>
456   {
457   public:
458     TextPosTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
~TextPosTextAttr()459     virtual ~TextPosTextAttr() { }
460 
461   protected:
462 
463     // TextAttr
464     virtual bool GetValueFor(Accessible* aAccessible, TextPosValue* aValue)
465       override;
466     virtual void ExposeValue(nsIPersistentProperties* aAttributes,
467                              const TextPosValue& aValue) override;
468 
469   private:
470     TextPosValue GetTextPosValue(nsIFrame* aFrame) const;
471   };
472 
473 }; // TextAttrMgr
474 
475 } // namespace a11y
476 } // namespace mozilla
477 
478 #endif
479