content/base/src/nsContentSink.h

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     7  * Base class for the XML and HTML content sinks, which construct a
     8  * DOM based on information from the parser.
     9  */
    11 #ifndef _nsContentSink_h_
    12 #define _nsContentSink_h_
    14 // Base class for contentsink implementations.
    16 #include "mozilla/Attributes.h"
    17 #include "nsICSSLoaderObserver.h"
    18 #include "nsWeakReference.h"
    19 #include "nsCOMPtr.h"
    20 #include "nsString.h"
    21 #include "nsAutoPtr.h"
    22 #include "nsGkAtoms.h"
    23 #include "nsITimer.h"
    24 #include "nsStubDocumentObserver.h"
    25 #include "nsIContentSink.h"
    26 #include "prlog.h"
    27 #include "nsCycleCollectionParticipant.h"
    28 #include "nsThreadUtils.h"
    30 class nsIDocument;
    31 class nsIURI;
    32 class nsIChannel;
    33 class nsIDocShell;
    34 class nsIParser;
    35 class nsIAtom;
    36 class nsIChannel;
    37 class nsIContent;
    38 class nsViewManager;
    39 class nsNodeInfoManager;
    40 class nsScriptLoader;
    41 class nsIApplicationCache;
    43 namespace mozilla {
    44 namespace css {
    45 class Loader;
    46 }
    47 }
    49 #ifdef DEBUG
    51 extern PRLogModuleInfo* gContentSinkLogModuleInfo;
    53 #define SINK_TRACE_CALLS              0x1
    54 #define SINK_TRACE_REFLOW             0x2
    55 #define SINK_ALWAYS_REFLOW            0x4
    57 #define SINK_LOG_TEST(_lm, _bit) (int((_lm)->level) & (_bit))
    59 #define SINK_TRACE(_lm, _bit, _args) \
    60   PR_BEGIN_MACRO                     \
    61     if (SINK_LOG_TEST(_lm, _bit)) {  \
    62       PR_LogPrint _args;             \
    63     }                                \
    64   PR_END_MACRO
    66 #else
    67 #define SINK_TRACE(_lm, _bit, _args)
    68 #endif
    70 #undef SINK_NO_INCREMENTAL
    72 //----------------------------------------------------------------------
    74 // 1/2 second fudge factor for window creation
    75 #define NS_DELAY_FOR_WINDOW_CREATION  500000
    77 class nsContentSink : public nsICSSLoaderObserver,
    78                       public nsSupportsWeakReference,
    79                       public nsStubDocumentObserver,
    80                       public nsITimerCallback
    81 {
    82   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    83   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsContentSink,
    84                                            nsICSSLoaderObserver)
    85     // nsITimerCallback
    86   NS_DECL_NSITIMERCALLBACK
    88   // nsICSSLoaderObserver
    89   NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, bool aWasAlternate,
    90                               nsresult aStatus) MOZ_OVERRIDE;
    92   virtual nsresult ProcessMETATag(nsIContent* aContent);
    94   // nsIContentSink implementation helpers
    95   NS_HIDDEN_(nsresult) WillParseImpl(void);
    96   NS_HIDDEN_(nsresult) WillInterruptImpl(void);
    97   NS_HIDDEN_(nsresult) WillResumeImpl(void);
    98   NS_HIDDEN_(nsresult) DidProcessATokenImpl(void);
    99   NS_HIDDEN_(void) WillBuildModelImpl(void);
   100   NS_HIDDEN_(void) DidBuildModelImpl(bool aTerminated);
   101   NS_HIDDEN_(void) DropParserAndPerfHint(void);
   102   bool IsScriptExecutingImpl();
   104   void NotifyAppend(nsIContent* aContent, uint32_t aStartIndex);
   106   // nsIDocumentObserver
   107   NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE
   108   NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE
   110   virtual void UpdateChildCounts() = 0;
   112   bool IsTimeToNotify();
   113   bool LinkContextIsOurDocument(const nsSubstring& aAnchor);
   114   bool Decode5987Format(nsAString& aEncoded);
   116   static void InitializeStatics();
   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
   142   };
   144   nsresult Init(nsIDocument* aDoc, nsIURI* aURI,
   145                 nsISupports* aContainer, nsIChannel* aChannel);
   147   nsresult ProcessHTTPHeaders(nsIChannel* aChannel);
   148   nsresult ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
   149                              nsIContent* aContent = nullptr);
   150   nsresult ProcessLinkHeader(const nsAString& aLinkData);
   151   nsresult ProcessLink(const nsSubstring& aAnchor,
   152                        const nsSubstring& aHref, const nsSubstring& aRel,
   153                        const nsSubstring& aTitle, const nsSubstring& aType,
   154                        const nsSubstring& aMedia);
   156   virtual nsresult ProcessStyleLink(nsIContent* aElement,
   157                                     const nsSubstring& aHref,
   158                                     bool aAlternate,
   159                                     const nsSubstring& aTitle,
   160                                     const nsSubstring& aType,
   161                                     const nsSubstring& aMedia);
   163   void PrefetchHref(const nsAString &aHref, nsINode *aSource,
   164                     bool aExplicit);
   166   // aHref can either be the usual URI format or of the form "//www.hostname.com"
   167   // without a scheme.
   168   void PrefetchDNS(const nsAString &aHref);
   170   // Gets the cache key (used to identify items in a cache) of the channel.
   171   nsresult GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey);
   173   // There is an offline cache manifest attribute specified and the
   174   // document is allowed to use the offline cache.  Process the cache
   175   // selection algorithm for this document and the manifest. Result is
   176   // an action that must be taken on the manifest, see
   177   // CacheSelectionAction enum above.
   178   //
   179   // @param aLoadApplicationCache
   180   //        The application cache from which the load originated, if
   181   //        any.
   182   // @param aManifestURI
   183   //        The manifest URI listed in the document.
   184   // @param aFetchedWithHTTPGetOrEquiv
   185   //        TRUE if this was fetched using the HTTP GET method.
   186   // @param aAction
   187   //        Out parameter, returns the action that should be performed
   188   //        by the calling function.
   189   nsresult SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
   190                              nsIURI *aManifestURI,
   191                              bool aFetchedWithHTTPGetOrEquiv,
   192                              CacheSelectionAction *aAction);
   194   // There is no offline cache manifest attribute specified.  Process
   195   // the cache selection algorithm w/o the manifest. Result is an
   196   // action that must be taken, see CacheSelectionAction enum
   197   // above. In case the offline cache manifest has to be updated the
   198   // manifest URI is returned in aManifestURI.
   199   //
   200   // @param aLoadApplicationCache
   201   //        The application cache from which the load originated, if
   202   //        any.
   203   // @param aManifestURI
   204   //        Out parameter, returns the manifest URI of the cache that
   205   //        was selected.
   206   // @param aAction
   207   //        Out parameter, returns the action that should be performed
   208   //        by the calling function.
   209   nsresult SelectDocAppCacheNoManifest(nsIApplicationCache *aLoadApplicationCache,
   210                                        nsIURI **aManifestURI,
   211                                        CacheSelectionAction *aAction);
   213 public:
   214   // Searches for the offline cache manifest attribute and calls one
   215   // of the above defined methods to select the document's application
   216   // cache, let it be associated with the document and eventually
   217   // schedule the cache update process.
   218   // This method MUST be called with the empty string as the argument
   219   // when there is no manifest attribute!
   220   void ProcessOfflineManifest(const nsAString& aManifestSpec);
   222   // Extracts the manifest attribute from the element if it is the root 
   223   // element and calls the above method.
   224   void ProcessOfflineManifest(nsIContent *aElement);
   226 protected:
   227   // Tries to scroll to the URI's named anchor. Once we've successfully
   228   // done that, further calls to this method will be ignored.
   229   void ScrollToRef();
   231   // Start layout.  If aIgnorePendingSheets is true, this will happen even if
   232   // we still have stylesheet loads pending.  Otherwise, we'll wait until the
   233   // stylesheets are all done loading.
   234 public:
   235   void StartLayout(bool aIgnorePendingSheets);
   237   static void NotifyDocElementCreated(nsIDocument* aDoc);
   239 protected:
   240   void
   241   FavorPerformanceHint(bool perfOverStarvation, uint32_t starvationDelay);
   243   inline int32_t GetNotificationInterval()
   244   {
   245     if (mDynamicLowerValue) {
   246       return 1000;
   247     }
   249     return sNotificationInterval;
   250   }
   252   virtual nsresult FlushTags() = 0;
   254   // Later on we might want to make this more involved somehow
   255   // (e.g. stop waiting after some timeout or whatnot).
   256   bool WaitForPendingSheets() { return mPendingSheetCount > 0; }
   258   void DoProcessLinkHeader();
   260   void StopDeflecting() {
   261     mDeflectedCount = sPerfDeflectCount;
   262   }
   264 private:
   265   // People shouldn't be allocating this class directly.  All subclasses should
   266   // be allocated using a zeroing operator new.
   267   void* operator new(size_t sz) CPP_THROW_NEW;  // Not to be implemented
   269 protected:
   271   nsCOMPtr<nsIDocument>         mDocument;
   272   nsRefPtr<nsParserBase>        mParser;
   273   nsCOMPtr<nsIURI>              mDocumentURI;
   274   nsCOMPtr<nsIDocShell>         mDocShell;
   275   nsRefPtr<mozilla::css::Loader> mCSSLoader;
   276   nsRefPtr<nsNodeInfoManager>   mNodeInfoManager;
   277   nsRefPtr<nsScriptLoader>      mScriptLoader;
   279   // back off timer notification after count
   280   int32_t mBackoffCount;
   282   // Time of last notification
   283   // Note: mLastNotificationTime is only valid once mLayoutStarted is true.
   284   PRTime mLastNotificationTime;
   286   // Timer used for notification
   287   nsCOMPtr<nsITimer> mNotificationTimer;
   289   // Have we already called BeginUpdate for this set of content changes?
   290   uint8_t mBeganUpdate : 1;
   291   uint8_t mLayoutStarted : 1;
   292   uint8_t mDynamicLowerValue : 1;
   293   uint8_t mParsing : 1;
   294   uint8_t mDroppedTimer : 1;
   295   // If true, we deferred starting layout until sheets load
   296   uint8_t mDeferredLayoutStart : 1;
   297   // If true, we deferred notifications until sheets load
   298   uint8_t mDeferredFlushTags : 1;
   299   // If false, we're not ourselves a document observer; that means we
   300   // shouldn't be performing any more content model notifications,
   301   // since we're not longer updating our child counts.
   302   uint8_t mIsDocumentObserver : 1;
   303   // True if this is parser is a fragment parser or an HTML DOMParser.
   304   // XML DOMParser leaves this to false for now!
   305   uint8_t mRunsToCompletion : 1;
   307   //
   308   // -- Can interrupt parsing members --
   309   //
   311   // The number of tokens that have been processed since we measured
   312   // if it's time to return to the main event loop.
   313   uint32_t mDeflectedCount;
   315   // Is there currently a pending event?
   316   bool mHasPendingEvent;
   318   // When to return to the main event loop
   319   uint32_t mCurrentParseEndTime;
   321   int32_t mBeginLoadTime;
   323   // Last mouse event or keyboard event time sampled by the content
   324   // sink
   325   uint32_t mLastSampledUserEventTime;
   327   int32_t mInMonolithicContainer;
   329   int32_t mInNotification;
   330   uint32_t mUpdatesInNotification;
   332   uint32_t mPendingSheetCount;
   334   nsRevocableEventPtr<nsRunnableMethod<nsContentSink, void, false> >
   335     mProcessLinkHeaderEvent;
   337   // Do we notify based on time?
   338   static bool sNotifyOnTimer;
   339   // Back off timer notification after count.
   340   static int32_t sBackoffCount;
   341   // Notification interval in microseconds
   342   static int32_t sNotificationInterval;
   343   // How many times to deflect in interactive/perf modes
   344   static int32_t sInteractiveDeflectCount;
   345   static int32_t sPerfDeflectCount;
   346   // 0 = don't check for pending events
   347   // 1 = don't deflect if there are pending events
   348   // 2 = bail if there are pending events
   349   static int32_t sPendingEventMode;
   350   // How often to probe for pending events. 1=every token
   351   static int32_t sEventProbeRate;
   352   // How long to stay off the event loop in interactive/perf modes
   353   static int32_t sInteractiveParseTime;
   354   static int32_t sPerfParseTime;
   355   // How long to be in interactive mode after an event
   356   static int32_t sInteractiveTime;
   357   // How long to stay in perf mode after initial loading
   358   static int32_t sInitialPerfTime;
   359   // Should we switch between perf-mode and interactive-mode
   360   static int32_t sEnablePerfMode;
   361 };
   363 #endif // _nsContentSink_h_

mercurial