Bug 1890793: Assert CallArgs::newTarget is not gray. r=spidermonkey-reviewers,sfink...
[gecko.git] / parser / html / nsHtml5TreeOpExecutor.h
blob169fa5a703a6f209fdfaf251425e986d555396d8
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
8 #include "nsAtom.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 "nsTHashSet.h"
22 #include "nsHashKeys.h"
23 #include "mozilla/LinkedList.h"
24 #include "nsHtml5DocumentBuilder.h"
25 #include "nsCharsetSource.h"
27 class nsHtml5Parser;
28 class nsHtml5StreamParser;
29 class nsIContent;
30 namespace mozilla {
31 namespace dom {
32 class Document;
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;
44 template <typename T>
45 using NotNull = mozilla::NotNull<T>;
47 public:
48 NS_DECL_ISUPPORTS_INHERITED
50 private:
51 #ifdef DEBUG
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;
57 #endif
59 /**
60 * Whether EOF needs to be suppressed
62 bool mSuppressEOF;
64 bool mReadingFromStage;
65 nsTArray<nsHtml5TreeOperation> mOpQueue;
66 nsHtml5StreamParser* mStreamParser;
68 /**
69 * URLs already preloaded/preloading.
71 nsTHashSet<nsCString> mPreloadedURLs;
73 nsCOMPtr<nsIURI> mSpeculationBaseURI;
75 nsCOMPtr<nsIURI> mViewSourceBaseURI;
77 /**
78 * Whether the parser has started
80 bool mStarted;
82 nsHtml5TreeOpStage mStage;
84 bool mRunFlushLoopOnStack;
86 bool mCallContinueInterruptedParsingIfEnabled;
88 /**
89 * Whether this executor has already complained about matters related
90 * to character encoding declarations.
92 bool mAlreadyComplainedAboutCharset;
94 /**
95 * Whether this executor has already complained about the tree being too
96 * deep.
98 bool mAlreadyComplainedAboutDeepTree;
100 public:
101 nsHtml5TreeOpExecutor();
103 protected:
104 virtual ~nsHtml5TreeOpExecutor();
106 public:
107 // nsIContentSink
110 * Unimplemented. For interface compat only.
112 NS_IMETHOD WillParse() override;
114 NS_IMETHOD WillBuildModel(nsDTDMode /* unused */) override {
115 return WillBuildModel();
117 nsresult WillBuildModel();
120 * Emits EOF.
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;
139 * Sets the parser.
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,
171 int32_t aLine);
173 bool IsScriptEnabled();
175 virtual nsresult MarkAsBroken(nsresult aReason) override;
177 void StartLayout(bool* aInterrupted);
179 void PauseDocUpdate(bool* aInterrupted);
181 void FlushSpeculativeLoads();
183 void RunFlushLoop();
185 nsresult FlushDocumentWrite();
187 void CommitToInternalEncoding();
189 [[nodiscard]] bool TakeOpsFromStage();
191 void MaybeSuspend();
193 void Start();
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,
207 bool aUnrecognized);
209 void MaybeComplainAboutDeepTree(uint32_t aLineNumber);
211 bool HasStarted() { return mStarted; }
213 bool IsFlushing() { return mFlushState >= eInFlush; }
215 #ifdef DEBUG
216 bool IsInFlushLoop() { return mRunFlushLoopOnStack; }
217 #endif
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;
228 void ClearOpQueue();
230 void RemoveFromStartOfOpQueue(size_t aNumberOfOpsToRemove);
232 inline size_t OpQueueLength() { return mOpQueue.Length(); }
234 nsHtml5TreeOpStage* GetStage() { return &mStage; }
236 void StartReadingFromStage() { mReadingFromStage = true; }
238 void StreamEnded();
240 #ifdef DEBUG
241 void AssertStageEmpty() { mStage.AssertEmpty(); }
242 #endif
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);
289 private:
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