|
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 /* loading of CSS style sheets using the network APIs */ |
|
7 |
|
8 #ifndef mozilla_css_Loader_h |
|
9 #define mozilla_css_Loader_h |
|
10 |
|
11 #include "nsIPrincipal.h" |
|
12 #include "nsAString.h" |
|
13 #include "nsAutoPtr.h" |
|
14 #include "nsCompatibility.h" |
|
15 #include "nsDataHashtable.h" |
|
16 #include "nsInterfaceHashtable.h" |
|
17 #include "nsRefPtrHashtable.h" |
|
18 #include "nsTArray.h" |
|
19 #include "nsTObserverArray.h" |
|
20 #include "nsURIHashKey.h" |
|
21 #include "mozilla/Attributes.h" |
|
22 #include "mozilla/CORSMode.h" |
|
23 #include "mozilla/MemoryReporting.h" |
|
24 |
|
25 class nsIAtom; |
|
26 class nsICSSLoaderObserver; |
|
27 class nsCSSStyleSheet; |
|
28 class nsIContent; |
|
29 class nsIDocument; |
|
30 class nsCSSParser; |
|
31 class nsMediaList; |
|
32 class nsIStyleSheetLinkingElement; |
|
33 class nsCycleCollectionTraversalCallback; |
|
34 |
|
35 namespace mozilla { |
|
36 namespace dom { |
|
37 class Element; |
|
38 } |
|
39 } |
|
40 |
|
41 namespace mozilla { |
|
42 |
|
43 class URIPrincipalAndCORSModeHashKey : public nsURIHashKey |
|
44 { |
|
45 public: |
|
46 typedef URIPrincipalAndCORSModeHashKey* KeyType; |
|
47 typedef const URIPrincipalAndCORSModeHashKey* KeyTypePointer; |
|
48 |
|
49 URIPrincipalAndCORSModeHashKey(const URIPrincipalAndCORSModeHashKey* aKey) |
|
50 : nsURIHashKey(aKey->mKey), mPrincipal(aKey->mPrincipal), |
|
51 mCORSMode(aKey->mCORSMode) |
|
52 { |
|
53 MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey); |
|
54 } |
|
55 URIPrincipalAndCORSModeHashKey(nsIURI* aURI, nsIPrincipal* aPrincipal, |
|
56 CORSMode aCORSMode) |
|
57 : nsURIHashKey(aURI), mPrincipal(aPrincipal), mCORSMode(aCORSMode) |
|
58 { |
|
59 MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey); |
|
60 } |
|
61 URIPrincipalAndCORSModeHashKey(const URIPrincipalAndCORSModeHashKey& toCopy) |
|
62 : nsURIHashKey(toCopy), mPrincipal(toCopy.mPrincipal), |
|
63 mCORSMode(toCopy.mCORSMode) |
|
64 { |
|
65 MOZ_COUNT_CTOR(URIPrincipalAndCORSModeHashKey); |
|
66 } |
|
67 ~URIPrincipalAndCORSModeHashKey() |
|
68 { |
|
69 MOZ_COUNT_DTOR(URIPrincipalAndCORSModeHashKey); |
|
70 } |
|
71 |
|
72 URIPrincipalAndCORSModeHashKey* GetKey() const { |
|
73 return const_cast<URIPrincipalAndCORSModeHashKey*>(this); |
|
74 } |
|
75 const URIPrincipalAndCORSModeHashKey* GetKeyPointer() const { return this; } |
|
76 |
|
77 bool KeyEquals(const URIPrincipalAndCORSModeHashKey* aKey) const { |
|
78 if (!nsURIHashKey::KeyEquals(aKey->mKey)) { |
|
79 return false; |
|
80 } |
|
81 |
|
82 if (!mPrincipal != !aKey->mPrincipal) { |
|
83 // One or the other has a principal, but not both... not equal |
|
84 return false; |
|
85 } |
|
86 |
|
87 if (mCORSMode != aKey->mCORSMode) { |
|
88 // Different CORS modes; we don't match |
|
89 return false; |
|
90 } |
|
91 |
|
92 bool eq; |
|
93 return !mPrincipal || |
|
94 (NS_SUCCEEDED(mPrincipal->Equals(aKey->mPrincipal, &eq)) && eq); |
|
95 } |
|
96 |
|
97 static const URIPrincipalAndCORSModeHashKey* |
|
98 KeyToPointer(URIPrincipalAndCORSModeHashKey* aKey) { return aKey; } |
|
99 static PLDHashNumber HashKey(const URIPrincipalAndCORSModeHashKey* aKey) { |
|
100 return nsURIHashKey::HashKey(aKey->mKey); |
|
101 } |
|
102 |
|
103 nsIURI* GetURI() const { return nsURIHashKey::GetKey(); } |
|
104 |
|
105 enum { ALLOW_MEMMOVE = true }; |
|
106 |
|
107 protected: |
|
108 nsCOMPtr<nsIPrincipal> mPrincipal; |
|
109 CORSMode mCORSMode; |
|
110 }; |
|
111 |
|
112 |
|
113 |
|
114 namespace css { |
|
115 |
|
116 class SheetLoadData; |
|
117 class ImportRule; |
|
118 |
|
119 /*********************************************************************** |
|
120 * Enum that describes the state of the sheet returned by CreateSheet. * |
|
121 ***********************************************************************/ |
|
122 enum StyleSheetState { |
|
123 eSheetStateUnknown = 0, |
|
124 eSheetNeedsParser, |
|
125 eSheetPending, |
|
126 eSheetLoading, |
|
127 eSheetComplete |
|
128 }; |
|
129 |
|
130 class Loader MOZ_FINAL { |
|
131 public: |
|
132 Loader(); |
|
133 Loader(nsIDocument*); |
|
134 |
|
135 private: |
|
136 // Private destructor, to discourage deletion outside of Release(): |
|
137 ~Loader(); |
|
138 |
|
139 public: |
|
140 NS_INLINE_DECL_REFCOUNTING(Loader) |
|
141 |
|
142 void DropDocumentReference(); // notification that doc is going away |
|
143 |
|
144 void SetCompatibilityMode(nsCompatibility aCompatMode) |
|
145 { mCompatMode = aCompatMode; } |
|
146 nsCompatibility GetCompatibilityMode() { return mCompatMode; } |
|
147 nsresult SetPreferredSheet(const nsAString& aTitle); |
|
148 |
|
149 // XXXbz sort out what the deal is with events! When should they fire? |
|
150 |
|
151 /** |
|
152 * Load an inline style sheet. If a successful result is returned and |
|
153 * *aCompleted is false, then aObserver is guaranteed to be notified |
|
154 * asynchronously once the sheet is marked complete. If an error is |
|
155 * returned, or if *aCompleted is true, aObserver will not be notified. In |
|
156 * addition to parsing the sheet, this method will insert it into the |
|
157 * stylesheet list of this CSSLoader's document. |
|
158 * |
|
159 * @param aElement the element linking to the stylesheet. This must not be |
|
160 * null and must implement nsIStyleSheetLinkingElement. |
|
161 * @param aBuffer the stylesheet data |
|
162 * @param aLineNumber the line number at which the stylesheet data started. |
|
163 * @param aTitle the title of the sheet. |
|
164 * @param aMedia the media string for the sheet. |
|
165 * @param aObserver the observer to notify when the load completes. |
|
166 * May be null. |
|
167 * @param [out] aCompleted whether parsing of the sheet completed. |
|
168 * @param [out] aIsAlternate whether the stylesheet ended up being an |
|
169 * alternate sheet. |
|
170 */ |
|
171 nsresult LoadInlineStyle(nsIContent* aElement, |
|
172 const nsAString& aBuffer, |
|
173 uint32_t aLineNumber, |
|
174 const nsAString& aTitle, |
|
175 const nsAString& aMedia, |
|
176 mozilla::dom::Element* aScopeElement, |
|
177 nsICSSLoaderObserver* aObserver, |
|
178 bool* aCompleted, |
|
179 bool* aIsAlternate); |
|
180 |
|
181 /** |
|
182 * Load a linked (document) stylesheet. If a successful result is returned, |
|
183 * aObserver is guaranteed to be notified asynchronously once the sheet is |
|
184 * loaded and marked complete. If an error is returned, aObserver will not |
|
185 * be notified. In addition to loading the sheet, this method will insert it |
|
186 * into the stylesheet list of this CSSLoader's document. |
|
187 * |
|
188 * @param aElement the element linking to the the stylesheet. May be null. |
|
189 * @param aURL the URL of the sheet. |
|
190 * @param aTitle the title of the sheet. |
|
191 * @param aMedia the media string for the sheet. |
|
192 * @param aHasAlternateRel whether the rel for this link included |
|
193 * "alternate". |
|
194 * @param aCORSMode the CORS mode for this load. |
|
195 * @param aObserver the observer to notify when the load completes. |
|
196 * May be null. |
|
197 * @param [out] aIsAlternate whether the stylesheet actually ended up beinga |
|
198 * an alternate sheet. Note that this need not match |
|
199 * aHasAlternateRel. |
|
200 */ |
|
201 nsresult LoadStyleLink(nsIContent* aElement, |
|
202 nsIURI* aURL, |
|
203 const nsAString& aTitle, |
|
204 const nsAString& aMedia, |
|
205 bool aHasAlternateRel, |
|
206 CORSMode aCORSMode, |
|
207 nsICSSLoaderObserver* aObserver, |
|
208 bool* aIsAlternate); |
|
209 |
|
210 /** |
|
211 * Load a child (@import-ed) style sheet. In addition to loading the sheet, |
|
212 * this method will insert it into the child sheet list of aParentSheet. If |
|
213 * there is no sheet currently being parsed and the child sheet is not |
|
214 * complete when this method returns, then when the child sheet becomes |
|
215 * complete aParentSheet will be QIed to nsICSSLoaderObserver and |
|
216 * asynchronously notified, just like for LoadStyleLink. Note that if the |
|
217 * child sheet is already complete when this method returns, no |
|
218 * nsICSSLoaderObserver notification will be sent. |
|
219 * |
|
220 * @param aParentSheet the parent of this child sheet |
|
221 * @param aURL the URL of the child sheet |
|
222 * @param aMedia the already-parsed media list for the child sheet |
|
223 * @param aRule the @import rule importing this child. This is used to |
|
224 * properly order the child sheet list of aParentSheet. |
|
225 */ |
|
226 nsresult LoadChildSheet(nsCSSStyleSheet* aParentSheet, |
|
227 nsIURI* aURL, |
|
228 nsMediaList* aMedia, |
|
229 ImportRule* aRule); |
|
230 |
|
231 /** |
|
232 * Synchronously load and return the stylesheet at aURL. Any child sheets |
|
233 * will also be loaded synchronously. Note that synchronous loads over some |
|
234 * protocols may involve spinning up a new event loop, so use of this method |
|
235 * does NOT guarantee not receiving any events before the sheet loads. This |
|
236 * method can be used to load sheets not associated with a document. |
|
237 * |
|
238 * @param aURL the URL of the sheet to load |
|
239 * @param aEnableUnsafeRules whether unsafe rules are enabled for this |
|
240 * sheet load |
|
241 * Unsafe rules are rules that can violate key Gecko invariants if misused. |
|
242 * In particular, most anonymous box pseudoelements must be very carefully |
|
243 * styled or we will have severe problems. Therefore unsafe rules should |
|
244 * never be enabled for stylesheets controlled by untrusted sites; preferably |
|
245 * unsafe rules should only be enabled for agent sheets. |
|
246 * @param aUseSystemPrincipal if true, give the resulting sheet the system |
|
247 * principal no matter where it's being loaded from. |
|
248 * @param [out] aSheet the loaded, complete sheet. |
|
249 * |
|
250 * NOTE: At the moment, this method assumes the sheet will be UTF-8, but |
|
251 * ideally it would allow arbitrary encodings. Callers should NOT depend on |
|
252 * non-UTF8 sheets being treated as UTF-8 by this method. |
|
253 * |
|
254 * NOTE: A successful return from this method doesn't indicate anything about |
|
255 * whether the data could be parsed as CSS and doesn't indicate anything |
|
256 * about the status of child sheets of the returned sheet. |
|
257 */ |
|
258 nsresult LoadSheetSync(nsIURI* aURL, bool aEnableUnsafeRules, |
|
259 bool aUseSystemPrincipal, |
|
260 nsCSSStyleSheet** aSheet); |
|
261 |
|
262 /** |
|
263 * As above, but aUseSystemPrincipal and aEnableUnsafeRules are assumed false. |
|
264 */ |
|
265 nsresult LoadSheetSync(nsIURI* aURL, nsCSSStyleSheet** aSheet) { |
|
266 return LoadSheetSync(aURL, false, false, aSheet); |
|
267 } |
|
268 |
|
269 /** |
|
270 * Asynchronously load the stylesheet at aURL. If a successful result is |
|
271 * returned, aObserver is guaranteed to be notified asynchronously once the |
|
272 * sheet is loaded and marked complete. This method can be used to load |
|
273 * sheets not associated with a document. |
|
274 * |
|
275 * @param aURL the URL of the sheet to load |
|
276 * @param aOriginPrincipal the principal to use for security checks. This |
|
277 * can be null to indicate that these checks should |
|
278 * be skipped. |
|
279 * @param aCharset the encoding to use for converting the sheet data |
|
280 * from bytes to Unicode. May be empty to indicate that the |
|
281 * charset of the CSSLoader's document should be used. This |
|
282 * is only used if neither the network transport nor the |
|
283 * sheet itself indicate an encoding. |
|
284 * @param aObserver the observer to notify when the load completes. |
|
285 * Must not be null. |
|
286 * @param [out] aSheet the sheet to load. Note that the sheet may well |
|
287 * not be loaded by the time this method returns. |
|
288 */ |
|
289 nsresult LoadSheet(nsIURI* aURL, |
|
290 nsIPrincipal* aOriginPrincipal, |
|
291 const nsCString& aCharset, |
|
292 nsICSSLoaderObserver* aObserver, |
|
293 nsCSSStyleSheet** aSheet); |
|
294 |
|
295 /** |
|
296 * Same as above, to be used when the caller doesn't care about the |
|
297 * not-yet-loaded sheet. |
|
298 */ |
|
299 nsresult LoadSheet(nsIURI* aURL, |
|
300 nsIPrincipal* aOriginPrincipal, |
|
301 const nsCString& aCharset, |
|
302 nsICSSLoaderObserver* aObserver, |
|
303 CORSMode aCORSMode = CORS_NONE); |
|
304 |
|
305 /** |
|
306 * Stop loading all sheets. All nsICSSLoaderObservers involved will be |
|
307 * notified with NS_BINDING_ABORTED as the status, possibly synchronously. |
|
308 */ |
|
309 nsresult Stop(void); |
|
310 |
|
311 /** |
|
312 * nsresult Loader::StopLoadingSheet(nsIURI* aURL), which notifies the |
|
313 * nsICSSLoaderObserver with NS_BINDING_ABORTED, was removed in Bug 556446. |
|
314 * It can be found in revision 2c44a32052ad. |
|
315 */ |
|
316 |
|
317 /** |
|
318 * Whether the loader is enabled or not. |
|
319 * When disabled, processing of new styles is disabled and an attempt |
|
320 * to do so will fail with a return code of |
|
321 * NS_ERROR_NOT_AVAILABLE. Note that this DOES NOT disable |
|
322 * currently loading styles or already processed styles. |
|
323 */ |
|
324 bool GetEnabled() { return mEnabled; } |
|
325 void SetEnabled(bool aEnabled) { mEnabled = aEnabled; } |
|
326 |
|
327 /** |
|
328 * Get the document we live for. May return null. |
|
329 */ |
|
330 nsIDocument* GetDocument() const { return mDocument; } |
|
331 |
|
332 /** |
|
333 * Return true if this loader has pending loads (ones that would send |
|
334 * notifications to an nsICSSLoaderObserver attached to this loader). |
|
335 * If called from inside nsICSSLoaderObserver::StyleSheetLoaded, this will |
|
336 * return false if and only if that is the last StyleSheetLoaded |
|
337 * notification the CSSLoader knows it's going to send. In other words, if |
|
338 * two sheets load at once (via load coalescing, e.g.), HasPendingLoads() |
|
339 * will return true during notification for the first one, and false |
|
340 * during notification for the second one. |
|
341 */ |
|
342 bool HasPendingLoads(); |
|
343 |
|
344 /** |
|
345 * Add an observer to this loader. The observer will be notified |
|
346 * for all loads that would have notified their own observers (even |
|
347 * if those loads don't have observers attached to them). |
|
348 * Load-specific observers will be notified before generic |
|
349 * observers. The loader holds a reference to the observer. |
|
350 * |
|
351 * aObserver must not be null. |
|
352 */ |
|
353 nsresult AddObserver(nsICSSLoaderObserver* aObserver); |
|
354 |
|
355 /** |
|
356 * Remove an observer added via AddObserver. |
|
357 */ |
|
358 void RemoveObserver(nsICSSLoaderObserver* aObserver); |
|
359 |
|
360 // These interfaces are public only for the benefit of static functions |
|
361 // within nsCSSLoader.cpp. |
|
362 |
|
363 // IsAlternate can change our currently selected style set if none |
|
364 // is selected and aHasAlternateRel is false. |
|
365 bool IsAlternate(const nsAString& aTitle, bool aHasAlternateRel); |
|
366 |
|
367 typedef nsTArray<nsRefPtr<SheetLoadData> > LoadDataArray; |
|
368 |
|
369 // Traverse the cached stylesheets we're holding on to. This should |
|
370 // only be called from the document that owns this loader. |
|
371 void TraverseCachedSheets(nsCycleCollectionTraversalCallback& cb); |
|
372 |
|
373 // Unlink the cached stylesheets we're holding on to. Again, this |
|
374 // should only be called from the document that owns this loader. |
|
375 void UnlinkCachedSheets(); |
|
376 |
|
377 // Measure our size. |
|
378 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; |
|
379 |
|
380 // Marks all the sheets at the given URI obsolete, and removes them from the |
|
381 // cache. |
|
382 nsresult ObsoleteSheet(nsIURI* aURI); |
|
383 |
|
384 private: |
|
385 friend class SheetLoadData; |
|
386 |
|
387 static PLDHashOperator |
|
388 RemoveEntriesWithURI(URIPrincipalAndCORSModeHashKey* aKey, |
|
389 nsRefPtr<nsCSSStyleSheet> &aSheet, |
|
390 void* aUserData); |
|
391 |
|
392 // Note: null aSourcePrincipal indicates that the content policy and |
|
393 // CheckLoadURI checks should be skipped. |
|
394 nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal, |
|
395 nsIURI* aTargetURI, |
|
396 nsISupports* aContext); |
|
397 |
|
398 |
|
399 // For inline style, the aURI param is null, but the aLinkingContent |
|
400 // must be non-null then. The loader principal must never be null |
|
401 // if aURI is not null. |
|
402 // *aIsAlternate is set based on aTitle and aHasAlternateRel. |
|
403 nsresult CreateSheet(nsIURI* aURI, |
|
404 nsIContent* aLinkingContent, |
|
405 nsIPrincipal* aLoaderPrincipal, |
|
406 CORSMode aCORSMode, |
|
407 bool aSyncLoad, |
|
408 bool aHasAlternateRel, |
|
409 const nsAString& aTitle, |
|
410 StyleSheetState& aSheetState, |
|
411 bool *aIsAlternate, |
|
412 nsCSSStyleSheet** aSheet); |
|
413 |
|
414 // Pass in either a media string or the nsMediaList from the |
|
415 // CSSParser. Don't pass both. |
|
416 // This method will set the sheet's enabled state based on isAlternate |
|
417 void PrepareSheet(nsCSSStyleSheet* aSheet, |
|
418 const nsAString& aTitle, |
|
419 const nsAString& aMediaString, |
|
420 nsMediaList* aMediaList, |
|
421 dom::Element* aScopeElement, |
|
422 bool isAlternate); |
|
423 |
|
424 nsresult InsertSheetInDoc(nsCSSStyleSheet* aSheet, |
|
425 nsIContent* aLinkingContent, |
|
426 nsIDocument* aDocument); |
|
427 |
|
428 nsresult InsertChildSheet(nsCSSStyleSheet* aSheet, |
|
429 nsCSSStyleSheet* aParentSheet, |
|
430 ImportRule* aParentRule); |
|
431 |
|
432 nsresult InternalLoadNonDocumentSheet(nsIURI* aURL, |
|
433 bool aAllowUnsafeRules, |
|
434 bool aUseSystemPrincipal, |
|
435 nsIPrincipal* aOriginPrincipal, |
|
436 const nsCString& aCharset, |
|
437 nsCSSStyleSheet** aSheet, |
|
438 nsICSSLoaderObserver* aObserver, |
|
439 CORSMode aCORSMode = CORS_NONE); |
|
440 |
|
441 // Post a load event for aObserver to be notified about aSheet. The |
|
442 // notification will be sent with status NS_OK unless the load event is |
|
443 // canceled at some point (in which case it will be sent with |
|
444 // NS_BINDING_ABORTED). aWasAlternate indicates the state when the load was |
|
445 // initiated, not the state at some later time. aURI should be the URI the |
|
446 // sheet was loaded from (may be null for inline sheets). aElement is the |
|
447 // owning element for this sheet. |
|
448 nsresult PostLoadEvent(nsIURI* aURI, |
|
449 nsCSSStyleSheet* aSheet, |
|
450 nsICSSLoaderObserver* aObserver, |
|
451 bool aWasAlternate, |
|
452 nsIStyleSheetLinkingElement* aElement); |
|
453 |
|
454 // Start the loads of all the sheets in mPendingDatas |
|
455 void StartAlternateLoads(); |
|
456 |
|
457 // Handle an event posted by PostLoadEvent |
|
458 void HandleLoadEvent(SheetLoadData* aEvent); |
|
459 |
|
460 // Note: LoadSheet is responsible for releasing aLoadData and setting the |
|
461 // sheet to complete on failure. |
|
462 nsresult LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState); |
|
463 |
|
464 // Parse the stylesheet in aLoadData. The sheet data comes from aInput. |
|
465 // Set aCompleted to true if the parse finished, false otherwise (e.g. if the |
|
466 // sheet had an @import). If aCompleted is true when this returns, then |
|
467 // ParseSheet also called SheetComplete on aLoadData. |
|
468 nsresult ParseSheet(const nsAString& aInput, |
|
469 SheetLoadData* aLoadData, |
|
470 bool& aCompleted); |
|
471 |
|
472 // The load of the sheet in aLoadData is done, one way or another. Do final |
|
473 // cleanup, including releasing aLoadData. |
|
474 void SheetComplete(SheetLoadData* aLoadData, nsresult aStatus); |
|
475 |
|
476 // The guts of SheetComplete. This may be called recursively on parent datas |
|
477 // or datas that had glommed on to a single load. The array is there so load |
|
478 // datas whose observers need to be notified can be added to it. |
|
479 void DoSheetComplete(SheetLoadData* aLoadData, nsresult aStatus, |
|
480 LoadDataArray& aDatasToNotify); |
|
481 |
|
482 struct Sheets { |
|
483 nsRefPtrHashtable<URIPrincipalAndCORSModeHashKey, nsCSSStyleSheet> |
|
484 mCompleteSheets; |
|
485 nsDataHashtable<URIPrincipalAndCORSModeHashKey, SheetLoadData*> |
|
486 mLoadingDatas; // weak refs |
|
487 nsDataHashtable<URIPrincipalAndCORSModeHashKey, SheetLoadData*> |
|
488 mPendingDatas; // weak refs |
|
489 }; |
|
490 nsAutoPtr<Sheets> mSheets; |
|
491 |
|
492 // We're not likely to have many levels of @import... But likely to have |
|
493 // some. Allocate some storage, what the hell. |
|
494 nsAutoTArray<SheetLoadData*, 8> mParsingDatas; |
|
495 |
|
496 // The array of posted stylesheet loaded events (SheetLoadDatas) we have. |
|
497 // Note that these are rare. |
|
498 LoadDataArray mPostedEvents; |
|
499 |
|
500 // Our array of "global" observers |
|
501 // XXXbz these are strong refs; should we be cycle collecting CSS loaders? |
|
502 nsTObserverArray<nsCOMPtr<nsICSSLoaderObserver> > mObservers; |
|
503 |
|
504 // the load data needs access to the document... |
|
505 nsIDocument* mDocument; // the document we live for |
|
506 |
|
507 |
|
508 // Number of datas still waiting to be notified on if we're notifying on a |
|
509 // whole bunch at once (e.g. in one of the stop methods). This is used to |
|
510 // make sure that HasPendingLoads() won't return false until we're notifying |
|
511 // on the last data we're working with. |
|
512 uint32_t mDatasToNotifyOn; |
|
513 |
|
514 nsCompatibility mCompatMode; |
|
515 nsString mPreferredSheet; // title of preferred sheet |
|
516 |
|
517 bool mEnabled; // is enabled to load new styles |
|
518 |
|
519 #ifdef DEBUG |
|
520 bool mSyncCallback; |
|
521 #endif |
|
522 }; |
|
523 |
|
524 } // namespace css |
|
525 } // namespace mozilla |
|
526 |
|
527 #endif /* mozilla_css_Loader_h */ |