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