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