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 "mozilla/dom/Document.h"
12 #include "mozilla/dom/DocumentFragment.h"
14 using mozilla::dom::Document
;
16 NS_IMPL_ISUPPORTS0(nsHtml5StringParser
)
18 nsHtml5StringParser::nsHtml5StringParser()
19 : mBuilder(new nsHtml5OplessBuilder()),
20 mTreeBuilder(new nsHtml5TreeBuilder(mBuilder
)),
21 mTokenizer(new nsHtml5Tokenizer(mTreeBuilder
.get(), false)) {
22 mTokenizer
->setInterner(&mAtomTable
);
25 nsHtml5StringParser::~nsHtml5StringParser() {}
27 nsresult
nsHtml5StringParser::ParseFragment(const nsAString
& aSourceBuffer
,
28 nsIContent
* aTargetNode
,
29 nsAtom
* aContextLocalName
,
30 int32_t aContextNamespace
,
32 bool aPreventScriptExecution
) {
33 NS_ENSURE_TRUE(aSourceBuffer
.Length() <= INT32_MAX
, NS_ERROR_OUT_OF_MEMORY
);
35 Document
* doc
= aTargetNode
->OwnerDoc();
36 nsIURI
* uri
= doc
->GetDocumentURI();
37 NS_ENSURE_TRUE(uri
, NS_ERROR_NOT_AVAILABLE
);
39 mTreeBuilder
->setFragmentContext(aContextLocalName
, aContextNamespace
,
40 aTargetNode
, aQuirks
);
43 if (!aPreventScriptExecution
) {
44 NS_ASSERTION(!aTargetNode
->IsInUncomposedDoc(),
45 "If script execution isn't prevented, "
46 "the target node must not be in doc.");
48 aTargetNode
->NodeType() == nsINode::DOCUMENT_FRAGMENT_NODE
,
49 "If script execution isn't prevented, must parse to DOM fragment.");
53 mTreeBuilder
->SetPreventScriptExecution(aPreventScriptExecution
);
55 return Tokenize(aSourceBuffer
, doc
, true);
58 nsresult
nsHtml5StringParser::ParseDocument(
59 const nsAString
& aSourceBuffer
, Document
* aTargetDoc
,
60 bool aScriptingEnabledForNoscriptParsing
) {
61 MOZ_ASSERT(!aTargetDoc
->GetFirstChild());
63 NS_ENSURE_TRUE(aSourceBuffer
.Length() <= INT32_MAX
, NS_ERROR_OUT_OF_MEMORY
);
65 mTreeBuilder
->setFragmentContext(nullptr, kNameSpaceID_None
, nullptr, false);
67 mTreeBuilder
->SetPreventScriptExecution(true);
69 return Tokenize(aSourceBuffer
, aTargetDoc
,
70 aScriptingEnabledForNoscriptParsing
);
73 nsresult
nsHtml5StringParser::Tokenize(
74 const nsAString
& aSourceBuffer
, Document
* aDocument
,
75 bool aScriptingEnabledForNoscriptParsing
) {
76 nsIURI
* uri
= aDocument
->GetDocumentURI();
78 mBuilder
->Init(aDocument
, uri
, nullptr, nullptr);
80 mBuilder
->SetParser(this);
81 mBuilder
->SetNodeInfoManager(aDocument
->NodeInfoManager());
83 // Mark the parser as *not* broken by passing NS_OK
84 nsresult rv
= mBuilder
->MarkAsBroken(NS_OK
);
86 mTreeBuilder
->setScriptingEnabled(aScriptingEnabledForNoscriptParsing
);
87 mTreeBuilder
->setIsSrcdocDocument(aDocument
->IsSrcdocDocument());
90 if (!aSourceBuffer
.IsEmpty()) {
91 bool lastWasCR
= false;
92 nsHtml5DependentUTF16Buffer
buffer(aSourceBuffer
);
93 while (buffer
.hasMore()) {
94 buffer
.adjust(lastWasCR
);
96 if (buffer
.hasMore()) {
97 if (!mTokenizer
->EnsureBufferSpace(buffer
.getLength())) {
98 rv
= mBuilder
->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY
);
101 lastWasCR
= mTokenizer
->tokenizeBuffer(&buffer
);
102 if (NS_FAILED(rv
= mBuilder
->IsBroken())) {
108 if (NS_SUCCEEDED(rv
)) {