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/. */
7 #ifndef mozilla_css_SheetLoadData_h
8 #define mozilla_css_SheetLoadData_h
10 #include "mozilla/css/Loader.h"
11 #include "mozilla/css/SheetParsingMode.h"
12 #include "mozilla/Encoding.h"
13 #include "mozilla/NotNull.h"
14 #include "nsIThreadInternal.h"
15 #include "nsProxyRelease.h"
20 class nsICSSLoaderObserver
;
24 class nsIReferrerInfo
;
29 /*********************************************
30 * Data needed to properly load a stylesheet *
31 *********************************************/
33 static_assert(eAuthorSheetFeatures
== 0 && eUserSheetFeatures
== 1 &&
34 eAgentSheetFeatures
== 2,
35 "sheet parsing mode constants won't fit "
36 "in SheetLoadData::mParsingMode");
38 class SheetLoadData final
: public nsIRunnable
, public nsIThreadObserver
{
39 typedef nsIStyleSheetLinkingElement::MediaMatched MediaMatched
;
40 typedef nsIStyleSheetLinkingElement::IsAlternate IsAlternate
;
43 virtual ~SheetLoadData();
46 // Data for loading a sheet linked from a document
47 SheetLoadData(Loader
* aLoader
, const nsAString
& aTitle
, nsIURI
* aURI
,
48 StyleSheet
* aSheet
, bool aSyncLoad
,
49 nsIStyleSheetLinkingElement
* aOwningElement
,
50 IsAlternate aIsAlternate
, MediaMatched aMediaMatched
,
51 nsICSSLoaderObserver
* aObserver
, nsIPrincipal
* aLoaderPrincipal
,
52 nsIReferrerInfo
* aReferrerInfo
, nsINode
* aRequestingNode
);
54 // Data for loading a sheet linked from an @import rule
55 SheetLoadData(Loader
* aLoader
, nsIURI
* aURI
, StyleSheet
* aSheet
,
56 SheetLoadData
* aParentData
, nsICSSLoaderObserver
* aObserver
,
57 nsIPrincipal
* aLoaderPrincipal
, nsIReferrerInfo
* aReferrerInfo
,
58 nsINode
* aRequestingNode
);
60 // Data for loading a non-document sheet
61 SheetLoadData(Loader
* aLoader
, nsIURI
* aURI
, StyleSheet
* aSheet
,
62 bool aSyncLoad
, bool aUseSystemPrincipal
,
63 const Encoding
* aPreloadEncoding
,
64 nsICSSLoaderObserver
* aObserver
, nsIPrincipal
* aLoaderPrincipal
,
65 nsIReferrerInfo
* aReferrerInfo
, nsINode
* aRequestingNode
);
67 nsIReferrerInfo
* ReferrerInfo() { return mReferrerInfo
; }
69 void ScheduleLoadEventIfNeeded();
71 NotNull
<const Encoding
*> DetermineNonBOMEncoding(nsACString
const& aSegment
,
72 nsIChannel
* aChannel
);
74 // The caller may have the bytes for the stylesheet split across two strings,
75 // so aBytes1 and aBytes2 refer to those pieces.
76 nsresult
VerifySheetReadyToParse(nsresult aStatus
, const nsACString
& aBytes1
,
77 const nsACString
& aBytes2
,
78 nsIChannel
* aChannel
);
82 NS_DECL_NSITHREADOBSERVER
84 // Hold a ref to the CSSLoader so we can call back to it to let it
85 // know the load finished
86 RefPtr
<Loader
> mLoader
;
88 // Title needed to pull datas out of the pending datas table when
89 // the preferred title is changed
92 // The encoding we decided to use for the sheet
93 const Encoding
* mEncoding
;
95 // URI we're loading. Null for inline sheets
96 nsCOMPtr
<nsIURI
> mURI
;
98 // Should be 1 for non-inline sheets.
101 // The sheet we're loading data for
102 RefPtr
<StyleSheet
> mSheet
;
104 // Linked list of datas for the same URI as us.
105 RefPtr
<SheetLoadData
> mNext
;
107 // Load data for the sheet that @import-ed us if we were @import-ed
109 RefPtr
<SheetLoadData
> mParentData
;
111 // Number of sheets we @import-ed that are still loading
112 uint32_t mPendingChildren
;
114 // mSyncLoad is true when the load needs to be synchronous.
115 // For LoadSheetSync, <link> to chrome stylesheets in UA Widgets,
116 // and children of sync loads.
119 // mIsNonDocumentSheet is true if the load was triggered by LoadSheetSync or
120 // LoadSheet or an @import from such a sheet. Non-document sheet loads can
121 // proceed even if we have no document.
122 bool mIsNonDocumentSheet
: 1;
124 // mIsLoading is true from the moment we are placed in the loader's
125 // "loading datas" table (right after the async channel is opened)
126 // to the moment we are removed from said table (due to the load
127 // completing or being cancelled).
130 // mIsBeingParsed is true if this stylesheet is currently being parsed.
131 bool mIsBeingParsed
: 1;
133 // mIsCancelled is set to true when a sheet load is stopped by
134 // Stop() or StopLoadingSheet() (which was removed in Bug 556446).
135 // SheetLoadData::OnStreamComplete() checks this to avoid parsing
136 // sheets that have been cancelled and such.
137 bool mIsCancelled
: 1;
139 // mMustNotify is true if the load data is being loaded async and
140 // the original function call that started the load has returned.
141 // This applies only to observer notifications; load/error events
142 // are fired for any SheetLoadData that has a non-null
144 bool mMustNotify
: 1;
146 // mWasAlternate is true if the sheet was an alternate when the load data was
148 bool mWasAlternate
: 1;
150 // mMediaMatched is true if the sheet matched its medialist when the load data
152 bool mMediaMatched
: 1;
154 // mUseSystemPrincipal is true if the system principal should be used for
155 // this sheet, no matter what the channel principal is. Only true for sync
157 bool mUseSystemPrincipal
: 1;
159 // If true, this SheetLoadData is being used as a way to handle
160 // async observer notification for an already-complete sheet.
161 bool mSheetAlreadyComplete
: 1;
163 // If true, the sheet is being loaded cross-origin without CORS permissions.
164 // This is completely normal and CORS isn't needed for such loads. This
165 // flag is simply useful in determining whether to set mBlockResourceTiming
166 // for a child sheet.
167 bool mIsCrossOriginNoCORS
: 1;
169 // If this flag is true, LoadSheet will call SetReportResourceTiming(false)
170 // on the timedChannel. This is to mark resources that are loaded by a
171 // cross-origin stylesheet with a no-cors policy.
172 // https://www.w3.org/TR/resource-timing/#processing-model
173 bool mBlockResourceTiming
: 1;
175 // Boolean flag indicating whether the load has failed. This will be set
176 // to true if this load, or the load of any descendant import, fails.
177 bool mLoadFailed
: 1;
179 // This is the element that imported the sheet. Needed to get the
180 // charset set on it and to fire load/error events.
181 nsCOMPtr
<nsIStyleSheetLinkingElement
> mOwningElement
;
183 // The observer that wishes to be notified of load completion
184 nsCOMPtr
<nsICSSLoaderObserver
> mObserver
;
186 // The principal that identifies who started loading us.
187 nsCOMPtr
<nsIPrincipal
> mLoaderPrincipal
;
189 // Referrer info of the load.
190 nsCOMPtr
<nsIReferrerInfo
> mReferrerInfo
;
192 // The node that identifies who started loading us.
193 nsCOMPtr
<nsINode
> mRequestingNode
;
195 // The encoding to use for preloading Must be empty if mOwningElement
197 const Encoding
* mPreloadEncoding
;
199 bool ShouldDefer() const { return mWasAlternate
|| !mMediaMatched
; }
202 void FireLoadEvent(nsIThreadInternal
* aThread
);
205 typedef nsMainThreadPtrHolder
<SheetLoadData
> SheetLoadDataHolder
;
208 } // namespace mozilla
211 * Casting SheetLoadData to nsISupports is ambiguous.
212 * This method handles that.
214 inline nsISupports
* ToSupports(mozilla::css::SheetLoadData
* p
) {
215 return NS_ISUPPORTS_CAST(nsIRunnable
*, p
);
218 #endif // mozilla_css_SheetLoadData_h