Bug 1825212 [wpt PR 39266] - [@scope] Propagate proximity from SubResult, a=testonly
[gecko.git] / dom / xml / nsXMLContentSink.h
blob41acbbc0272eaf2ef57bc2a13b1f5e4de8df2ff0
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 nsresult OnDocumentCreated(mozilla::dom::Document* aSourceDocument,
80 mozilla::dom::Document* aResultDocument) override;
81 nsresult OnTransformDone(mozilla::dom::Document* aSourceDocument,
82 nsresult aResult,
83 mozilla::dom::Document* aResultDocument) override;
85 // nsICSSLoaderObserver
86 NS_IMETHOD StyleSheetLoaded(mozilla::StyleSheet* aSheet, bool aWasDeferred,
87 nsresult aStatus) override;
88 static bool ParsePIData(const nsString& aData, nsString& aHref,
89 nsString& aTitle, nsString& aMedia,
90 bool& aIsAlternate);
92 protected:
93 virtual ~nsXMLContentSink();
95 nsIParser* GetParser();
97 void ContinueInterruptedParsingIfEnabled();
99 // Start layout. If aIgnorePendingSheets is true, this will happen even if
100 // we still have stylesheet loads pending. Otherwise, we'll wait until the
101 // stylesheets are all done loading.
102 virtual void MaybeStartLayout(bool aIgnorePendingSheets);
104 virtual nsresult AddAttributes(const char16_t** aNode,
105 mozilla::dom::Element* aElement);
106 nsresult AddText(const char16_t* aString, int32_t aLength);
108 virtual bool OnOpenContainer(const char16_t** aAtts, uint32_t aAttsCount,
109 int32_t aNameSpaceID, nsAtom* aTagName,
110 uint32_t aLineNumber) {
111 return true;
113 // Set the given content as the root element for the created document
114 // don't set if root element was already set.
115 // return TRUE if this call set the root element
116 virtual bool SetDocElement(int32_t aNameSpaceID, nsAtom* aTagName,
117 nsIContent* aContent);
118 virtual bool NotifyForDocElement() { return true; }
119 virtual nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
120 mozilla::dom::NodeInfo* aNodeInfo,
121 uint32_t aLineNumber, uint32_t aColumnNumber,
122 nsIContent** aResult, bool* aAppendContent,
123 mozilla::dom::FromParser aFromParser);
125 // aParent is allowed to be null here if this is the root content
126 // being closed
127 virtual nsresult CloseElement(nsIContent* aContent);
129 virtual nsresult FlushText(bool aReleaseTextNode = true);
131 nsresult AddContentAsLeaf(nsIContent* aContent);
133 nsIContent* GetCurrentContent();
134 StackNode* GetCurrentStackNode();
135 nsresult PushContent(nsIContent* aContent);
136 void PopContent();
137 bool HaveNotifiedForCurrentContent() const;
139 nsresult FlushTags() override;
141 void UpdateChildCounts() override;
143 void DidAddContent() {
144 if (!mXSLTProcessor && IsTimeToNotify()) {
145 FlushTags();
149 // nsContentSink override
150 virtual nsresult ProcessStyleLinkFromHeader(
151 const nsAString& aHref, bool aAlternate, const nsAString& aTitle,
152 const nsAString& aIntegrity, const nsAString& aType,
153 const nsAString& aMedia, const nsAString& aReferrerPolicy) override;
155 // Try to handle an XSLT style link. If NS_OK is returned and aWasXSLT is not
156 // null, *aWasXSLT will be set to whether we processed this link as XSLT.
158 // aProcessingInstruction can be null if this information comes from a Link
159 // header; otherwise it will be the xml-styleshset XML PI that the loading
160 // information comes from.
161 virtual nsresult MaybeProcessXSLTLink(
162 mozilla::dom::ProcessingInstruction* aProcessingInstruction,
163 const nsAString& aHref, bool aAlternate, const nsAString& aTitle,
164 const nsAString& aType, const nsAString& aMedia,
165 const nsAString& aReferrerPolicy, bool* aWasXSLT = nullptr);
167 nsresult LoadXSLStyleSheet(nsIURI* aUrl);
169 bool CanStillPrettyPrint();
171 nsresult MaybePrettyPrint();
173 bool IsMonolithicContainer(mozilla::dom::NodeInfo* aNodeInfo);
175 nsresult HandleStartElement(const char16_t* aName, const char16_t** aAtts,
176 uint32_t aAttsCount, uint32_t aLineNumber,
177 uint32_t aColumnNumber, bool aInterruptable);
178 nsresult HandleEndElement(const char16_t* aName, bool aInterruptable);
179 nsresult HandleCharacterData(const char16_t* aData, uint32_t aLength,
180 bool aInterruptable);
182 nsCOMPtr<nsIContent> mDocElement;
183 nsCOMPtr<nsIContent> mCurrentHead; // When set, we're in an XHTML <haed>
185 XMLContentSinkState mState;
187 // The length of the valid data in mText.
188 int32_t mTextLength;
190 int32_t mNotifyLevel;
191 RefPtr<nsTextNode> mLastTextNode;
193 uint8_t mPrettyPrintXML : 1;
194 uint8_t mPrettyPrintHasSpecialRoot : 1;
195 uint8_t mPrettyPrintHasFactoredElements : 1;
196 uint8_t mPrettyPrinting : 1; // True if we called PrettyPrint() and it
197 // decided we should in fact prettyprint.
198 // True to call prevent script execution in the fragment mode.
199 uint8_t mPreventScriptExecution : 1;
201 nsTArray<StackNode> mContentStack;
203 nsCOMPtr<nsIDocumentTransformer> mXSLTProcessor;
205 // Holds the children in the prolog until the root element is added, after
206 // which they're inserted in the document. However, if we're doing an XSLT
207 // transform this will actually hold all the children of the source document,
208 // until the transform is finished. After the transform is finished we'll just
209 // discard the children.
210 nsTArray<nsCOMPtr<nsIContent>> mDocumentChildren;
212 static const int NS_ACCUMULATION_BUFFER_SIZE = 4096;
213 // Our currently accumulated text that we have not flushed to a textnode yet.
214 char16_t mText[NS_ACCUMULATION_BUFFER_SIZE];
217 #endif // nsXMLContentSink_h__