1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/StyleRule.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,390 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 + * representation of CSS style rules (selectors+declaration) and CSS 1.11 + * selectors 1.12 + */ 1.13 + 1.14 +#ifndef mozilla_css_StyleRule_h__ 1.15 +#define mozilla_css_StyleRule_h__ 1.16 + 1.17 +#include "mozilla/Attributes.h" 1.18 +#include "mozilla/MemoryReporting.h" 1.19 +#include "mozilla/css/Rule.h" 1.20 + 1.21 +#include "nsString.h" 1.22 +#include "nsCOMPtr.h" 1.23 +#include "nsCSSPseudoElements.h" 1.24 +#include "nsCSSPseudoClasses.h" 1.25 + 1.26 +class nsIAtom; 1.27 +class nsCSSStyleSheet; 1.28 +struct nsCSSSelectorList; 1.29 +class nsCSSCompressedDataBlock; 1.30 + 1.31 +struct nsAtomList { 1.32 +public: 1.33 + nsAtomList(nsIAtom* aAtom); 1.34 + nsAtomList(const nsString& aAtomValue); 1.35 + ~nsAtomList(void); 1.36 + 1.37 + /** Do a deep clone. Should be used only on the first in the linked list. */ 1.38 + nsAtomList* Clone() const { return Clone(true); } 1.39 + 1.40 + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 1.41 + 1.42 + nsCOMPtr<nsIAtom> mAtom; 1.43 + nsAtomList* mNext; 1.44 +private: 1.45 + nsAtomList* Clone(bool aDeep) const; 1.46 + 1.47 + nsAtomList(const nsAtomList& aCopy) MOZ_DELETE; 1.48 + nsAtomList& operator=(const nsAtomList& aCopy) MOZ_DELETE; 1.49 +}; 1.50 + 1.51 +struct nsPseudoClassList { 1.52 +public: 1.53 + nsPseudoClassList(nsCSSPseudoClasses::Type aType); 1.54 + nsPseudoClassList(nsCSSPseudoClasses::Type aType, const char16_t *aString); 1.55 + nsPseudoClassList(nsCSSPseudoClasses::Type aType, const int32_t *aIntPair); 1.56 + nsPseudoClassList(nsCSSPseudoClasses::Type aType, 1.57 + nsCSSSelectorList *aSelectorList /* takes ownership */); 1.58 + ~nsPseudoClassList(void); 1.59 + 1.60 + /** Do a deep clone. Should be used only on the first in the linked list. */ 1.61 + nsPseudoClassList* Clone() const { return Clone(true); } 1.62 + 1.63 + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 1.64 + 1.65 + union { 1.66 + // For a given value of mType, we have either: 1.67 + // a. no value, which means mMemory is always null 1.68 + // (if none of the conditions for (b), (c), or (d) is true) 1.69 + // b. a string value, which means mString/mMemory is non-null 1.70 + // (if nsCSSPseudoClasses::HasStringArg(mType)) 1.71 + // c. an integer pair value, which means mNumbers/mMemory is non-null 1.72 + // (if nsCSSPseudoClasses::HasNthPairArg(mType)) 1.73 + // d. a selector list, which means mSelectors is non-null 1.74 + // (if nsCSSPseudoClasses::HasSelectorListArg(mType)) 1.75 + void* mMemory; // mString and mNumbers use NS_Alloc/NS_Free 1.76 + char16_t* mString; 1.77 + int32_t* mNumbers; 1.78 + nsCSSSelectorList* mSelectors; 1.79 + } u; 1.80 + nsCSSPseudoClasses::Type mType; 1.81 + nsPseudoClassList* mNext; 1.82 +private: 1.83 + nsPseudoClassList* Clone(bool aDeep) const; 1.84 + 1.85 + nsPseudoClassList(const nsPseudoClassList& aCopy) MOZ_DELETE; 1.86 + nsPseudoClassList& operator=(const nsPseudoClassList& aCopy) MOZ_DELETE; 1.87 +}; 1.88 + 1.89 +#define NS_ATTR_FUNC_SET 0 // [attr] 1.90 +#define NS_ATTR_FUNC_EQUALS 1 // [attr=value] 1.91 +#define NS_ATTR_FUNC_INCLUDES 2 // [attr~=value] (space separated) 1.92 +#define NS_ATTR_FUNC_DASHMATCH 3 // [attr|=value] ('-' truncated) 1.93 +#define NS_ATTR_FUNC_BEGINSMATCH 4 // [attr^=value] (begins with) 1.94 +#define NS_ATTR_FUNC_ENDSMATCH 5 // [attr$=value] (ends with) 1.95 +#define NS_ATTR_FUNC_CONTAINSMATCH 6 // [attr*=value] (contains substring) 1.96 + 1.97 +struct nsAttrSelector { 1.98 +public: 1.99 + nsAttrSelector(int32_t aNameSpace, const nsString& aAttr); 1.100 + nsAttrSelector(int32_t aNameSpace, const nsString& aAttr, uint8_t aFunction, 1.101 + const nsString& aValue, bool aCaseSensitive); 1.102 + nsAttrSelector(int32_t aNameSpace, nsIAtom* aLowercaseAttr, 1.103 + nsIAtom* aCasedAttr, uint8_t aFunction, 1.104 + const nsString& aValue, bool aCaseSensitive); 1.105 + ~nsAttrSelector(void); 1.106 + 1.107 + /** Do a deep clone. Should be used only on the first in the linked list. */ 1.108 + nsAttrSelector* Clone() const { return Clone(true); } 1.109 + 1.110 + nsString mValue; 1.111 + nsAttrSelector* mNext; 1.112 + nsCOMPtr<nsIAtom> mLowercaseAttr; 1.113 + nsCOMPtr<nsIAtom> mCasedAttr; 1.114 + int32_t mNameSpace; 1.115 + uint8_t mFunction; 1.116 + bool mCaseSensitive; // If we are in an HTML document, 1.117 + // is the value case sensitive? 1.118 +private: 1.119 + nsAttrSelector* Clone(bool aDeep) const; 1.120 + 1.121 + nsAttrSelector(const nsAttrSelector& aCopy) MOZ_DELETE; 1.122 + nsAttrSelector& operator=(const nsAttrSelector& aCopy) MOZ_DELETE; 1.123 +}; 1.124 + 1.125 +struct nsCSSSelector { 1.126 +public: 1.127 + nsCSSSelector(void); 1.128 + ~nsCSSSelector(void); 1.129 + 1.130 + /** Do a deep clone. Should be used only on the first in the linked list. */ 1.131 + nsCSSSelector* Clone() const { return Clone(true, true); } 1.132 + 1.133 + void Reset(void); 1.134 + void SetNameSpace(int32_t aNameSpace); 1.135 + void SetTag(const nsString& aTag); 1.136 + void AddID(const nsString& aID); 1.137 + void AddClass(const nsString& aClass); 1.138 + void AddPseudoClass(nsCSSPseudoClasses::Type aType); 1.139 + void AddPseudoClass(nsCSSPseudoClasses::Type aType, const char16_t* aString); 1.140 + void AddPseudoClass(nsCSSPseudoClasses::Type aType, const int32_t* aIntPair); 1.141 + // takes ownership of aSelectorList 1.142 + void AddPseudoClass(nsCSSPseudoClasses::Type aType, 1.143 + nsCSSSelectorList* aSelectorList); 1.144 + void AddAttribute(int32_t aNameSpace, const nsString& aAttr); 1.145 + void AddAttribute(int32_t aNameSpace, const nsString& aAttr, uint8_t aFunc, 1.146 + const nsString& aValue, bool aCaseSensitive); 1.147 + void SetOperator(char16_t aOperator); 1.148 + 1.149 + inline bool HasTagSelector() const { 1.150 + return !!mCasedTag; 1.151 + } 1.152 + 1.153 + inline bool IsPseudoElement() const { 1.154 + return mLowercaseTag && !mCasedTag; 1.155 + } 1.156 + 1.157 + // Calculate the specificity of this selector (not including its mNext!). 1.158 + int32_t CalcWeight() const; 1.159 + 1.160 + void ToString(nsAString& aString, nsCSSStyleSheet* aSheet, 1.161 + bool aAppend = false) const; 1.162 + 1.163 +private: 1.164 + void AddPseudoClassInternal(nsPseudoClassList *aPseudoClass); 1.165 + nsCSSSelector* Clone(bool aDeepNext, bool aDeepNegations) const; 1.166 + 1.167 + void AppendToStringWithoutCombinators(nsAString& aString, 1.168 + nsCSSStyleSheet* aSheet) const; 1.169 + void AppendToStringWithoutCombinatorsOrNegations(nsAString& aString, 1.170 + nsCSSStyleSheet* aSheet, 1.171 + bool aIsNegated) 1.172 + const; 1.173 + // Returns true if this selector can have a namespace specified (which 1.174 + // happens if and only if the default namespace would apply to this 1.175 + // selector). 1.176 + bool CanBeNamespaced(bool aIsNegated) const; 1.177 + // Calculate the specificity of this selector (not including its mNext 1.178 + // or its mNegations). 1.179 + int32_t CalcWeightWithoutNegations() const; 1.180 + 1.181 +public: 1.182 + // Get and set the selector's pseudo type 1.183 + nsCSSPseudoElements::Type PseudoType() const { 1.184 + return static_cast<nsCSSPseudoElements::Type>(mPseudoType); 1.185 + } 1.186 + void SetPseudoType(nsCSSPseudoElements::Type aType) { 1.187 + NS_ASSERTION(static_cast<int32_t>(aType) >= INT16_MIN && 1.188 + static_cast<int32_t>(aType) <= INT16_MAX, 1.189 + "Out of bounds - this will overflow mPseudoType"); 1.190 + mPseudoType = static_cast<int16_t>(aType); 1.191 + } 1.192 + 1.193 + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 1.194 + 1.195 + // For case-sensitive documents, mLowercaseTag is the same as mCasedTag, 1.196 + // but in case-insensitive documents (HTML) mLowercaseTag is lowercase. 1.197 + // Also, for pseudo-elements mCasedTag will be null but mLowercaseTag 1.198 + // contains their name. 1.199 + nsCOMPtr<nsIAtom> mLowercaseTag; 1.200 + nsCOMPtr<nsIAtom> mCasedTag; 1.201 + nsAtomList* mIDList; 1.202 + nsAtomList* mClassList; 1.203 + nsPseudoClassList* mPseudoClassList; // atom for the pseudo, string for 1.204 + // the argument to functional pseudos 1.205 + nsAttrSelector* mAttrList; 1.206 + nsCSSSelector* mNegations; 1.207 + nsCSSSelector* mNext; 1.208 + int32_t mNameSpace; 1.209 + char16_t mOperator; 1.210 +private: 1.211 + // int16_t to make sure it packs well with mOperator 1.212 + int16_t mPseudoType; 1.213 + 1.214 + nsCSSSelector(const nsCSSSelector& aCopy) MOZ_DELETE; 1.215 + nsCSSSelector& operator=(const nsCSSSelector& aCopy) MOZ_DELETE; 1.216 +}; 1.217 + 1.218 +/** 1.219 + * A selector list is the unit of selectors that each style rule has. 1.220 + * For example, "P B, H1 B { ... }" would be a selector list with two 1.221 + * items (where each |nsCSSSelectorList| object's |mSelectors| has 1.222 + * an |mNext| for the P or H1). We represent them as linked lists. 1.223 + */ 1.224 +class inDOMUtils; 1.225 + 1.226 +struct nsCSSSelectorList { 1.227 + nsCSSSelectorList(void); 1.228 + ~nsCSSSelectorList(void); 1.229 + 1.230 + /** 1.231 + * Create a new selector and push it onto the beginning of |mSelectors|, 1.232 + * setting its |mNext| to the current value of |mSelectors|. If there is an 1.233 + * earlier selector, set its |mOperator| to |aOperator|; else |aOperator| 1.234 + * must be char16_t(0). 1.235 + * Returns the new selector. 1.236 + * The list owns the new selector. 1.237 + * The caller is responsible for updating |mWeight|. 1.238 + */ 1.239 + nsCSSSelector* AddSelector(char16_t aOperator); 1.240 + 1.241 + /** 1.242 + * Should be used only on the first in the list 1.243 + */ 1.244 + void ToString(nsAString& aResult, nsCSSStyleSheet* aSheet); 1.245 + 1.246 + /** 1.247 + * Do a deep clone. Should be used only on the first in the list. 1.248 + */ 1.249 + nsCSSSelectorList* Clone() const { return Clone(true); } 1.250 + 1.251 + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 1.252 + 1.253 + nsCSSSelector* mSelectors; 1.254 + int32_t mWeight; 1.255 + nsCSSSelectorList* mNext; 1.256 +protected: 1.257 + friend class inDOMUtils; 1.258 + nsCSSSelectorList* Clone(bool aDeep) const; 1.259 + 1.260 +private: 1.261 + nsCSSSelectorList(const nsCSSSelectorList& aCopy) MOZ_DELETE; 1.262 + nsCSSSelectorList& operator=(const nsCSSSelectorList& aCopy) MOZ_DELETE; 1.263 +}; 1.264 + 1.265 +// 464bab7a-2fce-4f30-ab44-b7a5f3aae57d 1.266 +#define NS_CSS_STYLE_RULE_IMPL_CID \ 1.267 +{ 0x464bab7a, 0x2fce, 0x4f30, \ 1.268 + { 0xab, 0x44, 0xb7, 0xa5, 0xf3, 0xaa, 0xe5, 0x7d } } 1.269 + 1.270 +namespace mozilla { 1.271 +namespace css { 1.272 + 1.273 +class Declaration; 1.274 +class DOMCSSStyleRule; 1.275 + 1.276 +class StyleRule; 1.277 + 1.278 +class ImportantRule : public nsIStyleRule { 1.279 +public: 1.280 + ImportantRule(Declaration *aDeclaration); 1.281 + 1.282 + NS_DECL_ISUPPORTS 1.283 + 1.284 + // nsIStyleRule interface 1.285 + virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE; 1.286 +#ifdef DEBUG 1.287 + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; 1.288 +#endif 1.289 + 1.290 +protected: 1.291 + virtual ~ImportantRule(); 1.292 + 1.293 + // Not an owning reference; the StyleRule that owns this 1.294 + // ImportantRule also owns the mDeclaration, and any rule node 1.295 + // pointing to this rule keeps that StyleRule alive as well. 1.296 + Declaration* mDeclaration; 1.297 + 1.298 + friend class StyleRule; 1.299 +}; 1.300 + 1.301 +class StyleRule MOZ_FINAL : public Rule 1.302 +{ 1.303 + public: 1.304 + StyleRule(nsCSSSelectorList* aSelector, 1.305 + Declaration *aDeclaration); 1.306 +private: 1.307 + // for |Clone| 1.308 + StyleRule(const StyleRule& aCopy); 1.309 + // for |DeclarationChanged| 1.310 + StyleRule(StyleRule& aCopy, 1.311 + Declaration *aDeclaration); 1.312 +public: 1.313 + NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_RULE_IMPL_CID) 1.314 + 1.315 + NS_DECL_ISUPPORTS 1.316 + 1.317 + // null for style attribute 1.318 + nsCSSSelectorList* Selector() { return mSelector; } 1.319 + 1.320 + uint32_t GetLineNumber() const { return mLineNumber; } 1.321 + uint32_t GetColumnNumber() const { return mColumnNumber; } 1.322 + void SetLineNumberAndColumnNumber(uint32_t aLineNumber, 1.323 + uint32_t aColumnNumber) 1.324 + { mLineNumber = aLineNumber; mColumnNumber = aColumnNumber; } 1.325 + 1.326 + Declaration* GetDeclaration() const { return mDeclaration; } 1.327 + 1.328 + /** 1.329 + * Return a new |nsIStyleRule| instance that replaces the current 1.330 + * one, with |aDecl| replacing the previous declaration. Due to the 1.331 + * |nsIStyleRule| contract of immutability, this must be called if 1.332 + * the declaration is modified. 1.333 + * 1.334 + * |DeclarationChanged| handles replacing the object in the container 1.335 + * sheet or group rule if |aHandleContainer| is true. 1.336 + */ 1.337 + already_AddRefed<StyleRule> 1.338 + DeclarationChanged(Declaration* aDecl, bool aHandleContainer); 1.339 + 1.340 + nsIStyleRule* GetImportantRule() const { return mImportantRule; } 1.341 + 1.342 + /** 1.343 + * The rule processor must call this method before calling 1.344 + * nsRuleWalker::Forward on this rule during rule matching. 1.345 + */ 1.346 + void RuleMatched(); 1.347 + 1.348 + // hooks for DOM rule 1.349 + void GetCssText(nsAString& aCssText); 1.350 + void SetCssText(const nsAString& aCssText); 1.351 + void GetSelectorText(nsAString& aSelectorText); 1.352 + void SetSelectorText(const nsAString& aSelectorText); 1.353 + 1.354 + virtual int32_t GetType() const; 1.355 + 1.356 + virtual already_AddRefed<Rule> Clone() const; 1.357 + 1.358 + virtual nsIDOMCSSRule* GetDOMRule(); 1.359 + 1.360 + virtual nsIDOMCSSRule* GetExistingDOMRule(); 1.361 + 1.362 + // The new mapping function. 1.363 + virtual void MapRuleInfoInto(nsRuleData* aRuleData) MOZ_OVERRIDE; 1.364 + 1.365 +#ifdef DEBUG 1.366 + virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE; 1.367 +#endif 1.368 + 1.369 + virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 1.370 + 1.371 +private: 1.372 + ~StyleRule(); 1.373 + 1.374 +private: 1.375 + nsCSSSelectorList* mSelector; // null for style attribute 1.376 + Declaration* mDeclaration; 1.377 + ImportantRule* mImportantRule; // initialized by RuleMatched 1.378 + DOMCSSStyleRule* mDOMRule; 1.379 + // Keep the same type so that MSVC packs them. 1.380 + uint32_t mLineNumber; 1.381 + uint32_t mColumnNumber : 31; 1.382 + uint32_t mWasMatched : 1; 1.383 + 1.384 +private: 1.385 + StyleRule& operator=(const StyleRule& aCopy) MOZ_DELETE; 1.386 +}; 1.387 + 1.388 +NS_DEFINE_STATIC_IID_ACCESSOR(StyleRule, NS_CSS_STYLE_RULE_IMPL_CID) 1.389 + 1.390 +} // namespace css 1.391 +} // namespace mozilla 1.392 + 1.393 +#endif /* mozilla_css_StyleRule_h__ */