Loader.h 24 KB

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