Bug 1647875 [wpt PR 24320] - [AspectRatio] Add an in-flow test for computing a block...
[gecko.git] / parser / html / nsHtml5SpeculativeLoad.h
blobd5d25d24a3637821cf48be3553420a086c0d4a62
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef nsHtml5SpeculativeLoad_h
6 #define nsHtml5SpeculativeLoad_h
8 #include "nsString.h"
9 #include "nsContentUtils.h"
10 #include "nsHtml5DocumentMode.h"
11 #include "nsHtml5String.h"
12 #include "ReferrerInfo.h"
14 class nsHtml5TreeOpExecutor;
16 enum eHtml5SpeculativeLoad {
17 eSpeculativeLoadUninitialized,
18 eSpeculativeLoadBase,
19 eSpeculativeLoadCSP,
20 eSpeculativeLoadMetaReferrer,
21 eSpeculativeLoadImage,
22 eSpeculativeLoadOpenPicture,
23 eSpeculativeLoadEndPicture,
24 eSpeculativeLoadPictureSource,
25 eSpeculativeLoadScript,
26 eSpeculativeLoadScriptFromHead,
27 eSpeculativeLoadNoModuleScript,
28 eSpeculativeLoadNoModuleScriptFromHead,
29 eSpeculativeLoadStyle,
30 eSpeculativeLoadManifest,
31 eSpeculativeLoadSetDocumentCharset,
32 eSpeculativeLoadSetDocumentMode,
33 eSpeculativeLoadPreconnect,
34 eSpeculativeLoadFont,
35 eSpeculativeLoadFetch
38 class nsHtml5SpeculativeLoad {
39 using Encoding = mozilla::Encoding;
40 template <typename T>
41 using NotNull = mozilla::NotNull<T>;
43 public:
44 nsHtml5SpeculativeLoad();
45 ~nsHtml5SpeculativeLoad();
47 inline void InitBase(nsHtml5String aUrl) {
48 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
49 "Trying to reinitialize a speculative load!");
50 mOpCode = eSpeculativeLoadBase;
51 aUrl.ToString(mUrlOrSizes);
54 inline void InitMetaCSP(nsHtml5String aCSP) {
55 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
56 "Trying to reinitialize a speculative load!");
57 mOpCode = eSpeculativeLoadCSP;
58 nsString csp; // Not Auto, because using it to hold nsStringBuffer*
59 aCSP.ToString(csp);
60 mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity.Assign(
61 nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(csp));
64 inline void InitMetaReferrerPolicy(nsHtml5String aReferrerPolicy) {
65 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
66 "Trying to reinitialize a speculative load!");
67 mOpCode = eSpeculativeLoadMetaReferrer;
68 nsString
69 referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
70 aReferrerPolicy.ToString(referrerPolicy);
71 mReferrerPolicyOrIntegrity.Assign(
72 nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
73 referrerPolicy));
76 inline void InitImage(nsHtml5String aUrl, nsHtml5String aCrossOrigin,
77 nsHtml5String aReferrerPolicy, nsHtml5String aSrcset,
78 nsHtml5String aSizes, bool aLinkPreload) {
79 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
80 "Trying to reinitialize a speculative load!");
81 mOpCode = eSpeculativeLoadImage;
82 aUrl.ToString(mUrlOrSizes);
83 aCrossOrigin.ToString(mCrossOriginOrMedia);
84 nsString
85 referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
86 aReferrerPolicy.ToString(referrerPolicy);
87 mReferrerPolicyOrIntegrity.Assign(
88 nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
89 referrerPolicy));
90 aSrcset.ToString(mCharsetOrSrcset);
91 aSizes.ToString(
92 mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity);
93 mIsLinkPreload = aLinkPreload;
96 inline void InitFont(nsHtml5String aUrl, nsHtml5String aCrossOrigin,
97 nsHtml5String aReferrerPolicy) {
98 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
99 "Trying to reinitialize a speculative load!");
100 mOpCode = eSpeculativeLoadFont;
101 aUrl.ToString(mUrlOrSizes);
102 aCrossOrigin.ToString(mCrossOriginOrMedia);
103 nsString
104 referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
105 aReferrerPolicy.ToString(referrerPolicy);
106 mReferrerPolicyOrIntegrity.Assign(
107 nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
108 referrerPolicy));
109 // This can be only triggered by <link rel=preload type=font>
110 mIsLinkPreload = true;
113 inline void InitFetch(nsHtml5String aUrl, nsHtml5String aCrossOrigin,
114 nsHtml5String aReferrerPolicy) {
115 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
116 "Trying to reinitialize a speculative load!");
117 mOpCode = eSpeculativeLoadFetch;
118 aUrl.ToString(mUrlOrSizes);
119 aCrossOrigin.ToString(mCrossOriginOrMedia);
120 nsString
121 referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
122 aReferrerPolicy.ToString(referrerPolicy);
123 mReferrerPolicyOrIntegrity.Assign(
124 nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
125 referrerPolicy));
127 // This method can be only be triggered by <link rel=preload type=fetch>,
128 // hence this operation is always a preload.
129 mIsLinkPreload = true;
132 // <picture> elements have multiple <source> nodes followed by an <img>,
133 // where we use the first valid source, which may be the img. Because we
134 // can't determine validity at this point without parsing CSS and getting
135 // main thread state, we push preload operations for picture pushed and
136 // popped, so that the target of the preload ops can determine what picture
137 // and nesting level each source/img from the main preloading code exists
138 // at.
139 inline void InitOpenPicture() {
140 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
141 "Trying to reinitialize a speculative load!");
142 mOpCode = eSpeculativeLoadOpenPicture;
145 inline void InitEndPicture() {
146 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
147 "Trying to reinitialize a speculative load!");
148 mOpCode = eSpeculativeLoadEndPicture;
151 inline void InitPictureSource(nsHtml5String aSrcset, nsHtml5String aSizes,
152 nsHtml5String aType, nsHtml5String aMedia) {
153 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
154 "Trying to reinitialize a speculative load!");
155 mOpCode = eSpeculativeLoadPictureSource;
156 aSrcset.ToString(mCharsetOrSrcset);
157 aSizes.ToString(mUrlOrSizes);
158 aType.ToString(
159 mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity);
160 aMedia.ToString(mCrossOriginOrMedia);
163 inline void InitScript(nsHtml5String aUrl, nsHtml5String aCharset,
164 nsHtml5String aType, nsHtml5String aCrossOrigin,
165 nsHtml5String aIntegrity,
166 nsHtml5String aReferrerPolicy, bool aParserInHead,
167 bool aAsync, bool aDefer, bool aNoModule,
168 bool aLinkPreload) {
169 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
170 "Trying to reinitialize a speculative load!");
171 if (aNoModule) {
172 mOpCode = aParserInHead ? eSpeculativeLoadNoModuleScriptFromHead
173 : eSpeculativeLoadNoModuleScript;
174 } else {
175 mOpCode = aParserInHead ? eSpeculativeLoadScriptFromHead
176 : eSpeculativeLoadScript;
178 aUrl.ToString(mUrlOrSizes);
179 aCharset.ToString(mCharsetOrSrcset);
180 aType.ToString(
181 mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity);
182 aCrossOrigin.ToString(mCrossOriginOrMedia);
183 aIntegrity.ToString(mReferrerPolicyOrIntegrity);
184 nsAutoString referrerPolicy;
185 aReferrerPolicy.ToString(referrerPolicy);
186 referrerPolicy =
187 nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
188 referrerPolicy);
189 mScriptReferrerPolicy =
190 mozilla::dom::ReferrerInfo::ReferrerPolicyAttributeFromString(
191 referrerPolicy);
193 mIsAsync = aAsync;
194 mIsDefer = aDefer;
195 mIsLinkPreload = aLinkPreload;
198 inline void InitImportStyle(nsString&& aUrl) {
199 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
200 "Trying to reinitialize a speculative load!");
201 mOpCode = eSpeculativeLoadStyle;
202 mUrlOrSizes = std::move(aUrl);
203 mCharsetOrSrcset.SetIsVoid(true);
204 mCrossOriginOrMedia.SetIsVoid(true);
205 mReferrerPolicyOrIntegrity.SetIsVoid(true);
206 mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity.SetIsVoid(
207 true);
210 inline void InitStyle(nsHtml5String aUrl, nsHtml5String aCharset,
211 nsHtml5String aCrossOrigin,
212 nsHtml5String aReferrerPolicy, nsHtml5String aIntegrity,
213 bool aLinkPreload) {
214 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
215 "Trying to reinitialize a speculative load!");
216 mOpCode = eSpeculativeLoadStyle;
217 aUrl.ToString(mUrlOrSizes);
218 aCharset.ToString(mCharsetOrSrcset);
219 aCrossOrigin.ToString(mCrossOriginOrMedia);
220 nsString
221 referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
222 aReferrerPolicy.ToString(referrerPolicy);
223 mReferrerPolicyOrIntegrity.Assign(
224 nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
225 referrerPolicy));
226 aIntegrity.ToString(
227 mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity);
228 mIsLinkPreload = aLinkPreload;
232 * "Speculative" manifest loads aren't truly speculative--if a manifest
233 * gets loaded, we are committed to it. There can never be a <script>
234 * before the manifest, so the situation of having to undo a manifest due
235 * to document.write() never arises. The reason why a parser
236 * thread-discovered manifest gets loaded via the speculative load queue
237 * as opposed to tree operation queue is that the manifest must get
238 * processed before any actual speculative loads such as scripts. Thus,
239 * manifests seen by the parser thread have to maintain the queue order
240 * relative to true speculative loads. See bug 541079.
242 inline void InitManifest(nsHtml5String aUrl) {
243 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
244 "Trying to reinitialize a speculative load!");
245 mOpCode = eSpeculativeLoadManifest;
246 aUrl.ToString(mUrlOrSizes);
250 * "Speculative" charset setting isn't truly speculative. If the charset
251 * is set via this operation, we are committed to it unless chardet or
252 * a late meta cause a reload. The reason why a parser
253 * thread-discovered charset gets communicated via the speculative load
254 * queue as opposed to tree operation queue is that the charset change
255 * must get processed before any actual speculative loads such as style
256 * sheets. Thus, encoding decisions by the parser thread have to maintain
257 * the queue order relative to true speculative loads. See bug 675499.
259 inline void InitSetDocumentCharset(NotNull<const Encoding*> aEncoding,
260 int32_t aCharsetSource) {
261 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
262 "Trying to reinitialize a speculative load!");
263 mOpCode = eSpeculativeLoadSetDocumentCharset;
264 mCharsetOrSrcset.~nsString();
265 mEncoding = aEncoding;
266 mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity.Assign(
267 (char16_t)aCharsetSource);
271 * Speculative document mode setting isn't really speculative. Once it
272 * happens, we are committed to it. However, this information needs to
273 * travel in the speculation queue in order to have this information
274 * available before parsing the speculatively loaded style sheets.
276 inline void InitSetDocumentMode(nsHtml5DocumentMode aMode) {
277 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
278 "Trying to reinitialize a speculative load!");
279 mOpCode = eSpeculativeLoadSetDocumentMode;
280 mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity.Assign(
281 (char16_t)aMode);
284 inline void InitPreconnect(nsHtml5String aUrl, nsHtml5String aCrossOrigin) {
285 MOZ_ASSERT(mOpCode == eSpeculativeLoadUninitialized,
286 "Trying to reinitialize a speculative load!");
287 mOpCode = eSpeculativeLoadPreconnect;
288 aUrl.ToString(mUrlOrSizes);
289 aCrossOrigin.ToString(mCrossOriginOrMedia);
292 void Perform(nsHtml5TreeOpExecutor* aExecutor);
294 private:
295 nsHtml5SpeculativeLoad(const nsHtml5SpeculativeLoad&) = delete;
296 nsHtml5SpeculativeLoad& operator=(const nsHtml5SpeculativeLoad&) = delete;
298 eHtml5SpeculativeLoad mOpCode;
301 * Whether the refering element has async and/or defer attributes.
303 bool mIsAsync;
304 bool mIsDefer;
307 * True if and only if this is a speculative load initiated by <link
308 * rel="preload"> tag encounter. Passed to the handling loader as an
309 * indication to raise the priority.
311 bool mIsLinkPreload;
313 /* If mOpCode is eSpeculativeLoadPictureSource, this is the value of the
314 * "sizes" attribute. If the attribute is not set, this will be a void
315 * string. Otherwise it empty or the value of the url.
317 nsString mUrlOrSizes;
319 * If mOpCode is eSpeculativeLoadScript[FromHead], this is the value of the
320 * "integrity" attribute. If the attribute is not set, this will be a void
321 * string. Otherwise it is empty or the value of the referrer policy.
323 nsString mReferrerPolicyOrIntegrity;
325 * If mOpCode is eSpeculativeLoadStyle or eSpeculativeLoadScript[FromHead]
326 * then this is the value of the "charset" attribute. For
327 * eSpeculativeLoadSetDocumentCharset it is the charset that the
328 * document's charset is being set to. If mOpCode is eSpeculativeLoadImage
329 * or eSpeculativeLoadPictureSource, this is the value of the "srcset"
330 * attribute. If the attribute is not set, this will be a void string.
331 * Otherwise it's empty.
333 union {
334 nsString mCharsetOrSrcset;
335 const Encoding* mEncoding;
338 * If mOpCode is eSpeculativeLoadSetDocumentCharset, this is a
339 * one-character string whose single character's code point is to be
340 * interpreted as a charset source integer. If mOpCode is
341 * eSpeculativeLoadSetDocumentMode, this is a one-character string whose
342 * single character's code point is to be interpreted as an
343 * nsHtml5DocumentMode. If mOpCode is eSpeculativeLoadCSP, this is a meta
344 * element's CSP value. If mOpCode is eSpeculativeLoadImage, this is the
345 * value of the "sizes" attribute. If the attribute is not set, this will
346 * be a void string. If mOpCode is eSpeculativeLoadStyle, this
347 * is the value of the "integrity" attribute. If the attribute is not set,
348 * this will be a void string. Otherwise it is empty or the value of the
349 * referrer policy. Otherwise, it is empty or the value of the type attribute.
351 nsString mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity;
353 * If mOpCode is eSpeculativeLoadImage or eSpeculativeLoadScript[FromHead]
354 * or eSpeculativeLoadPreconnect this is the value of the "crossorigin"
355 * attribute. If the attribute is not set, this will be a void string.
356 * If mOpCode is eSpeculativeLoadPictureSource, this is the value of the
357 * "media" attribute. If the attribute is not set, this will be a void
358 * string.
360 nsString mCrossOriginOrMedia;
362 * If mOpCode is eSpeculativeLoadScript[FromHead] this represents the value
363 * of the "referrerpolicy" attribute. This field holds one of the values
364 * (REFERRER_POLICY_*) defined in nsIHttpChannel.
366 mozilla::dom::ReferrerPolicy mScriptReferrerPolicy;
369 #endif // nsHtml5SpeculativeLoad_h