1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "nsHtml5StringParser.h"
6 #include "nsHtml5DependentUTF16Buffer.h"
7 #include "nsHtml5Tokenizer.h"
8 #include "nsHtml5TreeBuilder.h"
9 #include "nsHtml5TreeOpExecutor.h"
10 #include "nsIContent.h"
11 #include "nsIDocument.h"
12 #include "mozilla/dom/DocumentFragment.h"
14 NS_IMPL_ISUPPORTS0(nsHtml5StringParser
)
16 nsHtml5StringParser::nsHtml5StringParser()
17 : mBuilder(new nsHtml5OplessBuilder())
18 , mTreeBuilder(new nsHtml5TreeBuilder(mBuilder
))
19 , mTokenizer(new nsHtml5Tokenizer(mTreeBuilder
, false))
21 mTokenizer
->setInterner(&mAtomTable
);
24 nsHtml5StringParser::~nsHtml5StringParser() {}
27 nsHtml5StringParser::ParseFragment(const nsAString
& aSourceBuffer
,
28 nsIContent
* aTargetNode
,
29 nsAtom
* aContextLocalName
,
30 int32_t aContextNamespace
,
32 bool aPreventScriptExecution
)
34 NS_ENSURE_TRUE(aSourceBuffer
.Length() <= INT32_MAX
, NS_ERROR_OUT_OF_MEMORY
);
36 nsIDocument
* doc
= aTargetNode
->OwnerDoc();
37 nsIURI
* uri
= doc
->GetDocumentURI();
38 NS_ENSURE_TRUE(uri
, NS_ERROR_NOT_AVAILABLE
);
40 mTreeBuilder
->setFragmentContext(
41 aContextLocalName
, aContextNamespace
, aTargetNode
, aQuirks
);
44 if (!aPreventScriptExecution
) {
45 NS_ASSERTION(!aTargetNode
->IsInUncomposedDoc(),
46 "If script execution isn't prevented, "
47 "the target node must not be in doc.");
49 aTargetNode
->NodeType() == nsINode::DOCUMENT_FRAGMENT_NODE
,
50 "If script execution isn't prevented, must parse to DOM fragment.");
54 mTreeBuilder
->SetPreventScriptExecution(aPreventScriptExecution
);
56 return Tokenize(aSourceBuffer
, doc
, true);
60 nsHtml5StringParser::ParseDocument(const nsAString
& aSourceBuffer
,
61 nsIDocument
* aTargetDoc
,
62 bool aScriptingEnabledForNoscriptParsing
)
64 MOZ_ASSERT(!aTargetDoc
->GetFirstChild());
66 NS_ENSURE_TRUE(aSourceBuffer
.Length() <= INT32_MAX
, NS_ERROR_OUT_OF_MEMORY
);
68 mTreeBuilder
->setFragmentContext(nullptr, kNameSpaceID_None
, nullptr, false);
70 mTreeBuilder
->SetPreventScriptExecution(true);
73 aSourceBuffer
, aTargetDoc
, aScriptingEnabledForNoscriptParsing
);
77 nsHtml5StringParser::Tokenize(const nsAString
& aSourceBuffer
,
78 nsIDocument
* aDocument
,
79 bool aScriptingEnabledForNoscriptParsing
)
82 nsIURI
* uri
= aDocument
->GetDocumentURI();
84 mBuilder
->Init(aDocument
, uri
, nullptr, nullptr);
86 mBuilder
->SetParser(this);
87 mBuilder
->SetNodeInfoManager(aDocument
->NodeInfoManager());
89 // Mark the parser as *not* broken by passing NS_OK
90 nsresult rv
= mBuilder
->MarkAsBroken(NS_OK
);
92 mTreeBuilder
->setScriptingEnabled(aScriptingEnabledForNoscriptParsing
);
93 mTreeBuilder
->setIsSrcdocDocument(aDocument
->IsSrcdocDocument());
96 if (!aSourceBuffer
.IsEmpty()) {
97 bool lastWasCR
= false;
98 nsHtml5DependentUTF16Buffer
buffer(aSourceBuffer
);
99 while (buffer
.hasMore()) {
100 buffer
.adjust(lastWasCR
);
102 if (buffer
.hasMore()) {
103 if (!mTokenizer
->EnsureBufferSpace(buffer
.getLength())) {
104 rv
= mBuilder
->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY
);
107 lastWasCR
= mTokenizer
->tokenizeBuffer(&buffer
);
108 if (NS_FAILED(rv
= mBuilder
->IsBroken())) {
114 if (NS_SUCCEEDED(rv
)) {