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 nsHtml5TreeOpExecutor_h
6 : #define nsHtml5TreeOpExecutor_h
7 :
8 : #include "nsIAtom.h"
9 : #include "nsTraceRefcnt.h"
10 : #include "nsHtml5TreeOperation.h"
11 : #include "nsHtml5SpeculativeLoad.h"
12 : #include "nsTArray.h"
13 : #include "nsContentSink.h"
14 : #include "nsNodeInfoManager.h"
15 : #include "nsHtml5DocumentMode.h"
16 : #include "nsIScriptElement.h"
17 : #include "nsIParser.h"
18 : #include "nsAHtml5TreeOpSink.h"
19 : #include "nsHtml5TreeOpStage.h"
20 : #include "nsIURI.h"
21 : #include "nsTHashtable.h"
22 : #include "nsHashKeys.h"
23 : #include "mozilla/LinkedList.h"
24 : #include "nsHtml5DocumentBuilder.h"
25 : #include "mozilla/net/ReferrerPolicy.h"
26 :
27 : class nsHtml5Parser;
28 : class nsHtml5StreamParser;
29 : class nsIContent;
30 : class nsIDocument;
31 :
32 : class nsHtml5TreeOpExecutor final : public nsHtml5DocumentBuilder,
33 : public nsIContentSink,
34 : public nsAHtml5TreeOpSink,
35 : public mozilla::LinkedListElement<nsHtml5TreeOpExecutor>
36 : {
37 : friend class nsHtml5FlushLoopGuard;
38 : typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
39 : using Encoding = mozilla::Encoding;
40 : template <typename T> using NotNull = mozilla::NotNull<T>;
41 :
42 : public:
43 : NS_DECL_ISUPPORTS_INHERITED
44 :
45 : private:
46 : static bool sExternalViewSource;
47 : #ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
48 : static uint32_t sAppendBatchMaxSize;
49 : static uint32_t sAppendBatchSlotsExamined;
50 : static uint32_t sAppendBatchExaminations;
51 : static uint32_t sLongestTimeOffTheEventLoop;
52 : static uint32_t sTimesFlushLoopInterrupted;
53 : #endif
54 :
55 : /**
56 : * Whether EOF needs to be suppressed
57 : */
58 : bool mSuppressEOF;
59 :
60 : bool mReadingFromStage;
61 : nsTArray<nsHtml5TreeOperation> mOpQueue;
62 : nsHtml5StreamParser* mStreamParser;
63 :
64 : /**
65 : * URLs already preloaded/preloading.
66 : */
67 : nsTHashtable<nsCStringHashKey> mPreloadedURLs;
68 :
69 : nsCOMPtr<nsIURI> mSpeculationBaseURI;
70 :
71 : /**
72 : * Speculative referrer policy
73 : */
74 : ReferrerPolicy mSpeculationReferrerPolicy;
75 :
76 : nsCOMPtr<nsIURI> mViewSourceBaseURI;
77 :
78 : /**
79 : * Whether the parser has started
80 : */
81 : bool mStarted;
82 :
83 : nsHtml5TreeOpStage mStage;
84 :
85 : bool mRunFlushLoopOnStack;
86 :
87 : bool mCallContinueInterruptedParsingIfEnabled;
88 :
89 : /**
90 : * Whether this executor has already complained about matters related
91 : * to character encoding declarations.
92 : */
93 : bool mAlreadyComplainedAboutCharset;
94 :
95 : public:
96 :
97 : nsHtml5TreeOpExecutor();
98 :
99 : protected:
100 :
101 : virtual ~nsHtml5TreeOpExecutor();
102 :
103 : public:
104 :
105 : // nsIContentSink
106 :
107 : /**
108 : * Unimplemented. For interface compat only.
109 : */
110 : NS_IMETHOD WillParse() override;
111 :
112 : /**
113 : *
114 : */
115 : NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
116 :
117 : /**
118 : * Emits EOF.
119 : */
120 : NS_IMETHOD DidBuildModel(bool aTerminated) override;
121 :
122 : /**
123 : * Forwards to nsContentSink
124 : */
125 : NS_IMETHOD WillInterrupt() override;
126 :
127 : /**
128 : * Unimplemented. For interface compat only.
129 : */
130 : NS_IMETHOD WillResume() override;
131 :
132 : /**
133 : * Sets the parser.
134 : */
135 : NS_IMETHOD SetParser(nsParserBase* aParser) override;
136 :
137 : /**
138 : * No-op for backwards compat.
139 : */
140 : virtual void FlushPendingNotifications(mozilla::FlushType aType) override;
141 :
142 : /**
143 : * Don't call. For interface compat only.
144 : */
145 0 : virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override
146 : {
147 0 : NS_NOTREACHED("No one should call this.");
148 0 : }
149 :
150 : /**
151 : * Returns the document.
152 : */
153 : virtual nsISupports *GetTarget() override;
154 :
155 : virtual void ContinueInterruptedParsingAsync() override;
156 :
157 17 : bool IsScriptExecuting() override
158 : {
159 17 : return IsScriptExecutingImpl();
160 : }
161 :
162 : // Not from interface
163 :
164 2 : void SetStreamParser(nsHtml5StreamParser* aStreamParser)
165 : {
166 2 : mStreamParser = aStreamParser;
167 2 : }
168 :
169 : void InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState, int32_t aLine);
170 :
171 : bool IsScriptEnabled();
172 :
173 : virtual nsresult MarkAsBroken(nsresult aReason) override;
174 :
175 : void StartLayout(bool* aInterrupted);
176 :
177 : void PauseDocUpdate(bool* aInterrupted);
178 :
179 : void FlushSpeculativeLoads();
180 :
181 : void RunFlushLoop();
182 :
183 : nsresult FlushDocumentWrite();
184 :
185 : void MaybeSuspend();
186 :
187 : void Start();
188 :
189 : void NeedsCharsetSwitchTo(NotNull<const Encoding*> aEncoding,
190 : int32_t aSource,
191 : uint32_t aLineNumber);
192 :
193 : void MaybeComplainAboutCharset(const char* aMsgId,
194 : bool aError,
195 : uint32_t aLineNumber);
196 :
197 : void ComplainAboutBogusProtocolCharset(nsIDocument* aDoc);
198 :
199 10 : bool IsComplete()
200 : {
201 10 : return !mParser;
202 : }
203 :
204 11 : bool HasStarted()
205 : {
206 11 : return mStarted;
207 : }
208 :
209 0 : bool IsFlushing()
210 : {
211 0 : return mFlushState >= eInFlush;
212 : }
213 :
214 : #ifdef DEBUG
215 5 : bool IsInFlushLoop()
216 : {
217 5 : return mRunFlushLoopOnStack;
218 : }
219 : #endif
220 :
221 : void RunScript(nsIContent* aScriptElement);
222 :
223 : /**
224 : * Flush the operations from the tree operations from the argument
225 : * queue unconditionally. (This is for the main thread case.)
226 : */
227 : virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) override;
228 :
229 5 : nsHtml5TreeOpStage* GetStage()
230 : {
231 5 : return &mStage;
232 : }
233 :
234 3 : void StartReadingFromStage()
235 : {
236 3 : mReadingFromStage = true;
237 3 : }
238 :
239 : void StreamEnded();
240 :
241 : #ifdef DEBUG
242 5 : void AssertStageEmpty()
243 : {
244 5 : mStage.AssertEmpty();
245 5 : }
246 : #endif
247 :
248 : nsIURI* GetViewSourceBaseURI();
249 :
250 : void PreloadScript(const nsAString& aURL,
251 : const nsAString& aCharset,
252 : const nsAString& aType,
253 : const nsAString& aCrossOrigin,
254 : const nsAString& aIntegrity,
255 : bool aScriptFromHead);
256 :
257 : void PreloadStyle(const nsAString& aURL, const nsAString& aCharset,
258 : const nsAString& aCrossOrigin,
259 : const nsAString& aIntegrity);
260 :
261 : void PreloadImage(const nsAString& aURL,
262 : const nsAString& aCrossOrigin,
263 : const nsAString& aSrcset,
264 : const nsAString& aSizes,
265 : const nsAString& aImageReferrerPolicy);
266 :
267 : void PreloadOpenPicture();
268 :
269 : void PreloadEndPicture();
270 :
271 : void PreloadPictureSource(const nsAString& aSrcset,
272 : const nsAString& aSizes,
273 : const nsAString& aType,
274 : const nsAString& aMedia);
275 :
276 : void SetSpeculationBase(const nsAString& aURL);
277 :
278 : void SetSpeculationReferrerPolicy(ReferrerPolicy aReferrerPolicy);
279 : void SetSpeculationReferrerPolicy(const nsAString& aReferrerPolicy);
280 :
281 : void AddSpeculationCSP(const nsAString& aCSP);
282 :
283 : void AddBase(const nsAString& aURL);
284 :
285 : static void InitializeStatics();
286 :
287 : private:
288 : nsHtml5Parser* GetParser();
289 :
290 : bool IsExternalViewSource();
291 :
292 : /**
293 : * Get a nsIURI for an nsString if the URL hasn't been preloaded yet.
294 : */
295 : already_AddRefed<nsIURI> ConvertIfNotPreloadedYet(const nsAString& aURL);
296 :
297 : /**
298 : * The base URI we would use for current preload operations
299 : */
300 : nsIURI* BaseURIForPreload();
301 :
302 : /**
303 : * Returns true if we haven't preloaded this URI yet, and adds it to the
304 : * list of preloaded URIs
305 : */
306 : bool ShouldPreloadURI(nsIURI *aURI);
307 : };
308 :
309 : #endif // nsHtml5TreeOpExecutor_h
|