LCOV - code coverage report
Current view: top level - layout/style - StyleRule.h (source / functions) Hit Total Coverage
Test: output.info Lines: 15 25 60.0 %
Date: 2017-07-14 16:53:18 Functions: 10 18 55.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : /*
       7             :  * representation of CSS style rules (selectors+declaration) and CSS
       8             :  * selectors
       9             :  */
      10             : 
      11             : #ifndef mozilla_css_StyleRule_h__
      12             : #define mozilla_css_StyleRule_h__
      13             : 
      14             : #include "mozilla/Attributes.h"
      15             : #include "mozilla/BindingStyleRule.h"
      16             : #include "mozilla/MemoryReporting.h"
      17             : #include "mozilla/StyleSetHandle.h"
      18             : #include "mozilla/UniquePtr.h"
      19             : 
      20             : #include "nsString.h"
      21             : #include "nsCOMPtr.h"
      22             : #include "nsCSSPseudoElements.h"
      23             : #include "nsIStyleRule.h"
      24             : #include "nsICSSStyleRuleDOMWrapper.h"
      25             : 
      26             : class nsIAtom;
      27             : struct nsCSSSelectorList;
      28             : 
      29             : namespace mozilla {
      30             : enum class CSSPseudoClassType : uint8_t;
      31             : class CSSStyleSheet;
      32             : } // namespace mozilla
      33             : 
      34             : struct nsAtomList {
      35             : public:
      36             :   explicit nsAtomList(nsIAtom* aAtom);
      37             :   explicit nsAtomList(const nsString& aAtomValue);
      38             :   ~nsAtomList(void);
      39             : 
      40             :   /** Do a deep clone.  Should be used only on the first in the linked list. */
      41           0 :   nsAtomList* Clone() const { return Clone(true); }
      42             : 
      43             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
      44             : 
      45             :   nsCOMPtr<nsIAtom> mAtom;
      46             :   nsAtomList*       mNext;
      47             : private:
      48             :   nsAtomList* Clone(bool aDeep) const;
      49             : 
      50             :   nsAtomList(const nsAtomList& aCopy) = delete;
      51             :   nsAtomList& operator=(const nsAtomList& aCopy) = delete;
      52             : };
      53             : 
      54             : struct nsPseudoClassList {
      55             : public:
      56             :   typedef mozilla::CSSPseudoClassType CSSPseudoClassType;
      57             : 
      58             :   explicit nsPseudoClassList(CSSPseudoClassType aType);
      59             :   nsPseudoClassList(CSSPseudoClassType aType, const char16_t *aString);
      60             :   nsPseudoClassList(CSSPseudoClassType aType, const int32_t *aIntPair);
      61             :   nsPseudoClassList(CSSPseudoClassType aType,
      62             :                     nsCSSSelectorList *aSelectorList /* takes ownership */);
      63             :   ~nsPseudoClassList(void);
      64             : 
      65             :   /** Do a deep clone.  Should be used only on the first in the linked list. */
      66           0 :   nsPseudoClassList* Clone() const { return Clone(true); }
      67             : 
      68             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
      69             : 
      70             :   union {
      71             :     // For a given value of mType, we have either:
      72             :     //   a. no value, which means mMemory is always null
      73             :     //      (if none of the conditions for (b), (c), or (d) is true)
      74             :     //   b. a string value, which means mString/mMemory is non-null
      75             :     //      (if nsCSSPseudoClasses::HasStringArg(mType))
      76             :     //   c. an integer pair value, which means mNumbers/mMemory is non-null
      77             :     //      (if nsCSSPseudoClasses::HasNthPairArg(mType))
      78             :     //   d. a selector list, which means mSelectors is non-null
      79             :     //      (if nsCSSPseudoClasses::HasSelectorListArg(mType))
      80             :     void*           mMemory; // mString and mNumbers use moz_xmalloc/free
      81             :     char16_t*       mString;
      82             :     int32_t*        mNumbers;
      83             :     nsCSSSelectorList* mSelectors;
      84             :   } u;
      85             :   CSSPseudoClassType mType;
      86             :   nsPseudoClassList* mNext;
      87             : private:
      88             :   nsPseudoClassList* Clone(bool aDeep) const;
      89             : 
      90             :   nsPseudoClassList(const nsPseudoClassList& aCopy) = delete;
      91             :   nsPseudoClassList& operator=(const nsPseudoClassList& aCopy) = delete;
      92             : };
      93             : 
      94             : #define NS_ATTR_FUNC_SET        0     // [attr]
      95             : #define NS_ATTR_FUNC_EQUALS     1     // [attr=value]
      96             : #define NS_ATTR_FUNC_INCLUDES   2     // [attr~=value] (space separated)
      97             : #define NS_ATTR_FUNC_DASHMATCH  3     // [attr|=value] ('-' truncated)
      98             : #define NS_ATTR_FUNC_BEGINSMATCH  4   // [attr^=value] (begins with)
      99             : #define NS_ATTR_FUNC_ENDSMATCH  5     // [attr$=value] (ends with)
     100             : #define NS_ATTR_FUNC_CONTAINSMATCH 6  // [attr*=value] (contains substring)
     101             : 
     102             : struct nsAttrSelector {
     103             : public:
     104             :   enum class ValueCaseSensitivity : uint8_t {
     105             :     CaseSensitive,
     106             :     CaseInsensitive,
     107             :     CaseInsensitiveInHTML
     108             :   };
     109             : 
     110             :   nsAttrSelector(int32_t aNameSpace, const nsString& aAttr);
     111             :   nsAttrSelector(int32_t aNameSpace, const nsString& aAttr, uint8_t aFunction,
     112             :                  const nsString& aValue,
     113             :                  ValueCaseSensitivity aValueCaseSensitivity);
     114             :   nsAttrSelector(int32_t aNameSpace, nsIAtom* aLowercaseAttr,
     115             :                  nsIAtom* aCasedAttr, uint8_t aFunction,
     116             :                  const nsString& aValue,
     117             :                  ValueCaseSensitivity aValueCaseSensitivity);
     118             :   ~nsAttrSelector(void);
     119             : 
     120             :   /** Do a deep clone.  Should be used only on the first in the linked list. */
     121           0 :   nsAttrSelector* Clone() const { return Clone(true); }
     122             : 
     123             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     124             : 
     125       42644 :   bool IsValueCaseSensitive(bool aInHTML) const {
     126       89034 :     return mValueCaseSensitivity == ValueCaseSensitivity::CaseSensitive ||
     127        7492 :       (!aInHTML &&
     128       46390 :        mValueCaseSensitivity == ValueCaseSensitivity::CaseInsensitiveInHTML);
     129             :   }
     130             : 
     131             :   nsString        mValue;
     132             :   nsAttrSelector* mNext;
     133             :   nsCOMPtr<nsIAtom> mLowercaseAttr;
     134             :   nsCOMPtr<nsIAtom> mCasedAttr;
     135             :   int32_t         mNameSpace;
     136             :   uint8_t         mFunction;
     137             :   ValueCaseSensitivity mValueCaseSensitivity;
     138             : 
     139             : private:
     140             :   nsAttrSelector* Clone(bool aDeep) const;
     141             : 
     142             :   nsAttrSelector(const nsAttrSelector& aCopy) = delete;
     143             :   nsAttrSelector& operator=(const nsAttrSelector& aCopy) = delete;
     144             : };
     145             : 
     146             : struct nsCSSSelector {
     147             : public:
     148             :   typedef mozilla::CSSPseudoClassType CSSPseudoClassType;
     149             : 
     150             :   nsCSSSelector(void);
     151             :   ~nsCSSSelector(void);
     152             : 
     153             :   /** Do a deep clone.  Should be used only on the first in the linked list. */
     154           0 :   nsCSSSelector* Clone() const { return Clone(true, true); }
     155             : 
     156             :   void Reset(void);
     157             :   void SetNameSpace(int32_t aNameSpace);
     158             :   void SetTag(const nsString& aTag);
     159             :   void AddID(const nsString& aID);
     160             :   void AddClass(const nsString& aClass);
     161             :   void AddPseudoClass(CSSPseudoClassType aType);
     162             :   void AddPseudoClass(CSSPseudoClassType aType, const char16_t* aString);
     163             :   void AddPseudoClass(CSSPseudoClassType aType, const int32_t* aIntPair);
     164             :   // takes ownership of aSelectorList
     165             :   void AddPseudoClass(CSSPseudoClassType aType,
     166             :                       nsCSSSelectorList* aSelectorList);
     167             :   void AddAttribute(int32_t aNameSpace, const nsString& aAttr);
     168             :   void AddAttribute(int32_t aNameSpace, const nsString& aAttr, uint8_t aFunc,
     169             :                     const nsString& aValue,
     170             :                     nsAttrSelector::ValueCaseSensitivity aValueCaseSensitivity);
     171             :   void SetOperator(char16_t aOperator);
     172             : 
     173           0 :   inline bool HasTagSelector() const {
     174           0 :     return !!mCasedTag;
     175             :   }
     176             : 
     177      751627 :   inline bool IsPseudoElement() const {
     178      751627 :     return mLowercaseTag && !mCasedTag;
     179             :   }
     180             : 
     181             :   // Calculate the specificity of this selector (not including its mNext!).
     182             :   int32_t CalcWeight() const;
     183             : 
     184             :   void ToString(nsAString& aString, mozilla::CSSStyleSheet* aSheet,
     185             :                 bool aAppend = false) const;
     186             : 
     187       15691 :   bool IsRestrictedSelector() const {
     188       15691 :     return PseudoType() == mozilla::CSSPseudoElementType::NotPseudo;
     189             :   }
     190             : 
     191             : #ifdef DEBUG
     192             :   nsCString RestrictedSelectorToString() const;
     193             : #endif
     194             : 
     195             : private:
     196             :   void AddPseudoClassInternal(nsPseudoClassList *aPseudoClass);
     197             :   nsCSSSelector* Clone(bool aDeepNext, bool aDeepNegations) const;
     198             : 
     199             :   void AppendToStringWithoutCombinators(
     200             :       nsAString& aString,
     201             :       mozilla::CSSStyleSheet* aSheet,
     202             :       bool aUseStandardNamespacePrefixes) const;
     203             :   void AppendToStringWithoutCombinatorsOrNegations(
     204             :       nsAString& aString,
     205             :       mozilla::CSSStyleSheet* aSheet,
     206             :       bool aIsNegated,
     207             :       bool aUseStandardNamespacePrefixes) const;
     208             :   // Returns true if this selector can have a namespace specified (which
     209             :   // happens if and only if the default namespace would apply to this
     210             :   // selector).
     211             :   bool CanBeNamespaced(bool aIsNegated) const;
     212             :   // Calculate the specificity of this selector (not including its mNext
     213             :   // or its mNegations).
     214             :   int32_t CalcWeightWithoutNegations() const;
     215             : 
     216             : public:
     217             :   // Get and set the selector's pseudo type
     218       42016 :   mozilla::CSSPseudoElementType PseudoType() const { return mPseudoType; }
     219         356 :   void SetPseudoType(mozilla::CSSPseudoElementType aType) {
     220         356 :     mPseudoType = aType;
     221         356 :   }
     222             : 
     223             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     224             : 
     225             :   // For case-sensitive documents, mLowercaseTag is the same as mCasedTag,
     226             :   // but in case-insensitive documents (HTML) mLowercaseTag is lowercase.
     227             :   // Also, for pseudo-elements mCasedTag will be null but mLowercaseTag
     228             :   // contains their name.
     229             :   nsCOMPtr<nsIAtom> mLowercaseTag;
     230             :   nsCOMPtr<nsIAtom> mCasedTag;
     231             :   nsAtomList*     mIDList;
     232             :   nsAtomList*     mClassList;
     233             :   nsPseudoClassList* mPseudoClassList; // atom for the pseudo, string for
     234             :                                        // the argument to functional pseudos
     235             :   nsAttrSelector* mAttrList;
     236             :   nsCSSSelector*  mNegations;
     237             :   nsCSSSelector*  mNext;
     238             :   int32_t         mNameSpace;
     239             :   char16_t       mOperator;
     240             : private:
     241             :   // The underlying type of CSSPseudoElementType is uint8_t and
     242             :   // it packs well with mOperator. (char16_t + uint8_t is less than 32bits.)
     243             :   mozilla::CSSPseudoElementType mPseudoType;
     244             : 
     245             :   nsCSSSelector(const nsCSSSelector& aCopy) = delete;
     246             :   nsCSSSelector& operator=(const nsCSSSelector& aCopy) = delete;
     247             : };
     248             : 
     249             : /**
     250             :  * A selector list is the unit of selectors that each style rule has.
     251             :  * For example, "P B, H1 B { ... }" would be a selector list with two
     252             :  * items (where each |nsCSSSelectorList| object's |mSelectors| has
     253             :  * an |mNext| for the P or H1).  We represent them as linked lists.
     254             :  */
     255             : namespace mozilla {
     256             : namespace css {
     257             : class StyleRule;
     258             : } // namespace css
     259             : } // namespace mozilla
     260             : 
     261             : struct nsCSSSelectorList {
     262             :   nsCSSSelectorList(void);
     263             :   ~nsCSSSelectorList(void);
     264             : 
     265             :   /**
     266             :    * Create a new selector and push it onto the beginning of |mSelectors|,
     267             :    * setting its |mNext| to the current value of |mSelectors|.  If there is an
     268             :    * earlier selector, set its |mOperator| to |aOperator|; else |aOperator|
     269             :    * must be char16_t(0).
     270             :    * Returns the new selector.
     271             :    * The list owns the new selector.
     272             :    * The caller is responsible for updating |mWeight|.
     273             :    */
     274             :   nsCSSSelector* AddSelector(char16_t aOperator);
     275             : 
     276             :   /**
     277             :    * Point |mSelectors| to its |mNext|, and delete the first node in the old
     278             :    * |mSelectors|.
     279             :    * Should only be used on a list with more than one selector in it.
     280             :    */
     281             :   void RemoveRightmostSelector();
     282             : 
     283             :   /**
     284             :    * Should be used only on the first in the list
     285             :    */
     286             :   void ToString(nsAString& aResult, mozilla::CSSStyleSheet* aSheet);
     287             : 
     288             :   /**
     289             :    * Do a deep clone.  Should be used only on the first in the list.
     290             :    */
     291           0 :   nsCSSSelectorList* Clone() const { return Clone(true); }
     292             : 
     293             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     294             : 
     295             :   nsCSSSelector*     mSelectors;
     296             :   int32_t            mWeight;
     297             :   nsCSSSelectorList* mNext;
     298             : protected:
     299             :   friend class mozilla::css::StyleRule;
     300             :   nsCSSSelectorList* Clone(bool aDeep) const;
     301             : 
     302             : private:
     303             :   nsCSSSelectorList(const nsCSSSelectorList& aCopy) = delete;
     304             :   nsCSSSelectorList& operator=(const nsCSSSelectorList& aCopy) = delete;
     305             : };
     306             : 
     307             : // 464bab7a-2fce-4f30-ab44-b7a5f3aae57d
     308             : #define NS_CSS_STYLE_RULE_IMPL_CID \
     309             : { 0x464bab7a, 0x2fce, 0x4f30, \
     310             :   { 0xab, 0x44, 0xb7, 0xa5, 0xf3, 0xaa, 0xe5, 0x7d } }
     311             : 
     312             : class DOMCSSDeclarationImpl;
     313             : 
     314             : namespace mozilla {
     315             : namespace css {
     316             : 
     317             : class Declaration;
     318             : 
     319             : class StyleRule final : public BindingStyleRule
     320             :                       , public nsICSSStyleRuleDOMWrapper
     321             : {
     322             :  public:
     323             :   StyleRule(nsCSSSelectorList* aSelector,
     324             :             Declaration *aDeclaration,
     325             :             uint32_t aLineNumber, uint32_t aColumnNumber);
     326             : private:
     327             :   // for |Clone|
     328             :   StyleRule(const StyleRule& aCopy);
     329             : public:
     330             :   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_RULE_IMPL_CID)
     331             : 
     332             :   NS_DECL_ISUPPORTS_INHERITED
     333        3061 :   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(StyleRule, Rule)
     334             :   bool IsCCLeaf() const override;
     335             : 
     336             :   NS_DECL_NSIDOMCSSSTYLERULE
     337             : 
     338             :   // nsICSSStyleRuleDOMWrapper
     339             :   NS_IMETHOD GetCSSStyleRule(BindingStyleRule **aResult) override;
     340             : 
     341             :   uint32_t GetSelectorCount() override;
     342             :   nsresult GetSelectorText(uint32_t aSelectorIndex,
     343             :                                    nsAString& aText) override;
     344             :   nsresult GetSpecificity(uint32_t aSelectorIndex,
     345             :                           uint64_t* aSpecificity) override;
     346             :   nsresult SelectorMatchesElement(dom::Element* aElement,
     347             :                                   uint32_t aSelectorIndex,
     348             :                                   const nsAString& aPseudo,
     349             :                                   bool* aMatches) override;
     350             : 
     351             :   // WebIDL interface
     352             :   uint16_t Type() const override;
     353             :   void GetCssTextImpl(nsAString& aCssText) const override;
     354             :   nsICSSDeclaration* Style() override;
     355             : 
     356             :   // null for style attribute
     357        8667 :   nsCSSSelectorList* Selector() { return mSelector; }
     358             : 
     359       10680 :   Declaration* GetDeclaration() const { return mDeclaration; }
     360             : 
     361             :   void SetDeclaration(Declaration* aDecl);
     362             : 
     363             :   int32_t GetType() const override;
     364             :   using Rule::GetType;
     365             : 
     366           0 :   CSSStyleSheet* GetStyleSheet() const
     367             :   {
     368           0 :     StyleSheet* sheet = Rule::GetStyleSheet();
     369           0 :     return sheet ? sheet->AsGecko() : nullptr;
     370             :   }
     371             : 
     372             :   already_AddRefed<Rule> Clone() const override;
     373             : 
     374             : #ifdef DEBUG
     375             :   void List(FILE* out = stdout, int32_t aIndent = 0) const override;
     376             : #endif
     377             : 
     378             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
     379             : 
     380             : private:
     381             :   ~StyleRule();
     382             : 
     383             :   // Drop our references to mDeclaration and mRule, and let them know we're
     384             :   // doing that.
     385             :   void DropReferences();
     386             : 
     387             :   nsCSSSelectorList*
     388             :   GetSelectorAtIndex(uint32_t aIndex, ErrorResult& rv);
     389             : 
     390             : private:
     391             :   nsCSSSelectorList*      mSelector; // null for style attribute
     392             :   RefPtr<Declaration>     mDeclaration;
     393             : 
     394             :   // We own it, and it aggregates its refcount with us.
     395             :   UniquePtr<DOMCSSDeclarationImpl> mDOMDeclaration;
     396             : 
     397             : private:
     398             :   StyleRule& operator=(const StyleRule& aCopy) = delete;
     399             : };
     400             : 
     401             : NS_DEFINE_STATIC_IID_ACCESSOR(StyleRule, NS_CSS_STYLE_RULE_IMPL_CID)
     402             : 
     403             : } // namespace css
     404             : } // namespace mozilla
     405             : 
     406             : #endif /* mozilla_css_StyleRule_h__ */

Generated by: LCOV version 1.13