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