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 #include "nsHtml5SpeculativeLoad.h"
6 #include "mozilla/Encoding.h"
7 #include "nsHtml5TreeOpExecutor.h"
8 
9 using namespace mozilla;
10 
nsHtml5SpeculativeLoad()11 nsHtml5SpeculativeLoad::nsHtml5SpeculativeLoad()
12     : mOpCode(eSpeculativeLoadUninitialized),
13       mIsAsync(false),
14       mIsDefer(false),
15       mIsLinkPreload(false),
16       mIsError(false),
17       mEncoding(nullptr) {
18   MOZ_COUNT_CTOR(nsHtml5SpeculativeLoad);
19   new (&mCharsetOrSrcset) nsString;
20 }
21 
~nsHtml5SpeculativeLoad()22 nsHtml5SpeculativeLoad::~nsHtml5SpeculativeLoad() {
23   MOZ_COUNT_DTOR(nsHtml5SpeculativeLoad);
24   NS_ASSERTION(mOpCode != eSpeculativeLoadUninitialized,
25                "Uninitialized speculative load.");
26   if (!(mOpCode == eSpeculativeLoadSetDocumentCharset ||
27         mOpCode == eSpeculativeLoadMaybeComplainAboutCharset)) {
28     mCharsetOrSrcset.~nsString();
29   }
30 }
31 
Perform(nsHtml5TreeOpExecutor * aExecutor)32 void nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor) {
33   switch (mOpCode) {
34     case eSpeculativeLoadBase:
35       aExecutor->SetSpeculationBase(mUrlOrSizes);
36       break;
37     case eSpeculativeLoadCSP:
38       aExecutor->AddSpeculationCSP(
39           mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity);
40       break;
41     case eSpeculativeLoadMetaReferrer:
42       aExecutor->UpdateReferrerInfoFromMeta(mReferrerPolicyOrIntegrity);
43       break;
44     case eSpeculativeLoadImage:
45       aExecutor->PreloadImage(
46           mUrlOrSizes, mCrossOrigin, mMedia, mCharsetOrSrcset,
47           mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity,
48           mReferrerPolicyOrIntegrity, mIsLinkPreload, mInitTimestamp);
49       break;
50     case eSpeculativeLoadOpenPicture:
51       aExecutor->PreloadOpenPicture();
52       break;
53     case eSpeculativeLoadEndPicture:
54       aExecutor->PreloadEndPicture();
55       break;
56     case eSpeculativeLoadPictureSource:
57       aExecutor->PreloadPictureSource(
58           mCharsetOrSrcset, mUrlOrSizes,
59           mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity,
60           mMedia);
61       break;
62     case eSpeculativeLoadScript:
63       aExecutor->PreloadScript(
64           mUrlOrSizes, mCharsetOrSrcset,
65           mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity,
66           mCrossOrigin, mMedia, mReferrerPolicyOrIntegrity,
67           mScriptReferrerPolicy, false, mIsAsync, mIsDefer, false,
68           mIsLinkPreload);
69       break;
70     case eSpeculativeLoadScriptFromHead:
71       aExecutor->PreloadScript(
72           mUrlOrSizes, mCharsetOrSrcset,
73           mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity,
74           mCrossOrigin, mMedia, mReferrerPolicyOrIntegrity,
75           mScriptReferrerPolicy, true, mIsAsync, mIsDefer, false,
76           mIsLinkPreload);
77       break;
78     case eSpeculativeLoadNoModuleScript:
79       aExecutor->PreloadScript(
80           mUrlOrSizes, mCharsetOrSrcset,
81           mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity,
82           mCrossOrigin, mMedia, mReferrerPolicyOrIntegrity,
83           mScriptReferrerPolicy, false, mIsAsync, mIsDefer, true,
84           mIsLinkPreload);
85       break;
86     case eSpeculativeLoadNoModuleScriptFromHead:
87       aExecutor->PreloadScript(
88           mUrlOrSizes, mCharsetOrSrcset,
89           mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity,
90           mCrossOrigin, mMedia, mReferrerPolicyOrIntegrity,
91           mScriptReferrerPolicy, true, mIsAsync, mIsDefer, true,
92           mIsLinkPreload);
93       break;
94     case eSpeculativeLoadStyle:
95       aExecutor->PreloadStyle(
96           mUrlOrSizes, mCharsetOrSrcset, mCrossOrigin, mMedia,
97           mReferrerPolicyOrIntegrity,
98           mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity,
99           mIsLinkPreload);
100       break;
101     case eSpeculativeLoadManifest:
102       // TODO: remove this
103       break;
104     case eSpeculativeLoadSetDocumentCharset: {
105       MOZ_ASSERT(mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity
106                          .Length() == 1,
107                  "Unexpected charset source string");
108       nsCharsetSource enumSource =
109           (nsCharsetSource)
110               mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity
111                   .First();
112       aExecutor->SetDocumentCharsetAndSource(WrapNotNull(mEncoding),
113                                              enumSource);
114       if (mCommitEncodingSpeculation) {
115         aExecutor->CommitToInternalEncoding();
116       }
117     } break;
118     case eSpeculativeLoadSetDocumentMode: {
119       NS_ASSERTION(mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity
120                            .Length() == 1,
121                    "Unexpected document mode string");
122       nsHtml5DocumentMode mode =
123           (nsHtml5DocumentMode)
124               mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity
125                   .First();
126       aExecutor->SetDocumentMode(mode);
127     } break;
128     case eSpeculativeLoadPreconnect:
129       aExecutor->Preconnect(mUrlOrSizes, mCrossOrigin);
130       break;
131     case eSpeculativeLoadFont:
132       aExecutor->PreloadFont(mUrlOrSizes, mCrossOrigin, mMedia,
133                              mReferrerPolicyOrIntegrity);
134       break;
135     case eSpeculativeLoadFetch:
136       aExecutor->PreloadFetch(mUrlOrSizes, mCrossOrigin, mMedia,
137                               mReferrerPolicyOrIntegrity);
138       break;
139     case eSpeculativeLoadMaybeComplainAboutCharset: {
140       MOZ_ASSERT(mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity
141                          .Length() == 2,
142                  "Unexpected line number string");
143       uint32_t high =
144           (uint32_t)
145               mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity
146                   .CharAt(0);
147       uint32_t low =
148           (uint32_t)
149               mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity
150                   .CharAt(1);
151       uint32_t line = (high << 16) | low;
152       aExecutor->MaybeComplainAboutCharset(mMsgId, mIsError, (int32_t)line);
153     } break;
154     default:
155       MOZ_ASSERT_UNREACHABLE("Bogus speculative load.");
156       break;
157   }
158 }
159