LCOV - code coverage report
Current view: top level - layout/style - StyleSheet.h (source / functions) Hit Total Coverage
Test: output.info Lines: 14 19 73.7 %
Date: 2017-07-14 16:53:18 Functions: 11 21 52.4 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
       7             : #ifndef mozilla_StyleSheet_h
       8             : #define mozilla_StyleSheet_h
       9             : 
      10             : #include "mozilla/css/SheetParsingMode.h"
      11             : #include "mozilla/dom/CSSStyleSheetBinding.h"
      12             : #include "mozilla/net/ReferrerPolicy.h"
      13             : #include "mozilla/StyleBackendType.h"
      14             : #include "mozilla/CORSMode.h"
      15             : #include "mozilla/ServoUtils.h"
      16             : 
      17             : #include "nsICSSLoaderObserver.h"
      18             : #include "nsIDOMCSSStyleSheet.h"
      19             : #include "nsWrapperCache.h"
      20             : 
      21             : class nsIDocument;
      22             : class nsINode;
      23             : class nsIPrincipal;
      24             : class nsCSSRuleProcessor;
      25             : 
      26             : namespace mozilla {
      27             : 
      28             : class CSSStyleSheet;
      29             : class ServoStyleSheet;
      30             : class StyleSetHandle;
      31             : struct StyleSheetInfo;
      32             : struct CSSStyleSheetInner;
      33             : 
      34             : namespace dom {
      35             : class CSSImportRule;
      36             : class CSSRuleList;
      37             : class MediaList;
      38             : class SRIMetadata;
      39             : } // namespace dom
      40             : 
      41             : namespace css {
      42             : class GroupRule;
      43             : class Rule;
      44             : }
      45             : 
      46             : /**
      47             :  * Superclass for data common to CSSStyleSheet and ServoStyleSheet.
      48             :  */
      49             : class StyleSheet : public nsIDOMCSSStyleSheet
      50             :                  , public nsICSSLoaderObserver
      51             :                  , public nsWrapperCache
      52             : {
      53             : protected:
      54             :   StyleSheet(StyleBackendType aType, css::SheetParsingMode aParsingMode);
      55             :   StyleSheet(const StyleSheet& aCopy,
      56             :              StyleSheet* aParentToUse,
      57             :              dom::CSSImportRule* aOwnerRuleToUse,
      58             :              nsIDocument* aDocumentToUse,
      59             :              nsINode* aOwningNodeToUse);
      60             :   virtual ~StyleSheet();
      61             : 
      62             : public:
      63             :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
      64        1186 :   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(StyleSheet,
      65             :                                                          nsIDOMCSSStyleSheet)
      66             : 
      67             :   /**
      68             :    * The different changes that a stylesheet may go through.
      69             :    *
      70             :    * Used by the StyleSets in order to handle more efficiently some kinds of
      71             :    * changes.
      72             :    */
      73             :   enum class ChangeType {
      74             :     Added,
      75             :     Removed,
      76             :     ApplicableStateChanged,
      77             :     RuleAdded,
      78             :     RuleRemoved,
      79             :     RuleChanged,
      80             :   };
      81             : 
      82          11 :   void SetOwningNode(nsINode* aOwningNode)
      83             :   {
      84          11 :     mOwningNode = aOwningNode;
      85          11 :   }
      86             : 
      87          63 :   css::SheetParsingMode ParsingMode() const { return mParsingMode; }
      88             :   mozilla::dom::CSSStyleSheetParsingMode ParsingModeDOM();
      89             : 
      90             :   /**
      91             :    * Whether the sheet is complete.
      92             :    */
      93             :   bool IsComplete() const;
      94             :   void SetComplete();
      95             : 
      96             :   /**
      97             :    * Set the stylesheet to be enabled.  This may or may not make it
      98             :    * applicable.  Note that this WILL inform the sheet's document of
      99             :    * its new applicable state if the state changes but WILL NOT call
     100             :    * BeginUpdate() or EndUpdate() on the document -- calling those is
     101             :    * the caller's responsibility.  This allows use of SetEnabled when
     102             :    * batched updates are desired.  If you want updates handled for
     103             :    * you, see nsIDOMStyleSheet::SetDisabled().
     104             :    */
     105             :   void SetEnabled(bool aEnabled);
     106             : 
     107         988 :   MOZ_DECL_STYLO_METHODS(CSSStyleSheet, ServoStyleSheet)
     108             : 
     109             :   // Whether the sheet is for an inline <style> element.
     110             :   inline bool IsInline() const;
     111             : 
     112             :   inline nsIURI* GetSheetURI() const;
     113             :   /* Get the URI this sheet was originally loaded from, if any.  Can
     114             :      return null */
     115             :   inline nsIURI* GetOriginalURI() const;
     116             :   inline nsIURI* GetBaseURI() const;
     117             :   /**
     118             :    * SetURIs must be called on all sheets before parsing into them.
     119             :    * SetURIs may only be called while the sheet is 1) incomplete and 2)
     120             :    * has no rules in it
     121             :    */
     122             :   inline void SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI,
     123             :                       nsIURI* aBaseURI);
     124             : 
     125             :   /**
     126             :    * Whether the sheet is applicable.  A sheet that is not applicable
     127             :    * should never be inserted into a style set.  A sheet may not be
     128             :    * applicable for a variety of reasons including being disabled and
     129             :    * being incomplete.
     130             :    */
     131             :   inline bool IsApplicable() const;
     132             :   inline bool HasRules() const;
     133             : 
     134             :   virtual already_AddRefed<StyleSheet> Clone(StyleSheet* aCloneParent,
     135             :                                              dom::CSSImportRule* aCloneOwnerRule,
     136             :                                              nsIDocument* aCloneDocument,
     137             :                                              nsINode* aCloneOwningNode) const = 0;
     138             : 
     139          88 :   bool IsModified() const { return mDirty; }
     140             : 
     141             :   void EnsureUniqueInner();
     142             : 
     143             :   // Append all of this sheet's child sheets to aArray.
     144             :   void AppendAllChildSheets(nsTArray<StyleSheet*>& aArray);
     145             : 
     146             :   // style sheet owner info
     147             :   enum DocumentAssociationMode : uint8_t {
     148             :     // OwnedByDocument means mDocument owns us (possibly via a chain of other
     149             :     // stylesheets).
     150             :     OwnedByDocument,
     151             :     // NotOwnedByDocument means we're owned by something that might have a
     152             :     // different lifetime than mDocument.
     153             :     NotOwnedByDocument
     154             :   };
     155        6469 :   nsIDocument* GetAssociatedDocument() const { return mDocument; }
     156           0 :   bool IsOwnedByDocument() const {
     157           0 :     return mDocumentAssociationMode == OwnedByDocument;
     158             :   }
     159             :   // aDocument must not be null.
     160             :   void SetAssociatedDocument(nsIDocument* aDocument,
     161             :                              DocumentAssociationMode aMode);
     162             :   void ClearAssociatedDocument();
     163          57 :   nsINode* GetOwnerNode() const { return mOwningNode; }
     164          56 :   inline StyleSheet* GetParentSheet() const { return mParent; }
     165             : 
     166           3 :   void SetOwnerRule(dom::CSSImportRule* aOwnerRule) {
     167           3 :     mOwnerRule = aOwnerRule; /* Not ref counted */
     168           3 :   }
     169           0 :   dom::CSSImportRule* GetOwnerRule() const { return mOwnerRule; }
     170             : 
     171             :   void PrependStyleSheet(StyleSheet* aSheet);
     172             : 
     173             :   // Prepend a stylesheet to the child list without calling Will/DidDirty.
     174             :   void PrependStyleSheetSilently(StyleSheet* aSheet);
     175             : 
     176             :   StyleSheet* GetFirstChild() const;
     177             :   StyleSheet* GetMostRecentlyAddedChildSheet() const {
     178             :     // New child sheet can only be prepended into the linked list of
     179             :     // child sheets, so the most recently added one is always the first.
     180             :     return GetFirstChild();
     181             :   }
     182             : 
     183             :   // Principal() never returns a null pointer.
     184             :   inline nsIPrincipal* Principal() const;
     185             :   /**
     186             :    * SetPrincipal should be called on all sheets before parsing into them.
     187             :    * This can only be called once with a non-null principal.  Calling this with
     188             :    * a null pointer is allowed and is treated as a no-op.
     189             :    */
     190             :   inline void SetPrincipal(nsIPrincipal* aPrincipal);
     191             : 
     192          73 :   void SetTitle(const nsAString& aTitle) { mTitle = aTitle; }
     193             :   void SetMedia(dom::MediaList* aMedia);
     194             : 
     195             :   // Get this style sheet's CORS mode
     196             :   inline CORSMode GetCORSMode() const;
     197             :   // Get this style sheet's Referrer Policy
     198             :   inline net::ReferrerPolicy GetReferrerPolicy() const;
     199             :   // Get this style sheet's integrity metadata
     200             :   inline void GetIntegrity(dom::SRIMetadata& aResult) const;
     201             : 
     202             :   virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
     203             : #ifdef DEBUG
     204             :   virtual void List(FILE* aOut = stdout, int32_t aIndex = 0) const;
     205             : #endif
     206             : 
     207             :   // WebIDL StyleSheet API
     208             :   // The XPCOM GetType is fine for WebIDL.
     209             :   // The XPCOM GetHref is fine for WebIDL
     210             :   // GetOwnerNode is defined above.
     211             :   inline StyleSheet* GetParentStyleSheet() const;
     212             :   // The XPCOM GetTitle is fine for WebIDL.
     213             :   dom::MediaList* Media();
     214           0 :   bool Disabled() const { return mDisabled; }
     215             :   // The XPCOM SetDisabled is fine for WebIDL.
     216             :   void GetSourceMapURL(nsAString& aTitle);
     217             :   void SetSourceMapURL(const nsAString& aSourceMapURL);
     218             : 
     219             :   // WebIDL CSSStyleSheet API
     220             :   // Can't be inline because we can't include ImportRule here.  And can't be
     221             :   // called GetOwnerRule because that would be ambiguous with the ImportRule
     222             :   // version.
     223             :   css::Rule* GetDOMOwnerRule() const;
     224             :   dom::CSSRuleList* GetCssRules(nsIPrincipal& aSubjectPrincipal,
     225             :                                 ErrorResult& aRv);
     226             :   uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex,
     227             :                       nsIPrincipal& aSubjectPrincipal,
     228             :                       ErrorResult& aRv);
     229             :   void DeleteRule(uint32_t aIndex,
     230             :                   nsIPrincipal& aSubjectPrincipal,
     231             :                   ErrorResult& aRv);
     232             : 
     233             :   // WebIDL miscellaneous bits
     234             :   inline dom::ParentObject GetParentObject() const;
     235             :   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
     236             : 
     237             :   // nsIDOMStyleSheet interface
     238             :   NS_IMETHOD GetType(nsAString& aType) final;
     239             :   NS_IMETHOD GetDisabled(bool* aDisabled) final;
     240             :   NS_IMETHOD SetDisabled(bool aDisabled) final;
     241             :   NS_IMETHOD GetOwnerNode(nsIDOMNode** aOwnerNode) final;
     242             :   NS_IMETHOD GetParentStyleSheet(nsIDOMStyleSheet** aParentStyleSheet) final;
     243             :   NS_IMETHOD GetHref(nsAString& aHref) final;
     244             :   NS_IMETHOD GetTitle(nsAString& aTitle) final;
     245             :   NS_IMETHOD GetMedia(nsIDOMMediaList** aMedia) final;
     246             : 
     247             :   // nsIDOMCSSStyleSheet
     248             :   NS_IMETHOD GetOwnerRule(nsIDOMCSSRule** aOwnerRule) final;
     249             :   NS_IMETHOD GetCssRules(nsIDOMCSSRuleList** aCssRules) final;
     250             :   NS_IMETHOD InsertRule(const nsAString& aRule, uint32_t aIndex,
     251             :                       uint32_t* aReturn) final;
     252             :   NS_IMETHOD DeleteRule(uint32_t aIndex) final;
     253             : 
     254             :   // Changes to sheets should be inside of a WillDirty-DidDirty pair.
     255             :   // However, the calls do not need to be matched; it's ok to call
     256             :   // WillDirty and then make no change and skip the DidDirty call.
     257             :   void WillDirty();
     258           0 :   virtual void DidDirty() {}
     259             : 
     260             :   void AddStyleSet(const StyleSetHandle& aStyleSet);
     261             :   void DropStyleSet(const StyleSetHandle& aStyleSet);
     262             : 
     263             :   nsresult DeleteRuleFromGroup(css::GroupRule* aGroup, uint32_t aIndex);
     264             :   nsresult InsertRuleIntoGroup(const nsAString& aRule,
     265             :                                css::GroupRule* aGroup, uint32_t aIndex);
     266             : 
     267             :   // Find the ID of the owner inner window.
     268             :   uint64_t FindOwningWindowInnerID() const;
     269             : 
     270             :   template<typename Func>
     271             :   void EnumerateChildSheets(Func aCallback) {
     272             :     for (StyleSheet* child = GetFirstChild(); child; child = child->mNext) {
     273             :       aCallback(child);
     274             :     }
     275             :   }
     276             : 
     277             : private:
     278             :   // Get a handle to the various stylesheet bits which live on the 'inner' for
     279             :   // gecko stylesheets and live on the StyleSheet for Servo stylesheets.
     280             :   inline StyleSheetInfo& SheetInfo();
     281             :   inline const StyleSheetInfo& SheetInfo() const;
     282             : 
     283             :   // Check if the rules are available for read and write.
     284             :   // It does the security check as well as whether the rules have been
     285             :   // completely loaded. aRv will have an exception set if this function
     286             :   // returns false.
     287             :   bool AreRulesAvailable(nsIPrincipal& aSubjectPrincipal,
     288             :                          ErrorResult& aRv);
     289             : 
     290             : protected:
     291             :   struct ChildSheetListBuilder {
     292             :     RefPtr<StyleSheet>* sheetSlot;
     293             :     StyleSheet* parent;
     294             : 
     295             :     void SetParentLinks(StyleSheet* aSheet);
     296             : 
     297             :     static void ReparentChildList(StyleSheet* aPrimarySheet,
     298             :                                   StyleSheet* aFirstChild);
     299             :   };
     300             : 
     301             :   void UnparentChildren();
     302             : 
     303             :   void LastRelease();
     304             : 
     305             :   // Return success if the subject principal subsumes the principal of our
     306             :   // inner, error otherwise.  This will also succeed if the subject has
     307             :   // UniversalXPConnect or if access is allowed by CORS.  In the latter case,
     308             :   // it will set the principal of the inner to the subject principal.
     309             :   void SubjectSubsumesInnerPrincipal(nsIPrincipal& aSubjectPrincipal,
     310             :                                      ErrorResult& aRv);
     311             : 
     312             :   // Drop our reference to mMedia
     313             :   void DropMedia();
     314             : 
     315             :   // Called from SetEnabled when the enabled state changed.
     316             :   void EnabledStateChanged();
     317             : 
     318             :   // Unlink our inner, if needed, for cycle collection
     319             :   virtual void UnlinkInner();
     320             :   // Traverse our inner, if needed, for cycle collection
     321             :   virtual void TraverseInner(nsCycleCollectionTraversalCallback &);
     322             : 
     323             :   // Return whether the given @import rule has pending child sheet.
     324             :   static bool RuleHasPendingChildSheet(css::Rule* aRule);
     325             : 
     326             :   StyleSheet*           mParent;    // weak ref
     327             : 
     328             :   nsString              mTitle;
     329             :   nsIDocument*          mDocument; // weak ref; parents maintain this for their children
     330             :   nsINode*              mOwningNode; // weak ref
     331             :   dom::CSSImportRule*   mOwnerRule; // weak ref
     332             : 
     333             :   RefPtr<dom::MediaList> mMedia;
     334             : 
     335             :   RefPtr<StyleSheet> mNext;
     336             : 
     337             :   // mParsingMode controls access to nonstandard style constructs that
     338             :   // are not safe for use on the public Web but necessary in UA sheets
     339             :   // and/or useful in user sheets.
     340             :   css::SheetParsingMode mParsingMode;
     341             : 
     342             :   const StyleBackendType mType;
     343             :   bool                  mDisabled;
     344             : 
     345             :   bool mDirty; // has been modified
     346             : 
     347             :   // mDocumentAssociationMode determines whether mDocument directly owns us (in
     348             :   // the sense that if it's known-live then we're known-live).  Always
     349             :   // NotOwnedByDocument when mDocument is null.
     350             :   DocumentAssociationMode mDocumentAssociationMode;
     351             : 
     352             :   // Core information we get from parsed sheets, which are shared amongst
     353             :   // StyleSheet clones.
     354             :   StyleSheetInfo* mInner;
     355             : 
     356             :   nsTArray<StyleSetHandle> mStyleSets;
     357             : 
     358             :   friend class ::nsCSSRuleProcessor;
     359             : 
     360             :   // Make CSSStyleSheet and ServoStyleSheet friends so they can access
     361             :   // protected members of other StyleSheet objects (useful for iterating
     362             :   // through children).
     363             :   friend class mozilla::CSSStyleSheet;
     364             :   friend class mozilla::ServoStyleSheet;
     365             : 
     366             :   // Make StyleSheetInfo and subclasses into friends so they can use
     367             :   // ChildSheetListBuilder.
     368             :   friend struct mozilla::StyleSheetInfo;
     369             :   friend struct mozilla::CSSStyleSheetInner;
     370             : };
     371             : 
     372             : } // namespace mozilla
     373             : 
     374             : #endif // mozilla_StyleSheet_h

Generated by: LCOV version 1.13