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"
30 class ProcessingInstruction
;
32 } // namespace mozilla
34 enum XMLContentSinkState
{
35 eXMLContentSinkState_InProlog
,
36 eXMLContentSinkState_InDocumentElement
,
37 eXMLContentSinkState_InEpilog
40 class nsXMLContentSink
: public nsContentSink
,
41 public nsIXMLContentSink
,
42 public nsITransformObserver
,
46 nsCOMPtr
<nsIContent
> mContent
;
52 nsresult
Init(mozilla::dom::Document
* aDoc
, nsIURI
* aURL
,
53 nsISupports
* aContainer
, nsIChannel
* aChannel
);
56 NS_DECL_ISUPPORTS_INHERITED
58 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLContentSink
, nsContentSink
)
63 NS_IMETHOD
WillParse(void) override
;
64 NS_IMETHOD
WillBuildModel(nsDTDMode aDTDMode
) override
;
65 NS_IMETHOD
DidBuildModel(bool aTerminated
) override
;
66 NS_IMETHOD
WillInterrupt(void) override
;
67 void WillResume() override
;
68 NS_IMETHOD
SetParser(nsParserBase
* aParser
) override
;
69 virtual void InitialTranslationCompleted() override
;
70 virtual void FlushPendingNotifications(mozilla::FlushType aType
) override
;
71 virtual void SetDocumentCharset(NotNull
<const Encoding
*> aEncoding
) override
;
72 virtual nsISupports
* GetTarget() override
;
73 virtual bool IsScriptExecuting() override
;
74 virtual void ContinueInterruptedParsingAsync() override
;
75 bool IsPrettyPrintXML() const override
{ return mPrettyPrintXML
; }
76 bool IsPrettyPrintHasSpecialRoot() const override
{
77 return mPrettyPrintHasSpecialRoot
;
80 // nsITransformObserver
81 NS_IMETHOD
OnDocumentCreated(
82 mozilla::dom::Document
* aResultDocument
) override
;
83 NS_IMETHOD
OnTransformDone(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
,
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
) {
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
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
);
138 bool HaveNotifiedForCurrentContent() const;
140 nsresult
FlushTags() override
;
142 void UpdateChildCounts() override
;
144 void DidAddContent() {
145 if (!mXSLTProcessor
&& IsTimeToNotify()) {
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
) override
;
156 // Try to handle an XSLT style link. If NS_OK is returned and aWasXSLT is not
157 // null, *aWasXSLT will be set to whether we processed this link as XSLT.
159 // aProcessingInstruction can be null if this information comes from a Link
160 // header; otherwise it will be the xml-styleshset XML PI that the loading
161 // information comes from.
162 virtual nsresult
MaybeProcessXSLTLink(
163 mozilla::dom::ProcessingInstruction
* aProcessingInstruction
,
164 const nsAString
& aHref
, bool aAlternate
, const nsAString
& aTitle
,
165 const nsAString
& aType
, const nsAString
& aMedia
,
166 const nsAString
& aReferrerPolicy
, bool* aWasXSLT
= nullptr);
168 nsresult
LoadXSLStyleSheet(nsIURI
* aUrl
);
170 bool CanStillPrettyPrint();
172 nsresult
MaybePrettyPrint();
174 bool IsMonolithicContainer(mozilla::dom::NodeInfo
* aNodeInfo
);
176 nsresult
HandleStartElement(const char16_t
* aName
, const char16_t
** aAtts
,
177 uint32_t aAttsCount
, uint32_t aLineNumber
,
178 uint32_t aColumnNumber
, bool aInterruptable
);
179 nsresult
HandleEndElement(const char16_t
* aName
, bool aInterruptable
);
180 nsresult
HandleCharacterData(const char16_t
* aData
, uint32_t aLength
,
181 bool aInterruptable
);
183 nsCOMPtr
<nsIContent
> mDocElement
;
184 nsCOMPtr
<nsIContent
> mCurrentHead
; // When set, we're in an XHTML <haed>
186 XMLContentSinkState mState
;
188 // The length of the valid data in mText.
191 int32_t mNotifyLevel
;
192 RefPtr
<nsTextNode
> mLastTextNode
;
194 uint8_t mPrettyPrintXML
: 1;
195 uint8_t mPrettyPrintHasSpecialRoot
: 1;
196 uint8_t mPrettyPrintHasFactoredElements
: 1;
197 uint8_t mPrettyPrinting
: 1; // True if we called PrettyPrint() and it
198 // decided we should in fact prettyprint.
199 // True to call prevent script execution in the fragment mode.
200 uint8_t mPreventScriptExecution
: 1;
202 nsTArray
<StackNode
> mContentStack
;
204 nsCOMPtr
<nsIDocumentTransformer
> mXSLTProcessor
;
206 // Holds the children in the prolog until the root element is added, after
207 // which they're inserted in the document. However, if we're doing an XSLT
208 // transform this will actually hold all the children of the source document,
209 // until the transform is finished. After the transform is finished we'll just
210 // discard the children.
211 nsTArray
<nsCOMPtr
<nsIContent
>> mDocumentChildren
;
213 static const int NS_ACCUMULATION_BUFFER_SIZE
= 4096;
214 // Our currently accumulated text that we have not flushed to a textnode yet.
215 char16_t mText
[NS_ACCUMULATION_BUFFER_SIZE
];
218 #endif // nsXMLContentSink_h__