Bug 1756164: part 2) Document the order of the external clipboard formats and remove...
[gecko.git] / dom / xml / nsXMLContentSink.h
blob059f84686440f772327a8f749264fcee7e2c31b8
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 {
28 namespace dom {
29 class NodeInfo;
30 class ProcessingInstruction;
31 } // namespace dom
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,
43 public nsIExpatSink {
44 public:
45 struct StackNode {
46 nsCOMPtr<nsIContent> mContent;
47 uint32_t mNumFlushed;
50 nsXMLContentSink();
52 nsresult Init(mozilla::dom::Document* aDoc, nsIURI* aURL,
53 nsISupports* aContainer, nsIChannel* aChannel);
55 // nsISupports
56 NS_DECL_ISUPPORTS_INHERITED
58 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLContentSink, nsContentSink)
60 NS_DECL_NSIEXPATSINK
62 // nsIContentSink
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,
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) 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.
189 int32_t mTextLength;
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__