Bug 1850713: remove duplicated setting of early hint preloader id in `ScriptLoader...
[gecko.git] / dom / base / nsContentSink.h
blob11b4712907522bbf83fb4b44503a6d894600b6f1
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /*
8 * Base class for the XML and HTML content sinks, which construct a
9 * DOM based on information from the parser.
12 #ifndef _nsContentSink_h_
13 #define _nsContentSink_h_
15 // Base class for contentsink implementations.
17 #include "mozilla/Attributes.h"
18 #include "nsICSSLoaderObserver.h"
19 #include "nsWeakReference.h"
20 #include "nsCOMPtr.h"
21 #include "nsString.h"
22 #include "nsGkAtoms.h"
23 #include "nsITimer.h"
24 #include "nsStubDocumentObserver.h"
25 #include "nsIContentSink.h"
26 #include "mozilla/Logging.h"
27 #include "nsCycleCollectionParticipant.h"
28 #include "nsThreadUtils.h"
29 #include "mozilla/StaticPrefs_content.h"
31 class nsIURI;
32 class nsIChannel;
33 class nsIDocShell;
34 class nsAtom;
35 class nsIChannel;
36 class nsIContent;
37 class nsNodeInfoManager;
39 namespace mozilla {
40 namespace css {
41 class Loader;
42 } // namespace css
44 namespace dom {
45 class Document;
46 class ScriptLoader;
47 } // namespace dom
49 namespace net {
50 struct LinkHeader;
52 } // namespace mozilla
54 #ifdef DEBUG
56 extern mozilla::LazyLogModule gContentSinkLogModuleInfo;
58 # define SINK_TRACE_CALLS 0x1
59 # define SINK_TRACE_REFLOW 0x2
60 # define SINK_ALWAYS_REFLOW 0x4
62 # define SINK_LOG_TEST(_lm, _bit) (int((_lm)->Level()) & (_bit))
64 # define SINK_TRACE(_lm, _bit, _args) \
65 do { \
66 if (SINK_LOG_TEST(_lm, _bit)) { \
67 printf_stderr _args; \
68 } \
69 } while (0)
71 #else
72 # define SINK_TRACE(_lm, _bit, _args)
73 #endif
75 #undef SINK_NO_INCREMENTAL
77 //----------------------------------------------------------------------
79 class nsContentSink : public nsICSSLoaderObserver,
80 public nsSupportsWeakReference,
81 public nsStubDocumentObserver,
82 public nsITimerCallback,
83 public nsINamed {
84 protected:
85 using Document = mozilla::dom::Document;
87 private:
88 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
89 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsContentSink, nsICSSLoaderObserver)
90 // nsITimerCallback
91 NS_DECL_NSITIMERCALLBACK
93 NS_DECL_NSINAMED
95 // nsICSSLoaderObserver
96 NS_IMETHOD StyleSheetLoaded(mozilla::StyleSheet* aSheet, bool aWasDeferred,
97 nsresult aStatus) override;
99 // nsIContentSink implementation helpers
100 nsresult WillParseImpl(void);
101 nsresult WillInterruptImpl(void);
102 void WillResumeImpl();
103 nsresult DidProcessATokenImpl(void);
104 void WillBuildModelImpl(void);
105 void DidBuildModelImpl(bool aTerminated);
106 void DropParserAndPerfHint(void);
107 bool IsScriptExecutingImpl();
109 void NotifyAppend(nsIContent* aContent, uint32_t aStartIndex);
111 // nsIDocumentObserver
112 NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE
113 NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE
115 virtual void UpdateChildCounts() = 0;
117 bool IsTimeToNotify();
119 protected:
120 nsContentSink();
121 virtual ~nsContentSink();
123 nsresult Init(Document* aDoc, nsIURI* aURI, nsISupports* aContainer,
124 nsIChannel* aChannel);
126 nsresult ProcessHTTPHeaders(nsIChannel* aChannel);
127 // aEarlyHintPreloaderId zero means no early hint channel to connect back
128 nsresult ProcessLinkFromHeader(const mozilla::net::LinkHeader& aHeader,
129 uint64_t aEarlyHintPreloaderId);
131 virtual nsresult ProcessStyleLinkFromHeader(
132 const nsAString& aHref, bool aAlternate, const nsAString& aTitle,
133 const nsAString& aIntegrity, const nsAString& aType,
134 const nsAString& aMedia, const nsAString& aReferrerPolicy);
136 void PrefetchHref(const nsAString& aHref, const nsAString& aAs,
137 const nsAString& aType, const nsAString& aMedia);
138 void PreloadHref(const nsAString& aHref, const nsAString& aAs,
139 const nsAString& aType, const nsAString& aMedia,
140 const nsAString& aNonce, const nsAString& aIntegrity,
141 const nsAString& aSrcset, const nsAString& aSizes,
142 const nsAString& aCORS, const nsAString& aReferrerPolicy,
143 uint64_t aEarlyHintPreloaderId);
145 void PreloadModule(const nsAString& aHref, const nsAString& aAs,
146 const nsAString& aMedia, const nsAString& aNonce,
147 const nsAString& aIntegrity, const nsAString& aCORS,
148 const nsAString& aReferrerPolicy,
149 uint64_t aEarlyHintPreloaderId);
151 // For PrefetchDNS() aHref can either be the usual
152 // URI format or of the form "//www.hostname.com" without a scheme.
153 void PrefetchDNS(const nsAString& aHref);
155 // Gets the cache key (used to identify items in a cache) of the channel.
156 nsresult GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey);
158 public:
159 // For Preconnect() aHref can either be the usual
160 // URI format or of the form "//www.hostname.com" without a scheme.
161 void Preconnect(const nsAString& aHref, const nsAString& aCrossOrigin);
163 protected:
164 // Tries to scroll to the URI's named anchor. Once we've successfully
165 // done that, further calls to this method will be ignored.
166 MOZ_CAN_RUN_SCRIPT_BOUNDARY void ScrollToRef();
168 // Start layout. If aIgnorePendingSheets is true, this will happen even if
169 // we still have stylesheet loads pending. Otherwise, we'll wait until the
170 // stylesheets are all done loading.
171 public:
172 void StartLayout(bool aIgnorePendingSheets);
174 static void NotifyDocElementCreated(Document* aDoc);
176 Document* GetDocument() { return mDocument; }
178 // Later on we might want to make this more involved somehow
179 // (e.g. stop waiting after some timeout or whatnot).
180 bool WaitForPendingSheets() { return mPendingSheetCount > 0; }
182 protected:
183 inline int32_t GetNotificationInterval() {
184 if (mDynamicLowerValue) {
185 return 1000;
188 return mozilla::StaticPrefs::content_notify_interval();
191 virtual nsresult FlushTags() = 0;
193 void DoProcessLinkHeader();
195 void StopDeflecting() {
196 mDeflectedCount = mozilla::StaticPrefs::content_sink_perf_deflect_count();
199 protected:
200 RefPtr<Document> mDocument;
201 RefPtr<nsParserBase> mParser;
202 nsCOMPtr<nsIURI> mDocumentURI;
203 nsCOMPtr<nsIDocShell> mDocShell;
204 RefPtr<mozilla::css::Loader> mCSSLoader;
205 RefPtr<nsNodeInfoManager> mNodeInfoManager;
206 RefPtr<mozilla::dom::ScriptLoader> mScriptLoader;
208 // back off timer notification after count
209 int32_t mBackoffCount;
211 // Time of last notification
212 // Note: mLastNotificationTime is only valid once mLayoutStarted is true.
213 PRTime mLastNotificationTime;
215 // Timer used for notification
216 nsCOMPtr<nsITimer> mNotificationTimer;
218 uint8_t mLayoutStarted : 1;
219 uint8_t mDynamicLowerValue : 1;
220 uint8_t mParsing : 1;
221 uint8_t mDroppedTimer : 1;
222 // If true, we deferred starting layout until sheets load
223 uint8_t mDeferredLayoutStart : 1;
224 // If true, we deferred notifications until sheets load
225 uint8_t mDeferredFlushTags : 1;
226 // If false, we're not ourselves a document observer; that means we
227 // shouldn't be performing any more content model notifications,
228 // since we're not longer updating our child counts.
229 uint8_t mIsDocumentObserver : 1;
230 // True if this is parser is a fragment parser or an HTML DOMParser.
231 // XML DOMParser leaves this to false for now!
232 uint8_t mRunsToCompletion : 1;
233 // True if we are blocking load event.
234 bool mIsBlockingOnload : 1;
237 // -- Can interrupt parsing members --
240 // The number of tokens that have been processed since we measured
241 // if it's time to return to the main event loop.
242 uint32_t mDeflectedCount;
244 // Is there currently a pending event?
245 bool mHasPendingEvent;
247 // When to return to the main event loop
248 uint32_t mCurrentParseEndTime;
250 int32_t mBeginLoadTime;
252 // Last mouse event or keyboard event time sampled by the content
253 // sink
254 uint32_t mLastSampledUserEventTime;
256 int32_t mInMonolithicContainer;
258 int32_t mInNotification;
259 uint32_t mUpdatesInNotification;
261 uint32_t mPendingSheetCount;
263 nsRevocableEventPtr<nsRunnableMethod<nsContentSink, void, false> >
264 mProcessLinkHeaderEvent;
267 #endif // _nsContentSink_h_