Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/css/Loader.h
Line
Count
Source (jump to first uncovered line)
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
/* loading of CSS style sheets using the network APIs */
8
9
#ifndef mozilla_css_Loader_h
10
#define mozilla_css_Loader_h
11
12
#include "nsIPrincipal.h"
13
#include "nsCompatibility.h"
14
#include "nsCycleCollectionParticipant.h"
15
#include "nsDataHashtable.h"
16
#include "nsRefPtrHashtable.h"
17
#include "nsStringFwd.h"
18
#include "nsTArray.h"
19
#include "nsTObserverArray.h"
20
#include "nsURIHashKey.h"
21
#include "nsIStyleSheetLinkingElement.h"
22
#include "mozilla/Attributes.h"
23
#include "mozilla/CORSMode.h"
24
#include "mozilla/StyleSheetInlines.h"
25
#include "mozilla/Maybe.h"
26
#include "mozilla/MemoryReporting.h"
27
#include "mozilla/Move.h"
28
#include "mozilla/StyleSheet.h"
29
#include "mozilla/UniquePtr.h"
30
#include "mozilla/net/ReferrerPolicy.h"
31
32
class nsICSSLoaderObserver;
33
class nsIConsoleReportCollector;
34
class nsIContent;
35
class nsIDocument;
36
37
namespace mozilla {
38
namespace dom {
39
class DocGroup;
40
class Element;
41
} // namespace dom
42
} // namespace mozilla
43
44
namespace mozilla {
45
46
class URIPrincipalReferrerPolicyAndCORSModeHashKey : public nsURIHashKey
47
{
48
public:
49
  typedef URIPrincipalReferrerPolicyAndCORSModeHashKey* KeyType;
50
  typedef const URIPrincipalReferrerPolicyAndCORSModeHashKey* KeyTypePointer;
51
  typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
52
53
  explicit URIPrincipalReferrerPolicyAndCORSModeHashKey(const URIPrincipalReferrerPolicyAndCORSModeHashKey* aKey)
54
    : nsURIHashKey(aKey->mKey),
55
      mPrincipal(aKey->mPrincipal),
56
      mCORSMode(aKey->mCORSMode),
57
      mReferrerPolicy(aKey->mReferrerPolicy)
58
0
  {
59
0
    MOZ_COUNT_CTOR(URIPrincipalReferrerPolicyAndCORSModeHashKey);
60
0
  }
61
62
  URIPrincipalReferrerPolicyAndCORSModeHashKey(nsIURI* aURI,
63
                                               nsIPrincipal* aPrincipal,
64
                                               CORSMode aCORSMode,
65
                                               ReferrerPolicy aReferrerPolicy)
66
    : nsURIHashKey(aURI),
67
      mPrincipal(aPrincipal),
68
      mCORSMode(aCORSMode),
69
      mReferrerPolicy(aReferrerPolicy)
70
0
  {
71
0
    MOZ_COUNT_CTOR(URIPrincipalReferrerPolicyAndCORSModeHashKey);
72
0
  }
73
74
  URIPrincipalReferrerPolicyAndCORSModeHashKey(URIPrincipalReferrerPolicyAndCORSModeHashKey&& toMove)
75
    : nsURIHashKey(std::move(toMove)),
76
      mPrincipal(std::move(toMove.mPrincipal)),
77
      mCORSMode(std::move(toMove.mCORSMode)),
78
      mReferrerPolicy(std::move(toMove.mReferrerPolicy))
79
0
  {
80
0
    MOZ_COUNT_CTOR(URIPrincipalReferrerPolicyAndCORSModeHashKey);
81
0
  }
82
83
  explicit URIPrincipalReferrerPolicyAndCORSModeHashKey(css::SheetLoadData* aLoadData);
84
85
  ~URIPrincipalReferrerPolicyAndCORSModeHashKey()
86
0
  {
87
0
    MOZ_COUNT_DTOR(URIPrincipalReferrerPolicyAndCORSModeHashKey);
88
0
  }
89
90
0
  URIPrincipalReferrerPolicyAndCORSModeHashKey* GetKey() const {
91
0
    return const_cast<URIPrincipalReferrerPolicyAndCORSModeHashKey*>(this);
92
0
  }
93
0
  const URIPrincipalReferrerPolicyAndCORSModeHashKey* GetKeyPointer() const { return this; }
94
95
0
  bool KeyEquals(const URIPrincipalReferrerPolicyAndCORSModeHashKey* aKey) const {
96
0
    if (!nsURIHashKey::KeyEquals(aKey->mKey)) {
97
0
      return false;
98
0
    }
99
0
100
0
    if (!mPrincipal != !aKey->mPrincipal) {
101
0
      // One or the other has a principal, but not both... not equal
102
0
      return false;
103
0
    }
104
0
105
0
    if (mCORSMode != aKey->mCORSMode) {
106
0
      // Different CORS modes; we don't match
107
0
      return false;
108
0
    }
109
0
110
0
    if (mReferrerPolicy != aKey->mReferrerPolicy) {
111
0
      // Different ReferrerPolicy; we don't match
112
0
      return false;
113
0
    }
114
0
115
0
    bool eq;
116
0
    return !mPrincipal ||
117
0
      (NS_SUCCEEDED(mPrincipal->Equals(aKey->mPrincipal, &eq)) && eq);
118
0
  }
119
120
  static const URIPrincipalReferrerPolicyAndCORSModeHashKey*
121
0
  KeyToPointer(URIPrincipalReferrerPolicyAndCORSModeHashKey* aKey) { return aKey; }
122
0
  static PLDHashNumber HashKey(const URIPrincipalReferrerPolicyAndCORSModeHashKey* aKey) {
123
0
    return nsURIHashKey::HashKey(aKey->mKey);
124
0
  }
125
126
0
  nsIURI* GetURI() const { return nsURIHashKey::GetKey(); }
127
128
  enum { ALLOW_MEMMOVE = true };
129
130
protected:
131
  nsCOMPtr<nsIPrincipal> mPrincipal;
132
  CORSMode mCORSMode;
133
  ReferrerPolicy mReferrerPolicy;
134
};
135
136
137
138
namespace css {
139
140
class SheetLoadData;
141
class ImportRule;
142
143
/*********************
144
 * Style sheet reuse *
145
 *********************/
146
147
class MOZ_RAII LoaderReusableStyleSheets
148
{
149
public:
150
  LoaderReusableStyleSheets()
151
0
  {
152
0
  }
153
154
  /**
155
   * Look for a reusable sheet (see AddReusableSheet) matching the
156
   * given URL.  If found, set aResult, remove the reused sheet from
157
   * the internal list, and return true.  If not found, return false;
158
   * in this case, aResult is not modified.
159
   *
160
   * @param aURL the url to match
161
   * @param aResult [out] the style sheet which can be reused
162
   */
163
  bool FindReusableStyleSheet(nsIURI* aURL, RefPtr<StyleSheet>& aResult);
164
165
  /**
166
   * Indicate that a certain style sheet is available for reuse if its
167
   * URI matches the URI of an @import.  Sheets should be added in the
168
   * opposite order in which they are intended to be reused.
169
   *
170
   * @param aSheet the sheet which can be reused
171
   */
172
0
  void AddReusableSheet(StyleSheet* aSheet) {
173
0
    mReusableSheets.AppendElement(aSheet);
174
0
  }
175
176
private:
177
  LoaderReusableStyleSheets(const LoaderReusableStyleSheets&) = delete;
178
  LoaderReusableStyleSheets& operator=(const LoaderReusableStyleSheets&) = delete;
179
180
  // The sheets that can be reused.
181
  nsTArray<RefPtr<StyleSheet>> mReusableSheets;
182
};
183
184
/***********************************************************************
185
 * Enum that describes the state of the sheet returned by CreateSheet. *
186
 ***********************************************************************/
187
enum StyleSheetState {
188
  eSheetStateUnknown = 0,
189
  eSheetNeedsParser,
190
  eSheetPending,
191
  eSheetLoading,
192
  eSheetComplete
193
};
194
195
class Loader final {
196
  typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
197
198
public:
199
  typedef nsIStyleSheetLinkingElement::Completed Completed;
200
  typedef nsIStyleSheetLinkingElement::HasAlternateRel HasAlternateRel;
201
  typedef nsIStyleSheetLinkingElement::IsAlternate IsAlternate;
202
  typedef nsIStyleSheetLinkingElement::IsInline IsInline;
203
  typedef nsIStyleSheetLinkingElement::MediaMatched MediaMatched;
204
  typedef nsIStyleSheetLinkingElement::Update LoadSheetResult;
205
  typedef nsIStyleSheetLinkingElement::SheetInfo SheetInfo;
206
207
  Loader();
208
  // aDocGroup is used for dispatching SheetLoadData in PostLoadEvent(). It
209
  // can be null if you want to use this constructor, and there's no
210
  // document when the Loader is constructed.
211
  explicit Loader(mozilla::dom::DocGroup*);
212
  explicit Loader(nsIDocument*);
213
214
 private:
215
  // Private destructor, to discourage deletion outside of Release():
216
  ~Loader();
217
218
 public:
219
  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Loader)
220
  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(Loader)
221
222
  void DropDocumentReference(); // notification that doc is going away
223
224
  void SetCompatibilityMode(nsCompatibility aCompatMode)
225
0
  { mCompatMode = aCompatMode; }
226
0
  nsCompatibility GetCompatibilityMode() { return mCompatMode; }
227
228
  // TODO(emilio): Is the complexity of this method and carrying the titles
229
  // around worth it? The alternate sheets will load anyhow eventually...
230
  void DocumentStyleSheetSetChanged();
231
232
  // XXXbz sort out what the deal is with events!  When should they fire?
233
234
  /**
235
   * Load an inline style sheet.  If a successful result is returned and
236
   * result.WillNotify() is true, then aObserver is guaranteed to be notified
237
   * asynchronously once the sheet is marked complete.  If an error is
238
   * returned, or if result.WillNotify() is false, aObserver will not be
239
   * notified.  In addition to parsing the sheet, this method will insert it
240
   * into the stylesheet list of this CSSLoader's document.
241
   * @param aObserver the observer to notify when the load completes.
242
   *        May be null.
243
   * @param aBuffer the stylesheet data
244
   * @param aLineNumber the line number at which the stylesheet data started.
245
   */
246
  Result<LoadSheetResult, nsresult>
247
    LoadInlineStyle(const SheetInfo&,
248
                    const nsAString& aBuffer,
249
                    uint32_t aLineNumber,
250
                    nsICSSLoaderObserver* aObserver);
251
252
  /**
253
   * Load a linked (document) stylesheet.  If a successful result is returned,
254
   * aObserver is guaranteed to be notified asynchronously once the sheet is
255
   * loaded and marked complete, i.e., result.WillNotify() will always return
256
   * true.  If an error is returned, aObserver will not be notified.  In
257
   * addition to loading the sheet, this method will insert it into the
258
   * stylesheet list of this CSSLoader's document.
259
   * @param aObserver the observer to notify when the load completes.
260
   *                  May be null.
261
   */
262
  Result<LoadSheetResult, nsresult>
263
    LoadStyleLink(const SheetInfo&, nsICSSLoaderObserver* aObserver);
264
265
  /**
266
   * Load a child (@import-ed) style sheet.  In addition to loading the sheet,
267
   * this method will insert it into the child sheet list of aParentSheet.  If
268
   * there is no sheet currently being parsed and the child sheet is not
269
   * complete when this method returns, then when the child sheet becomes
270
   * complete aParentSheet will be QIed to nsICSSLoaderObserver and
271
   * asynchronously notified, just like for LoadStyleLink.  Note that if the
272
   * child sheet is already complete when this method returns, no
273
   * nsICSSLoaderObserver notification will be sent.
274
   *
275
   * @param aParentSheet the parent of this child sheet
276
   * @param aParentData the SheetLoadData corresponding to the load of the
277
   *                    parent sheet.
278
   * @param aURL the URL of the child sheet
279
   * @param aMedia the already-parsed media list for the child sheet
280
   * @param aSavedSheets any saved style sheets which could be reused
281
   *              for this load
282
   */
283
  nsresult LoadChildSheet(StyleSheet* aParentSheet,
284
                          SheetLoadData* aParentData,
285
                          nsIURI* aURL,
286
                          dom::MediaList* aMedia,
287
                          LoaderReusableStyleSheets* aSavedSheets);
288
289
  /**
290
   * Synchronously load and return the stylesheet at aURL.  Any child sheets
291
   * will also be loaded synchronously.  Note that synchronous loads over some
292
   * protocols may involve spinning up a new event loop, so use of this method
293
   * does NOT guarantee not receiving any events before the sheet loads.  This
294
   * method can be used to load sheets not associated with a document.
295
   *
296
   * @param aURL the URL of the sheet to load
297
   * @param aParsingMode the mode in which to parse the sheet
298
   *        (see comments at enum SheetParsingMode, above).
299
   * @param aUseSystemPrincipal if true, give the resulting sheet the system
300
   * principal no matter where it's being loaded from.
301
   * @param [out] aSheet the loaded, complete sheet.
302
   *
303
   * NOTE: At the moment, this method assumes the sheet will be UTF-8, but
304
   * ideally it would allow arbitrary encodings.  Callers should NOT depend on
305
   * non-UTF8 sheets being treated as UTF-8 by this method.
306
   *
307
   * NOTE: A successful return from this method doesn't indicate anything about
308
   * whether the data could be parsed as CSS and doesn't indicate anything
309
   * about the status of child sheets of the returned sheet.
310
   */
311
  nsresult LoadSheetSync(nsIURI* aURL,
312
                         SheetParsingMode aParsingMode,
313
                         bool aUseSystemPrincipal,
314
                         RefPtr<StyleSheet>* aSheet);
315
316
  /**
317
   * As above, but defaults aParsingMode to eAuthorSheetFeatures and
318
   * aUseSystemPrincipal to false.
319
   */
320
0
  nsresult LoadSheetSync(nsIURI* aURL, RefPtr<StyleSheet>* aSheet) {
321
0
    return LoadSheetSync(aURL, eAuthorSheetFeatures, false, aSheet);
322
0
  }
323
324
  /**
325
   * Asynchronously load the stylesheet at aURL.  If a successful result is
326
   * returned, aObserver is guaranteed to be notified asynchronously once the
327
   * sheet is loaded and marked complete.  This method can be used to load
328
   * sheets not associated with a document.
329
   *
330
   * @param aURL the URL of the sheet to load
331
   * @param aParsingMode the mode in which to parse the sheet
332
   *        (see comments at enum SheetParsingMode, above).
333
   * @param aUseSystemPrincipal if true, give the resulting sheet the system
334
   * principal no matter where it's being loaded from.
335
   * @param aObserver the observer to notify when the load completes.
336
   *                  Must not be null.
337
   * @param [out] aSheet the sheet to load. Note that the sheet may well
338
   *              not be loaded by the time this method returns.
339
   *
340
   * NOTE: At the moment, this method assumes the sheet will be UTF-8, but
341
   * ideally it would allow arbitrary encodings.  Callers should NOT depend on
342
   * non-UTF8 sheets being treated as UTF-8 by this method.
343
   */
344
  nsresult LoadSheet(nsIURI* aURL,
345
                     SheetParsingMode aParsingMode,
346
                     bool aUseSystemPrincipal,
347
                     nsICSSLoaderObserver* aObserver,
348
                     RefPtr<StyleSheet>* aSheet);
349
350
  /**
351
   * Asynchronously load the stylesheet at aURL.  If a successful result is
352
   * returned, aObserver is guaranteed to be notified asynchronously once the
353
   * sheet is loaded and marked complete.  This method can be used to load
354
   * sheets not associated with a document.  This method cannot be used to
355
   * load user or agent sheets.
356
   *
357
   * @param aURL the URL of the sheet to load
358
   * @param aOriginPrincipal the principal to use for security checks.  This
359
   *                         can be null to indicate that these checks should
360
   *                         be skipped.
361
   * @param aObserver the observer to notify when the load completes.
362
   *                  Must not be null.
363
   * @param [out] aSheet the sheet to load. Note that the sheet may well
364
   *              not be loaded by the time this method returns.
365
   */
366
  nsresult LoadSheet(nsIURI* aURL,
367
                     nsIPrincipal* aOriginPrincipal,
368
                     nsICSSLoaderObserver* aObserver,
369
                     RefPtr<StyleSheet>* aSheet);
370
371
  /**
372
   * Same as above, to be used when the caller doesn't care about the
373
   * not-yet-loaded sheet.
374
   */
375
  nsresult LoadSheet(nsIURI* aURL,
376
                     bool aIsPreload,
377
                     nsIPrincipal* aOriginPrincipal,
378
                     const Encoding* aPreloadEncoding,
379
                     nsICSSLoaderObserver* aObserver,
380
                     CORSMode aCORSMode = CORS_NONE,
381
                     ReferrerPolicy aReferrerPolicy = mozilla::net::RP_Unset,
382
                     const nsAString& aIntegrity = EmptyString());
383
384
  /**
385
   * Stop loading all sheets.  All nsICSSLoaderObservers involved will be
386
   * notified with NS_BINDING_ABORTED as the status, possibly synchronously.
387
   */
388
  void Stop();
389
390
  /**
391
   * nsresult Loader::StopLoadingSheet(nsIURI* aURL), which notifies the
392
   * nsICSSLoaderObserver with NS_BINDING_ABORTED, was removed in Bug 556446.
393
   * It can be found in revision 2c44a32052ad.
394
   */
395
396
  /**
397
   * Whether the loader is enabled or not.
398
   * When disabled, processing of new styles is disabled and an attempt
399
   * to do so will fail with a return code of
400
   * NS_ERROR_NOT_AVAILABLE. Note that this DOES NOT disable
401
   * currently loading styles or already processed styles.
402
   */
403
0
  bool GetEnabled() { return mEnabled; }
404
0
  void SetEnabled(bool aEnabled) { mEnabled = aEnabled; }
405
406
  /**
407
   * Get the document we live for. May return null.
408
   */
409
0
  nsIDocument* GetDocument() const { return mDocument; }
410
411
  /**
412
   * Return true if this loader has pending loads (ones that would send
413
   * notifications to an nsICSSLoaderObserver attached to this loader).
414
   * If called from inside nsICSSLoaderObserver::StyleSheetLoaded, this will
415
   * return false if and only if that is the last StyleSheetLoaded
416
   * notification the CSSLoader knows it's going to send.  In other words, if
417
   * two sheets load at once (via load coalescing, e.g.), HasPendingLoads()
418
   * will return true during notification for the first one, and false
419
   * during notification for the second one.
420
   */
421
  bool HasPendingLoads();
422
423
  /**
424
   * Add an observer to this loader.  The observer will be notified
425
   * for all loads that would have notified their own observers (even
426
   * if those loads don't have observers attached to them).
427
   * Load-specific observers will be notified before generic
428
   * observers.  The loader holds a reference to the observer.
429
   *
430
   * aObserver must not be null.
431
   */
432
  nsresult AddObserver(nsICSSLoaderObserver* aObserver);
433
434
  /**
435
   * Remove an observer added via AddObserver.
436
   */
437
  void RemoveObserver(nsICSSLoaderObserver* aObserver);
438
439
  // These interfaces are public only for the benefit of static functions
440
  // within nsCSSLoader.cpp.
441
442
  // IsAlternateSheet can change our currently selected style set if none is
443
  // selected and aHasAlternateRel is false.
444
  IsAlternate IsAlternateSheet(const nsAString& aTitle, bool aHasAlternateRel);
445
446
  typedef nsTArray<RefPtr<SheetLoadData>> LoadDataArray;
447
448
  // Measure our size.
449
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
450
451
private:
452
  friend class SheetLoadData;
453
  friend class StreamLoader;
454
455
  // Helpers to conditionally block onload if mDocument is non-null.
456
  void BlockOnload();
457
  void UnblockOnload(bool aFireSync);
458
459
  // Helper to select the correct dispatch target for asynchronous events for
460
  // this loader.
461
  already_AddRefed<nsISerialEventTarget> DispatchTarget();
462
463
  nsresult CheckContentPolicy(nsIPrincipal* aLoadingPrincipal,
464
                              nsIPrincipal* aTriggeringPrincipal,
465
                              nsIURI* aTargetURI,
466
                              nsINode* aRequestingNode,
467
                              bool aIsPreload);
468
469
  nsresult CreateSheet(const SheetInfo& aInfo,
470
                       nsIPrincipal* aLoaderPrincipal,
471
                       css::SheetParsingMode aParsingMode,
472
                       bool aSyncLoad,
473
                       StyleSheetState& aSheetState,
474
                       RefPtr<StyleSheet>* aSheet)
475
0
  {
476
0
    return CreateSheet(aInfo.mURI,
477
0
                       aInfo.mContent,
478
0
                       aLoaderPrincipal,
479
0
                       aParsingMode,
480
0
                       aInfo.mCORSMode,
481
0
                       aInfo.mReferrerPolicy,
482
0
                       aInfo.mIntegrity,
483
0
                       aSyncLoad,
484
0
                       aSheetState,
485
0
                       aSheet);
486
0
  }
487
488
  // For inline style, the aURI param is null, but the aLinkingContent
489
  // must be non-null then.  The loader principal must never be null
490
  // if aURI is not null.
491
  nsresult CreateSheet(nsIURI* aURI,
492
                       nsIContent* aLinkingContent,
493
                       nsIPrincipal* aLoaderPrincipal,
494
                       css::SheetParsingMode aParsingMode,
495
                       CORSMode aCORSMode,
496
                       ReferrerPolicy aReferrerPolicy,
497
                       const nsAString& aIntegrity,
498
                       bool aSyncLoad,
499
                       StyleSheetState& aSheetState,
500
                       RefPtr<StyleSheet>* aSheet);
501
502
  // Pass in either a media string or the MediaList from the CSSParser.  Don't
503
  // pass both.
504
  //
505
  // This method will set the sheet's enabled state based on aIsAlternate
506
  MediaMatched PrepareSheet(StyleSheet* aSheet,
507
                            const nsAString& aTitle,
508
                            const nsAString& aMediaString,
509
                            dom::MediaList* aMediaList,
510
                            IsAlternate);
511
512
  // Inserts a style sheet in a document or a ShadowRoot.
513
  void InsertSheetInTree(StyleSheet& aSheet, nsIContent* aLinkingContent);
514
  // Inserts a style sheet into a parent style sheet.
515
  void InsertChildSheet(StyleSheet& aSheet, StyleSheet& aParentSheet);
516
517
  nsresult InternalLoadNonDocumentSheet(
518
    nsIURI* aURL,
519
    bool aIsPreload,
520
    SheetParsingMode aParsingMode,
521
    bool aUseSystemPrincipal,
522
    nsIPrincipal* aOriginPrincipal,
523
    const Encoding* aPreloadEncoding,
524
    RefPtr<StyleSheet>* aSheet,
525
    nsICSSLoaderObserver* aObserver,
526
    CORSMode aCORSMode = CORS_NONE,
527
    ReferrerPolicy aReferrerPolicy = mozilla::net::RP_Unset,
528
    const nsAString& aIntegrity = EmptyString());
529
530
  // Post a load event for aObserver to be notified about aSheet.  The
531
  // notification will be sent with status NS_OK unless the load event is
532
  // canceled at some point (in which case it will be sent with
533
  // NS_BINDING_ABORTED).  aWasAlternate indicates the state when the load was
534
  // initiated, not the state at some later time.  aURI should be the URI the
535
  // sheet was loaded from (may be null for inline sheets).  aElement is the
536
  // owning element for this sheet.
537
  nsresult PostLoadEvent(nsIURI* aURI,
538
                         StyleSheet* aSheet,
539
                         nsICSSLoaderObserver* aObserver,
540
                         IsAlternate aWasAlternate,
541
                         MediaMatched aMediaMatched,
542
                         nsIStyleSheetLinkingElement* aElement);
543
544
  // Start the loads of all the sheets in mPendingDatas
545
  void StartDeferredLoads();
546
547
  // Handle an event posted by PostLoadEvent
548
  void HandleLoadEvent(SheetLoadData* aEvent);
549
550
  // Note: LoadSheet is responsible for releasing aLoadData and setting the
551
  // sheet to complete on failure.
552
  nsresult LoadSheet(SheetLoadData* aLoadData,
553
                     StyleSheetState aSheetState,
554
                     bool aIsPreLoad);
555
556
  enum class AllowAsyncParse
557
  {
558
    Yes,
559
    No,
560
  };
561
562
  // Parse the stylesheet in the load data.
563
  //
564
  // Returns whether the parse finished. It may not finish e.g. if the sheet had
565
  // an @import.
566
  //
567
  // If this function returns Completed::Yes, then ParseSheet also called
568
  // SheetComplete on aLoadData.
569
  Completed ParseSheet(const nsACString& aBytes, SheetLoadData*, AllowAsyncParse);
570
571
  // The load of the sheet in aLoadData is done, one way or another.  Do final
572
  // cleanup, including releasing aLoadData.
573
  void SheetComplete(SheetLoadData* aLoadData, nsresult aStatus);
574
575
  // The guts of SheetComplete.  This may be called recursively on parent datas
576
  // or datas that had glommed on to a single load.  The array is there so load
577
  // datas whose observers need to be notified can be added to it.
578
  void DoSheetComplete(SheetLoadData* aLoadData, LoadDataArray& aDatasToNotify);
579
580
  // Mark the given SheetLoadData, as well as any of its siblings, parents, etc
581
  // transitively, as failed.  The idea is to mark as failed any load that was
582
  // directly or indirectly @importing the sheet this SheetLoadData represents.
583
  void MarkLoadTreeFailed(SheetLoadData* aLoadData);
584
585
  // If there's Referrer-Policy reponse header, the loading data and key should
586
  // be updated with the referer policy parsed from the header.
587
  void UpdateLoadingData(URIPrincipalReferrerPolicyAndCORSModeHashKey* aOldKey,
588
                         SheetLoadData* aData);
589
590
  struct Sheets {
591
    nsBaseHashtable<URIPrincipalReferrerPolicyAndCORSModeHashKey,
592
                    RefPtr<StyleSheet>,
593
                    StyleSheet*> mCompleteSheets;
594
    nsDataHashtable<URIPrincipalReferrerPolicyAndCORSModeHashKey, SheetLoadData*>
595
                      mLoadingDatas; // weak refs
596
    nsDataHashtable<URIPrincipalReferrerPolicyAndCORSModeHashKey, SheetLoadData*>
597
                      mPendingDatas; // weak refs
598
  };
599
  UniquePtr<Sheets> mSheets;
600
601
  // The array of posted stylesheet loaded events (SheetLoadDatas) we have.
602
  // Note that these are rare.
603
  LoadDataArray mPostedEvents;
604
605
  // Our array of "global" observers
606
  nsTObserverArray<nsCOMPtr<nsICSSLoaderObserver> > mObservers;
607
608
  // This reference is nulled by the Document in it's destructor through
609
  // DropDocumentReference().
610
  nsIDocument* MOZ_NON_OWNING_REF mDocument;  // the document we live for
611
612
  // For dispatching events via DocGroup::Dispatch() when mDocument is nullptr.
613
  RefPtr<mozilla::dom::DocGroup> mDocGroup;
614
615
  // Number of datas still waiting to be notified on if we're notifying on a
616
  // whole bunch at once (e.g. in one of the stop methods).  This is used to
617
  // make sure that HasPendingLoads() won't return false until we're notifying
618
  // on the last data we're working with.
619
  uint32_t          mDatasToNotifyOn;
620
621
  nsCompatibility   mCompatMode;
622
623
  bool              mEnabled; // is enabled to load new styles
624
625
  nsCOMPtr<nsIConsoleReportCollector> mReporter;
626
627
#ifdef DEBUG
628
  bool              mSyncCallback;
629
#endif
630
};
631
632
} // namespace css
633
} // namespace mozilla
634
635
#endif /* mozilla_css_Loader_h */