1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=2 et tw=79: */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is mozilla.org code.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 1998
21 * the Initial Developer. All Rights Reserved.
24 * Pierre Phaneuf <pp@ludusdesign.com>
25 * Henri Sivonen <hsivonen@iki.fi>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #include "nsCompatibility.h"
42 #include "nsScriptLoader.h"
43 #include "nsNetUtil.h"
44 #include "nsIStyleSheetLinkingElement.h"
45 #include "nsICharsetAlias.h"
46 #include "nsIWebShellServices.h"
47 #include "nsIDocShell.h"
48 #include "nsEncoderDecoderUtils.h"
49 #include "nsContentUtils.h"
50 #include "nsICharsetDetector.h"
51 #include "nsIScriptElement.h"
52 #include "nsIMarkupDocumentViewer.h"
53 #include "nsIDocShellTreeItem.h"
54 #include "nsIContentViewer.h"
55 #include "nsIScriptGlobalObjectOwner.h"
56 #include "nsIScriptSecurityManager.h"
57 #include "nsHtml5DocumentMode.h"
58 #include "nsHtml5Tokenizer.h"
59 #include "nsHtml5UTF16Buffer.h"
60 #include "nsHtml5TreeBuilder.h"
61 #include "nsHtml5Parser.h"
62 #include "nsHtml5AtomTable.h"
63 #include "nsIDOMDocumentFragment.h"
65 NS_INTERFACE_TABLE_HEAD(nsHtml5Parser
)
66 NS_INTERFACE_TABLE2(nsHtml5Parser
, nsIParser
, nsISupportsWeakReference
)
67 NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsHtml5Parser
)
70 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHtml5Parser
)
71 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHtml5Parser
)
73 NS_IMPL_CYCLE_COLLECTION_CLASS(nsHtml5Parser
)
75 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsHtml5Parser
)
76 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mExecutor
,
78 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mStreamParser
,
80 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
82 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHtml5Parser
)
83 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mExecutor
)
84 tmp
->DropStreamParser();
85 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
87 nsHtml5Parser::nsHtml5Parser()
88 : mFirstBuffer(new nsHtml5UTF16Buffer(0))
89 , mLastBuffer(mFirstBuffer
)
90 , mExecutor(new nsHtml5TreeOpExecutor())
91 , mTreeBuilder(new nsHtml5TreeBuilder(mExecutor
, nsnull
))
92 , mTokenizer(new nsHtml5Tokenizer(mTreeBuilder
))
93 , mRootContextLineNumber(1)
95 mAtomTable
.Init(); // we aren't checking for OOM anyway...
96 mTokenizer
->setInterner(&mAtomTable
);
97 // There's a zeroing operator new for everything else
100 nsHtml5Parser::~nsHtml5Parser()
103 if (mDocWriteSpeculativeTokenizer
) {
104 mDocWriteSpeculativeTokenizer
->end();
109 nsHtml5Parser::SetContentSink(nsIContentSink
* aSink
)
111 NS_ASSERTION(aSink
== static_cast<nsIContentSink
*> (mExecutor
),
112 "Attempt to set a foreign sink.");
115 NS_IMETHODIMP_(nsIContentSink
*)
116 nsHtml5Parser::GetContentSink()
118 return static_cast<nsIContentSink
*> (mExecutor
);
122 nsHtml5Parser::GetCommand(nsCString
& aCommand
)
124 aCommand
.Assign("view");
128 nsHtml5Parser::SetCommand(const char* aCommand
)
130 NS_ASSERTION(!strcmp(aCommand
, "view"), "Parser command was not view");
134 nsHtml5Parser::SetCommand(eParserCommands aParserCommand
)
136 NS_ASSERTION(aParserCommand
== eViewNormal
,
137 "Parser command was not eViewNormal.");
141 nsHtml5Parser::SetDocumentCharset(const nsACString
& aCharset
,
142 PRInt32 aCharsetSource
)
144 NS_PRECONDITION(!mExecutor
->HasStarted(),
145 "Document charset set too late.");
146 NS_PRECONDITION(mStreamParser
, "Setting charset on a script-only parser.");
147 nsCAutoString trimmed
;
148 trimmed
.Assign(aCharset
);
149 trimmed
.Trim(" \t\r\n\f");
150 mStreamParser
->SetDocumentCharset(trimmed
, aCharsetSource
);
151 mExecutor
->SetDocumentCharsetAndSource(trimmed
,
156 nsHtml5Parser::SetParserFilter(nsIParserFilter
* aFilter
)
158 NS_ERROR("Attempt to set a parser filter on HTML5 parser.");
162 nsHtml5Parser::GetChannel(nsIChannel
** aChannel
)
165 return mStreamParser
->GetChannel(aChannel
);
167 return NS_ERROR_NOT_AVAILABLE
;
172 nsHtml5Parser::GetDTD(nsIDTD
** aDTD
)
179 nsHtml5Parser::GetStreamListener(nsIStreamListener
** aListener
)
181 NS_IF_ADDREF(*aListener
= mStreamParser
);
186 nsHtml5Parser::ContinueInterruptedParsing()
188 NS_NOTREACHED("Don't call. For interface compat only.");
189 return NS_ERROR_NOT_IMPLEMENTED
;
193 nsHtml5Parser::BlockParser()
199 nsHtml5Parser::UnblockParser()
204 NS_IMETHODIMP_(PRBool
)
205 nsHtml5Parser::IsParserEnabled()
210 NS_IMETHODIMP_(PRBool
)
211 nsHtml5Parser::IsComplete()
213 return mExecutor
->IsComplete();
217 nsHtml5Parser::Parse(nsIURI
* aURL
, // legacy parameter; ignored
218 nsIRequestObserver
* aObserver
,
220 nsDTDMode aMode
) // legacy; ignored
223 * Do NOT cause WillBuildModel to be called synchronously from here!
224 * The document won't be ready for it until OnStartRequest!
226 NS_PRECONDITION(!mExecutor
->HasStarted(),
227 "Tried to start parse without initializing the parser.");
228 NS_PRECONDITION(mStreamParser
,
229 "Can't call this Parse() variant on script-created parser");
230 mStreamParser
->SetObserver(aObserver
);
231 mExecutor
->SetStreamParser(mStreamParser
);
232 mExecutor
->SetParser(this);
233 mRootContextKey
= aKey
;
238 nsHtml5Parser::Parse(const nsAString
& aSourceBuffer
,
240 const nsACString
& aContentType
, // ignored
242 nsDTDMode aMode
) // ignored
244 NS_PRECONDITION(!mExecutor
->IsFragmentMode(),
245 "Document.write called in fragment mode!");
247 // Maintain a reference to ourselves so we don't go away
248 // till we're completely done. The old parser grips itself in this method.
249 nsCOMPtr
<nsIParser
> kungFuDeathGrip(this);
251 // Gripping the other objects just in case, since the other old grip
252 // required grips to these, too.
253 nsRefPtr
<nsHtml5StreamParser
> streamKungFuDeathGrip(mStreamParser
);
254 nsRefPtr
<nsHtml5TreeOpExecutor
> treeOpKungFuDeathGrip(mExecutor
);
256 if (!mExecutor
->HasStarted()) {
257 NS_ASSERTION(!mStreamParser
,
258 "Had stream parser but document.write started life cycle.");
259 // This is the first document.write() on a document.open()ed document
260 mExecutor
->SetParser(this);
261 mTreeBuilder
->setScriptingEnabled(mExecutor
->IsScriptEnabled());
265 * If you move the following line, be very careful not to cause
266 * WillBuildModel to be called before the document has had its
267 * script global object set.
269 mExecutor
->WillBuildModel(eDTDMode_unknown
);
272 // Return early if the parser has processed EOF
273 if (mExecutor
->IsComplete()) {
277 if (aLastCall
&& aSourceBuffer
.IsEmpty() && aKey
== GetRootContextKey()) {
279 NS_ASSERTION(!mStreamParser
,
280 "Had stream parser but got document.close().");
281 mDocumentClosed
= PR_TRUE
;
288 NS_ASSERTION(IsInsertionPointDefined(),
289 "Doc.write reached parser with undefined insertion point.");
291 NS_ASSERTION(!(mStreamParser
&& !aKey
),
292 "Got a null key in a non-script-created parser");
294 if (aSourceBuffer
.IsEmpty()) {
298 nsRefPtr
<nsHtml5UTF16Buffer
> buffer
=
299 new nsHtml5UTF16Buffer(aSourceBuffer
.Length());
300 memcpy(buffer
->getBuffer(),
301 aSourceBuffer
.BeginReading(),
302 aSourceBuffer
.Length() * sizeof(PRUnichar
));
303 buffer
->setEnd(aSourceBuffer
.Length());
305 // The buffer is inserted to the stream here in case it won't be parsed
307 // The script is identified by aKey. If there's nothing in the buffer
308 // chain for that key, we'll insert at the head of the queue.
309 // When the script leaves something in the queue, a zero-length
310 // key-holder "buffer" is inserted in the queue. If the same script
311 // leaves something in the chain again, it will be inserted immediately
312 // before the old key holder belonging to the same script.
313 nsHtml5UTF16Buffer
* prevSearchBuf
= nsnull
;
314 nsHtml5UTF16Buffer
* searchBuf
= mFirstBuffer
;
316 // after document.open, the first level of document.write has null key
318 while (searchBuf
!= mLastBuffer
) {
319 if (searchBuf
->key
== aKey
) {
320 // found a key holder
321 // now insert the new buffer between the previous buffer
322 // and the key holder.
323 buffer
->next
= searchBuf
;
325 prevSearchBuf
->next
= buffer
;
327 mFirstBuffer
= buffer
;
331 prevSearchBuf
= searchBuf
;
332 searchBuf
= searchBuf
->next
;
334 if (searchBuf
== mLastBuffer
) {
336 nsHtml5UTF16Buffer
* keyHolder
= new nsHtml5UTF16Buffer(aKey
);
337 keyHolder
->next
= mFirstBuffer
;
338 buffer
->next
= keyHolder
;
339 mFirstBuffer
= buffer
;
342 // we have a first level document.write after document.open()
343 // insert immediately before mLastBuffer
344 while (searchBuf
!= mLastBuffer
) {
345 prevSearchBuf
= searchBuf
;
346 searchBuf
= searchBuf
->next
;
348 buffer
->next
= mLastBuffer
;
350 prevSearchBuf
->next
= buffer
;
352 mFirstBuffer
= buffer
;
356 while (!mBlocked
&& buffer
->hasMore()) {
357 buffer
->adjust(mLastWasCR
);
358 mLastWasCR
= PR_FALSE
;
359 if (buffer
->hasMore()) {
360 PRInt32 lineNumberSave
;
361 PRBool inRootContext
= (!mStreamParser
&& (aKey
== mRootContextKey
));
363 mTokenizer
->setLineNumber(mRootContextLineNumber
);
365 // we aren't the root context, so save the line number on the
366 // *stack* so that we can restore it.
367 lineNumberSave
= mTokenizer
->getLineNumber();
370 mLastWasCR
= mTokenizer
->tokenizeBuffer(buffer
);
373 mRootContextLineNumber
= mTokenizer
->getLineNumber();
375 mTokenizer
->setLineNumber(lineNumberSave
);
378 if (mTreeBuilder
->HasScript()) {
379 mTreeBuilder
->Flush(); // Move ops to the executor
380 mExecutor
->FlushDocumentWrite(); // run the ops
382 // Ignore suspension requests
386 if (!mBlocked
) { // buffer was tokenized to completion
387 NS_ASSERTION(!buffer
->hasMore(), "Buffer wasn't tokenized to completion?");
388 // Scripting semantics require a forced tree builder flush here
389 mTreeBuilder
->Flush(); // Move ops to the executor
390 mExecutor
->FlushDocumentWrite(); // run the ops
391 } else if (buffer
->hasMore()) {
392 // The buffer wasn't tokenized to completion. Tokenize the untokenized
393 // content in order to preload stuff. This content will be retokenized
394 // later for normal parsing.
395 if (!mDocWriteSpeculatorActive
) {
396 mDocWriteSpeculatorActive
= PR_TRUE
;
397 if (!mDocWriteSpeculativeTreeBuilder
) {
398 // Lazily initialize if uninitialized
399 mDocWriteSpeculativeTreeBuilder
=
400 new nsHtml5TreeBuilder(nsnull
, mExecutor
->GetStage());
401 mDocWriteSpeculativeTokenizer
=
402 new nsHtml5Tokenizer(mDocWriteSpeculativeTreeBuilder
);
403 mDocWriteSpeculativeTokenizer
->setInterner(&mAtomTable
);
404 mDocWriteSpeculativeTokenizer
->start();
406 mDocWriteSpeculativeTokenizer
->resetToDataState();
407 mDocWriteSpeculativeTreeBuilder
->loadState(mTreeBuilder
, &mAtomTable
);
408 mDocWriteSpeculativeLastWasCR
= PR_FALSE
;
411 // Note that with multilevel document.write if we didn't just activate the
412 // speculator, it's possible that the speculator is now in the wrong state.
413 // That's OK for the sake of simplicity. The worst that can happen is
414 // that the speculative loads aren't exactly right. The content will be
415 // reparsed anyway for non-preload purposes.
417 PRInt32 originalStart
= buffer
->getStart();
418 while (buffer
->hasMore()) {
419 buffer
->adjust(mDocWriteSpeculativeLastWasCR
);
420 if (buffer
->hasMore()) {
421 mDocWriteSpeculativeLastWasCR
=
422 mDocWriteSpeculativeTokenizer
->tokenizeBuffer(buffer
);
425 buffer
->setStart(originalStart
);
427 mDocWriteSpeculativeTreeBuilder
->Flush();
428 mDocWriteSpeculativeTreeBuilder
->DropHandles();
429 mExecutor
->FlushSpeculativeLoads();
436 * This magic value is passed to the previous method on document.close()
438 NS_IMETHODIMP_(void *)
439 nsHtml5Parser::GetRootContextKey()
441 return mRootContextKey
;
445 nsHtml5Parser::Terminate()
447 // We should only call DidBuildModel once, so don't do anything if this is
448 // the second time that Terminate has been called.
449 if (mExecutor
->IsComplete()) {
452 // XXX - [ until we figure out a way to break parser-sink circularity ]
453 // Hack - Hold a reference until we are completely done...
454 nsCOMPtr
<nsIParser
> kungFuDeathGrip(this);
455 nsRefPtr
<nsHtml5StreamParser
> streamKungFuDeathGrip(mStreamParser
);
456 nsRefPtr
<nsHtml5TreeOpExecutor
> treeOpKungFuDeathGrip(mExecutor
);
458 mStreamParser
->Terminate();
460 return mExecutor
->DidBuildModel(PR_TRUE
);
464 nsHtml5Parser::ParseFragment(const nsAString
& aSourceBuffer
,
466 nsTArray
<nsString
>& aTagStack
,
468 const nsACString
& aContentType
,
471 return NS_ERROR_NOT_IMPLEMENTED
;
475 nsHtml5Parser::ParseFragment(const nsAString
& aSourceBuffer
,
476 nsIContent
* aTargetNode
,
477 nsIAtom
* aContextLocalName
,
478 PRInt32 aContextNamespace
,
481 return NS_ERROR_NOT_IMPLEMENTED
;
485 nsHtml5Parser::ParseHtml5Fragment(const nsAString
& aSourceBuffer
,
486 nsIContent
* aTargetNode
,
487 nsIAtom
* aContextLocalName
,
488 PRInt32 aContextNamespace
,
490 PRBool aPreventScriptExecution
)
492 nsIDocument
* doc
= aTargetNode
->GetOwnerDoc();
493 NS_ENSURE_TRUE(doc
, NS_ERROR_NOT_AVAILABLE
);
495 nsIURI
* uri
= doc
->GetDocumentURI();
496 NS_ENSURE_TRUE(uri
, NS_ERROR_NOT_AVAILABLE
);
498 Initialize(doc
, uri
, nsnull
, nsnull
);
500 mExecutor
->SetParser(this);
501 mExecutor
->SetNodeInfoManager(doc
->NodeInfoManager());
503 nsIContent
* target
= aTargetNode
;
504 mTreeBuilder
->setFragmentContext(aContextLocalName
,
510 if (!aPreventScriptExecution
) {
511 nsCOMPtr
<nsIDOMDocumentFragment
> domFrag
= do_QueryInterface(aTargetNode
);
512 NS_ASSERTION(domFrag
,
513 "If script execution isn't prevented, must parse to DOM fragment.");
517 mExecutor
->EnableFragmentMode(aPreventScriptExecution
);
519 NS_PRECONDITION(!mExecutor
->HasStarted(),
520 "Tried to start parse without initializing the parser.");
521 mTreeBuilder
->setScriptingEnabled(mExecutor
->IsScriptEnabled());
523 mExecutor
->Start(); // Don't call WillBuildModel in fragment case
524 if (!aSourceBuffer
.IsEmpty()) {
525 PRBool lastWasCR
= PR_FALSE
;
526 nsHtml5UTF16Buffer
buffer(aSourceBuffer
.Length());
527 memcpy(buffer
.getBuffer(),
528 aSourceBuffer
.BeginReading(),
529 aSourceBuffer
.Length() * sizeof(PRUnichar
));
530 buffer
.setEnd(aSourceBuffer
.Length());
531 while (buffer
.hasMore()) {
532 buffer
.adjust(lastWasCR
);
533 lastWasCR
= PR_FALSE
;
534 if (buffer
.hasMore()) {
535 lastWasCR
= mTokenizer
->tokenizeBuffer(&buffer
);
540 mTreeBuilder
->StreamEnded();
541 mTreeBuilder
->Flush();
542 mExecutor
->FlushDocumentWrite();
544 mExecutor
->DropParserAndPerfHint();
545 mExecutor
->DropHeldElements();
546 mTreeBuilder
->DropHandles();
552 nsHtml5Parser::BuildModel()
554 NS_NOTREACHED("Don't call this!");
555 return NS_ERROR_NOT_IMPLEMENTED
;
559 nsHtml5Parser::CancelParsingEvents()
561 NS_NOTREACHED("Don't call this!");
562 return NS_ERROR_NOT_IMPLEMENTED
;
566 nsHtml5Parser::Reset()
568 NS_PRECONDITION(mExecutor
->IsFragmentMode(),
569 "Reset called on a non-fragment parser.");
571 mLastWasCR
= PR_FALSE
;
573 mDocumentClosed
= PR_FALSE
;
574 mStreamParser
= nsnull
;
575 mRootContextLineNumber
= 1;
576 mParserInsertedScriptsBeingEvaluated
= 0;
577 mRootContextKey
= nsnull
;
578 mAtomTable
.Clear(); // should be already cleared in the fragment case anyway
579 // Portable parser objects
580 mFirstBuffer
->next
= nsnull
;
581 mFirstBuffer
->setStart(0);
582 mFirstBuffer
->setEnd(0);
583 mLastBuffer
= mFirstBuffer
;
587 nsHtml5Parser::CanInterrupt()
589 // nsContentSink needs this to let nsContentSink::DidProcessATokenImpl
595 nsHtml5Parser::IsInsertionPointDefined()
597 return !mExecutor
->IsFlushing() &&
598 (!mStreamParser
|| mParserInsertedScriptsBeingEvaluated
);
602 nsHtml5Parser::BeginEvaluatingParserInsertedScript()
604 ++mParserInsertedScriptsBeingEvaluated
;
608 nsHtml5Parser::EndEvaluatingParserInsertedScript()
610 --mParserInsertedScriptsBeingEvaluated
;
614 nsHtml5Parser::MarkAsNotScriptCreated()
616 NS_PRECONDITION(!mStreamParser
, "Must not call this twice.");
617 mStreamParser
= new nsHtml5StreamParser(mExecutor
, this);
621 nsHtml5Parser::IsScriptCreated()
623 return !mStreamParser
;
628 // not from interface
630 nsHtml5Parser::ParseUntilBlocked()
632 NS_PRECONDITION(!mExecutor
->IsFragmentMode(),
633 "ParseUntilBlocked called in fragment mode.");
639 if (mExecutor
->IsComplete()) {
642 NS_ASSERTION(mExecutor
->HasStarted(), "Bad life cycle.");
644 mDocWriteSpeculatorActive
= PR_FALSE
;
647 if (!mFirstBuffer
->hasMore()) {
648 if (mFirstBuffer
== mLastBuffer
) {
649 if (mExecutor
->IsComplete()) {
650 // something like cache manisfests stopped the parse in mid-flight
653 if (mDocumentClosed
) {
654 NS_ASSERTION(!mStreamParser
,
655 "This should only happen with script-created parser.");
657 mTreeBuilder
->StreamEnded();
658 mTreeBuilder
->Flush();
659 mExecutor
->FlushDocumentWrite();
663 // never release the last buffer.
664 NS_ASSERTION(!mLastBuffer
->getStart() && !mLastBuffer
->getEnd(),
665 "Sentinel buffer had its indeces changed.");
667 if (mReturnToStreamParserPermitted
&&
668 !mExecutor
->IsScriptExecuting()) {
669 mTreeBuilder
->Flush();
670 mReturnToStreamParserPermitted
= PR_FALSE
;
671 mStreamParser
->ContinueAfterScripts(mTokenizer
,
676 // Script-created parser
677 mTreeBuilder
->Flush();
678 // No need to flush the executor, because the executor is already
680 NS_ASSERTION(mExecutor
->IsInFlushLoop(),
681 "How did we come here without being in the flush loop?");
683 return; // no more data for now but expecting more
685 mFirstBuffer
= mFirstBuffer
->next
;
689 if (mBlocked
|| mExecutor
->IsComplete()) {
693 // now we have a non-empty buffer
694 mFirstBuffer
->adjust(mLastWasCR
);
695 mLastWasCR
= PR_FALSE
;
696 if (mFirstBuffer
->hasMore()) {
697 PRBool inRootContext
= (!mStreamParser
&&
698 (mFirstBuffer
->key
== mRootContextKey
));
700 mTokenizer
->setLineNumber(mRootContextLineNumber
);
702 mLastWasCR
= mTokenizer
->tokenizeBuffer(mFirstBuffer
);
704 mRootContextLineNumber
= mTokenizer
->getLineNumber();
706 if (mTreeBuilder
->HasScript()) {
707 mTreeBuilder
->Flush();
708 mExecutor
->FlushDocumentWrite();
719 nsHtml5Parser::Initialize(nsIDocument
* aDoc
,
721 nsISupports
* aContainer
,
722 nsIChannel
* aChannel
)
724 return mExecutor
->Init(aDoc
, aURI
, aContainer
, aChannel
);
728 nsHtml5Parser::StartTokenizer(PRBool aScriptingEnabled
) {
729 mTreeBuilder
->setScriptingEnabled(aScriptingEnabled
);
734 nsHtml5Parser::InitializeDocWriteParserState(nsAHtml5TreeBuilderState
* aState
,
737 mTokenizer
->resetToDataState();
738 mTokenizer
->setLineNumber(aLine
);
739 mTreeBuilder
->loadState(aState
, &mAtomTable
);
740 mLastWasCR
= PR_FALSE
;
741 mReturnToStreamParserPermitted
= PR_TRUE
;
745 nsHtml5Parser::ContinueAfterFailedCharsetSwitch()
747 NS_PRECONDITION(mStreamParser
,
748 "Tried to continue after failed charset switch without a stream parser");
749 mStreamParser
->ContinueAfterFailedCharsetSwitch();