Bug 1867190 - Initialise the PHC allocate delay later r=glandium
[gecko.git] / dom / xml / nsXMLContentSink.h
blobe19fae926533ff97b6514644e27aa7b5237f4b06
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 #ifndef nsXMLContentSink_h__
8 #define nsXMLContentSink_h__
10 #include "js/ColumnNumber.h" // JS::ColumnNumberOneOrigin
11 #include "mozilla/Attributes.h"
12 #include "nsContentSink.h"
13 #include "nsIXMLContentSink.h"
14 #include "nsIExpatSink.h"
15 #include "nsIDocumentTransformer.h"
16 #include "nsTArray.h"
17 #include "nsCOMPtr.h"
18 #include "nsCRT.h"
19 #include "nsCycleCollectionParticipant.h"
20 #include "nsIDTD.h"
21 #include "mozilla/dom/FromParser.h"
23 class nsIURI;
24 class nsIContent;
25 class nsIParser;
26 class nsTextNode;
28 namespace mozilla::dom {
29 class NodeInfo;
30 class ProcessingInstruction;
31 } // namespace mozilla::dom
33 enum XMLContentSinkState {
34 eXMLContentSinkState_InProlog,
35 eXMLContentSinkState_InDocumentElement,
36 eXMLContentSinkState_InEpilog
39 class nsXMLContentSink : public nsContentSink,
40 public nsIXMLContentSink,
41 public nsITransformObserver,
42 public nsIExpatSink {
43 public:
44 struct StackNode {
45 nsCOMPtr<nsIContent> mContent;
46 uint32_t mNumFlushed;
49 nsXMLContentSink();
51 nsresult Init(mozilla::dom::Document* aDoc, nsIURI* aURL,
52 nsISupports* aContainer, nsIChannel* aChannel);
54 // nsISupports
55 NS_DECL_ISUPPORTS_INHERITED
57 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLContentSink, nsContentSink)
59 NS_DECL_NSIEXPATSINK
61 // nsIContentSink
62 NS_IMETHOD WillParse(void) override;
63 NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
64 NS_IMETHOD DidBuildModel(bool aTerminated) override;
65 NS_IMETHOD WillInterrupt(void) override;
66 void WillResume() override;
67 NS_IMETHOD SetParser(nsParserBase* aParser) override;
68 virtual void InitialTranslationCompleted() override;
69 virtual void FlushPendingNotifications(mozilla::FlushType aType) override;
70 virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override;
71 virtual nsISupports* GetTarget() override;
72 virtual bool IsScriptExecuting() override;
73 virtual void ContinueInterruptedParsingAsync() override;
74 bool IsPrettyPrintXML() const override { return mPrettyPrintXML; }
75 bool IsPrettyPrintHasSpecialRoot() const override {
76 return mPrettyPrintHasSpecialRoot;
79 // nsITransformObserver
80 nsresult OnDocumentCreated(mozilla::dom::Document* aSourceDocument,
81 mozilla::dom::Document* aResultDocument) override;
82 nsresult OnTransformDone(mozilla::dom::Document* aSourceDocument,
83 nsresult aResult,
84 mozilla::dom::Document* aResultDocument) override;
86 // nsICSSLoaderObserver
87 NS_IMETHOD StyleSheetLoaded(mozilla::StyleSheet* aSheet, bool aWasDeferred,
88 nsresult aStatus) override;
89 static bool ParsePIData(const nsString& aData, nsString& aHref,
90 nsString& aTitle, nsString& aMedia,
91 bool& aIsAlternate);
93 protected:
94 virtual ~nsXMLContentSink();
96 nsIParser* GetParser();
98 void ContinueInterruptedParsingIfEnabled();
100 // Start layout. If aIgnorePendingSheets is true, this will happen even if
101 // we still have stylesheet loads pending. Otherwise, we'll wait until the
102 // stylesheets are all done loading.
103 virtual void MaybeStartLayout(bool aIgnorePendingSheets);
105 virtual nsresult AddAttributes(const char16_t** aNode,
106 mozilla::dom::Element* aElement);
107 nsresult AddText(const char16_t* aString, int32_t aLength);
109 virtual bool OnOpenContainer(const char16_t** aAtts, uint32_t aAttsCount,
110 int32_t aNameSpaceID, nsAtom* aTagName,
111 uint32_t aLineNumber) {
112 return true;
114 // Set the given content as the root element for the created document
115 // don't set if root element was already set.
116 // return TRUE if this call set the root element
117 virtual bool SetDocElement(int32_t aNameSpaceID, nsAtom* aTagName,
118 nsIContent* aContent);
119 virtual bool NotifyForDocElement() { return true; }
120 virtual nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
121 mozilla::dom::NodeInfo* aNodeInfo,
122 uint32_t aLineNumber, uint32_t aColumnNumber,
123 nsIContent** aResult, bool* aAppendContent,
124 mozilla::dom::FromParser aFromParser);
126 // aParent is allowed to be null here if this is the root content
127 // being closed
128 virtual nsresult CloseElement(nsIContent* aContent);
130 virtual nsresult FlushText(bool aReleaseTextNode = true);
132 nsresult AddContentAsLeaf(nsIContent* aContent);
134 nsIContent* GetCurrentContent();
135 StackNode* GetCurrentStackNode();
136 nsresult PushContent(nsIContent* aContent);
137 void PopContent();
138 bool HaveNotifiedForCurrentContent() const;
140 nsresult FlushTags() override;
142 void UpdateChildCounts() override;
144 void DidAddContent() {
145 if (!mXSLTProcessor && IsTimeToNotify()) {
146 FlushTags();
150 // nsContentSink override
151 virtual nsresult ProcessStyleLinkFromHeader(
152 const nsAString& aHref, bool aAlternate, const nsAString& aTitle,
153 const nsAString& aIntegrity, const nsAString& aType,
154 const nsAString& aMedia, const nsAString& aReferrerPolicy,
155 const nsAString& aFetchPriority) override;
157 // Try to handle an XSLT style link. If NS_OK is returned and aWasXSLT is not
158 // null, *aWasXSLT will be set to whether we processed this link as XSLT.
160 // aProcessingInstruction can be null if this information comes from a Link
161 // header; otherwise it will be the xml-styleshset XML PI that the loading
162 // information comes from.
163 virtual nsresult MaybeProcessXSLTLink(
164 mozilla::dom::ProcessingInstruction* aProcessingInstruction,
165 const nsAString& aHref, bool aAlternate, const nsAString& aTitle,
166 const nsAString& aType, const nsAString& aMedia,
167 const nsAString& aReferrerPolicy, bool* aWasXSLT = nullptr);
169 nsresult LoadXSLStyleSheet(nsIURI* aUrl);
171 bool CanStillPrettyPrint();
173 nsresult MaybePrettyPrint();
175 bool IsMonolithicContainer(mozilla::dom::NodeInfo* aNodeInfo);
177 nsresult HandleStartElement(const char16_t* aName, const char16_t** aAtts,
178 uint32_t aAttsCount, uint32_t aLineNumber,
179 uint32_t aColumnNumber, bool aInterruptable);
180 nsresult HandleEndElement(const char16_t* aName, bool aInterruptable);
181 nsresult HandleCharacterData(const char16_t* aData, uint32_t aLength,
182 bool aInterruptable);
184 nsCOMPtr<nsIContent> mDocElement;
185 nsCOMPtr<nsIContent> mCurrentHead; // When set, we're in an XHTML <haed>
187 XMLContentSinkState mState;
189 // The length of the valid data in mText.
190 int32_t mTextLength;
192 int32_t mNotifyLevel;
193 RefPtr<nsTextNode> mLastTextNode;
195 uint8_t mPrettyPrintXML : 1;
196 uint8_t mPrettyPrintHasSpecialRoot : 1;
197 uint8_t mPrettyPrintHasFactoredElements : 1;
198 uint8_t mPrettyPrinting : 1; // True if we called PrettyPrint() and it
199 // decided we should in fact prettyprint.
200 // True to call prevent script execution in the fragment mode.
201 uint8_t mPreventScriptExecution : 1;
203 nsTArray<StackNode> mContentStack;
205 nsCOMPtr<nsIDocumentTransformer> mXSLTProcessor;
207 // Holds the children in the prolog until the root element is added, after
208 // which they're inserted in the document. However, if we're doing an XSLT
209 // transform this will actually hold all the children of the source document,
210 // until the transform is finished. After the transform is finished we'll just
211 // discard the children.
212 nsTArray<nsCOMPtr<nsIContent>> mDocumentChildren;
214 static const int NS_ACCUMULATION_BUFFER_SIZE = 4096;
215 // Our currently accumulated text that we have not flushed to a textnode yet.
216 char16_t mText[NS_ACCUMULATION_BUFFER_SIZE];
219 #endif // nsXMLContentSink_h__