Bug 1635702 [wpt PR 23413] - Move some internal scroll anchoring tests to wpt, a...
[gecko.git] / layout / style / SheetLoadData.h
blob1c783c8f9ea16df483f878343c4347e0df903fc6
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"
17 namespace mozilla {
18 class StyleSheet;
20 class nsICSSLoaderObserver;
21 class nsINode;
22 class nsIPrincipal;
23 class nsIURI;
24 class nsIReferrerInfo;
26 namespace mozilla {
27 namespace css {
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 using MediaMatched = nsIStyleSheetLinkingElement::MediaMatched;
40 using IsAlternate = nsIStyleSheetLinkingElement::IsAlternate;
41 using IsPreload = Loader::IsPreload;
42 using UseSystemPrincipal = Loader::UseSystemPrincipal;
44 protected:
45 virtual ~SheetLoadData();
47 public:
48 // Data for loading a sheet linked from a document
49 SheetLoadData(Loader* aLoader, const nsAString& aTitle, nsIURI* aURI,
50 StyleSheet* aSheet, bool aSyncLoad,
51 nsIStyleSheetLinkingElement* aOwningElement,
52 IsAlternate aIsAlternate, MediaMatched aMediaMatched,
53 IsPreload aIsPreload, nsICSSLoaderObserver* aObserver,
54 nsIPrincipal* aLoaderPrincipal, nsIReferrerInfo* aReferrerInfo,
55 nsINode* aRequestingNode);
57 // Data for loading a sheet linked from an @import rule
58 SheetLoadData(Loader* aLoader, nsIURI* aURI, StyleSheet* aSheet,
59 SheetLoadData* aParentData, nsICSSLoaderObserver* aObserver,
60 nsIPrincipal* aLoaderPrincipal, nsIReferrerInfo* aReferrerInfo,
61 nsINode* aRequestingNode);
63 // Data for loading a non-document sheet
64 SheetLoadData(Loader* aLoader, nsIURI* aURI, StyleSheet* aSheet,
65 bool aSyncLoad, UseSystemPrincipal, IsPreload,
66 const Encoding* aPreloadEncoding,
67 nsICSSLoaderObserver* aObserver, nsIPrincipal* aLoaderPrincipal,
68 nsIReferrerInfo* aReferrerInfo, nsINode* aRequestingNode);
70 nsIReferrerInfo* ReferrerInfo() { return mReferrerInfo; }
72 void ScheduleLoadEventIfNeeded();
74 NotNull<const Encoding*> DetermineNonBOMEncoding(nsACString const& aSegment,
75 nsIChannel* aChannel);
77 // The caller may have the bytes for the stylesheet split across two strings,
78 // so aBytes1 and aBytes2 refer to those pieces.
79 nsresult VerifySheetReadyToParse(nsresult aStatus, const nsACString& aBytes1,
80 const nsACString& aBytes2,
81 nsIChannel* aChannel);
83 NS_DECL_ISUPPORTS
84 NS_DECL_NSIRUNNABLE
85 NS_DECL_NSITHREADOBSERVER
87 // Hold a ref to the CSSLoader so we can call back to it to let it
88 // know the load finished
89 const RefPtr<Loader> mLoader;
91 // Title needed to pull datas out of the pending datas table when
92 // the preferred title is changed
93 const nsString mTitle;
95 // The encoding we decided to use for the sheet
96 const Encoding* mEncoding;
98 // URI we're loading. Null for inline sheets
99 nsCOMPtr<nsIURI> mURI;
101 // Should be 1 for non-inline sheets.
102 uint32_t mLineNumber;
104 // The sheet we're loading data for
105 const RefPtr<StyleSheet> mSheet;
107 // Linked list of datas for the same URI as us.
108 RefPtr<SheetLoadData> mNext;
110 // Load data for the sheet that @import-ed us if we were @import-ed
111 // during the parse
112 const RefPtr<SheetLoadData> mParentData;
114 // Number of sheets we @import-ed that are still loading
115 uint32_t mPendingChildren;
117 // mSyncLoad is true when the load needs to be synchronous.
118 // For LoadSheetSync, <link> to chrome stylesheets in UA Widgets,
119 // and children of sync loads.
120 const bool mSyncLoad : 1;
122 // mIsNonDocumentSheet is true if the load was triggered by LoadSheetSync or
123 // LoadSheet or an @import from such a sheet. Non-document sheet loads can
124 // proceed even if we have no document.
125 const bool mIsNonDocumentSheet : 1;
127 // mIsLoading is true from the moment we are placed in the loader's
128 // "loading datas" table (right after the async channel is opened)
129 // to the moment we are removed from said table (due to the load
130 // completing or being cancelled).
131 bool mIsLoading : 1;
133 // mIsBeingParsed is true if this stylesheet is currently being parsed.
134 bool mIsBeingParsed : 1;
136 // mIsCancelled is set to true when a sheet load is stopped by
137 // Stop() or StopLoadingSheet() (which was removed in Bug 556446).
138 // SheetLoadData::OnStreamComplete() checks this to avoid parsing
139 // sheets that have been cancelled and such.
140 bool mIsCancelled : 1;
142 // mMustNotify is true if the load data is being loaded async and
143 // the original function call that started the load has returned.
144 // This applies only to observer notifications; load/error events
145 // are fired for any SheetLoadData that has a non-null
146 // mOwningElement.
147 bool mMustNotify : 1;
149 // mWasAlternate is true if the sheet was an alternate when the load data was
150 // created.
151 const bool mWasAlternate : 1;
153 // mMediaMatched is true if the sheet matched its medialist when the load data
154 // was created.
155 const bool mMediaMatched : 1;
157 // mUseSystemPrincipal is true if the system principal should be used for
158 // this sheet, no matter what the channel principal is. Only true for sync
159 // loads.
160 const bool mUseSystemPrincipal : 1;
162 // If true, this SheetLoadData is being used as a way to handle
163 // async observer notification for an already-complete sheet.
164 bool mSheetAlreadyComplete : 1;
166 // If true, the sheet is being loaded cross-origin without CORS permissions.
167 // This is completely normal and CORS isn't needed for such loads. This
168 // flag is simply useful in determining whether to set mBlockResourceTiming
169 // for a child sheet.
170 bool mIsCrossOriginNoCORS : 1;
172 // If this flag is true, LoadSheet will call SetReportResourceTiming(false)
173 // on the timedChannel. This is to mark resources that are loaded by a
174 // cross-origin stylesheet with a no-cors policy.
175 // https://www.w3.org/TR/resource-timing/#processing-model
176 bool mBlockResourceTiming : 1;
178 // Boolean flag indicating whether the load has failed. This will be set
179 // to true if this load, or the load of any descendant import, fails.
180 bool mLoadFailed : 1;
182 // Whether this is a preload, and which kind of preload it is.
184 // TODO(emilio): This can become a bitfield once we build with a GCC version
185 // that has the fix for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414,
186 // which causes a false positive warning here.
187 const IsPreload mIsPreload;
189 // This is the element that imported the sheet. Needed to get the
190 // charset set on it and to fire load/error events.
191 const nsCOMPtr<nsIStyleSheetLinkingElement> mOwningElement;
193 // The observer that wishes to be notified of load completion
194 const nsCOMPtr<nsICSSLoaderObserver> mObserver;
196 // The principal that identifies who started loading us.
197 const nsCOMPtr<nsIPrincipal> mLoaderPrincipal;
199 // Referrer info of the load.
200 const nsCOMPtr<nsIReferrerInfo> mReferrerInfo;
202 // The node that identifies who started loading us.
203 const nsCOMPtr<nsINode> mRequestingNode;
205 // The encoding to use for preloading Must be empty if mOwningElement
206 // is non-null.
207 const Encoding* const mPreloadEncoding;
209 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
210 // Whether SheetComplete was called.
211 bool mSheetCompleteCalled = false;
212 #endif
214 bool ShouldDefer() const { return mWasAlternate || !mMediaMatched; }
216 // If there are no child sheets outstanding, mark us as complete.
217 // Otherwise, the children are holding strong refs to the data
218 // and will call SheetComplete() on it when they complete.
219 void SheetFinishedParsingAsync() {
220 MOZ_ASSERT(mIsBeingParsed);
221 mIsBeingParsed = false;
222 if (!mPendingChildren) {
223 mLoader->SheetComplete(*this, NS_OK);
227 bool IsLinkPreload() const { return mIsPreload == IsPreload::FromLink; }
229 private:
230 void FireLoadEvent(nsIThreadInternal* aThread);
233 using SheetLoadDataHolder = nsMainThreadPtrHolder<SheetLoadData>;
235 } // namespace css
236 } // namespace mozilla
239 * Casting SheetLoadData to nsISupports is ambiguous.
240 * This method handles that.
242 inline nsISupports* ToSupports(mozilla::css::SheetLoadData* p) {
243 return NS_ISUPPORTS_CAST(nsIRunnable*, p);
246 #endif // mozilla_css_SheetLoadData_h