StyleRule.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  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. * representation of CSS style rules (selectors+declaration) and CSS
  7. * selectors
  8. */
  9. #ifndef mozilla_css_StyleRule_h__
  10. #define mozilla_css_StyleRule_h__
  11. #include "mozilla/Attributes.h"
  12. #include "mozilla/MemoryReporting.h"
  13. #include "mozilla/css/Rule.h"
  14. #include "nsString.h"
  15. #include "nsCOMPtr.h"
  16. #include "nsCSSPseudoElements.h"
  17. #include "nsIStyleRule.h"
  18. class nsIAtom;
  19. struct nsCSSSelectorList;
  20. namespace mozilla {
  21. enum class CSSPseudoClassType : uint8_t;
  22. class CSSStyleSheet;
  23. } // namespace mozilla
  24. struct nsAtomList {
  25. public:
  26. explicit nsAtomList(nsIAtom* aAtom);
  27. explicit nsAtomList(const nsString& aAtomValue);
  28. ~nsAtomList(void);
  29. /** Do a deep clone. Should be used only on the first in the linked list. */
  30. nsAtomList* Clone() const { return Clone(true); }
  31. size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  32. nsCOMPtr<nsIAtom> mAtom;
  33. nsAtomList* mNext;
  34. private:
  35. nsAtomList* Clone(bool aDeep) const;
  36. nsAtomList(const nsAtomList& aCopy) = delete;
  37. nsAtomList& operator=(const nsAtomList& aCopy) = delete;
  38. };
  39. struct nsPseudoClassList {
  40. public:
  41. typedef mozilla::CSSPseudoClassType CSSPseudoClassType;
  42. explicit nsPseudoClassList(CSSPseudoClassType aType);
  43. nsPseudoClassList(CSSPseudoClassType aType, const char16_t *aString);
  44. nsPseudoClassList(CSSPseudoClassType aType, const int32_t *aIntPair);
  45. nsPseudoClassList(CSSPseudoClassType aType,
  46. nsCSSSelectorList *aSelectorList /* takes ownership */);
  47. ~nsPseudoClassList(void);
  48. /** Do a deep clone. Should be used only on the first in the linked list. */
  49. nsPseudoClassList* Clone() const { return Clone(true); }
  50. size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  51. union {
  52. // For a given value of mType, we have either:
  53. // a. no value, which means mMemory is always null
  54. // (if none of the conditions for (b), (c), or (d) is true)
  55. // b. a string value, which means mString/mMemory is non-null
  56. // (if nsCSSPseudoClasses::HasStringArg(mType))
  57. // c. an integer pair value, which means mNumbers/mMemory is non-null
  58. // (if nsCSSPseudoClasses::HasNthPairArg(mType))
  59. // d. a selector list, which means mSelectors is non-null
  60. // (if nsCSSPseudoClasses::HasSelectorListArg(mType))
  61. void* mMemory; // mString and mNumbers use moz_xmalloc/free
  62. char16_t* mString;
  63. int32_t* mNumbers;
  64. nsCSSSelectorList* mSelectors;
  65. } u;
  66. CSSPseudoClassType mType;
  67. nsPseudoClassList* mNext;
  68. private:
  69. nsPseudoClassList* Clone(bool aDeep) const;
  70. nsPseudoClassList(const nsPseudoClassList& aCopy) = delete;
  71. nsPseudoClassList& operator=(const nsPseudoClassList& aCopy) = delete;
  72. };
  73. #define NS_ATTR_FUNC_SET 0 // [attr]
  74. #define NS_ATTR_FUNC_EQUALS 1 // [attr=value]
  75. #define NS_ATTR_FUNC_INCLUDES 2 // [attr~=value] (space separated)
  76. #define NS_ATTR_FUNC_DASHMATCH 3 // [attr|=value] ('-' truncated)
  77. #define NS_ATTR_FUNC_BEGINSMATCH 4 // [attr^=value] (begins with)
  78. #define NS_ATTR_FUNC_ENDSMATCH 5 // [attr$=value] (ends with)
  79. #define NS_ATTR_FUNC_CONTAINSMATCH 6 // [attr*=value] (contains substring)
  80. struct nsAttrSelector {
  81. public:
  82. enum class ValueCaseSensitivity : uint8_t {
  83. CaseSensitive,
  84. CaseInsensitive,
  85. CaseInsensitiveInHTML
  86. };
  87. nsAttrSelector(int32_t aNameSpace, const nsString& aAttr);
  88. nsAttrSelector(int32_t aNameSpace, const nsString& aAttr, uint8_t aFunction,
  89. const nsString& aValue,
  90. ValueCaseSensitivity aValueCaseSensitivity);
  91. nsAttrSelector(int32_t aNameSpace, nsIAtom* aLowercaseAttr,
  92. nsIAtom* aCasedAttr, uint8_t aFunction,
  93. const nsString& aValue,
  94. ValueCaseSensitivity aValueCaseSensitivity);
  95. ~nsAttrSelector(void);
  96. /** Do a deep clone. Should be used only on the first in the linked list. */
  97. nsAttrSelector* Clone() const { return Clone(true); }
  98. size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  99. bool IsValueCaseSensitive(bool aInHTML) const {
  100. return mValueCaseSensitivity == ValueCaseSensitivity::CaseSensitive ||
  101. (!aInHTML &&
  102. mValueCaseSensitivity == ValueCaseSensitivity::CaseInsensitiveInHTML);
  103. }
  104. nsString mValue;
  105. nsAttrSelector* mNext;
  106. nsCOMPtr<nsIAtom> mLowercaseAttr;
  107. nsCOMPtr<nsIAtom> mCasedAttr;
  108. int32_t mNameSpace;
  109. uint8_t mFunction;
  110. ValueCaseSensitivity mValueCaseSensitivity;
  111. private:
  112. nsAttrSelector* Clone(bool aDeep) const;
  113. nsAttrSelector(const nsAttrSelector& aCopy) = delete;
  114. nsAttrSelector& operator=(const nsAttrSelector& aCopy) = delete;
  115. };
  116. struct nsCSSSelector {
  117. public:
  118. typedef mozilla::CSSPseudoClassType CSSPseudoClassType;
  119. nsCSSSelector(void);
  120. ~nsCSSSelector(void);
  121. /** Do a deep clone. Should be used only on the first in the linked list. */
  122. nsCSSSelector* Clone() const { return Clone(true, true); }
  123. void Reset(void);
  124. void SetNameSpace(int32_t aNameSpace);
  125. void SetTag(const nsString& aTag);
  126. void AddID(const nsString& aID);
  127. void AddClass(const nsString& aClass);
  128. void AddPseudoClass(CSSPseudoClassType aType);
  129. void AddPseudoClass(CSSPseudoClassType aType, const char16_t* aString);
  130. void AddPseudoClass(CSSPseudoClassType aType, const int32_t* aIntPair);
  131. // takes ownership of aSelectorList
  132. void AddPseudoClass(CSSPseudoClassType aType,
  133. nsCSSSelectorList* aSelectorList);
  134. void AddAttribute(int32_t aNameSpace, const nsString& aAttr);
  135. void AddAttribute(int32_t aNameSpace, const nsString& aAttr, uint8_t aFunc,
  136. const nsString& aValue,
  137. nsAttrSelector::ValueCaseSensitivity aValueCaseSensitivity);
  138. void SetOperator(char16_t aOperator);
  139. inline bool HasTagSelector() const {
  140. return !!mCasedTag;
  141. }
  142. inline bool IsPseudoElement() const {
  143. return mLowercaseTag && !mCasedTag;
  144. }
  145. // Calculate the specificity of this selector (not including its mNext!).
  146. int32_t CalcWeight() const;
  147. void ToString(nsAString& aString, mozilla::CSSStyleSheet* aSheet,
  148. bool aAppend = false) const;
  149. bool IsRestrictedSelector() const {
  150. return PseudoType() == mozilla::CSSPseudoElementType::NotPseudo;
  151. }
  152. #ifdef DEBUG
  153. nsCString RestrictedSelectorToString() const;
  154. #endif
  155. private:
  156. void AddPseudoClassInternal(nsPseudoClassList *aPseudoClass);
  157. nsCSSSelector* Clone(bool aDeepNext, bool aDeepNegations) const;
  158. void AppendToStringWithoutCombinators(
  159. nsAString& aString,
  160. mozilla::CSSStyleSheet* aSheet,
  161. bool aUseStandardNamespacePrefixes) const;
  162. void AppendToStringWithoutCombinatorsOrNegations(
  163. nsAString& aString,
  164. mozilla::CSSStyleSheet* aSheet,
  165. bool aIsNegated,
  166. bool aUseStandardNamespacePrefixes) const;
  167. // Returns true if this selector can have a namespace specified (which
  168. // happens if and only if the default namespace would apply to this
  169. // selector).
  170. bool CanBeNamespaced(bool aIsNegated) const;
  171. // Calculate the specificity of this selector (not including its mNext
  172. // or its mNegations).
  173. int32_t CalcWeightWithoutNegations() const;
  174. public:
  175. // Get and set the selector's pseudo type
  176. mozilla::CSSPseudoElementType PseudoType() const { return mPseudoType; }
  177. void SetPseudoType(mozilla::CSSPseudoElementType aType) {
  178. mPseudoType = aType;
  179. }
  180. size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  181. // For case-sensitive documents, mLowercaseTag is the same as mCasedTag,
  182. // but in case-insensitive documents (HTML) mLowercaseTag is lowercase.
  183. // Also, for pseudo-elements mCasedTag will be null but mLowercaseTag
  184. // contains their name.
  185. nsCOMPtr<nsIAtom> mLowercaseTag;
  186. nsCOMPtr<nsIAtom> mCasedTag;
  187. nsAtomList* mIDList;
  188. nsAtomList* mClassList;
  189. nsPseudoClassList* mPseudoClassList; // atom for the pseudo, string for
  190. // the argument to functional pseudos
  191. nsAttrSelector* mAttrList;
  192. nsCSSSelector* mNegations;
  193. nsCSSSelector* mNext;
  194. int32_t mNameSpace;
  195. char16_t mOperator;
  196. private:
  197. // The underlying type of CSSPseudoElementType is uint8_t and
  198. // it packs well with mOperator. (char16_t + uint8_t is less than 32bits.)
  199. mozilla::CSSPseudoElementType mPseudoType;
  200. nsCSSSelector(const nsCSSSelector& aCopy) = delete;
  201. nsCSSSelector& operator=(const nsCSSSelector& aCopy) = delete;
  202. };
  203. /**
  204. * A selector list is the unit of selectors that each style rule has.
  205. * For example, "P B, H1 B { ... }" would be a selector list with two
  206. * items (where each |nsCSSSelectorList| object's |mSelectors| has
  207. * an |mNext| for the P or H1). We represent them as linked lists.
  208. */
  209. class inDOMUtils;
  210. struct nsCSSSelectorList {
  211. nsCSSSelectorList(void);
  212. ~nsCSSSelectorList(void);
  213. /**
  214. * Create a new selector and push it onto the beginning of |mSelectors|,
  215. * setting its |mNext| to the current value of |mSelectors|. If there is an
  216. * earlier selector, set its |mOperator| to |aOperator|; else |aOperator|
  217. * must be char16_t(0).
  218. * Returns the new selector.
  219. * The list owns the new selector.
  220. * The caller is responsible for updating |mWeight|.
  221. */
  222. nsCSSSelector* AddSelector(char16_t aOperator);
  223. /**
  224. * Point |mSelectors| to its |mNext|, and delete the first node in the old
  225. * |mSelectors|.
  226. * Should only be used on a list with more than one selector in it.
  227. */
  228. void RemoveRightmostSelector();
  229. /**
  230. * Should be used only on the first in the list
  231. */
  232. void ToString(nsAString& aResult, mozilla::CSSStyleSheet* aSheet);
  233. /**
  234. * Do a deep clone. Should be used only on the first in the list.
  235. */
  236. nsCSSSelectorList* Clone() const { return Clone(true); }
  237. size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
  238. nsCSSSelector* mSelectors;
  239. int32_t mWeight;
  240. nsCSSSelectorList* mNext;
  241. protected:
  242. friend class inDOMUtils;
  243. nsCSSSelectorList* Clone(bool aDeep) const;
  244. private:
  245. nsCSSSelectorList(const nsCSSSelectorList& aCopy) = delete;
  246. nsCSSSelectorList& operator=(const nsCSSSelectorList& aCopy) = delete;
  247. };
  248. // 464bab7a-2fce-4f30-ab44-b7a5f3aae57d
  249. #define NS_CSS_STYLE_RULE_IMPL_CID \
  250. { 0x464bab7a, 0x2fce, 0x4f30, \
  251. { 0xab, 0x44, 0xb7, 0xa5, 0xf3, 0xaa, 0xe5, 0x7d } }
  252. namespace mozilla {
  253. namespace css {
  254. class Declaration;
  255. class DOMCSSStyleRule;
  256. class StyleRule final : public Rule
  257. {
  258. public:
  259. StyleRule(nsCSSSelectorList* aSelector,
  260. Declaration *aDeclaration,
  261. uint32_t aLineNumber, uint32_t aColumnNumber);
  262. private:
  263. // for |Clone|
  264. StyleRule(const StyleRule& aCopy);
  265. public:
  266. NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_RULE_IMPL_CID)
  267. NS_DECL_ISUPPORTS
  268. // null for style attribute
  269. nsCSSSelectorList* Selector() { return mSelector; }
  270. Declaration* GetDeclaration() const { return mDeclaration; }
  271. void SetDeclaration(Declaration* aDecl);
  272. // hooks for DOM rule
  273. void GetCssText(nsAString& aCssText);
  274. void SetCssText(const nsAString& aCssText);
  275. void GetSelectorText(nsAString& aSelectorText);
  276. void SetSelectorText(const nsAString& aSelectorText);
  277. virtual int32_t GetType() const override;
  278. virtual already_AddRefed<Rule> Clone() const override;
  279. virtual nsIDOMCSSRule* GetDOMRule() override;
  280. virtual nsIDOMCSSRule* GetExistingDOMRule() override;
  281. #ifdef DEBUG
  282. virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
  283. #endif
  284. virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
  285. private:
  286. ~StyleRule();
  287. private:
  288. nsCSSSelectorList* mSelector; // null for style attribute
  289. RefPtr<Declaration> mDeclaration;
  290. RefPtr<DOMCSSStyleRule> mDOMRule;
  291. private:
  292. StyleRule& operator=(const StyleRule& aCopy) = delete;
  293. };
  294. NS_DEFINE_STATIC_IID_ACCESSOR(StyleRule, NS_CSS_STYLE_RULE_IMPL_CID)
  295. } // namespace css
  296. } // namespace mozilla
  297. #endif /* mozilla_css_StyleRule_h__ */