1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Communicator client code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #ifndef nsXMLContentSink_h__
39 : #define nsXMLContentSink_h__
40 :
41 : #include "nsContentSink.h"
42 : #include "nsIXMLContentSink.h"
43 : #include "nsIExpatSink.h"
44 : #include "nsIDocumentTransformer.h"
45 : #include "nsTArray.h"
46 : #include "nsCOMPtr.h"
47 : #include "nsCRT.h"
48 : #include "nsCycleCollectionParticipant.h"
49 : #include "nsIDTD.h"
50 : #include "mozilla/dom/FromParser.h"
51 :
52 : class nsIDocument;
53 : class nsIURI;
54 : class nsIContent;
55 : class nsINodeInfo;
56 : class nsIParser;
57 : class nsIViewManager;
58 :
59 : typedef enum {
60 : eXMLContentSinkState_InProlog,
61 : eXMLContentSinkState_InDocumentElement,
62 : eXMLContentSinkState_InEpilog
63 : } XMLContentSinkState;
64 :
65 73508 : struct StackNode {
66 : nsCOMPtr<nsIContent> mContent;
67 : PRUint32 mNumFlushed;
68 : };
69 :
70 : class nsXMLContentSink : public nsContentSink,
71 : public nsIXMLContentSink,
72 : public nsITransformObserver,
73 : public nsIExpatSink
74 : {
75 : public:
76 : nsXMLContentSink();
77 : virtual ~nsXMLContentSink();
78 :
79 4152 : NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
80 :
81 : nsresult Init(nsIDocument* aDoc,
82 : nsIURI* aURL,
83 : nsISupports* aContainer,
84 : nsIChannel* aChannel);
85 :
86 : // nsISupports
87 : NS_DECL_ISUPPORTS_INHERITED
88 :
89 2928 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsXMLContentSink,
90 : nsContentSink)
91 :
92 : NS_DECL_NSIEXPATSINK
93 :
94 : // nsIContentSink
95 : NS_IMETHOD WillParse(void);
96 : NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode);
97 : NS_IMETHOD DidBuildModel(bool aTerminated);
98 : NS_IMETHOD WillInterrupt(void);
99 : NS_IMETHOD WillResume(void);
100 : NS_IMETHOD SetParser(nsParserBase* aParser);
101 : virtual void FlushPendingNotifications(mozFlushType aType);
102 : NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
103 : virtual nsISupports *GetTarget();
104 : virtual bool IsScriptExecuting();
105 : virtual void ContinueInterruptedParsingAsync();
106 :
107 : // nsITransformObserver
108 : NS_IMETHOD OnDocumentCreated(nsIDocument *aResultDocument);
109 : NS_IMETHOD OnTransformDone(nsresult aResult, nsIDocument *aResultDocument);
110 :
111 : // nsICSSLoaderObserver
112 : NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet, bool aWasAlternate,
113 : nsresult aStatus);
114 : static bool ParsePIData(const nsString &aData, nsString &aHref,
115 : nsString &aTitle, nsString &aMedia,
116 : bool &aIsAlternate);
117 :
118 : protected:
119 :
120 : nsIParser* GetParser();
121 :
122 : void ContinueInterruptedParsingIfEnabled();
123 :
124 : // Start layout. If aIgnorePendingSheets is true, this will happen even if
125 : // we still have stylesheet loads pending. Otherwise, we'll wait until the
126 : // stylesheets are all done loading.
127 : virtual void MaybeStartLayout(bool aIgnorePendingSheets);
128 :
129 : virtual nsresult AddAttributes(const PRUnichar** aNode, nsIContent* aContent);
130 : nsresult AddText(const PRUnichar* aString, PRInt32 aLength);
131 :
132 36753 : virtual bool OnOpenContainer(const PRUnichar **aAtts,
133 : PRUint32 aAttsCount,
134 : PRInt32 aNameSpaceID,
135 : nsIAtom* aTagName,
136 36753 : PRUint32 aLineNumber) { return true; }
137 : // Set the given content as the root element for the created document
138 : // don't set if root element was already set.
139 : // return TRUE if this call set the root element
140 : virtual bool SetDocElement(PRInt32 aNameSpaceID,
141 : nsIAtom *aTagName,
142 : nsIContent *aContent);
143 1048 : virtual bool NotifyForDocElement() { return true; }
144 : virtual nsresult CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
145 : nsINodeInfo* aNodeInfo, PRUint32 aLineNumber,
146 : nsIContent** aResult, bool* aAppendContent,
147 : mozilla::dom::FromParser aFromParser);
148 :
149 : // aParent is allowed to be null here if this is the root content
150 : // being closed
151 : virtual nsresult CloseElement(nsIContent* aContent);
152 :
153 : virtual nsresult FlushText(bool aReleaseTextNode = true);
154 :
155 : nsresult AddContentAsLeaf(nsIContent *aContent);
156 :
157 : nsIContent* GetCurrentContent();
158 : StackNode* GetCurrentStackNode();
159 : nsresult PushContent(nsIContent *aContent);
160 : void PopContent();
161 : bool HaveNotifiedForCurrentContent() const;
162 :
163 : nsresult FlushTags();
164 :
165 : void UpdateChildCounts();
166 :
167 75318 : void DidAddContent()
168 : {
169 75318 : if (IsTimeToNotify()) {
170 0 : FlushTags();
171 : }
172 75318 : }
173 :
174 : // nsContentSink override
175 : virtual nsresult ProcessStyleLink(nsIContent* aElement,
176 : const nsSubstring& aHref,
177 : bool aAlternate,
178 : const nsSubstring& aTitle,
179 : const nsSubstring& aType,
180 : const nsSubstring& aMedia);
181 :
182 : nsresult LoadXSLStyleSheet(nsIURI* aUrl);
183 :
184 : bool CanStillPrettyPrint();
185 :
186 : nsresult MaybePrettyPrint();
187 :
188 : bool IsMonolithicContainer(nsINodeInfo* aNodeInfo);
189 :
190 : nsresult HandleStartElement(const PRUnichar *aName, const PRUnichar **aAtts,
191 : PRUint32 aAttsCount, PRInt32 aIndex,
192 : PRUint32 aLineNumber,
193 : bool aInterruptable);
194 : nsresult HandleEndElement(const PRUnichar *aName, bool aInterruptable);
195 : nsresult HandleCharacterData(const PRUnichar *aData, PRUint32 aLength,
196 : bool aInterruptable);
197 :
198 : nsIContent* mDocElement;
199 : nsCOMPtr<nsIContent> mCurrentHead; // When set, we're in an XHTML <haed>
200 : PRUnichar* mText;
201 :
202 : XMLContentSinkState mState;
203 :
204 : PRInt32 mTextLength;
205 : PRInt32 mTextSize;
206 :
207 : PRInt32 mNotifyLevel;
208 : nsCOMPtr<nsIContent> mLastTextNode;
209 : PRInt32 mLastTextNodeSize;
210 :
211 : PRUint8 mConstrainSize : 1;
212 : PRUint8 mPrettyPrintXML : 1;
213 : PRUint8 mPrettyPrintHasSpecialRoot : 1;
214 : PRUint8 mPrettyPrintHasFactoredElements : 1;
215 : PRUint8 mPrettyPrinting : 1; // True if we called PrettyPrint() and it
216 : // decided we should in fact prettyprint.
217 :
218 : nsTArray<StackNode> mContentStack;
219 :
220 : nsCOMPtr<nsIDocumentTransformer> mXSLTProcessor;
221 : };
222 :
223 : #endif // nsXMLContentSink_h__
|