Line data Source code
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/. */
6 :
7 : #ifndef nsXMLContentSink_h__
8 : #define nsXMLContentSink_h__
9 :
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"
21 :
22 : class nsIDocument;
23 : class nsIURI;
24 : class nsIContent;
25 : class nsIParser;
26 :
27 : namespace mozilla {
28 : namespace dom {
29 : class NodeInfo;
30 : } // namespace dom
31 : } // namespace mozilla
32 :
33 : typedef enum {
34 : eXMLContentSinkState_InProlog,
35 : eXMLContentSinkState_InDocumentElement,
36 : eXMLContentSinkState_InEpilog
37 : } XMLContentSinkState;
38 :
39 282 : struct StackNode {
40 : nsCOMPtr<nsIContent> mContent;
41 : uint32_t mNumFlushed;
42 : };
43 :
44 : class nsXMLContentSink : public nsContentSink,
45 : public nsIXMLContentSink,
46 : public nsITransformObserver,
47 : public nsIExpatSink
48 : {
49 : public:
50 : nsXMLContentSink();
51 :
52 : nsresult Init(nsIDocument* aDoc,
53 : nsIURI* aURL,
54 : nsISupports* aContainer,
55 : nsIChannel* aChannel);
56 :
57 : // nsISupports
58 : NS_DECL_ISUPPORTS_INHERITED
59 :
60 22 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsXMLContentSink,
61 : nsContentSink)
62 :
63 : NS_DECL_NSIEXPATSINK
64 :
65 : // nsIContentSink
66 : NS_IMETHOD WillParse(void) override;
67 : NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
68 : NS_IMETHOD DidBuildModel(bool aTerminated) override;
69 : NS_IMETHOD WillInterrupt(void) override;
70 : NS_IMETHOD WillResume(void) override;
71 : NS_IMETHOD SetParser(nsParserBase* aParser) override;
72 : virtual void FlushPendingNotifications(mozilla::FlushType aType) override;
73 : virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override;
74 : virtual nsISupports *GetTarget() override;
75 : virtual bool IsScriptExecuting() override;
76 : virtual void ContinueInterruptedParsingAsync() override;
77 :
78 : // nsITransformObserver
79 : NS_IMETHOD OnDocumentCreated(nsIDocument *aResultDocument) override;
80 : NS_IMETHOD OnTransformDone(nsresult aResult, nsIDocument *aResultDocument) override;
81 :
82 : // nsICSSLoaderObserver
83 : NS_IMETHOD StyleSheetLoaded(mozilla::StyleSheet* aSheet,
84 : bool aWasAlternate,
85 : nsresult aStatus) override;
86 : static bool ParsePIData(const nsString &aData, nsString &aHref,
87 : nsString &aTitle, nsString &aMedia,
88 : bool &aIsAlternate);
89 :
90 : protected:
91 : virtual ~nsXMLContentSink();
92 :
93 : nsIParser* GetParser();
94 :
95 : void ContinueInterruptedParsingIfEnabled();
96 :
97 : // Start layout. If aIgnorePendingSheets is true, this will happen even if
98 : // we still have stylesheet loads pending. Otherwise, we'll wait until the
99 : // stylesheets are all done loading.
100 : virtual void MaybeStartLayout(bool aIgnorePendingSheets);
101 :
102 : virtual nsresult AddAttributes(const char16_t** aNode, nsIContent* aContent);
103 : nsresult AddText(const char16_t* aString, int32_t aLength);
104 :
105 130 : virtual bool OnOpenContainer(const char16_t **aAtts,
106 : uint32_t aAttsCount,
107 : int32_t aNameSpaceID,
108 : nsIAtom* aTagName,
109 130 : uint32_t aLineNumber) { return true; }
110 : // Set the given content as the root element for the created document
111 : // don't set if root element was already set.
112 : // return TRUE if this call set the root element
113 : virtual bool SetDocElement(int32_t aNameSpaceID,
114 : nsIAtom *aTagName,
115 : nsIContent *aContent);
116 21 : virtual bool NotifyForDocElement() { return true; }
117 : virtual nsresult CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
118 : mozilla::dom::NodeInfo* aNodeInfo, uint32_t aLineNumber,
119 : nsIContent** aResult, bool* aAppendContent,
120 : mozilla::dom::FromParser aFromParser);
121 :
122 : // aParent is allowed to be null here if this is the root content
123 : // being closed
124 : virtual nsresult CloseElement(nsIContent* aContent);
125 :
126 : virtual nsresult FlushText(bool aReleaseTextNode = true);
127 :
128 : nsresult AddContentAsLeaf(nsIContent *aContent);
129 :
130 : nsIContent* GetCurrentContent();
131 : StackNode* GetCurrentStackNode();
132 : nsresult PushContent(nsIContent *aContent);
133 : void PopContent();
134 : bool HaveNotifiedForCurrentContent() const;
135 :
136 : nsresult FlushTags() override;
137 :
138 : void UpdateChildCounts() override;
139 :
140 310 : void DidAddContent()
141 : {
142 310 : if (IsTimeToNotify()) {
143 1 : FlushTags();
144 : }
145 310 : }
146 :
147 : // nsContentSink override
148 : virtual nsresult ProcessStyleLink(nsIContent* aElement,
149 : const nsAString& aHref,
150 : bool aAlternate,
151 : const nsAString& aTitle,
152 : const nsAString& aType,
153 : const nsAString& aMedia) override;
154 :
155 : nsresult LoadXSLStyleSheet(nsIURI* aUrl);
156 :
157 : bool CanStillPrettyPrint();
158 :
159 : nsresult MaybePrettyPrint();
160 :
161 : bool IsMonolithicContainer(mozilla::dom::NodeInfo* aNodeInfo);
162 :
163 : nsresult HandleStartElement(const char16_t *aName, const char16_t **aAtts,
164 : uint32_t aAttsCount, uint32_t aLineNumber,
165 : bool aInterruptable);
166 : nsresult HandleEndElement(const char16_t *aName, bool aInterruptable);
167 : nsresult HandleCharacterData(const char16_t *aData, uint32_t aLength,
168 : bool aInterruptable);
169 :
170 : nsCOMPtr<nsIContent> mDocElement;
171 : nsCOMPtr<nsIContent> mCurrentHead; // When set, we're in an XHTML <haed>
172 :
173 : XMLContentSinkState mState;
174 :
175 : // The length of the valid data in mText.
176 : int32_t mTextLength;
177 :
178 : int32_t mNotifyLevel;
179 : nsCOMPtr<nsIContent> mLastTextNode;
180 :
181 : uint8_t mPrettyPrintXML : 1;
182 : uint8_t mPrettyPrintHasSpecialRoot : 1;
183 : uint8_t mPrettyPrintHasFactoredElements : 1;
184 : uint8_t mPrettyPrinting : 1; // True if we called PrettyPrint() and it
185 : // decided we should in fact prettyprint.
186 : // True to call prevent script execution in the fragment mode.
187 : uint8_t mPreventScriptExecution : 1;
188 :
189 : nsTArray<StackNode> mContentStack;
190 :
191 : nsCOMPtr<nsIDocumentTransformer> mXSLTProcessor;
192 :
193 : static const int NS_ACCUMULATION_BUFFER_SIZE = 4096;
194 : // Our currently accumulated text that we have not flushed to a textnode yet.
195 : char16_t mText[NS_ACCUMULATION_BUFFER_SIZE];
196 : };
197 :
198 : #endif // nsXMLContentSink_h__
|