1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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.org 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 : * Henri Sivonen <hsivonen@iki.fi>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef NS_HTML5_PARSER__
40 : #define NS_HTML5_PARSER__
41 :
42 : #include "nsAutoPtr.h"
43 : #include "nsIParser.h"
44 : #include "nsDeque.h"
45 : #include "nsIURL.h"
46 : #include "nsParserCIID.h"
47 : #include "nsITokenizer.h"
48 : #include "nsThreadUtils.h"
49 : #include "nsIContentSink.h"
50 : #include "nsIRequest.h"
51 : #include "nsIChannel.h"
52 : #include "nsCOMArray.h"
53 : #include "nsContentSink.h"
54 : #include "nsIHTMLDocument.h"
55 : #include "nsCycleCollectionParticipant.h"
56 : #include "nsIInputStream.h"
57 : #include "nsDetectionConfident.h"
58 : #include "nsHtml5OwningUTF16Buffer.h"
59 : #include "nsHtml5TreeOpExecutor.h"
60 : #include "nsHtml5StreamParser.h"
61 : #include "nsHtml5AtomTable.h"
62 : #include "nsWeakReference.h"
63 :
64 : class nsHtml5Parser : public nsIParser,
65 : public nsSupportsWeakReference
66 : {
67 : public:
68 0 : NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
69 0 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
70 :
71 1464 : NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHtml5Parser, nsIParser)
72 :
73 : nsHtml5Parser();
74 : virtual ~nsHtml5Parser();
75 :
76 : /* Start nsIParser */
77 : /**
78 : * No-op for backwards compat.
79 : */
80 : NS_IMETHOD_(void) SetContentSink(nsIContentSink* aSink);
81 :
82 : /**
83 : * Returns the tree op executor for backwards compat.
84 : */
85 : NS_IMETHOD_(nsIContentSink*) GetContentSink();
86 :
87 : /**
88 : * Always returns "view" for backwards compat.
89 : */
90 : NS_IMETHOD_(void) GetCommand(nsCString& aCommand);
91 :
92 : /**
93 : * No-op for backwards compat.
94 : */
95 : NS_IMETHOD_(void) SetCommand(const char* aCommand);
96 :
97 : /**
98 : * No-op for backwards compat.
99 : */
100 : NS_IMETHOD_(void) SetCommand(eParserCommands aParserCommand);
101 :
102 : /**
103 : * Call this method once you've created a parser, and want to instruct it
104 : * about what charset to load
105 : *
106 : * @param aCharset the charset of a document
107 : * @param aCharsetSource the source of the charset
108 : */
109 : NS_IMETHOD_(void) SetDocumentCharset(const nsACString& aCharset, PRInt32 aSource);
110 :
111 : /**
112 : * Don't call. For interface compat only.
113 : */
114 0 : NS_IMETHOD_(void) GetDocumentCharset(nsACString& aCharset, PRInt32& aSource)
115 : {
116 0 : NS_NOTREACHED("No one should call this.");
117 0 : }
118 :
119 : /**
120 : * Get the channel associated with this parser
121 : * @param aChannel out param that will contain the result
122 : * @return NS_OK if successful or NS_NOT_AVAILABLE if not
123 : */
124 : NS_IMETHOD GetChannel(nsIChannel** aChannel);
125 :
126 : /**
127 : * Return |this| for backwards compat.
128 : */
129 : NS_IMETHOD GetDTD(nsIDTD** aDTD);
130 :
131 : /**
132 : * Get the stream parser for this parser
133 : */
134 : virtual nsIStreamListener* GetStreamListener();
135 :
136 : /**
137 : * Don't call. For interface compat only.
138 : */
139 : NS_IMETHOD ContinueInterruptedParsing();
140 :
141 : /**
142 : * Blocks the parser.
143 : */
144 : NS_IMETHOD_(void) BlockParser();
145 :
146 : /**
147 : * Unblocks the parser.
148 : */
149 : NS_IMETHOD_(void) UnblockParser();
150 :
151 : /**
152 : * Asynchronously continues parsing.
153 : */
154 : NS_IMETHOD_(void) ContinueInterruptedParsingAsync();
155 :
156 : /**
157 : * Query whether the parser is enabled (i.e. not blocked) or not.
158 : */
159 : NS_IMETHOD_(bool) IsParserEnabled();
160 :
161 : /**
162 : * Query whether the parser thinks it's done with parsing.
163 : */
164 : NS_IMETHOD_(bool) IsComplete();
165 :
166 : /**
167 : * Set up request observer.
168 : *
169 : * @param aURL used for View Source title
170 : * @param aListener a listener to forward notifications to
171 : * @param aKey the root context key (used for document.write)
172 : * @param aMode ignored (for interface compat only)
173 : */
174 : NS_IMETHOD Parse(nsIURI* aURL,
175 : nsIRequestObserver* aListener = nsnull,
176 : void* aKey = 0,
177 : nsDTDMode aMode = eDTDMode_autodetect);
178 :
179 : /**
180 : * document.write and document.close
181 : *
182 : * @param aSourceBuffer the argument of document.write (empty for .close())
183 : * @param aKey a key unique to the script element that caused this call
184 : * @param aContentType "text/html" for HTML mode, else text/plain mode
185 : * @param aLastCall true if .close() false if .write()
186 : * @param aMode ignored (for interface compat only)
187 : */
188 : NS_IMETHOD Parse(const nsAString& aSourceBuffer,
189 : void* aKey,
190 : const nsACString& aContentType,
191 : bool aLastCall,
192 : nsDTDMode aMode = eDTDMode_autodetect);
193 :
194 : /**
195 : * Stops the parser prematurely
196 : */
197 : NS_IMETHOD Terminate();
198 :
199 : /**
200 : * Don't call. For interface backwards compat only.
201 : */
202 : NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer,
203 : nsTArray<nsString>& aTagStack);
204 :
205 : /**
206 : * Don't call. For interface compat only.
207 : */
208 : NS_IMETHOD BuildModel();
209 :
210 : /**
211 : * Don't call. For interface compat only.
212 : */
213 : NS_IMETHODIMP CancelParsingEvents();
214 :
215 : /**
216 : * Don't call. For interface compat only.
217 : */
218 : virtual void Reset();
219 :
220 : /**
221 : * True in fragment mode and during synchronous document.write
222 : */
223 : virtual bool CanInterrupt();
224 :
225 : /**
226 : * True if the insertion point (per HTML5) is defined.
227 : */
228 : virtual bool IsInsertionPointDefined();
229 :
230 : /**
231 : * Call immediately before starting to evaluate a parser-inserted script.
232 : */
233 : virtual void BeginEvaluatingParserInsertedScript();
234 :
235 : /**
236 : * Call immediately after having evaluated a parser-inserted script.
237 : */
238 : virtual void EndEvaluatingParserInsertedScript();
239 :
240 : /**
241 : * Marks the HTML5 parser as not a script-created parser: Prepares the
242 : * parser to be able to read a stream.
243 : *
244 : * @param aCommand the parser command (Yeah, this is bad API design. Let's
245 : * make this better when retiring nsIParser)
246 : */
247 : virtual void MarkAsNotScriptCreated(const char* aCommand);
248 :
249 : /**
250 : * True if this is a script-created HTML5 parser.
251 : */
252 : virtual bool IsScriptCreated();
253 :
254 : /* End nsIParser */
255 :
256 : // Not from an external interface
257 : // Non-inherited methods
258 :
259 : public:
260 :
261 : /**
262 : * Initializes the parser to load from a channel.
263 : */
264 : virtual nsresult Initialize(nsIDocument* aDoc,
265 : nsIURI* aURI,
266 : nsISupports* aContainer,
267 : nsIChannel* aChannel);
268 :
269 : inline nsHtml5Tokenizer* GetTokenizer() {
270 : return mTokenizer;
271 : }
272 :
273 : void InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState, PRInt32 aLine);
274 :
275 0 : void DropStreamParser() {
276 0 : if (mStreamParser) {
277 0 : mStreamParser->DropTimer();
278 0 : mStreamParser = nsnull;
279 : }
280 0 : }
281 :
282 : void StartTokenizer(bool aScriptingEnabled);
283 :
284 : void ContinueAfterFailedCharsetSwitch();
285 :
286 0 : nsHtml5StreamParser* GetStreamParser() {
287 0 : return mStreamParser;
288 : }
289 :
290 : /**
291 : * Parse until pending data is exhausted or a script blocks the parser
292 : */
293 : void ParseUntilBlocked();
294 :
295 : private:
296 :
297 : // State variables
298 :
299 : /**
300 : * Whether the last character tokenized was a carriage return (for CRLF)
301 : */
302 : bool mLastWasCR;
303 :
304 : /**
305 : * Whether the last character tokenized was a carriage return (for CRLF)
306 : * when preparsing document.write.
307 : */
308 : bool mDocWriteSpeculativeLastWasCR;
309 :
310 : /**
311 : * The parser is in the fragment mode
312 : */
313 : bool mFragmentMode;
314 :
315 : /**
316 : * The parser is blocking on a script
317 : */
318 : bool mBlocked;
319 :
320 : /**
321 : * Whether the document.write() speculator is already active.
322 : */
323 : bool mDocWriteSpeculatorActive;
324 :
325 : /**
326 : * The number of parser-inserted script currently being evaluated.
327 : */
328 : PRInt32 mParserInsertedScriptsBeingEvaluated;
329 :
330 : /**
331 : * True if document.close() has been called.
332 : */
333 : bool mDocumentClosed;
334 :
335 : bool mInDocumentWrite;
336 :
337 : // Gecko integration
338 : void* mRootContextKey;
339 :
340 : // Portable parser objects
341 : /**
342 : * The first buffer in the pending UTF-16 buffer queue
343 : */
344 : nsRefPtr<nsHtml5OwningUTF16Buffer> mFirstBuffer;
345 :
346 : /**
347 : * The last buffer in the pending UTF-16 buffer queue. Always points
348 : * to a sentinel object with nsnull as its parser key.
349 : */
350 : nsHtml5OwningUTF16Buffer* mLastBuffer; // weak ref;
351 :
352 : /**
353 : * The tree operation executor
354 : */
355 : nsRefPtr<nsHtml5TreeOpExecutor> mExecutor;
356 :
357 : /**
358 : * The HTML5 tree builder
359 : */
360 : const nsAutoPtr<nsHtml5TreeBuilder> mTreeBuilder;
361 :
362 : /**
363 : * The HTML5 tokenizer
364 : */
365 : const nsAutoPtr<nsHtml5Tokenizer> mTokenizer;
366 :
367 : /**
368 : * Another HTML5 tree builder for preloading document.written content.
369 : */
370 : nsAutoPtr<nsHtml5TreeBuilder> mDocWriteSpeculativeTreeBuilder;
371 :
372 : /**
373 : * Another HTML5 tokenizer for preloading document.written content.
374 : */
375 : nsAutoPtr<nsHtml5Tokenizer> mDocWriteSpeculativeTokenizer;
376 :
377 : /**
378 : * The stream parser.
379 : */
380 : nsRefPtr<nsHtml5StreamParser> mStreamParser;
381 :
382 : /**
383 : *
384 : */
385 : PRInt32 mRootContextLineNumber;
386 :
387 : /**
388 : * Whether it's OK to transfer parsing back to the stream parser
389 : */
390 : bool mReturnToStreamParserPermitted;
391 :
392 : /**
393 : * The scoped atom table
394 : */
395 : nsHtml5AtomTable mAtomTable;
396 :
397 : };
398 : #endif
|