1 : /* ***** BEGIN LICENSE BLOCK *****
2 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 : *
4 : * The contents of this file are subject to the Mozilla Public License Version
5 : * 1.1 (the "License"); you may not use this file except in compliance with
6 : * the License. You may obtain a copy of the License at
7 : * http://www.mozilla.org/MPL/
8 : *
9 : * Software distributed under the License is distributed on an "AS IS" basis,
10 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 : * for the specific language governing rights and limitations under the
12 : * License.
13 : *
14 : * The Original Code is mozilla.org code.
15 : *
16 : * The Initial Developer of the Original Code is
17 : * Netscape Communications Corporation.
18 : * Portions created by the Initial Developer are Copyright (C) 1998
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Pierre Phaneuf <pp@ludusdesign.com>
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 : #include "nsHtml5StringParser.h"
40 : #include "nsHtml5TreeOpExecutor.h"
41 : #include "nsHtml5TreeBuilder.h"
42 : #include "nsHtml5Tokenizer.h"
43 : #include "nsIContent.h"
44 : #include "nsIDocument.h"
45 : #include "nsIDOMDocumentFragment.h"
46 : #include "nsHtml5DependentUTF16Buffer.h"
47 :
48 960 : NS_IMPL_ISUPPORTS0(nsHtml5StringParser)
49 :
50 12 : nsHtml5StringParser::nsHtml5StringParser()
51 12 : : mExecutor(new nsHtml5TreeOpExecutor(true))
52 24 : , mTreeBuilder(new nsHtml5TreeBuilder(mExecutor, nsnull))
53 72 : , mTokenizer(new nsHtml5Tokenizer(mTreeBuilder, false))
54 : {
55 12 : MOZ_COUNT_CTOR(nsHtml5StringParser);
56 12 : mAtomTable.Init(); // we aren't checking for OOM anyway...
57 12 : mTokenizer->setInterner(&mAtomTable);
58 12 : }
59 :
60 36 : nsHtml5StringParser::~nsHtml5StringParser()
61 : {
62 12 : MOZ_COUNT_DTOR(nsHtml5StringParser);
63 48 : }
64 :
65 : nsresult
66 0 : nsHtml5StringParser::ParseFragment(const nsAString& aSourceBuffer,
67 : nsIContent* aTargetNode,
68 : nsIAtom* aContextLocalName,
69 : PRInt32 aContextNamespace,
70 : bool aQuirks,
71 : bool aPreventScriptExecution)
72 : {
73 0 : NS_ENSURE_TRUE(aSourceBuffer.Length() <= PR_INT32_MAX,
74 : NS_ERROR_OUT_OF_MEMORY);
75 :
76 0 : nsIDocument* doc = aTargetNode->OwnerDoc();
77 0 : nsIURI* uri = doc->GetDocumentURI();
78 0 : NS_ENSURE_TRUE(uri, NS_ERROR_NOT_AVAILABLE);
79 :
80 0 : nsIContent* target = aTargetNode;
81 : mTreeBuilder->setFragmentContext(aContextLocalName,
82 : aContextNamespace,
83 : &target,
84 0 : aQuirks);
85 :
86 : #ifdef DEBUG
87 0 : if (!aPreventScriptExecution) {
88 0 : NS_ASSERTION(!aTargetNode->IsInDoc(),
89 : "If script execution isn't prevented, "
90 : "the target node must not be in doc.");
91 0 : nsCOMPtr<nsIDOMDocumentFragment> domFrag = do_QueryInterface(aTargetNode);
92 0 : NS_ASSERTION(domFrag,
93 : "If script execution isn't prevented, must parse to DOM fragment.");
94 : }
95 : #endif
96 :
97 0 : mExecutor->EnableFragmentMode(aPreventScriptExecution);
98 :
99 0 : Tokenize(aSourceBuffer, doc, true);
100 0 : return NS_OK;
101 : }
102 :
103 : nsresult
104 234 : nsHtml5StringParser::ParseDocument(const nsAString& aSourceBuffer,
105 : nsIDocument* aTargetDoc,
106 : bool aScriptingEnabledForNoscriptParsing)
107 : {
108 234 : MOZ_ASSERT(!aTargetDoc->GetFirstChild());
109 :
110 234 : NS_ENSURE_TRUE(aSourceBuffer.Length() <= PR_INT32_MAX,
111 : NS_ERROR_OUT_OF_MEMORY);
112 :
113 : mTreeBuilder->setFragmentContext(nsnull,
114 : kNameSpaceID_None,
115 : nsnull,
116 234 : false);
117 :
118 234 : mExecutor->PreventScriptExecution();
119 :
120 234 : Tokenize(aSourceBuffer, aTargetDoc, aScriptingEnabledForNoscriptParsing);
121 234 : return NS_OK;
122 : }
123 :
124 : void
125 234 : nsHtml5StringParser::Tokenize(const nsAString& aSourceBuffer,
126 : nsIDocument* aDocument,
127 : bool aScriptingEnabledForNoscriptParsing) {
128 :
129 234 : nsIURI* uri = aDocument->GetDocumentURI();
130 :
131 234 : mExecutor->Init(aDocument, uri, nsnull, nsnull);
132 :
133 234 : mExecutor->SetParser(this);
134 234 : mExecutor->SetNodeInfoManager(aDocument->NodeInfoManager());
135 :
136 234 : NS_PRECONDITION(!mExecutor->HasStarted(),
137 : "Tried to start parse without initializing the parser.");
138 234 : mTreeBuilder->setScriptingEnabled(aScriptingEnabledForNoscriptParsing);
139 234 : mTokenizer->start();
140 234 : mExecutor->Start(); // Don't call WillBuildModel in fragment case
141 234 : if (!aSourceBuffer.IsEmpty()) {
142 234 : bool lastWasCR = false;
143 468 : nsHtml5DependentUTF16Buffer buffer(aSourceBuffer);
144 702 : while (buffer.hasMore()) {
145 234 : buffer.adjust(lastWasCR);
146 234 : lastWasCR = false;
147 234 : if (buffer.hasMore()) {
148 234 : lastWasCR = mTokenizer->tokenizeBuffer(&buffer);
149 234 : if (mTreeBuilder->HasScript()) {
150 : // Flush on each script, because the execution prevention code
151 : // can handle at most one script per flush.
152 0 : mTreeBuilder->Flush(); // Move ops to the executor
153 0 : mExecutor->FlushDocumentWrite(); // run the ops
154 : }
155 : }
156 : }
157 : }
158 234 : mTokenizer->eof();
159 234 : mTreeBuilder->StreamEnded();
160 234 : mTreeBuilder->Flush();
161 234 : mExecutor->FlushDocumentWrite();
162 234 : mTokenizer->end();
163 234 : mExecutor->DropParserAndPerfHint();
164 234 : mExecutor->DropHeldElements();
165 234 : mTreeBuilder->DropHandles();
166 234 : mAtomTable.Clear();
167 234 : mExecutor->Reset();
168 234 : }
|