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 "nsIDOMCSSStyleSheet.h"
18 #include "nsWrapperCache.h"
19 
20 class nsIDocument;
21 class nsINode;
22 class nsIPrincipal;
23 class nsMediaList;
24 
25 namespace mozilla {
26 
27 class CSSStyleSheet;
28 class ServoStyleSheet;
29 struct StyleSheetInfo;
30 
31 namespace dom {
32 class CSSRuleList;
33 class SRIMetadata;
34 } // namespace dom
35 
36 /**
37  * Superclass for data common to CSSStyleSheet and ServoStyleSheet.
38  */
39 class StyleSheet : public nsIDOMCSSStyleSheet
40                  , public nsWrapperCache
41 {
42 protected:
43   StyleSheet(StyleBackendType aType, css::SheetParsingMode aParsingMode);
44   StyleSheet(const StyleSheet& aCopy,
45              nsIDocument* aDocumentToUse,
46              nsINode* aOwningNodeToUse);
~StyleSheet()47   virtual ~StyleSheet() {}
48 
49 public:
50   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(StyleSheet)51   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(StyleSheet)
52 
53   void SetOwningNode(nsINode* aOwningNode)
54   {
55     mOwningNode = aOwningNode;
56   }
57 
ParsingMode()58   css::SheetParsingMode ParsingMode() { return mParsingMode; }
59   mozilla::dom::CSSStyleSheetParsingMode ParsingModeDOM();
60 
61   // The document this style sheet is associated with.  May be null
GetDocument()62   nsIDocument* GetDocument() const { return mDocument; }
63 
64   /**
65    * Whether the sheet is complete.
66    */
67   bool IsComplete() const;
68   void SetComplete();
69 
70   MOZ_DECL_STYLO_METHODS(CSSStyleSheet, ServoStyleSheet)
71 
72   // Whether the sheet is for an inline <style> element.
73   inline bool IsInline() const;
74 
75   inline nsIURI* GetSheetURI() const;
76   /* Get the URI this sheet was originally loaded from, if any.  Can
77      return null */
78   inline nsIURI* GetOriginalURI() const;
79   inline nsIURI* GetBaseURI() const;
80   /**
81    * SetURIs must be called on all sheets before parsing into them.
82    * SetURIs may only be called while the sheet is 1) incomplete and 2)
83    * has no rules in it
84    */
85   inline void SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI,
86                       nsIURI* aBaseURI);
87 
88   /**
89    * Whether the sheet is applicable.  A sheet that is not applicable
90    * should never be inserted into a style set.  A sheet may not be
91    * applicable for a variety of reasons including being disabled and
92    * being incomplete.
93    */
94   inline bool IsApplicable() const;
95   inline bool HasRules() const;
96 
97   // style sheet owner info
GetOwningDocument()98   nsIDocument* GetOwningDocument() const { return mDocument; }
99   inline void SetOwningDocument(nsIDocument* aDocument);
GetOwnerNode()100   nsINode* GetOwnerNode() const { return mOwningNode; }
101   inline StyleSheet* GetParentSheet() const;
102 
103   inline void AppendStyleSheet(StyleSheet* aSheet);
104 
105   // Principal() never returns a null pointer.
106   inline nsIPrincipal* Principal() const;
107   /**
108    * SetPrincipal should be called on all sheets before parsing into them.
109    * This can only be called once with a non-null principal.  Calling this with
110    * a null pointer is allowed and is treated as a no-op.
111    */
112   inline void SetPrincipal(nsIPrincipal* aPrincipal);
113 
114   // Get this style sheet's CORS mode
115   inline CORSMode GetCORSMode() const;
116   // Get this style sheet's Referrer Policy
117   inline net::ReferrerPolicy GetReferrerPolicy() const;
118   // Get this style sheet's integrity metadata
119   inline void GetIntegrity(dom::SRIMetadata& aResult) const;
120 
121   inline size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
122 #ifdef DEBUG
123   inline void List(FILE* aOut = stdout, int32_t aIndex = 0) const;
124 #endif
125 
126   // WebIDL StyleSheet API
127   // The XPCOM GetType is fine for WebIDL.
128   // The XPCOM GetHref is fine for WebIDL
129   // GetOwnerNode is defined above.
130   inline StyleSheet* GetParentStyleSheet() const;
131   // The XPCOM GetTitle is fine for WebIDL.
132   virtual nsMediaList* Media() = 0;
Disabled()133   bool Disabled() const { return mDisabled; }
134   // The XPCOM SetDisabled is fine for WebIDL.
135 
136   // WebIDL CSSStyleSheet API
137   virtual nsIDOMCSSRule* GetDOMOwnerRule() const = 0;
138   dom::CSSRuleList* GetCssRules(nsIPrincipal& aSubjectPrincipal,
139                                 ErrorResult& aRv);
140   uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex,
141                       nsIPrincipal& aSubjectPrincipal,
142                       ErrorResult& aRv);
143   void DeleteRule(uint32_t aIndex,
144                   nsIPrincipal& aSubjectPrincipal,
145                   ErrorResult& aRv);
146 
147   // WebIDL miscellaneous bits
148   inline dom::ParentObject GetParentObject() const;
149   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
150 
151   // nsIDOMStyleSheet interface
152   NS_IMETHOD GetType(nsAString& aType) final;
153   NS_IMETHOD GetDisabled(bool* aDisabled) final;
154   NS_IMETHOD SetDisabled(bool aDisabled) final;
155   NS_IMETHOD GetOwnerNode(nsIDOMNode** aOwnerNode) final;
156   NS_IMETHOD GetParentStyleSheet(nsIDOMStyleSheet** aParentStyleSheet) final;
157   NS_IMETHOD GetHref(nsAString& aHref) final;
158   NS_IMETHOD GetTitle(nsAString& aTitle) final;
159   NS_IMETHOD GetMedia(nsIDOMMediaList** aMedia) final;
160 
161   // nsIDOMCSSStyleSheet
162   NS_IMETHOD GetOwnerRule(nsIDOMCSSRule** aOwnerRule) final;
163   NS_IMETHOD GetCssRules(nsIDOMCSSRuleList** aCssRules) final;
164   NS_IMETHOD InsertRule(const nsAString& aRule, uint32_t aIndex,
165                       uint32_t* aReturn) final;
166   NS_IMETHOD DeleteRule(uint32_t aIndex) final;
167 
168   // Changes to sheets should be inside of a WillDirty-DidDirty pair.
169   // However, the calls do not need to be matched; it's ok to call
170   // WillDirty and then make no change and skip the DidDirty call.
171   inline void WillDirty();
172   inline void DidDirty();
173 
174 private:
175   // Get a handle to the various stylesheet bits which live on the 'inner' for
176   // gecko stylesheets and live on the StyleSheet for Servo stylesheets.
177   inline StyleSheetInfo& SheetInfo();
178   inline const StyleSheetInfo& SheetInfo() const;
179 
180   // Check if the rules are available for read and write.
181   // It does the security check as well as whether the rules have been
182   // completely loaded. aRv will have an exception set if this function
183   // returns false.
184   bool AreRulesAvailable(nsIPrincipal& aSubjectPrincipal,
185                          ErrorResult& aRv);
186 
187 protected:
188   // Return success if the subject principal subsumes the principal of our
189   // inner, error otherwise.  This will also succeed if the subject has
190   // UniversalXPConnect or if access is allowed by CORS.  In the latter case,
191   // it will set the principal of the inner to the subject principal.
192   void SubjectSubsumesInnerPrincipal(nsIPrincipal& aSubjectPrincipal,
193                                      ErrorResult& aRv);
194 
195   nsString              mTitle;
196   nsIDocument*          mDocument; // weak ref; parents maintain this for their children
197   nsINode*              mOwningNode; // weak ref
198 
199   // mParsingMode controls access to nonstandard style constructs that
200   // are not safe for use on the public Web but necessary in UA sheets
201   // and/or useful in user sheets.
202   css::SheetParsingMode mParsingMode;
203 
204   const StyleBackendType mType;
205   bool                  mDisabled;
206 };
207 
208 } // namespace mozilla
209 
210 #endif // mozilla_StyleSheet_h
211