michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsHtml5TreeOpExecutor_h michael@0: #define nsHtml5TreeOpExecutor_h michael@0: michael@0: #include "nsIAtom.h" michael@0: #include "nsIContent.h" michael@0: #include "nsIDocument.h" michael@0: #include "nsTraceRefcnt.h" michael@0: #include "nsHtml5TreeOperation.h" michael@0: #include "nsHtml5SpeculativeLoad.h" michael@0: #include "nsTArray.h" michael@0: #include "nsContentSink.h" michael@0: #include "nsNodeInfoManager.h" michael@0: #include "nsHtml5DocumentMode.h" michael@0: #include "nsIScriptElement.h" michael@0: #include "nsIParser.h" michael@0: #include "nsAHtml5TreeOpSink.h" michael@0: #include "nsHtml5TreeOpStage.h" michael@0: #include "nsIURI.h" michael@0: #include "nsTHashtable.h" michael@0: #include "nsHashKeys.h" michael@0: #include "mozilla/LinkedList.h" michael@0: #include "nsHtml5DocumentBuilder.h" michael@0: michael@0: class nsHtml5Parser; michael@0: class nsHtml5TreeBuilder; michael@0: class nsHtml5Tokenizer; michael@0: class nsHtml5StreamParser; michael@0: michael@0: class nsHtml5TreeOpExecutor : public nsHtml5DocumentBuilder, michael@0: public nsIContentSink, michael@0: public nsAHtml5TreeOpSink, michael@0: public mozilla::LinkedListElement michael@0: { michael@0: friend class nsHtml5FlushLoopGuard; michael@0: michael@0: public: michael@0: NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW michael@0: NS_DECL_ISUPPORTS_INHERITED michael@0: michael@0: private: michael@0: static bool sExternalViewSource; michael@0: #ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH michael@0: static uint32_t sAppendBatchMaxSize; michael@0: static uint32_t sAppendBatchSlotsExamined; michael@0: static uint32_t sAppendBatchExaminations; michael@0: static uint32_t sLongestTimeOffTheEventLoop; michael@0: static uint32_t sTimesFlushLoopInterrupted; michael@0: #endif michael@0: michael@0: /** michael@0: * Whether EOF needs to be suppressed michael@0: */ michael@0: bool mSuppressEOF; michael@0: michael@0: bool mReadingFromStage; michael@0: nsTArray mOpQueue; michael@0: nsHtml5StreamParser* mStreamParser; michael@0: michael@0: /** michael@0: * URLs already preloaded/preloading. michael@0: */ michael@0: nsTHashtable mPreloadedURLs; michael@0: michael@0: nsCOMPtr mSpeculationBaseURI; michael@0: michael@0: nsCOMPtr mViewSourceBaseURI; michael@0: michael@0: /** michael@0: * Whether the parser has started michael@0: */ michael@0: bool mStarted; michael@0: michael@0: nsHtml5TreeOpStage mStage; michael@0: michael@0: bool mRunFlushLoopOnStack; michael@0: michael@0: bool mCallContinueInterruptedParsingIfEnabled; michael@0: michael@0: /** michael@0: * Whether this executor has already complained about matters related michael@0: * to character encoding declarations. michael@0: */ michael@0: bool mAlreadyComplainedAboutCharset; michael@0: michael@0: public: michael@0: michael@0: nsHtml5TreeOpExecutor(); michael@0: virtual ~nsHtml5TreeOpExecutor(); michael@0: michael@0: // nsIContentSink michael@0: michael@0: /** michael@0: * Unimplemented. For interface compat only. michael@0: */ michael@0: NS_IMETHOD WillParse(); michael@0: michael@0: /** michael@0: * michael@0: */ michael@0: NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode); michael@0: michael@0: /** michael@0: * Emits EOF. michael@0: */ michael@0: NS_IMETHOD DidBuildModel(bool aTerminated); michael@0: michael@0: /** michael@0: * Forwards to nsContentSink michael@0: */ michael@0: NS_IMETHOD WillInterrupt(); michael@0: michael@0: /** michael@0: * Unimplemented. For interface compat only. michael@0: */ michael@0: NS_IMETHOD WillResume(); michael@0: michael@0: /** michael@0: * Sets the parser. michael@0: */ michael@0: NS_IMETHOD SetParser(nsParserBase* aParser); michael@0: michael@0: /** michael@0: * No-op for backwards compat. michael@0: */ michael@0: virtual void FlushPendingNotifications(mozFlushType aType); michael@0: michael@0: /** michael@0: * Don't call. For interface compat only. michael@0: */ michael@0: NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { michael@0: NS_NOTREACHED("No one should call this."); michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: /** michael@0: * Returns the document. michael@0: */ michael@0: virtual nsISupports *GetTarget(); michael@0: michael@0: virtual void ContinueInterruptedParsingAsync(); michael@0: michael@0: // XXX Does anyone need this? michael@0: nsIDocShell* GetDocShell() michael@0: { michael@0: return mDocShell; michael@0: } michael@0: michael@0: bool IsScriptExecuting() michael@0: { michael@0: return IsScriptExecutingImpl(); michael@0: } michael@0: michael@0: // Not from interface michael@0: michael@0: void SetStreamParser(nsHtml5StreamParser* aStreamParser) michael@0: { michael@0: mStreamParser = aStreamParser; michael@0: } michael@0: michael@0: void InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState, int32_t aLine); michael@0: michael@0: bool IsScriptEnabled(); michael@0: michael@0: virtual nsresult MarkAsBroken(nsresult aReason); michael@0: michael@0: void StartLayout(); michael@0: michael@0: void FlushSpeculativeLoads(); michael@0: michael@0: void RunFlushLoop(); michael@0: michael@0: nsresult FlushDocumentWrite(); michael@0: michael@0: void MaybeSuspend(); michael@0: michael@0: void Start(); michael@0: michael@0: void NeedsCharsetSwitchTo(const char* aEncoding, michael@0: int32_t aSource, michael@0: uint32_t aLineNumber); michael@0: michael@0: void MaybeComplainAboutCharset(const char* aMsgId, michael@0: bool aError, michael@0: uint32_t aLineNumber); michael@0: michael@0: void ComplainAboutBogusProtocolCharset(nsIDocument* aDoc); michael@0: michael@0: bool IsComplete() michael@0: { michael@0: return !mParser; michael@0: } michael@0: michael@0: bool HasStarted() michael@0: { michael@0: return mStarted; michael@0: } michael@0: michael@0: bool IsFlushing() michael@0: { michael@0: return mFlushState >= eInFlush; michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: bool IsInFlushLoop() michael@0: { michael@0: return mRunFlushLoopOnStack; michael@0: } michael@0: #endif michael@0: michael@0: void RunScript(nsIContent* aScriptElement); michael@0: michael@0: /** michael@0: * Flush the operations from the tree operations from the argument michael@0: * queue unconditionally. (This is for the main thread case.) michael@0: */ michael@0: virtual void MoveOpsFrom(nsTArray& aOpQueue); michael@0: michael@0: nsHtml5TreeOpStage* GetStage() michael@0: { michael@0: return &mStage; michael@0: } michael@0: michael@0: void StartReadingFromStage() michael@0: { michael@0: mReadingFromStage = true; michael@0: } michael@0: michael@0: void StreamEnded(); michael@0: michael@0: #ifdef DEBUG michael@0: void AssertStageEmpty() michael@0: { michael@0: mStage.AssertEmpty(); michael@0: } michael@0: #endif michael@0: michael@0: nsIURI* GetViewSourceBaseURI(); michael@0: michael@0: void PreloadScript(const nsAString& aURL, michael@0: const nsAString& aCharset, michael@0: const nsAString& aType, michael@0: const nsAString& aCrossOrigin, michael@0: bool aScriptFromHead); michael@0: michael@0: void PreloadStyle(const nsAString& aURL, const nsAString& aCharset, michael@0: const nsAString& aCrossOrigin); michael@0: michael@0: void PreloadImage(const nsAString& aURL, const nsAString& aCrossOrigin); michael@0: michael@0: void SetSpeculationBase(const nsAString& aURL); michael@0: michael@0: static void InitializeStatics(); michael@0: michael@0: private: michael@0: nsHtml5Parser* GetParser(); michael@0: michael@0: bool IsExternalViewSource(); michael@0: michael@0: /** michael@0: * Get a nsIURI for an nsString if the URL hasn't been preloaded yet. michael@0: */ michael@0: already_AddRefed ConvertIfNotPreloadedYet(const nsAString& aURL); michael@0: michael@0: }; michael@0: michael@0: #endif // nsHtml5TreeOpExecutor_h