Bug 1750871 - run mochitest-remote on fission everywhere. r=releng-reviewers,aki
[gecko.git] / dom / base / nsContentSink.h
blob54edbd95100be910fc5eb14f88f68a6a9f30f3f1
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 "nsNetUtil.h"
20 #include "nsWeakReference.h"
21 #include "nsCOMPtr.h"
22 #include "nsString.h"
23 #include "nsGkAtoms.h"
24 #include "nsITimer.h"
25 #include "nsStubDocumentObserver.h"
26 #include "nsIContentSink.h"
27 #include "mozilla/Logging.h"
28 #include "nsCycleCollectionParticipant.h"
29 #include "nsThreadUtils.h"
30 #include "mozilla/StaticPrefs_content.h"
32 class nsIURI;
33 class nsIChannel;
34 class nsIDocShell;
35 class nsAtom;
36 class nsIChannel;
37 class nsIContent;
38 class nsNodeInfoManager;
40 namespace mozilla {
41 namespace css {
42 class Loader;
43 } // namespace css
45 namespace dom {
46 class Document;
47 class ScriptLoader;
48 } // namespace dom
49 } // namespace mozilla
51 #ifdef DEBUG
53 extern mozilla::LazyLogModule gContentSinkLogModuleInfo;
55 # define SINK_TRACE_CALLS 0x1
56 # define SINK_TRACE_REFLOW 0x2
57 # define SINK_ALWAYS_REFLOW 0x4
59 # define SINK_LOG_TEST(_lm, _bit) (int((_lm)->Level()) & (_bit))
61 # define SINK_TRACE(_lm, _bit, _args) \
62 do { \
63 if (SINK_LOG_TEST(_lm, _bit)) { \
64 printf_stderr _args; \
65 } \
66 } while (0)
68 #else
69 # define SINK_TRACE(_lm, _bit, _args)
70 #endif
72 #undef SINK_NO_INCREMENTAL
74 //----------------------------------------------------------------------
76 class nsContentSink : public nsICSSLoaderObserver,
77 public nsSupportsWeakReference,
78 public nsStubDocumentObserver,
79 public nsITimerCallback,
80 public nsINamed {
81 protected:
82 using Document = mozilla::dom::Document;
84 private:
85 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
86 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsContentSink, nsICSSLoaderObserver)
87 // nsITimerCallback
88 NS_DECL_NSITIMERCALLBACK
90 NS_DECL_NSINAMED
92 // nsICSSLoaderObserver
93 NS_IMETHOD StyleSheetLoaded(mozilla::StyleSheet* aSheet, bool aWasDeferred,
94 nsresult aStatus) override;
96 // nsIContentSink implementation helpers
97 nsresult WillParseImpl(void);
98 nsresult WillInterruptImpl(void);
99 nsresult WillResumeImpl(void);
100 nsresult DidProcessATokenImpl(void);
101 void WillBuildModelImpl(void);
102 void DidBuildModelImpl(bool aTerminated);
103 void DropParserAndPerfHint(void);
104 bool IsScriptExecutingImpl();
106 void NotifyAppend(nsIContent* aContent, uint32_t aStartIndex);
108 // nsIDocumentObserver
109 NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE
110 NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE
112 virtual void UpdateChildCounts() = 0;
114 bool IsTimeToNotify();
115 bool LinkContextIsOurDocument(const nsAString& aAnchor);
117 protected:
118 nsContentSink();
119 virtual ~nsContentSink();
121 nsresult Init(Document* aDoc, nsIURI* aURI, nsISupports* aContainer,
122 nsIChannel* aChannel);
124 nsresult ProcessHTTPHeaders(nsIChannel* aChannel);
125 nsresult ProcessLinkFromHeader(const LinkHeader& aHeader);
127 virtual nsresult ProcessStyleLinkFromHeader(
128 const nsAString& aHref, bool aAlternate, const nsAString& aTitle,
129 const nsAString& aIntegrity, const nsAString& aType,
130 const nsAString& aMedia, const nsAString& aReferrerPolicy);
132 void PrefetchHref(const nsAString& aHref, const nsAString& aAs,
133 const nsAString& aType, const nsAString& aMedia);
134 void PreloadHref(const nsAString& aHref, const nsAString& aAs,
135 const nsAString& aType, const nsAString& aMedia,
136 const nsAString& aIntegrity, const nsAString& aSrcset,
137 const nsAString& aSizes, const nsAString& aCORS,
138 const nsAString& aReferrerPolicy);
140 // For PrefetchDNS() aHref can either be the usual
141 // URI format or of the form "//www.hostname.com" without a scheme.
142 void PrefetchDNS(const nsAString& aHref);
144 // Gets the cache key (used to identify items in a cache) of the channel.
145 nsresult GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey);
147 public:
148 // For Preconnect() aHref can either be the usual
149 // URI format or of the form "//www.hostname.com" without a scheme.
150 void Preconnect(const nsAString& aHref, const nsAString& aCrossOrigin);
152 protected:
153 // Tries to scroll to the URI's named anchor. Once we've successfully
154 // done that, further calls to this method will be ignored.
155 MOZ_CAN_RUN_SCRIPT_BOUNDARY void ScrollToRef();
157 // Start layout. If aIgnorePendingSheets is true, this will happen even if
158 // we still have stylesheet loads pending. Otherwise, we'll wait until the
159 // stylesheets are all done loading.
160 public:
161 void StartLayout(bool aIgnorePendingSheets);
163 static void NotifyDocElementCreated(Document* aDoc);
165 Document* GetDocument() { return mDocument; }
167 protected:
168 void FavorPerformanceHint(bool perfOverStarvation, uint32_t starvationDelay);
170 inline int32_t GetNotificationInterval() {
171 if (mDynamicLowerValue) {
172 return 1000;
175 return mozilla::StaticPrefs::content_notify_interval();
178 virtual nsresult FlushTags() = 0;
180 // Later on we might want to make this more involved somehow
181 // (e.g. stop waiting after some timeout or whatnot).
182 bool WaitForPendingSheets() { return mPendingSheetCount > 0; }
184 void DoProcessLinkHeader();
186 void StopDeflecting() {
187 mDeflectedCount = mozilla::StaticPrefs::content_sink_perf_deflect_count();
190 protected:
191 RefPtr<Document> mDocument;
192 RefPtr<nsParserBase> mParser;
193 nsCOMPtr<nsIURI> mDocumentURI;
194 nsCOMPtr<nsIDocShell> mDocShell;
195 RefPtr<mozilla::css::Loader> mCSSLoader;
196 RefPtr<nsNodeInfoManager> mNodeInfoManager;
197 RefPtr<mozilla::dom::ScriptLoader> mScriptLoader;
199 // back off timer notification after count
200 int32_t mBackoffCount;
202 // Time of last notification
203 // Note: mLastNotificationTime is only valid once mLayoutStarted is true.
204 PRTime mLastNotificationTime;
206 // Timer used for notification
207 nsCOMPtr<nsITimer> mNotificationTimer;
209 uint8_t mLayoutStarted : 1;
210 uint8_t mDynamicLowerValue : 1;
211 uint8_t mParsing : 1;
212 uint8_t mDroppedTimer : 1;
213 // If true, we deferred starting layout until sheets load
214 uint8_t mDeferredLayoutStart : 1;
215 // If true, we deferred notifications until sheets load
216 uint8_t mDeferredFlushTags : 1;
217 // If false, we're not ourselves a document observer; that means we
218 // shouldn't be performing any more content model notifications,
219 // since we're not longer updating our child counts.
220 uint8_t mIsDocumentObserver : 1;
221 // True if this is parser is a fragment parser or an HTML DOMParser.
222 // XML DOMParser leaves this to false for now!
223 uint8_t mRunsToCompletion : 1;
224 // True if we are blocking load event.
225 bool mIsBlockingOnload : 1;
228 // -- Can interrupt parsing members --
231 // The number of tokens that have been processed since we measured
232 // if it's time to return to the main event loop.
233 uint32_t mDeflectedCount;
235 // Is there currently a pending event?
236 bool mHasPendingEvent;
238 // When to return to the main event loop
239 uint32_t mCurrentParseEndTime;
241 int32_t mBeginLoadTime;
243 // Last mouse event or keyboard event time sampled by the content
244 // sink
245 uint32_t mLastSampledUserEventTime;
247 int32_t mInMonolithicContainer;
249 int32_t mInNotification;
250 uint32_t mUpdatesInNotification;
252 uint32_t mPendingSheetCount;
254 nsRevocableEventPtr<nsRunnableMethod<nsContentSink, void, false> >
255 mProcessLinkHeaderEvent;
258 #endif // _nsContentSink_h_