nsHtml5DocumentBuilder.h (3945B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 sw=2 et tw=78: */ 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/. */ 6 7 #ifndef nsHtml5DocumentBuilder_h 8 #define nsHtml5DocumentBuilder_h 9 10 #include "mozilla/dom/Document.h" 11 #include "nsContentSink.h" 12 #include "nsHtml5DocumentMode.h" 13 #include "nsIContent.h" 14 15 namespace mozilla::dom { 16 class Document; 17 } 18 19 typedef nsIContent* nsIContentPtr; 20 21 enum eHtml5FlushState { 22 eNotFlushing = 0, // not flushing 23 eInFlush = 1, // the Flush() method is on the call stack 24 eInDocUpdate = 2, // inside an update batch on the document 25 }; 26 27 class nsHtml5DocumentBuilder : public nsContentSink { 28 using Encoding = mozilla::Encoding; 29 template <typename T> 30 using NotNull = mozilla::NotNull<T>; 31 32 public: 33 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHtml5DocumentBuilder, 34 nsContentSink) 35 36 NS_DECL_ISUPPORTS_INHERITED 37 38 inline void HoldElement(already_AddRefed<nsIContent> aContent) { 39 *(mOwnedElements.AppendElement()) = aContent; 40 } 41 42 nsresult Init(Document* aDoc, nsIURI* aURI, nsISupports* aContainer, 43 nsIChannel* aChannel); 44 45 // Getters and setters for fields from nsContentSink 46 Document* GetDocument() { return mDocument; } 47 48 nsNodeInfoManager* GetNodeInfoManager() { return mNodeInfoManager; } 49 50 /** 51 * Marks this parser as broken and tells the stream parser (if any) to 52 * terminate. 53 * 54 * @return aReason for convenience 55 */ 56 virtual nsresult MarkAsBroken(nsresult aReason); 57 58 /** 59 * Checks if this parser is broken. Returns a non-NS_OK (i.e. non-0) 60 * value if broken. 61 */ 62 inline nsresult IsBroken() { return mBroken; } 63 64 inline bool IsComplete() { return !mParser; } 65 66 inline void BeginDocUpdate() { 67 MOZ_RELEASE_ASSERT(IsInFlush(), "Tried to double-open doc update."); 68 MOZ_RELEASE_ASSERT(mParser, "Started doc update without parser."); 69 mFlushState = eInDocUpdate; 70 mDocument->BeginUpdate(); 71 } 72 73 inline void EndDocUpdate() { 74 MOZ_RELEASE_ASSERT(IsInDocUpdate(), 75 "Tried to end doc update without one open."); 76 mFlushState = eInFlush; 77 mDocument->EndUpdate(); 78 } 79 80 inline void BeginFlush() { 81 MOZ_RELEASE_ASSERT(mFlushState == eNotFlushing, 82 "Tried to start a flush when already flushing."); 83 MOZ_RELEASE_ASSERT(mParser, "Started a flush without parser."); 84 mFlushState = eInFlush; 85 } 86 87 inline void EndFlush() { 88 MOZ_RELEASE_ASSERT(IsInFlush(), "Tried to end flush when not flushing."); 89 mFlushState = eNotFlushing; 90 } 91 92 inline bool IsInDocUpdate() { return mFlushState == eInDocUpdate; } 93 94 inline bool IsInFlush() { return mFlushState == eInFlush; } 95 96 /** 97 * Sets up style sheet load / parse 98 */ 99 void UpdateStyleSheet(nsIContent* aElement); 100 101 void SetDocumentMode(nsHtml5DocumentMode m); 102 103 void SetNodeInfoManager(nsNodeInfoManager* aManager) { 104 mNodeInfoManager = aManager; 105 } 106 107 // nsContentSink methods 108 virtual void UpdateChildCounts() override; 109 virtual nsresult FlushTags() override; 110 111 protected: 112 explicit nsHtml5DocumentBuilder(bool aRunsToCompletion); 113 virtual ~nsHtml5DocumentBuilder(); 114 115 protected: 116 nsTArray<nsCOMPtr<nsIContent>> mOwnedElements; 117 /** 118 * Non-NS_OK if this parser should refuse to process any more input. 119 * For example, the parser needs to be marked as broken if it drops some 120 * input due to a memory allocation failure. In such a case, the whole 121 * parser needs to be marked as broken, because some input has been lost 122 * and parsing more input could lead to a DOM where pieces of HTML source 123 * that weren't supposed to become scripts become scripts. 124 */ 125 nsresult mBroken; 126 eHtml5FlushState mFlushState; 127 }; 128 129 #endif // nsHtml5DocumentBuilder_h