Line data Source code
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/. */
4 :
5 : #ifndef nsHtml5SpeculativeLoad_h
6 : #define nsHtml5SpeculativeLoad_h
7 :
8 : #include "nsString.h"
9 : #include "nsContentUtils.h"
10 :
11 : class nsHtml5TreeOpExecutor;
12 :
13 : enum eHtml5SpeculativeLoad {
14 : #ifdef DEBUG
15 : eSpeculativeLoadUninitialized,
16 : #endif
17 : eSpeculativeLoadBase,
18 : eSpeculativeLoadCSP,
19 : eSpeculativeLoadMetaReferrer,
20 : eSpeculativeLoadImage,
21 : eSpeculativeLoadOpenPicture,
22 : eSpeculativeLoadEndPicture,
23 : eSpeculativeLoadPictureSource,
24 : eSpeculativeLoadScript,
25 : eSpeculativeLoadScriptFromHead,
26 : eSpeculativeLoadStyle,
27 : eSpeculativeLoadManifest,
28 : eSpeculativeLoadSetDocumentCharset,
29 : eSpeculativeLoadSetDocumentMode,
30 : eSpeculativeLoadPreconnect
31 : };
32 :
33 : class nsHtml5SpeculativeLoad {
34 : public:
35 : nsHtml5SpeculativeLoad();
36 : ~nsHtml5SpeculativeLoad();
37 :
38 0 : inline void InitBase(nsHtml5String aUrl)
39 : {
40 0 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
41 : "Trying to reinitialize a speculative load!");
42 0 : mOpCode = eSpeculativeLoadBase;
43 0 : aUrl.ToString(mUrl);
44 0 : }
45 :
46 0 : inline void InitMetaCSP(nsHtml5String aCSP)
47 : {
48 0 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
49 : "Trying to reinitialize a speculative load!");
50 0 : mOpCode = eSpeculativeLoadCSP;
51 0 : nsString csp; // Not Auto, because using it to hold nsStringBuffer*
52 0 : aCSP.ToString(csp);
53 0 : mMetaCSP.Assign(
54 0 : nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(csp));
55 0 : }
56 :
57 0 : inline void InitMetaReferrerPolicy(nsHtml5String aReferrerPolicy)
58 : {
59 0 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
60 : "Trying to reinitialize a speculative load!");
61 0 : mOpCode = eSpeculativeLoadMetaReferrer;
62 : nsString
63 0 : referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
64 0 : aReferrerPolicy.ToString(referrerPolicy);
65 0 : mReferrerPolicy.Assign(
66 0 : nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
67 0 : referrerPolicy));
68 0 : }
69 :
70 0 : inline void InitImage(nsHtml5String aUrl,
71 : nsHtml5String aCrossOrigin,
72 : nsHtml5String aReferrerPolicy,
73 : nsHtml5String aSrcset,
74 : nsHtml5String aSizes)
75 : {
76 0 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
77 : "Trying to reinitialize a speculative load!");
78 0 : mOpCode = eSpeculativeLoadImage;
79 0 : aUrl.ToString(mUrl);
80 0 : aCrossOrigin.ToString(mCrossOrigin);
81 : nsString
82 0 : referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
83 0 : aReferrerPolicy.ToString(referrerPolicy);
84 0 : mReferrerPolicy.Assign(
85 0 : nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
86 0 : referrerPolicy));
87 0 : aSrcset.ToString(mSrcset);
88 0 : aSizes.ToString(mSizes);
89 0 : }
90 :
91 : // <picture> elements have multiple <source> nodes followed by an <img>,
92 : // where we use the first valid source, which may be the img. Because we
93 : // can't determine validity at this point without parsing CSS and getting
94 : // main thread state, we push preload operations for picture pushed and
95 : // popped, so that the target of the preload ops can determine what picture
96 : // and nesting level each source/img from the main preloading code exists
97 : // at.
98 0 : inline void InitOpenPicture()
99 : {
100 0 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
101 : "Trying to reinitialize a speculative load!");
102 0 : mOpCode = eSpeculativeLoadOpenPicture;
103 0 : }
104 :
105 0 : inline void InitEndPicture()
106 : {
107 0 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
108 : "Trying to reinitialize a speculative load!");
109 0 : mOpCode = eSpeculativeLoadEndPicture;
110 0 : }
111 :
112 0 : inline void InitPictureSource(nsHtml5String aSrcset,
113 : nsHtml5String aSizes,
114 : nsHtml5String aType,
115 : nsHtml5String aMedia)
116 : {
117 0 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
118 : "Trying to reinitialize a speculative load!");
119 0 : mOpCode = eSpeculativeLoadPictureSource;
120 0 : aSrcset.ToString(mSrcset);
121 0 : aSizes.ToString(mSizes);
122 0 : aType.ToString(mTypeOrCharsetSourceOrDocumentMode);
123 0 : aMedia.ToString(mMedia);
124 0 : }
125 :
126 4 : inline void InitScript(nsHtml5String aUrl,
127 : nsHtml5String aCharset,
128 : nsHtml5String aType,
129 : nsHtml5String aCrossOrigin,
130 : nsHtml5String aIntegrity,
131 : bool aParserInHead)
132 : {
133 4 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
134 : "Trying to reinitialize a speculative load!");
135 4 : mOpCode = aParserInHead ?
136 : eSpeculativeLoadScriptFromHead : eSpeculativeLoadScript;
137 4 : aUrl.ToString(mUrl);
138 4 : aCharset.ToString(mCharset);
139 4 : aType.ToString(mTypeOrCharsetSourceOrDocumentMode);
140 4 : aCrossOrigin.ToString(mCrossOrigin);
141 4 : aIntegrity.ToString(mIntegrity);
142 4 : }
143 :
144 0 : inline void InitStyle(nsHtml5String aUrl,
145 : nsHtml5String aCharset,
146 : nsHtml5String aCrossOrigin,
147 : nsHtml5String aIntegrity)
148 : {
149 0 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
150 : "Trying to reinitialize a speculative load!");
151 0 : mOpCode = eSpeculativeLoadStyle;
152 0 : aUrl.ToString(mUrl);
153 0 : aCharset.ToString(mCharset);
154 0 : aCrossOrigin.ToString(mCrossOrigin);
155 0 : aIntegrity.ToString(mIntegrity);
156 0 : }
157 :
158 : /**
159 : * "Speculative" manifest loads aren't truly speculative--if a manifest
160 : * gets loaded, we are committed to it. There can never be a <script>
161 : * before the manifest, so the situation of having to undo a manifest due
162 : * to document.write() never arises. The reason why a parser
163 : * thread-discovered manifest gets loaded via the speculative load queue
164 : * as opposed to tree operation queue is that the manifest must get
165 : * processed before any actual speculative loads such as scripts. Thus,
166 : * manifests seen by the parser thread have to maintain the queue order
167 : * relative to true speculative loads. See bug 541079.
168 : */
169 2 : inline void InitManifest(nsHtml5String aUrl)
170 : {
171 2 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
172 : "Trying to reinitialize a speculative load!");
173 2 : mOpCode = eSpeculativeLoadManifest;
174 2 : aUrl.ToString(mUrl);
175 2 : }
176 :
177 : /**
178 : * "Speculative" charset setting isn't truly speculative. If the charset
179 : * is set via this operation, we are committed to it unless chardet or
180 : * a late meta cause a reload. The reason why a parser
181 : * thread-discovered charset gets communicated via the speculative load
182 : * queue as opposed to tree operation queue is that the charset change
183 : * must get processed before any actual speculative loads such as style
184 : * sheets. Thus, encoding decisions by the parser thread have to maintain
185 : * the queue order relative to true speculative loads. See bug 675499.
186 : */
187 2 : inline void InitSetDocumentCharset(nsACString& aCharset,
188 : int32_t aCharsetSource)
189 : {
190 2 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
191 : "Trying to reinitialize a speculative load!");
192 2 : mOpCode = eSpeculativeLoadSetDocumentCharset;
193 2 : CopyUTF8toUTF16(aCharset, mCharset);
194 2 : mTypeOrCharsetSourceOrDocumentMode.Assign((char16_t)aCharsetSource);
195 2 : }
196 :
197 : /**
198 : * Speculative document mode setting isn't really speculative. Once it
199 : * happens, we are committed to it. However, this information needs to
200 : * travel in the speculation queue in order to have this information
201 : * available before parsing the speculatively loaded style sheets.
202 : */
203 2 : inline void InitSetDocumentMode(nsHtml5DocumentMode aMode)
204 : {
205 2 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
206 : "Trying to reinitialize a speculative load!");
207 2 : mOpCode = eSpeculativeLoadSetDocumentMode;
208 2 : mTypeOrCharsetSourceOrDocumentMode.Assign((char16_t)aMode);
209 2 : }
210 :
211 0 : inline void InitPreconnect(nsHtml5String aUrl, nsHtml5String aCrossOrigin)
212 : {
213 0 : NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
214 : "Trying to reinitialize a speculative load!");
215 0 : mOpCode = eSpeculativeLoadPreconnect;
216 0 : aUrl.ToString(mUrl);
217 0 : aCrossOrigin.ToString(mCrossOrigin);
218 0 : }
219 :
220 : void Perform(nsHtml5TreeOpExecutor* aExecutor);
221 :
222 : private:
223 : eHtml5SpeculativeLoad mOpCode;
224 : nsString mUrl;
225 : nsString mReferrerPolicy;
226 : nsString mMetaCSP;
227 :
228 : /**
229 : * If mOpCode is eSpeculativeLoadStyle or eSpeculativeLoadScript[FromHead]
230 : * then this is the value of the "charset" attribute. For
231 : * eSpeculativeLoadSetDocumentCharset it is the charset that the
232 : * document's charset is being set to. Otherwise it's empty.
233 : */
234 : nsString mCharset;
235 : /**
236 : * If mOpCode is eSpeculativeLoadSetDocumentCharset, this is a
237 : * one-character string whose single character's code point is to be
238 : * interpreted as a charset source integer. If mOpCode is
239 : * eSpeculativeLoadSetDocumentMode, this is a one-character string whose
240 : * single character's code point is to be interpreted as an
241 : * nsHtml5DocumentMode. Otherwise, it is empty or the value of the type
242 : * attribute.
243 : */
244 : nsString mTypeOrCharsetSourceOrDocumentMode;
245 : /**
246 : * If mOpCode is eSpeculativeLoadImage or eSpeculativeLoadScript[FromHead]
247 : * or eSpeculativeLoadPreconnect this is the value of the "crossorigin"
248 : * attribute. If the attribute is not set, this will be a void string.
249 : */
250 : nsString mCrossOrigin;
251 : /**
252 : * If mOpCode is eSpeculativeLoadImage or eSpeculativeLoadPictureSource,
253 : * this is the value of "srcset" attribute. If the attribute is not set,
254 : * this will be a void string.
255 : */
256 : nsString mSrcset;
257 : /**
258 : * If mOpCode is eSpeculativeLoadPictureSource, this is the value of "sizes"
259 : * attribute. If the attribute is not set, this will be a void string.
260 : */
261 : nsString mSizes;
262 : /**
263 : * If mOpCode is eSpeculativeLoadPictureSource, this is the value of "media"
264 : * attribute. If the attribute is not set, this will be a void string.
265 : */
266 : nsString mMedia;
267 : /**
268 : * If mOpCode is eSpeculativeLoadScript[FromHead], this is the value of the
269 : * "integrity" attribute. If the attribute is not set, this will be a void
270 : * string.
271 : */
272 : nsString mIntegrity;
273 : };
274 :
275 : #endif // nsHtml5SpeculativeLoad_h
|