Bug 1700051: part 35) Reduce accessibility of `mSoftText.mDOMMapping` to `private...
[gecko.git] / dom / base / nsContentSink.h
blob6c75d8aa08920214e5de7ca7bc5cd145f25f2858
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;
38 class nsIApplicationCache;
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 typedef mozilla::dom::Document 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);
116 bool Decode5987Format(nsAString& aEncoded);
118 protected:
119 nsContentSink();
120 virtual ~nsContentSink();
122 enum CacheSelectionAction {
123 // There is no offline cache manifest specified by the document,
124 // or the document was loaded from a cache other than the one it
125 // specifies via its manifest attribute and IS NOT a top-level
126 // document, or an error occurred during the cache selection
127 // algorithm.
128 CACHE_SELECTION_NONE = 0,
130 // The offline cache manifest must be updated.
131 CACHE_SELECTION_UPDATE = 1,
133 // The document was loaded from a cache other than the one it
134 // specifies via its manifest attribute and IS a top-level
135 // document. In this case, the document is marked as foreign in
136 // the cache it was loaded from and must be reloaded from the
137 // correct cache (the one it specifies).
138 CACHE_SELECTION_RELOAD = 2,
140 // Some conditions require we must reselect the cache without the manifest
141 CACHE_SELECTION_RESELECT_WITHOUT_MANIFEST = 3
144 nsresult Init(Document* aDoc, nsIURI* aURI, nsISupports* aContainer,
145 nsIChannel* aChannel);
147 nsresult ProcessHTTPHeaders(nsIChannel* aChannel);
148 nsresult ProcessLinkHeader(const nsAString& aLinkData);
149 nsresult ProcessLinkFromHeader(
150 const nsAString& aAnchor, const nsAString& aHref, const nsAString& aRel,
151 const nsAString& aTitle, const nsAString& aIntegrity,
152 const nsAString& aSrcset, const nsAString& aSizes, const nsAString& aType,
153 const nsAString& aMedia, const nsAString& aCrossOrigin,
154 const nsAString& aReferrerPolicy, const nsAString& aAs);
156 virtual nsresult ProcessStyleLinkFromHeader(
157 const nsAString& aHref, bool aAlternate, const nsAString& aTitle,
158 const nsAString& aIntegrity, const nsAString& aType,
159 const nsAString& aMedia, const nsAString& aReferrerPolicy);
161 void PrefetchHref(const nsAString& aHref, const nsAString& aAs,
162 const nsAString& aType, const nsAString& aMedia);
163 void PreloadHref(const nsAString& aHref, const nsAString& aAs,
164 const nsAString& aType, const nsAString& aMedia,
165 const nsAString& aIntegrity, const nsAString& aSrcset,
166 const nsAString& aSizes, const nsAString& aCORS,
167 const nsAString& aReferrerPolicy);
169 // For PrefetchDNS() aHref can either be the usual
170 // URI format or of the form "//www.hostname.com" without a scheme.
171 void PrefetchDNS(const nsAString& aHref);
173 // Gets the cache key (used to identify items in a cache) of the channel.
174 nsresult GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey);
176 // There is an offline cache manifest attribute specified and the
177 // document is allowed to use the offline cache. Process the cache
178 // selection algorithm for this document and the manifest. Result is
179 // an action that must be taken on the manifest, see
180 // CacheSelectionAction enum above.
182 // @param aLoadApplicationCache
183 // The application cache from which the load originated, if
184 // any.
185 // @param aManifestURI
186 // The manifest URI listed in the document.
187 // @param aFetchedWithHTTPGetOrEquiv
188 // TRUE if this was fetched using the HTTP GET method.
189 // @param aAction
190 // Out parameter, returns the action that should be performed
191 // by the calling function.
192 nsresult SelectDocAppCache(nsIApplicationCache* aLoadApplicationCache,
193 nsIURI* aManifestURI,
194 bool aFetchedWithHTTPGetOrEquiv,
195 CacheSelectionAction* aAction);
197 // There is no offline cache manifest attribute specified. Process
198 // the cache selection algorithm w/o the manifest. Result is an
199 // action that must be taken, see CacheSelectionAction enum
200 // above. In case the offline cache manifest has to be updated the
201 // manifest URI is returned in aManifestURI.
203 // @param aLoadApplicationCache
204 // The application cache from which the load originated, if
205 // any.
206 // @param aManifestURI
207 // Out parameter, returns the manifest URI of the cache that
208 // was selected.
209 // @param aAction
210 // Out parameter, returns the action that should be performed
211 // by the calling function.
212 nsresult SelectDocAppCacheNoManifest(
213 nsIApplicationCache* aLoadApplicationCache, nsIURI** aManifestURI,
214 CacheSelectionAction* aAction);
216 public:
217 // Searches for the offline cache manifest attribute and calls one
218 // of the above defined methods to select the document's application
219 // cache, let it be associated with the document and eventually
220 // schedule the cache update process.
221 // This method MUST be called with the empty string as the argument
222 // when there is no manifest attribute!
223 void ProcessOfflineManifest(const nsAString& aManifestSpec);
225 // Extracts the manifest attribute from the element if it is the root
226 // element and calls the above method.
227 void ProcessOfflineManifest(nsIContent* aElement);
229 // For Preconnect() aHref can either be the usual
230 // URI format or of the form "//www.hostname.com" without a scheme.
231 void Preconnect(const nsAString& aHref, const nsAString& aCrossOrigin);
233 protected:
234 // Tries to scroll to the URI's named anchor. Once we've successfully
235 // done that, further calls to this method will be ignored.
236 MOZ_CAN_RUN_SCRIPT_BOUNDARY void ScrollToRef();
238 // Start layout. If aIgnorePendingSheets is true, this will happen even if
239 // we still have stylesheet loads pending. Otherwise, we'll wait until the
240 // stylesheets are all done loading.
241 public:
242 void StartLayout(bool aIgnorePendingSheets);
244 static void NotifyDocElementCreated(Document* aDoc);
246 Document* GetDocument() { return mDocument; }
248 protected:
249 void FavorPerformanceHint(bool perfOverStarvation, uint32_t starvationDelay);
251 inline int32_t GetNotificationInterval() {
252 if (mDynamicLowerValue) {
253 return 1000;
256 return mozilla::StaticPrefs::content_notify_interval();
259 virtual nsresult FlushTags() = 0;
261 // Later on we might want to make this more involved somehow
262 // (e.g. stop waiting after some timeout or whatnot).
263 bool WaitForPendingSheets() { return mPendingSheetCount > 0; }
265 void DoProcessLinkHeader();
267 void StopDeflecting() {
268 mDeflectedCount = mozilla::StaticPrefs::content_sink_perf_deflect_count();
271 protected:
272 RefPtr<Document> mDocument;
273 RefPtr<nsParserBase> mParser;
274 nsCOMPtr<nsIURI> mDocumentURI;
275 nsCOMPtr<nsIDocShell> mDocShell;
276 RefPtr<mozilla::css::Loader> mCSSLoader;
277 RefPtr<nsNodeInfoManager> mNodeInfoManager;
278 RefPtr<mozilla::dom::ScriptLoader> mScriptLoader;
280 // back off timer notification after count
281 int32_t mBackoffCount;
283 // Time of last notification
284 // Note: mLastNotificationTime is only valid once mLayoutStarted is true.
285 PRTime mLastNotificationTime;
287 // Timer used for notification
288 nsCOMPtr<nsITimer> mNotificationTimer;
290 uint8_t mLayoutStarted : 1;
291 uint8_t mDynamicLowerValue : 1;
292 uint8_t mParsing : 1;
293 uint8_t mDroppedTimer : 1;
294 // If true, we deferred starting layout until sheets load
295 uint8_t mDeferredLayoutStart : 1;
296 // If true, we deferred notifications until sheets load
297 uint8_t mDeferredFlushTags : 1;
298 // If false, we're not ourselves a document observer; that means we
299 // shouldn't be performing any more content model notifications,
300 // since we're not longer updating our child counts.
301 uint8_t mIsDocumentObserver : 1;
302 // True if this is parser is a fragment parser or an HTML DOMParser.
303 // XML DOMParser leaves this to false for now!
304 uint8_t mRunsToCompletion : 1;
305 // True if we are blocking load event.
306 bool mIsBlockingOnload : 1;
309 // -- Can interrupt parsing members --
312 // The number of tokens that have been processed since we measured
313 // if it's time to return to the main event loop.
314 uint32_t mDeflectedCount;
316 // Is there currently a pending event?
317 bool mHasPendingEvent;
319 // When to return to the main event loop
320 uint32_t mCurrentParseEndTime;
322 int32_t mBeginLoadTime;
324 // Last mouse event or keyboard event time sampled by the content
325 // sink
326 uint32_t mLastSampledUserEventTime;
328 int32_t mInMonolithicContainer;
330 int32_t mInNotification;
331 uint32_t mUpdatesInNotification;
333 uint32_t mPendingSheetCount;
335 nsRevocableEventPtr<nsRunnableMethod<nsContentSink, void, false> >
336 mProcessLinkHeaderEvent;
339 #endif // _nsContentSink_h_