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"
18 #include "nsCycleCollectionParticipant.h"
20 #include "mozilla/dom/FromParser.h"
27 namespace mozilla::dom
{
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
,
44 nsCOMPtr
<nsIContent
> mContent
;
50 nsresult
Init(mozilla::dom::Document
* aDoc
, nsIURI
* aURL
,
51 nsISupports
* aContainer
, nsIChannel
* aChannel
);
54 NS_DECL_ISUPPORTS_INHERITED
56 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLContentSink
, nsContentSink
)
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
,
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
,
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
) {
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
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
);
137 bool HaveNotifiedForCurrentContent() const;
139 nsresult
FlushTags() override
;
141 void UpdateChildCounts() override
;
143 void DidAddContent() {
144 if (!mXSLTProcessor
&& IsTimeToNotify()) {
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.
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__