mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-25 01:47:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
362
dom/base/nsContentSink.h
Normal file
362
dom/base/nsContentSink.h
Normal file
|
|
@ -0,0 +1,362 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* Base class for the XML and HTML content sinks, which construct a
|
||||
* DOM based on information from the parser.
|
||||
*/
|
||||
|
||||
#ifndef _nsContentSink_h_
|
||||
#define _nsContentSink_h_
|
||||
|
||||
// Base class for contentsink implementations.
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsICSSLoaderObserver.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsStubDocumentObserver.h"
|
||||
#include "nsIContentSink.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class nsIDocument;
|
||||
class nsIURI;
|
||||
class nsIChannel;
|
||||
class nsIDocShell;
|
||||
class nsIAtom;
|
||||
class nsIChannel;
|
||||
class nsIContent;
|
||||
class nsNodeInfoManager;
|
||||
class nsScriptLoader;
|
||||
class nsIApplicationCache;
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
class Loader;
|
||||
} // namespace css
|
||||
} // namespace mozilla
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
extern mozilla::LazyLogModule gContentSinkLogModuleInfo;
|
||||
|
||||
#define SINK_TRACE_CALLS 0x1
|
||||
#define SINK_TRACE_REFLOW 0x2
|
||||
#define SINK_ALWAYS_REFLOW 0x4
|
||||
|
||||
#define SINK_LOG_TEST(_lm, _bit) (int((_lm)->Level()) & (_bit))
|
||||
|
||||
#define SINK_TRACE(_lm, _bit, _args) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (SINK_LOG_TEST(_lm, _bit)) { \
|
||||
PR_LogPrint _args; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#else
|
||||
#define SINK_TRACE(_lm, _bit, _args)
|
||||
#endif
|
||||
|
||||
#undef SINK_NO_INCREMENTAL
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// 1/2 second fudge factor for window creation
|
||||
#define NS_DELAY_FOR_WINDOW_CREATION 500000
|
||||
|
||||
class nsContentSink : public nsICSSLoaderObserver,
|
||||
public nsSupportsWeakReference,
|
||||
public nsStubDocumentObserver,
|
||||
public nsITimerCallback
|
||||
{
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsContentSink,
|
||||
nsICSSLoaderObserver)
|
||||
// nsITimerCallback
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
// nsICSSLoaderObserver
|
||||
NS_IMETHOD StyleSheetLoaded(mozilla::StyleSheet* aSheet,
|
||||
bool aWasAlternate,
|
||||
nsresult aStatus) override;
|
||||
|
||||
virtual nsresult ProcessMETATag(nsIContent* aContent);
|
||||
|
||||
// nsIContentSink implementation helpers
|
||||
nsresult WillParseImpl(void);
|
||||
nsresult WillInterruptImpl(void);
|
||||
nsresult WillResumeImpl(void);
|
||||
nsresult DidProcessATokenImpl(void);
|
||||
void WillBuildModelImpl(void);
|
||||
void DidBuildModelImpl(bool aTerminated);
|
||||
void DropParserAndPerfHint(void);
|
||||
bool IsScriptExecutingImpl();
|
||||
|
||||
void NotifyAppend(nsIContent* aContent, uint32_t aStartIndex);
|
||||
|
||||
// nsIDocumentObserver
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE
|
||||
|
||||
virtual void UpdateChildCounts() = 0;
|
||||
|
||||
bool IsTimeToNotify();
|
||||
bool LinkContextIsOurDocument(const nsSubstring& aAnchor);
|
||||
bool Decode5987Format(nsAString& aEncoded);
|
||||
|
||||
static void InitializeStatics();
|
||||
|
||||
protected:
|
||||
nsContentSink();
|
||||
virtual ~nsContentSink();
|
||||
|
||||
enum CacheSelectionAction {
|
||||
// There is no offline cache manifest specified by the document,
|
||||
// or the document was loaded from a cache other than the one it
|
||||
// specifies via its manifest attribute and IS NOT a top-level
|
||||
// document, or an error occurred during the cache selection
|
||||
// algorithm.
|
||||
CACHE_SELECTION_NONE = 0,
|
||||
|
||||
// The offline cache manifest must be updated.
|
||||
CACHE_SELECTION_UPDATE = 1,
|
||||
|
||||
// The document was loaded from a cache other than the one it
|
||||
// specifies via its manifest attribute and IS a top-level
|
||||
// document. In this case, the document is marked as foreign in
|
||||
// the cache it was loaded from and must be reloaded from the
|
||||
// correct cache (the one it specifies).
|
||||
CACHE_SELECTION_RELOAD = 2,
|
||||
|
||||
// Some conditions require we must reselect the cache without the manifest
|
||||
CACHE_SELECTION_RESELECT_WITHOUT_MANIFEST = 3
|
||||
};
|
||||
|
||||
nsresult Init(nsIDocument* aDoc, nsIURI* aURI,
|
||||
nsISupports* aContainer, nsIChannel* aChannel);
|
||||
|
||||
nsresult ProcessHTTPHeaders(nsIChannel* aChannel);
|
||||
nsresult ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
|
||||
nsIContent* aContent = nullptr);
|
||||
nsresult ProcessLinkHeader(const nsAString& aLinkData);
|
||||
nsresult ProcessLink(const nsSubstring& aAnchor,
|
||||
const nsSubstring& aHref, const nsSubstring& aRel,
|
||||
const nsSubstring& aTitle, const nsSubstring& aType,
|
||||
const nsSubstring& aMedia, const nsSubstring& aCrossOrigin);
|
||||
|
||||
virtual nsresult ProcessStyleLink(nsIContent* aElement,
|
||||
const nsSubstring& aHref,
|
||||
bool aAlternate,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aType,
|
||||
const nsSubstring& aMedia);
|
||||
|
||||
void PrefetchHref(const nsAString &aHref, nsINode *aSource,
|
||||
bool aExplicit);
|
||||
|
||||
// For PrefetchDNS() aHref can either be the usual
|
||||
// URI format or of the form "//www.hostname.com" without a scheme.
|
||||
void PrefetchDNS(const nsAString &aHref);
|
||||
|
||||
// Gets the cache key (used to identify items in a cache) of the channel.
|
||||
nsresult GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey);
|
||||
|
||||
// There is an offline cache manifest attribute specified and the
|
||||
// document is allowed to use the offline cache. Process the cache
|
||||
// selection algorithm for this document and the manifest. Result is
|
||||
// an action that must be taken on the manifest, see
|
||||
// CacheSelectionAction enum above.
|
||||
//
|
||||
// @param aLoadApplicationCache
|
||||
// The application cache from which the load originated, if
|
||||
// any.
|
||||
// @param aManifestURI
|
||||
// The manifest URI listed in the document.
|
||||
// @param aFetchedWithHTTPGetOrEquiv
|
||||
// TRUE if this was fetched using the HTTP GET method.
|
||||
// @param aAction
|
||||
// Out parameter, returns the action that should be performed
|
||||
// by the calling function.
|
||||
nsresult SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
|
||||
nsIURI *aManifestURI,
|
||||
bool aFetchedWithHTTPGetOrEquiv,
|
||||
CacheSelectionAction *aAction);
|
||||
|
||||
// There is no offline cache manifest attribute specified. Process
|
||||
// the cache selection algorithm w/o the manifest. Result is an
|
||||
// action that must be taken, see CacheSelectionAction enum
|
||||
// above. In case the offline cache manifest has to be updated the
|
||||
// manifest URI is returned in aManifestURI.
|
||||
//
|
||||
// @param aLoadApplicationCache
|
||||
// The application cache from which the load originated, if
|
||||
// any.
|
||||
// @param aManifestURI
|
||||
// Out parameter, returns the manifest URI of the cache that
|
||||
// was selected.
|
||||
// @param aAction
|
||||
// Out parameter, returns the action that should be performed
|
||||
// by the calling function.
|
||||
nsresult SelectDocAppCacheNoManifest(nsIApplicationCache *aLoadApplicationCache,
|
||||
nsIURI **aManifestURI,
|
||||
CacheSelectionAction *aAction);
|
||||
|
||||
public:
|
||||
// Searches for the offline cache manifest attribute and calls one
|
||||
// of the above defined methods to select the document's application
|
||||
// cache, let it be associated with the document and eventually
|
||||
// schedule the cache update process.
|
||||
// This method MUST be called with the empty string as the argument
|
||||
// when there is no manifest attribute!
|
||||
void ProcessOfflineManifest(const nsAString& aManifestSpec);
|
||||
|
||||
// Extracts the manifest attribute from the element if it is the root
|
||||
// element and calls the above method.
|
||||
void ProcessOfflineManifest(nsIContent *aElement);
|
||||
|
||||
// For Preconnect() aHref can either be the usual
|
||||
// URI format or of the form "//www.hostname.com" without a scheme.
|
||||
void Preconnect(const nsAString& aHref, const nsAString& aCrossOrigin);
|
||||
|
||||
protected:
|
||||
// Tries to scroll to the URI's named anchor. Once we've successfully
|
||||
// done that, further calls to this method will be ignored.
|
||||
void ScrollToRef();
|
||||
|
||||
// Start layout. If aIgnorePendingSheets is true, this will happen even if
|
||||
// we still have stylesheet loads pending. Otherwise, we'll wait until the
|
||||
// stylesheets are all done loading.
|
||||
public:
|
||||
void StartLayout(bool aIgnorePendingSheets);
|
||||
|
||||
static void NotifyDocElementCreated(nsIDocument* aDoc);
|
||||
|
||||
protected:
|
||||
void
|
||||
FavorPerformanceHint(bool perfOverStarvation, uint32_t starvationDelay);
|
||||
|
||||
inline int32_t GetNotificationInterval()
|
||||
{
|
||||
if (mDynamicLowerValue) {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
return sNotificationInterval;
|
||||
}
|
||||
|
||||
virtual nsresult FlushTags() = 0;
|
||||
|
||||
// Later on we might want to make this more involved somehow
|
||||
// (e.g. stop waiting after some timeout or whatnot).
|
||||
bool WaitForPendingSheets() { return mPendingSheetCount > 0; }
|
||||
|
||||
void DoProcessLinkHeader();
|
||||
|
||||
void StopDeflecting() {
|
||||
mDeflectedCount = sPerfDeflectCount;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
RefPtr<nsParserBase> mParser;
|
||||
nsCOMPtr<nsIURI> mDocumentURI;
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
RefPtr<mozilla::css::Loader> mCSSLoader;
|
||||
RefPtr<nsNodeInfoManager> mNodeInfoManager;
|
||||
RefPtr<nsScriptLoader> mScriptLoader;
|
||||
|
||||
// back off timer notification after count
|
||||
int32_t mBackoffCount;
|
||||
|
||||
// Time of last notification
|
||||
// Note: mLastNotificationTime is only valid once mLayoutStarted is true.
|
||||
PRTime mLastNotificationTime;
|
||||
|
||||
// Timer used for notification
|
||||
nsCOMPtr<nsITimer> mNotificationTimer;
|
||||
|
||||
// Have we already called BeginUpdate for this set of content changes?
|
||||
uint8_t mBeganUpdate : 1;
|
||||
uint8_t mLayoutStarted : 1;
|
||||
uint8_t mDynamicLowerValue : 1;
|
||||
uint8_t mParsing : 1;
|
||||
uint8_t mDroppedTimer : 1;
|
||||
// If true, we deferred starting layout until sheets load
|
||||
uint8_t mDeferredLayoutStart : 1;
|
||||
// If true, we deferred notifications until sheets load
|
||||
uint8_t mDeferredFlushTags : 1;
|
||||
// If false, we're not ourselves a document observer; that means we
|
||||
// shouldn't be performing any more content model notifications,
|
||||
// since we're not longer updating our child counts.
|
||||
uint8_t mIsDocumentObserver : 1;
|
||||
// True if this is parser is a fragment parser or an HTML DOMParser.
|
||||
// XML DOMParser leaves this to false for now!
|
||||
uint8_t mRunsToCompletion : 1;
|
||||
|
||||
//
|
||||
// -- Can interrupt parsing members --
|
||||
//
|
||||
|
||||
// The number of tokens that have been processed since we measured
|
||||
// if it's time to return to the main event loop.
|
||||
uint32_t mDeflectedCount;
|
||||
|
||||
// Is there currently a pending event?
|
||||
bool mHasPendingEvent;
|
||||
|
||||
// When to return to the main event loop
|
||||
uint32_t mCurrentParseEndTime;
|
||||
|
||||
int32_t mBeginLoadTime;
|
||||
|
||||
// Last mouse event or keyboard event time sampled by the content
|
||||
// sink
|
||||
uint32_t mLastSampledUserEventTime;
|
||||
|
||||
int32_t mInMonolithicContainer;
|
||||
|
||||
int32_t mInNotification;
|
||||
uint32_t mUpdatesInNotification;
|
||||
|
||||
uint32_t mPendingSheetCount;
|
||||
|
||||
nsRevocableEventPtr<nsRunnableMethod<nsContentSink, void, false> >
|
||||
mProcessLinkHeaderEvent;
|
||||
|
||||
// Do we notify based on time?
|
||||
static bool sNotifyOnTimer;
|
||||
// Back off timer notification after count.
|
||||
static int32_t sBackoffCount;
|
||||
// Notification interval in microseconds
|
||||
static int32_t sNotificationInterval;
|
||||
// How many times to deflect in interactive/perf modes
|
||||
static int32_t sInteractiveDeflectCount;
|
||||
static int32_t sPerfDeflectCount;
|
||||
// 0 = don't check for pending events
|
||||
// 1 = don't deflect if there are pending events
|
||||
// 2 = bail if there are pending events
|
||||
static int32_t sPendingEventMode;
|
||||
// How often to probe for pending events. 1=every token
|
||||
static int32_t sEventProbeRate;
|
||||
// How long to stay off the event loop in interactive/perf modes
|
||||
static int32_t sInteractiveParseTime;
|
||||
static int32_t sPerfParseTime;
|
||||
// How long to be in interactive mode after an event
|
||||
static int32_t sInteractiveTime;
|
||||
// How long to stay in perf mode after initial loading
|
||||
static int32_t sInitialPerfTime;
|
||||
// Should we switch between perf-mode and interactive-mode
|
||||
static int32_t sEnablePerfMode;
|
||||
};
|
||||
|
||||
#endif // _nsContentSink_h_
|
||||
Loading…
Add table
Add a link
Reference in a new issue