layout/style/nsCSSStyleSheet.h

changeset 2
7e26c7da4463
equal deleted inserted replaced
-1:000000000000 0:033b3667bb98
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 // vim:cindent:tabstop=2:expandtab:shiftwidth=2:
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 /* representation of a CSS style sheet */
8
9 #ifndef nsCSSStyleSheet_h_
10 #define nsCSSStyleSheet_h_
11
12 #include "mozilla/Attributes.h"
13 #include "mozilla/MemoryReporting.h"
14 #include "mozilla/dom/Element.h"
15
16 #include "nscore.h"
17 #include "nsCOMPtr.h"
18 #include "nsAutoPtr.h"
19 #include "nsIStyleSheet.h"
20 #include "nsIDOMCSSStyleSheet.h"
21 #include "nsICSSLoaderObserver.h"
22 #include "nsCOMArray.h"
23 #include "nsTArray.h"
24 #include "nsString.h"
25 #include "mozilla/CORSMode.h"
26 #include "nsCycleCollectionParticipant.h"
27 #include "nsWrapperCache.h"
28
29 class nsXMLNameSpaceMap;
30 class nsCSSRuleProcessor;
31 class nsIPrincipal;
32 class nsIURI;
33 class nsMediaList;
34 class nsMediaQueryResultCacheKey;
35 class nsCSSStyleSheet;
36 class nsPresContext;
37
38 namespace mozilla {
39 namespace css {
40 class Rule;
41 class GroupRule;
42 class ImportRule;
43 }
44 }
45
46 // -------------------------------
47 // CSS Style Sheet Inner Data Container
48 //
49
50 class nsCSSStyleSheetInner {
51 public:
52 friend class nsCSSStyleSheet;
53 friend class nsCSSRuleProcessor;
54 private:
55 nsCSSStyleSheetInner(nsCSSStyleSheet* aPrimarySheet,
56 mozilla::CORSMode aCORSMode);
57 nsCSSStyleSheetInner(nsCSSStyleSheetInner& aCopy,
58 nsCSSStyleSheet* aPrimarySheet);
59 ~nsCSSStyleSheetInner();
60
61 nsCSSStyleSheetInner* CloneFor(nsCSSStyleSheet* aPrimarySheet);
62 void AddSheet(nsCSSStyleSheet* aSheet);
63 void RemoveSheet(nsCSSStyleSheet* aSheet);
64
65 void RebuildNameSpaces();
66
67 // Create a new namespace map
68 nsresult CreateNamespaceMap();
69
70 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
71
72 nsAutoTArray<nsCSSStyleSheet*, 8> mSheets;
73 nsCOMPtr<nsIURI> mSheetURI; // for error reports, etc.
74 nsCOMPtr<nsIURI> mOriginalSheetURI; // for GetHref. Can be null.
75 nsCOMPtr<nsIURI> mBaseURI; // for resolving relative URIs
76 nsCOMPtr<nsIPrincipal> mPrincipal;
77 nsCOMArray<mozilla::css::Rule> mOrderedRules;
78 nsAutoPtr<nsXMLNameSpaceMap> mNameSpaceMap;
79 // Linked list of child sheets. This is al fundamentally broken, because
80 // each of the child sheets has a unique parent... We can only hope (and
81 // currently this is the case) that any time page JS can get ts hands on a
82 // child sheet that means we've already ensured unique inners throughout its
83 // parent chain and things are good.
84 nsRefPtr<nsCSSStyleSheet> mFirstChild;
85 mozilla::CORSMode mCORSMode;
86 bool mComplete;
87
88 #ifdef DEBUG
89 bool mPrincipalSet;
90 #endif
91 };
92
93
94 // -------------------------------
95 // CSS Style Sheet
96 //
97
98 class CSSRuleListImpl;
99
100 // CID for the nsCSSStyleSheet class
101 // ca926f30-2a7e-477e-8467-803fb32af20a
102 #define NS_CSS_STYLE_SHEET_IMPL_CID \
103 { 0xca926f30, 0x2a7e, 0x477e, \
104 { 0x84, 0x67, 0x80, 0x3f, 0xb3, 0x2a, 0xf2, 0x0a } }
105
106
107 class nsCSSStyleSheet MOZ_FINAL : public nsIStyleSheet,
108 public nsIDOMCSSStyleSheet,
109 public nsICSSLoaderObserver,
110 public nsWrapperCache
111 {
112 public:
113 nsCSSStyleSheet(mozilla::CORSMode aCORSMode);
114
115 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
116 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSStyleSheet,
117 nsIStyleSheet)
118
119 NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_SHEET_IMPL_CID)
120
121 // nsIStyleSheet interface
122 virtual nsIURI* GetSheetURI() const MOZ_OVERRIDE;
123 virtual nsIURI* GetBaseURI() const MOZ_OVERRIDE;
124 virtual void GetTitle(nsString& aTitle) const MOZ_OVERRIDE;
125 virtual void GetType(nsString& aType) const MOZ_OVERRIDE;
126 virtual bool HasRules() const MOZ_OVERRIDE;
127 virtual bool IsApplicable() const MOZ_OVERRIDE;
128 virtual void SetEnabled(bool aEnabled) MOZ_OVERRIDE;
129 virtual bool IsComplete() const MOZ_OVERRIDE;
130 virtual void SetComplete() MOZ_OVERRIDE;
131 virtual nsIStyleSheet* GetParentSheet() const MOZ_OVERRIDE; // may be null
132 virtual nsIDocument* GetOwningDocument() const MOZ_OVERRIDE; // may be null
133 virtual void SetOwningDocument(nsIDocument* aDocument) MOZ_OVERRIDE;
134
135 // Find the ID of the owner inner window.
136 uint64_t FindOwningWindowInnerID() const;
137 #ifdef DEBUG
138 virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
139 #endif
140
141 void AppendStyleSheet(nsCSSStyleSheet* aSheet);
142 void InsertStyleSheetAt(nsCSSStyleSheet* aSheet, int32_t aIndex);
143
144 // XXX do these belong here or are they generic?
145 void PrependStyleRule(mozilla::css::Rule* aRule);
146 void AppendStyleRule(mozilla::css::Rule* aRule);
147 void ReplaceStyleRule(mozilla::css::Rule* aOld, mozilla::css::Rule* aNew);
148
149 int32_t StyleRuleCount() const;
150 mozilla::css::Rule* GetStyleRuleAt(int32_t aIndex) const;
151
152 nsresult DeleteRuleFromGroup(mozilla::css::GroupRule* aGroup, uint32_t aIndex);
153 nsresult InsertRuleIntoGroup(const nsAString& aRule, mozilla::css::GroupRule* aGroup, uint32_t aIndex, uint32_t* _retval);
154 nsresult ReplaceRuleInGroup(mozilla::css::GroupRule* aGroup, mozilla::css::Rule* aOld, mozilla::css::Rule* aNew);
155
156 int32_t StyleSheetCount() const;
157
158 /**
159 * SetURIs must be called on all sheets before parsing into them.
160 * SetURIs may only be called while the sheet is 1) incomplete and 2)
161 * has no rules in it
162 */
163 void SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, nsIURI* aBaseURI);
164
165 /**
166 * SetPrincipal should be called on all sheets before parsing into them.
167 * This can only be called once with a non-null principal. Calling this with
168 * a null pointer is allowed and is treated as a no-op.
169 */
170 void SetPrincipal(nsIPrincipal* aPrincipal);
171
172 // Principal() never returns a null pointer.
173 nsIPrincipal* Principal() const { return mInner->mPrincipal; }
174
175 // The document this style sheet is associated with. May be null
176 nsIDocument* GetDocument() const { return mDocument; }
177
178 void SetTitle(const nsAString& aTitle) { mTitle = aTitle; }
179 void SetMedia(nsMediaList* aMedia);
180 void SetOwningNode(nsINode* aOwningNode) { mOwningNode = aOwningNode; /* Not ref counted */ }
181
182 void SetOwnerRule(mozilla::css::ImportRule* aOwnerRule) { mOwnerRule = aOwnerRule; /* Not ref counted */ }
183 mozilla::css::ImportRule* GetOwnerRule() const { return mOwnerRule; }
184
185 nsXMLNameSpaceMap* GetNameSpaceMap() const { return mInner->mNameSpaceMap; }
186
187 already_AddRefed<nsCSSStyleSheet> Clone(nsCSSStyleSheet* aCloneParent,
188 mozilla::css::ImportRule* aCloneOwnerRule,
189 nsIDocument* aCloneDocument,
190 nsINode* aCloneOwningNode) const;
191
192 bool IsModified() const { return mDirty; }
193
194 void SetModifiedByChildRule() {
195 NS_ASSERTION(mDirty,
196 "sheet must be marked dirty before handing out child rules");
197 DidDirty();
198 }
199
200 nsresult AddRuleProcessor(nsCSSRuleProcessor* aProcessor);
201 nsresult DropRuleProcessor(nsCSSRuleProcessor* aProcessor);
202
203 /**
204 * Like the DOM insertRule() method, but doesn't do any security checks
205 */
206 nsresult InsertRuleInternal(const nsAString& aRule,
207 uint32_t aIndex, uint32_t* aReturn);
208
209 /* Get the URI this sheet was originally loaded from, if any. Can
210 return null */
211 virtual nsIURI* GetOriginalURI() const;
212
213 // nsICSSLoaderObserver interface
214 NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, bool aWasAlternate,
215 nsresult aStatus) MOZ_OVERRIDE;
216
217 enum EnsureUniqueInnerResult {
218 // No work was needed to ensure a unique inner.
219 eUniqueInner_AlreadyUnique,
220 // A clone was done to ensure a unique inner (which means the style
221 // rules in this sheet have changed).
222 eUniqueInner_ClonedInner
223 };
224 EnsureUniqueInnerResult EnsureUniqueInner();
225
226 // Append all of this sheet's child sheets to aArray.
227 void AppendAllChildSheets(nsTArray<nsCSSStyleSheet*>& aArray);
228
229 bool UseForPresentation(nsPresContext* aPresContext,
230 nsMediaQueryResultCacheKey& aKey) const;
231
232 nsresult ParseSheet(const nsAString& aInput);
233
234 // nsIDOMStyleSheet interface
235 NS_DECL_NSIDOMSTYLESHEET
236
237 // nsIDOMCSSStyleSheet interface
238 NS_DECL_NSIDOMCSSSTYLESHEET
239
240 // Function used as a callback to rebuild our inner's child sheet
241 // list after we clone a unique inner for ourselves.
242 static bool RebuildChildList(mozilla::css::Rule* aRule, void* aBuilder);
243
244 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
245
246 // Get this style sheet's CORS mode
247 mozilla::CORSMode GetCORSMode() const { return mInner->mCORSMode; }
248
249 mozilla::dom::Element* GetScopeElement() const { return mScopeElement; }
250 void SetScopeElement(mozilla::dom::Element* aScopeElement)
251 {
252 mScopeElement = aScopeElement;
253 }
254
255 // WebIDL StyleSheet API
256 // Our nsIStyleSheet::GetType is a const method, so it ends up
257 // ambiguous with with the XPCOM version. Just disambiguate.
258 void GetType(nsString& aType) {
259 const_cast<const nsCSSStyleSheet*>(this)->GetType(aType);
260 }
261 // Our XPCOM GetHref is fine for WebIDL
262 nsINode* GetOwnerNode() const { return mOwningNode; }
263 nsCSSStyleSheet* GetParentStyleSheet() const { return mParent; }
264 // Our nsIStyleSheet::GetTitle is a const method, so it ends up
265 // ambiguous with with the XPCOM version. Just disambiguate.
266 void GetTitle(nsString& aTitle) {
267 const_cast<const nsCSSStyleSheet*>(this)->GetTitle(aTitle);
268 }
269 nsMediaList* Media();
270 bool Disabled() const { return mDisabled; }
271 // The XPCOM SetDisabled is fine for WebIDL
272
273 // WebIDL CSSStyleSheet API
274 // Can't be inline because we can't include ImportRule here. And can't be
275 // called GetOwnerRule because that would be ambiguous with the ImportRule
276 // version.
277 nsIDOMCSSRule* GetDOMOwnerRule() const;
278 nsIDOMCSSRuleList* GetCssRules(mozilla::ErrorResult& aRv);
279 uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex,
280 mozilla::ErrorResult& aRv) {
281 uint32_t retval;
282 aRv = InsertRule(aRule, aIndex, &retval);
283 return retval;
284 }
285 void DeleteRule(uint32_t aIndex, mozilla::ErrorResult& aRv) {
286 aRv = DeleteRule(aIndex);
287 }
288
289 // WebIDL miscellaneous bits
290 mozilla::dom::ParentObject GetParentObject() const {
291 if (mOwningNode) {
292 return mozilla::dom::ParentObject(mOwningNode);
293 }
294
295 return mozilla::dom::ParentObject(static_cast<nsIStyleSheet*>(mParent),
296 mParent);
297 }
298 virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
299
300 private:
301 nsCSSStyleSheet(const nsCSSStyleSheet& aCopy,
302 nsCSSStyleSheet* aParentToUse,
303 mozilla::css::ImportRule* aOwnerRuleToUse,
304 nsIDocument* aDocumentToUse,
305 nsINode* aOwningNodeToUse);
306
307 nsCSSStyleSheet(const nsCSSStyleSheet& aCopy) MOZ_DELETE;
308 nsCSSStyleSheet& operator=(const nsCSSStyleSheet& aCopy) MOZ_DELETE;
309
310 protected:
311 virtual ~nsCSSStyleSheet();
312
313 void ClearRuleCascades();
314
315 void WillDirty();
316 void DidDirty();
317
318 // Return success if the subject principal subsumes the principal of our
319 // inner, error otherwise. This will also succeed if the subject has
320 // UniversalXPConnect or if access is allowed by CORS. In the latter case,
321 // it will set the principal of the inner to the subject principal.
322 nsresult SubjectSubsumesInnerPrincipal();
323
324 // Add the namespace mapping from this @namespace rule to our namespace map
325 nsresult RegisterNamespaceRule(mozilla::css::Rule* aRule);
326
327 // Drop our reference to mRuleCollection
328 void DropRuleCollection();
329
330 // Drop our reference to mMedia
331 void DropMedia();
332
333 // Unlink our inner, if needed, for cycle collection
334 void UnlinkInner();
335 // Traverse our inner, if needed, for cycle collection
336 void TraverseInner(nsCycleCollectionTraversalCallback &);
337
338 protected:
339 nsString mTitle;
340 nsRefPtr<nsMediaList> mMedia;
341 nsRefPtr<nsCSSStyleSheet> mNext;
342 nsCSSStyleSheet* mParent; // weak ref
343 mozilla::css::ImportRule* mOwnerRule; // weak ref
344
345 nsRefPtr<CSSRuleListImpl> mRuleCollection;
346 nsIDocument* mDocument; // weak ref; parents maintain this for their children
347 nsINode* mOwningNode; // weak ref
348 bool mDisabled;
349 bool mDirty; // has been modified
350 nsRefPtr<mozilla::dom::Element> mScopeElement;
351
352 nsCSSStyleSheetInner* mInner;
353
354 nsAutoTArray<nsCSSRuleProcessor*, 8>* mRuleProcessors;
355
356 friend class nsMediaList;
357 friend class nsCSSRuleProcessor;
358 friend struct ChildSheetListBuilder;
359 };
360
361 NS_DEFINE_STATIC_IID_ACCESSOR(nsCSSStyleSheet, NS_CSS_STYLE_SHEET_IMPL_CID)
362
363 #endif /* !defined(nsCSSStyleSheet_h_) */

mercurial