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 nsHtml5TreeOpExecutor_h
6 #define nsHtml5TreeOpExecutor_h
9 #include "nsTraceRefcnt.h"
10 #include "nsHtml5TreeOperation.h"
11 #include "nsHtml5SpeculativeLoad.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"
21 #include "nsTHashSet.h"
22 #include "nsHashKeys.h"
23 #include "mozilla/LinkedList.h"
24 #include "nsHtml5DocumentBuilder.h"
25 #include "nsCharsetSource.h"
28 class nsHtml5StreamParser
;
34 } // namespace mozilla
36 class nsHtml5TreeOpExecutor final
37 : public nsHtml5DocumentBuilder
,
38 public nsIContentSink
,
39 public nsAHtml5TreeOpSink
,
40 public mozilla::LinkedListElement
<nsHtml5TreeOpExecutor
> {
41 friend class nsHtml5FlushLoopGuard
;
42 typedef mozilla::dom::ReferrerPolicy ReferrerPolicy
;
43 using Encoding
= mozilla::Encoding
;
45 using NotNull
= mozilla::NotNull
<T
>;
48 NS_DECL_ISUPPORTS_INHERITED
52 static uint32_t sAppendBatchMaxSize
;
53 static uint32_t sAppendBatchSlotsExamined
;
54 static uint32_t sAppendBatchExaminations
;
55 static uint32_t sLongestTimeOffTheEventLoop
;
56 static uint32_t sTimesFlushLoopInterrupted
;
60 * Whether EOF needs to be suppressed
64 bool mReadingFromStage
;
65 nsTArray
<nsHtml5TreeOperation
> mOpQueue
;
66 nsHtml5StreamParser
* mStreamParser
;
69 * URLs already preloaded/preloading.
71 nsTHashSet
<nsCString
> mPreloadedURLs
;
73 nsCOMPtr
<nsIURI
> mSpeculationBaseURI
;
75 nsCOMPtr
<nsIURI
> mViewSourceBaseURI
;
78 * Whether the parser has started
82 nsHtml5TreeOpStage mStage
;
84 bool mRunFlushLoopOnStack
;
86 bool mCallContinueInterruptedParsingIfEnabled
;
89 * Whether this executor has already complained about matters related
90 * to character encoding declarations.
92 bool mAlreadyComplainedAboutCharset
;
95 * Whether this executor has already complained about the tree being too
98 bool mAlreadyComplainedAboutDeepTree
;
101 nsHtml5TreeOpExecutor();
104 virtual ~nsHtml5TreeOpExecutor();
110 * Unimplemented. For interface compat only.
112 NS_IMETHOD
WillParse() override
;
114 NS_IMETHOD
WillBuildModel(nsDTDMode
/* unused */) override
{
115 return WillBuildModel();
117 nsresult
WillBuildModel();
122 NS_IMETHOD
DidBuildModel(bool aTerminated
) override
;
125 * Forwards to nsContentSink
127 NS_IMETHOD
WillInterrupt() override
;
130 * Unimplemented. For interface compat only.
132 void WillResume() override
;
134 virtual nsIContentSink
* AsExecutor() override
{ return this; }
136 virtual void InitialTranslationCompleted() override
;
141 NS_IMETHOD
SetParser(nsParserBase
* aParser
) override
;
144 * No-op for backwards compat.
146 virtual void FlushPendingNotifications(mozilla::FlushType aType
) override
;
149 * Don't call. For interface compat only.
151 virtual void SetDocumentCharset(NotNull
<const Encoding
*> aEncoding
) override
{
152 MOZ_ASSERT_UNREACHABLE("No one should call this.");
156 * Returns the document.
158 virtual nsISupports
* GetTarget() override
;
160 virtual void ContinueInterruptedParsingAsync() override
;
162 bool IsScriptExecuting() override
{ return IsScriptExecutingImpl(); }
164 // Not from interface
166 void SetStreamParser(nsHtml5StreamParser
* aStreamParser
) {
167 mStreamParser
= aStreamParser
;
170 void InitializeDocWriteParserState(nsAHtml5TreeBuilderState
* aState
,
173 bool IsScriptEnabled();
175 virtual nsresult
MarkAsBroken(nsresult aReason
) override
;
177 void StartLayout(bool* aInterrupted
);
179 void PauseDocUpdate(bool* aInterrupted
);
181 void FlushSpeculativeLoads();
185 nsresult
FlushDocumentWrite();
187 void CommitToInternalEncoding();
189 [[nodiscard
]] bool TakeOpsFromStage();
195 void SetDocumentCharsetAndSource(NotNull
<const Encoding
*> aEncoding
,
196 nsCharsetSource aCharsetSource
);
198 void UpdateCharsetSource(nsCharsetSource aCharsetSource
);
200 void NeedsCharsetSwitchTo(NotNull
<const Encoding
*> aEncoding
, int32_t aSource
,
201 uint32_t aLineNumber
);
203 void MaybeComplainAboutCharset(const char* aMsgId
, bool aError
,
204 uint32_t aLineNumber
);
206 void ComplainAboutBogusProtocolCharset(mozilla::dom::Document
* aDoc
,
209 void MaybeComplainAboutDeepTree(uint32_t aLineNumber
);
211 bool HasStarted() { return mStarted
; }
213 bool IsFlushing() { return mFlushState
>= eInFlush
; }
216 bool IsInFlushLoop() { return mRunFlushLoopOnStack
; }
219 void RunScript(nsIContent
* aScriptElement
, bool aMayDocumentWriteOrBlock
);
222 * Flush the operations from the tree operations from the argument
223 * queue unconditionally. (This is for the main thread case.)
225 [[nodiscard
]] virtual bool MoveOpsFrom(
226 nsTArray
<nsHtml5TreeOperation
>& aOpQueue
) override
;
230 void RemoveFromStartOfOpQueue(size_t aNumberOfOpsToRemove
);
232 inline size_t OpQueueLength() { return mOpQueue
.Length(); }
234 nsHtml5TreeOpStage
* GetStage() { return &mStage
; }
236 void StartReadingFromStage() { mReadingFromStage
= true; }
241 void AssertStageEmpty() { mStage
.AssertEmpty(); }
244 nsIURI
* GetViewSourceBaseURI();
246 void PreloadScript(const nsAString
& aURL
, const nsAString
& aCharset
,
247 const nsAString
& aType
, const nsAString
& aCrossOrigin
,
248 const nsAString
& aMedia
, const nsAString
& aNonce
,
249 const nsAString
& aFetchPriority
,
250 const nsAString
& aIntegrity
,
251 ReferrerPolicy aReferrerPolicy
, bool aScriptFromHead
,
252 bool aAsync
, bool aDefer
, bool aLinkPreload
);
254 void PreloadStyle(const nsAString
& aURL
, const nsAString
& aCharset
,
255 const nsAString
& aCrossOrigin
, const nsAString
& aMedia
,
256 const nsAString
& aReferrerPolicy
, const nsAString
& aNonce
,
257 const nsAString
& aIntegrity
, bool aLinkPreload
,
258 const nsAString
& aFetchPriority
);
260 void PreloadImage(const nsAString
& aURL
, const nsAString
& aCrossOrigin
,
261 const nsAString
& aMedia
, const nsAString
& aSrcset
,
262 const nsAString
& aSizes
,
263 const nsAString
& aImageReferrerPolicy
, bool aLinkPreload
,
264 const nsAString
& aFetchPriority
);
266 void PreloadOpenPicture();
268 void PreloadEndPicture();
270 void PreloadPictureSource(const nsAString
& aSrcset
, const nsAString
& aSizes
,
271 const nsAString
& aType
, const nsAString
& aMedia
);
273 void PreloadFont(const nsAString
& aURL
, const nsAString
& aCrossOrigin
,
274 const nsAString
& aMedia
, const nsAString
& aReferrerPolicy
,
275 const nsAString
& aFetchPriority
);
277 void PreloadFetch(const nsAString
& aURL
, const nsAString
& aCrossOrigin
,
278 const nsAString
& aMedia
, const nsAString
& aReferrerPolicy
,
279 const nsAString
& aFetchPriority
);
281 void SetSpeculationBase(const nsAString
& aURL
);
283 void UpdateReferrerInfoFromMeta(const nsAString
& aMetaReferrer
);
285 void AddSpeculationCSP(const nsAString
& aCSP
);
287 void AddBase(const nsAString
& aURL
);
290 nsHtml5Parser
* GetParser();
292 bool IsExternalViewSource();
295 * Get a nsIURI for an nsString if the URL hasn't been preloaded yet.
297 already_AddRefed
<nsIURI
> ConvertIfNotPreloadedYet(const nsAString
& aURL
);
300 * The above, plus also checks that the media attribute applies.
302 already_AddRefed
<nsIURI
> ConvertIfNotPreloadedYetAndMediaApplies(
303 const nsAString
& aURL
, const nsAString
& aMedia
);
305 /** Returns whether the given media attribute applies to mDocument */
306 bool MediaApplies(const nsAString
& aMedia
);
309 * The base URI we would use for current preload operations
311 nsIURI
* BaseURIForPreload();
314 * Returns true if we haven't preloaded this URI yet, and adds it to the
315 * list of preloaded URIs
317 bool ShouldPreloadURI(nsIURI
* aURI
);
319 ReferrerPolicy
GetPreloadReferrerPolicy(const nsAString
& aReferrerPolicy
);
321 ReferrerPolicy
GetPreloadReferrerPolicy(ReferrerPolicy aReferrerPolicy
);
324 #endif // nsHtml5TreeOpExecutor_h