1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=2 sw=2 et tw=78: */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
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/
10 : *
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
14 : * License.
15 : *
16 : * The Original Code is Mozilla Communicator client code.
17 : *
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.
22 : *
23 : * Contributor(s):
24 : * Pierre Phaneuf <pp@ludusdesign.com>
25 : * Henri Sivonen <hsivonen@iki.fi>
26 : *
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.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : #include "nsContentErrors.h"
42 : #include "nsIPresShell.h"
43 : #include "nsEvent.h"
44 : #include "nsGUIEvent.h"
45 : #include "nsEventDispatcher.h"
46 : #include "nsContentUtils.h"
47 : #include "nsNodeUtils.h"
48 :
49 : #define NS_HTML5_TREE_DEPTH_LIMIT 200
50 :
51 : class nsPresContext;
52 :
53 12 : nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
54 : nsHtml5TreeOpStage* aStage)
55 : : scriptingEnabled(false)
56 : , fragment(false)
57 : , contextNode(nsnull)
58 : , formPointer(nsnull)
59 : , headPointer(nsnull)
60 : , mViewSource(nsnull)
61 : , mOpSink(aOpSink)
62 12 : , mHandles(new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH])
63 : , mHandlesUsed(0)
64 : , mSpeculativeLoadStage(aStage)
65 : , mCurrentHtmlScriptIsAsyncOrDefer(false)
66 : #ifdef DEBUG
67 24 : , mActive(false)
68 : #endif
69 : {
70 12 : MOZ_COUNT_CTOR(nsHtml5TreeBuilder);
71 12 : }
72 :
73 36 : nsHtml5TreeBuilder::~nsHtml5TreeBuilder()
74 : {
75 12 : MOZ_COUNT_DTOR(nsHtml5TreeBuilder);
76 12 : NS_ASSERTION(!mActive, "nsHtml5TreeBuilder deleted without ever calling end() on it!");
77 12 : mOpQueue.Clear();
78 48 : }
79 :
80 : nsIContent**
81 780 : nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes)
82 : {
83 780 : NS_PRECONDITION(aAttributes, "Got null attributes.");
84 780 : NS_PRECONDITION(aName, "Got null name.");
85 780 : NS_PRECONDITION(aNamespace == kNameSpaceID_XHTML ||
86 : aNamespace == kNameSpaceID_SVG ||
87 : aNamespace == kNameSpaceID_MathML,
88 : "Bogus namespace.");
89 :
90 780 : nsIContent** content = AllocateContentHandle();
91 780 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
92 780 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
93 : treeOp->Init(aNamespace,
94 : aName,
95 : aAttributes,
96 : content,
97 780 : !!mSpeculativeLoadStage);
98 : // mSpeculativeLoadStage is non-null only in the off-the-main-thread
99 : // tree builder, which handles the network stream
100 :
101 : // Start wall of code for speculative loading and line numbers
102 :
103 780 : if (mSpeculativeLoadStage) {
104 0 : switch (aNamespace) {
105 : case kNameSpaceID_XHTML:
106 0 : if (nsHtml5Atoms::img == aName) {
107 0 : nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
108 0 : if (url) {
109 : nsString* crossOrigin =
110 0 : aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
111 : mSpeculativeLoadQueue.AppendElement()->
112 : InitImage(*url,
113 0 : crossOrigin ? *crossOrigin : NullString());
114 : }
115 0 : } else if (nsHtml5Atoms::script == aName) {
116 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
117 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
118 0 : treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
119 :
120 0 : nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
121 0 : if (url) {
122 0 : nsString* charset = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
123 0 : nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
124 : nsString* crossOrigin =
125 0 : aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
126 : mSpeculativeLoadQueue.AppendElement()->
127 : InitScript(*url,
128 : (charset) ? *charset : EmptyString(),
129 : (type) ? *type : EmptyString(),
130 0 : (crossOrigin) ? *crossOrigin : NullString());
131 : mCurrentHtmlScriptIsAsyncOrDefer =
132 0 : aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
133 0 : aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER);
134 : }
135 0 : } else if (nsHtml5Atoms::link == aName) {
136 0 : nsString* rel = aAttributes->getValue(nsHtml5AttributeName::ATTR_REL);
137 : // Not splitting on space here is bogus but the old parser didn't even
138 : // do a case-insensitive check.
139 0 : if (rel && rel->LowerCaseEqualsASCII("stylesheet")) {
140 0 : nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
141 0 : if (url) {
142 0 : nsString* charset = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
143 : mSpeculativeLoadQueue.AppendElement()->InitStyle(*url,
144 0 : (charset) ? *charset : EmptyString());
145 : }
146 : }
147 0 : } else if (nsHtml5Atoms::video == aName) {
148 0 : nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER);
149 0 : if (url) {
150 0 : mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString());
151 : }
152 0 : } else if (nsHtml5Atoms::style == aName) {
153 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
154 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
155 0 : treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
156 0 : } else if (nsHtml5Atoms::html == aName) {
157 0 : nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
158 0 : if (url) {
159 0 : mSpeculativeLoadQueue.AppendElement()->InitManifest(*url);
160 : } else {
161 0 : mSpeculativeLoadQueue.AppendElement()->InitManifest(EmptyString());
162 : }
163 0 : } else if (nsHtml5Atoms::base == aName) {
164 : nsString* url =
165 0 : aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
166 0 : if (url) {
167 0 : mSpeculativeLoadQueue.AppendElement()->InitBase(*url);
168 : }
169 : }
170 0 : break;
171 : case kNameSpaceID_SVG:
172 0 : if (nsHtml5Atoms::image == aName) {
173 0 : nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
174 0 : if (url) {
175 0 : mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString());
176 : }
177 0 : } else if (nsHtml5Atoms::script == aName) {
178 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
179 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
180 0 : treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
181 :
182 0 : nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
183 0 : if (url) {
184 0 : nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
185 : nsString* crossOrigin =
186 0 : aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
187 : mSpeculativeLoadQueue.AppendElement()->
188 : InitScript(*url,
189 0 : EmptyString(),
190 : (type) ? *type : EmptyString(),
191 0 : (crossOrigin) ? *crossOrigin : NullString());
192 : }
193 0 : } else if (nsHtml5Atoms::style == aName) {
194 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
195 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
196 0 : treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
197 :
198 0 : nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
199 0 : if (url) {
200 0 : mSpeculativeLoadQueue.AppendElement()->InitStyle(*url, EmptyString());
201 : }
202 : }
203 0 : break;
204 : }
205 780 : } else if (aNamespace != kNameSpaceID_MathML) {
206 : // No speculative loader--just line numbers and defer/async check
207 780 : if (nsHtml5Atoms::style == aName) {
208 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
209 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
210 0 : treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
211 780 : } else if (nsHtml5Atoms::script == aName) {
212 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
213 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
214 0 : treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
215 0 : if (aNamespace == kNameSpaceID_XHTML) {
216 : mCurrentHtmlScriptIsAsyncOrDefer =
217 0 : aAttributes->contains(nsHtml5AttributeName::ATTR_SRC) &&
218 0 : (aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
219 0 : aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER));
220 : }
221 780 : } else if (aNamespace == kNameSpaceID_XHTML && nsHtml5Atoms::html == aName) {
222 234 : nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
223 234 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
224 234 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
225 234 : if (url) {
226 0 : treeOp->Init(eTreeOpProcessOfflineManifest, *url);
227 : } else {
228 234 : treeOp->Init(eTreeOpProcessOfflineManifest, EmptyString());
229 : }
230 : }
231 : }
232 :
233 : // End wall of code for speculative loading
234 :
235 780 : return content;
236 : }
237 :
238 : nsIContent**
239 0 : nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes, nsIContent** aFormElement)
240 : {
241 0 : nsIContent** content = createElement(aNamespace, aName, aAttributes);
242 0 : if (aFormElement) {
243 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
244 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
245 0 : treeOp->Init(eTreeOpSetFormElement, content, aFormElement);
246 : }
247 0 : return content;
248 : }
249 :
250 : nsIContent**
251 234 : nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttributes)
252 : {
253 234 : nsIContent** content = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::html, aAttributes);
254 234 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
255 234 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
256 234 : treeOp->Init(eTreeOpAppendToDocument, content);
257 234 : return content;
258 : }
259 :
260 : void
261 0 : nsHtml5TreeBuilder::detachFromParent(nsIContent** aElement)
262 : {
263 0 : NS_PRECONDITION(aElement, "Null element");
264 :
265 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
266 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
267 0 : treeOp->Init(eTreeOpDetach, aElement);
268 0 : }
269 :
270 : void
271 546 : nsHtml5TreeBuilder::appendElement(nsIContent** aChild, nsIContent** aParent)
272 : {
273 546 : NS_PRECONDITION(aChild, "Null child");
274 546 : NS_PRECONDITION(aParent, "Null parent");
275 546 : if (deepTreeSurrogateParent) {
276 0 : return;
277 : }
278 546 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
279 546 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
280 546 : treeOp->Init(eTreeOpAppend, aChild, aParent);
281 : }
282 :
283 : void
284 0 : nsHtml5TreeBuilder::appendChildrenToNewParent(nsIContent** aOldParent, nsIContent** aNewParent)
285 : {
286 0 : NS_PRECONDITION(aOldParent, "Null old parent");
287 0 : NS_PRECONDITION(aNewParent, "Null new parent");
288 :
289 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
290 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
291 0 : treeOp->Init(eTreeOpAppendChildrenToNewParent, aOldParent, aNewParent);
292 0 : }
293 :
294 : void
295 0 : nsHtml5TreeBuilder::insertFosterParentedCharacters(PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength, nsIContent** aTable, nsIContent** aStackParent)
296 : {
297 0 : NS_PRECONDITION(aBuffer, "Null buffer");
298 0 : NS_PRECONDITION(aTable, "Null table");
299 0 : NS_PRECONDITION(aStackParent, "Null stack parent");
300 :
301 0 : PRUnichar* bufferCopy = new PRUnichar[aLength];
302 0 : memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar));
303 :
304 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
305 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
306 0 : treeOp->Init(eTreeOpFosterParentText, bufferCopy, aLength, aStackParent, aTable);
307 0 : }
308 :
309 : void
310 0 : nsHtml5TreeBuilder::insertFosterParentedChild(nsIContent** aChild, nsIContent** aTable, nsIContent** aStackParent)
311 : {
312 0 : NS_PRECONDITION(aChild, "Null child");
313 0 : NS_PRECONDITION(aTable, "Null table");
314 0 : NS_PRECONDITION(aStackParent, "Null stack parent");
315 :
316 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
317 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
318 0 : treeOp->Init(eTreeOpFosterParent, aChild, aStackParent, aTable);
319 0 : }
320 :
321 : void
322 287 : nsHtml5TreeBuilder::appendCharacters(nsIContent** aParent, PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength)
323 : {
324 287 : NS_PRECONDITION(aBuffer, "Null buffer");
325 287 : NS_PRECONDITION(aParent, "Null parent");
326 :
327 574 : PRUnichar* bufferCopy = new PRUnichar[aLength];
328 287 : memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar));
329 :
330 287 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
331 287 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
332 : treeOp->Init(eTreeOpAppendText, bufferCopy, aLength,
333 287 : deepTreeSurrogateParent ? deepTreeSurrogateParent : aParent);
334 287 : }
335 :
336 : void
337 0 : nsHtml5TreeBuilder::appendIsindexPrompt(nsIContent** aParent)
338 : {
339 0 : NS_PRECONDITION(aParent, "Null parent");
340 :
341 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
342 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
343 0 : treeOp->Init(eTreeOpAppendIsindexPrompt, aParent);
344 0 : }
345 :
346 : void
347 0 : nsHtml5TreeBuilder::appendComment(nsIContent** aParent, PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength)
348 : {
349 0 : NS_PRECONDITION(aBuffer, "Null buffer");
350 0 : NS_PRECONDITION(aParent, "Null parent");
351 0 : if (deepTreeSurrogateParent) {
352 0 : return;
353 : }
354 :
355 0 : PRUnichar* bufferCopy = new PRUnichar[aLength];
356 0 : memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar));
357 :
358 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
359 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
360 0 : treeOp->Init(eTreeOpAppendComment, bufferCopy, aLength, aParent);
361 : }
362 :
363 : void
364 0 : nsHtml5TreeBuilder::appendCommentToDocument(PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength)
365 : {
366 0 : NS_PRECONDITION(aBuffer, "Null buffer");
367 :
368 0 : PRUnichar* bufferCopy = new PRUnichar[aLength];
369 0 : memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar));
370 :
371 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
372 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
373 0 : treeOp->Init(eTreeOpAppendCommentToDocument, bufferCopy, aLength);
374 0 : }
375 :
376 : void
377 1 : nsHtml5TreeBuilder::addAttributesToElement(nsIContent** aElement, nsHtml5HtmlAttributes* aAttributes)
378 : {
379 1 : NS_PRECONDITION(aElement, "Null element");
380 1 : NS_PRECONDITION(aAttributes, "Null attributes");
381 :
382 1 : if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
383 1 : return;
384 : }
385 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
386 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
387 0 : treeOp->Init(aElement, aAttributes);
388 : }
389 :
390 : void
391 468 : nsHtml5TreeBuilder::markMalformedIfScript(nsIContent** aElement)
392 : {
393 468 : NS_PRECONDITION(aElement, "Null element");
394 :
395 468 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
396 468 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
397 468 : treeOp->Init(eTreeOpMarkMalformedIfScript, aElement);
398 468 : }
399 :
400 : void
401 234 : nsHtml5TreeBuilder::start(bool fragment)
402 : {
403 234 : mCurrentHtmlScriptIsAsyncOrDefer = false;
404 234 : deepTreeSurrogateParent = nsnull;
405 : #ifdef DEBUG
406 234 : mActive = true;
407 : #endif
408 234 : }
409 :
410 : void
411 234 : nsHtml5TreeBuilder::end()
412 : {
413 234 : mOpQueue.Clear();
414 : #ifdef DEBUG
415 234 : mActive = false;
416 : #endif
417 234 : }
418 :
419 : void
420 0 : nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName, nsString* aPublicId, nsString* aSystemId)
421 : {
422 0 : NS_PRECONDITION(aName, "Null name");
423 :
424 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
425 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
426 0 : treeOp->Init(aName, *aPublicId, *aSystemId);
427 : // nsXMLContentSink can flush here, but what's the point?
428 : // It can also interrupt here, but we can't.
429 0 : }
430 :
431 : void
432 780 : nsHtml5TreeBuilder::elementPushed(PRInt32 aNamespace, nsIAtom* aName, nsIContent** aElement)
433 : {
434 780 : NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
435 780 : NS_ASSERTION(aName, "Element doesn't have local name!");
436 780 : NS_ASSERTION(aElement, "No element!");
437 : /*
438 : * The frame constructor uses recursive algorithms, so it can't deal with
439 : * arbitrarily deep trees. This is especially a problem on Windows where
440 : * the permitted depth of the runtime stack is rather small.
441 : *
442 : * The following is a protection against author incompetence--not against
443 : * malice. There are other ways to make the DOM deep anyway.
444 : *
445 : * The basic idea is that when the tree builder stack gets too deep,
446 : * append operations no longer append to the node that the HTML parsing
447 : * algorithm says they should but instead text nodes are append to the last
448 : * element that was seen before a magic tree builder stack threshold was
449 : * reached and element and comment nodes aren't appended to the DOM at all.
450 : *
451 : * However, for security reasons, non-child descendant text nodes inside an
452 : * SVG script or style element should not become children. Also, non-cell
453 : * table elements shouldn't be used as surrogate parents for user experience
454 : * reasons.
455 : */
456 780 : if (!deepTreeSurrogateParent && currentPtr >= NS_HTML5_TREE_DEPTH_LIMIT &&
457 : !(aName == nsHtml5Atoms::script ||
458 : aName == nsHtml5Atoms::table ||
459 : aName == nsHtml5Atoms::thead ||
460 : aName == nsHtml5Atoms::tfoot ||
461 : aName == nsHtml5Atoms::tbody ||
462 : aName == nsHtml5Atoms::tr ||
463 : aName == nsHtml5Atoms::colgroup ||
464 0 : aName == nsHtml5Atoms::style)) {
465 0 : deepTreeSurrogateParent = aElement;
466 : }
467 780 : if (aNamespace != kNameSpaceID_XHTML) {
468 0 : return;
469 : }
470 780 : if (aName == nsHtml5Atoms::body || aName == nsHtml5Atoms::frameset) {
471 234 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
472 234 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
473 234 : treeOp->Init(eTreeOpStartLayout);
474 234 : return;
475 : }
476 : }
477 :
478 : void
479 780 : nsHtml5TreeBuilder::elementPopped(PRInt32 aNamespace, nsIAtom* aName, nsIContent** aElement)
480 : {
481 780 : NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
482 780 : NS_ASSERTION(aName, "Element doesn't have local name!");
483 780 : NS_ASSERTION(aElement, "No element!");
484 780 : if (deepTreeSurrogateParent && currentPtr <= NS_HTML5_TREE_DEPTH_LIMIT) {
485 0 : deepTreeSurrogateParent = nsnull;
486 : }
487 780 : if (aNamespace == kNameSpaceID_MathML) {
488 0 : return;
489 : }
490 : // we now have only SVG and HTML
491 780 : if (aName == nsHtml5Atoms::script) {
492 0 : if (mCurrentHtmlScriptIsAsyncOrDefer) {
493 0 : NS_ASSERTION(aNamespace == kNameSpaceID_XHTML,
494 : "Only HTML scripts may be async/defer.");
495 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
496 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
497 0 : treeOp->Init(eTreeOpRunScriptAsyncDefer, aElement);
498 0 : mCurrentHtmlScriptIsAsyncOrDefer = false;
499 0 : return;
500 : }
501 0 : requestSuspension();
502 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
503 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
504 0 : treeOp->InitScript(aElement);
505 0 : return;
506 : }
507 780 : if (aName == nsHtml5Atoms::title) {
508 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
509 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
510 0 : treeOp->Init(eTreeOpDoneAddingChildren, aElement);
511 0 : return;
512 : }
513 780 : if (aName == nsHtml5Atoms::style || (aNamespace == kNameSpaceID_XHTML && aName == nsHtml5Atoms::link)) {
514 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
515 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
516 0 : treeOp->Init(eTreeOpUpdateStyleSheet, aElement);
517 0 : return;
518 : }
519 780 : if (aNamespace == kNameSpaceID_SVG) {
520 0 : if (aName == nsHtml5Atoms::svg) {
521 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
522 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
523 0 : treeOp->Init(eTreeOpSvgLoad, aElement);
524 : }
525 0 : return;
526 : }
527 : // we now have only HTML
528 : // Some HTML nodes need DoneAddingChildren() called to initialize
529 : // properly (e.g. form state restoration).
530 : // XXX expose ElementName group here and do switch
531 780 : if (aName == nsHtml5Atoms::object ||
532 : aName == nsHtml5Atoms::applet) {
533 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
534 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
535 0 : treeOp->Init(eTreeOpDoneAddingChildren, aElement);
536 0 : return;
537 : }
538 780 : if (aName == nsHtml5Atoms::select ||
539 : aName == nsHtml5Atoms::textarea) {
540 0 : if (!formPointer) {
541 : // If form inputs don't belong to a form, their state preservation
542 : // won't work right without an append notification flush at this
543 : // point. See bug 497861 and bug 539895.
544 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
545 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
546 0 : treeOp->Init(eTreeOpFlushPendingAppendNotifications);
547 : }
548 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
549 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
550 0 : treeOp->Init(eTreeOpDoneAddingChildren, aElement);
551 0 : return;
552 : }
553 780 : if (aName == nsHtml5Atoms::input ||
554 : aName == nsHtml5Atoms::button ||
555 : aName == nsHtml5Atoms::menuitem) {
556 0 : if (!formPointer) {
557 : // If form inputs don't belong to a form, their state preservation
558 : // won't work right without an append notification flush at this
559 : // point. See bug 497861.
560 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
561 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
562 0 : treeOp->Init(eTreeOpFlushPendingAppendNotifications);
563 : }
564 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
565 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
566 0 : treeOp->Init(eTreeOpDoneCreatingElement, aElement);
567 0 : return;
568 : }
569 780 : if (aName == nsHtml5Atoms::meta && !fragment) {
570 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
571 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
572 0 : treeOp->Init(eTreeOpProcessMeta, aElement);
573 0 : return;
574 : }
575 780 : if (aName == nsHtml5Atoms::audio || aName == nsHtml5Atoms::video) {
576 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
577 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
578 0 : treeOp->Init(eTreeOpDoneCreatingElement, aElement);
579 0 : return;
580 : }
581 :
582 780 : return;
583 : }
584 :
585 : void
586 322 : nsHtml5TreeBuilder::accumulateCharacters(const PRUnichar* aBuf, PRInt32 aStart, PRInt32 aLength)
587 : {
588 322 : PRInt32 newFillLen = charBufferLen + aLength;
589 322 : if (newFillLen > charBuffer.length) {
590 0 : PRInt32 newAllocLength = newFillLen + (newFillLen >> 1);
591 0 : jArray<PRUnichar,PRInt32> newBuf = jArray<PRUnichar,PRInt32>::newJArray(newAllocLength);
592 0 : memcpy(newBuf, charBuffer, sizeof(PRUnichar) * charBufferLen);
593 0 : charBuffer = newBuf;
594 : }
595 322 : memcpy(charBuffer + charBufferLen, aBuf + aStart, sizeof(PRUnichar) * aLength);
596 322 : charBufferLen = newFillLen;
597 322 : }
598 :
599 : nsIContent**
600 780 : nsHtml5TreeBuilder::AllocateContentHandle()
601 : {
602 780 : if (mHandlesUsed == NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH) {
603 0 : mOldHandles.AppendElement(mHandles.forget());
604 0 : mHandles = new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH];
605 0 : mHandlesUsed = 0;
606 : }
607 : #ifdef DEBUG
608 780 : mHandles[mHandlesUsed] = (nsIContent*)0xC0DEDBAD;
609 : #endif
610 780 : return &mHandles[mHandlesUsed++];
611 : }
612 :
613 : bool
614 234 : nsHtml5TreeBuilder::HasScript()
615 : {
616 234 : PRUint32 len = mOpQueue.Length();
617 234 : if (!len) {
618 0 : return false;
619 : }
620 234 : return mOpQueue.ElementAt(len - 1).IsRunScript();
621 : }
622 :
623 : bool
624 234 : nsHtml5TreeBuilder::Flush(bool aDiscretionary)
625 : {
626 468 : if (!aDiscretionary ||
627 : !(charBufferLen &&
628 : currentPtr >= 0 &&
629 0 : stack[currentPtr]->isFosterParenting())) {
630 : // Don't flush text on discretionary flushes if the current element on
631 : // the stack is a foster-parenting element and there's pending text,
632 : // because flushing in that case would make the tree shape dependent on
633 : // where the flush points fall.
634 234 : flushCharacters();
635 : }
636 234 : FlushLoads();
637 234 : if (mOpSink) {
638 234 : bool hasOps = !mOpQueue.IsEmpty();
639 234 : if (hasOps) {
640 234 : mOpSink->MoveOpsFrom(mOpQueue);
641 : }
642 234 : return hasOps;
643 : }
644 : // no op sink: throw away ops
645 0 : mOpQueue.Clear();
646 0 : return false;
647 : }
648 :
649 : void
650 234 : nsHtml5TreeBuilder::FlushLoads()
651 : {
652 234 : if (!mSpeculativeLoadQueue.IsEmpty()) {
653 0 : mSpeculativeLoadStage->MoveSpeculativeLoadsFrom(mSpeculativeLoadQueue);
654 : }
655 234 : }
656 :
657 : void
658 0 : nsHtml5TreeBuilder::SetDocumentCharset(nsACString& aCharset,
659 : PRInt32 aCharsetSource)
660 : {
661 0 : if (mSpeculativeLoadStage) {
662 : mSpeculativeLoadQueue.AppendElement()->InitSetDocumentCharset(
663 0 : aCharset, aCharsetSource);
664 : } else {
665 : mOpQueue.AppendElement()->Init(
666 0 : eTreeOpSetDocumentCharset, aCharset, aCharsetSource);
667 : }
668 0 : }
669 :
670 : void
671 234 : nsHtml5TreeBuilder::StreamEnded()
672 : {
673 : // The fragment mode calls DidBuildModel from nsHtml5Parser.
674 : // Letting DidBuildModel be called from the executor in the fragment case
675 : // confuses the EndLoad logic of nsHTMLDocument, since nsHTMLDocument
676 : // thinks it is dealing with document.written content as opposed to
677 : // innerHTML content.
678 234 : if (!fragment) {
679 234 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
680 234 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
681 234 : treeOp->Init(eTreeOpStreamEnded);
682 : }
683 234 : }
684 :
685 : void
686 0 : nsHtml5TreeBuilder::NeedsCharsetSwitchTo(const nsACString& aCharset,
687 : PRInt32 aCharsetSource)
688 : {
689 0 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
690 0 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
691 0 : treeOp->Init(eTreeOpNeedsCharsetSwitchTo, aCharset, aCharsetSource);
692 0 : }
693 :
694 : void
695 0 : nsHtml5TreeBuilder::AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, PRInt32 aLine)
696 : {
697 0 : NS_PRECONDITION(HasScript(), "No script to add a snapshot to!");
698 0 : NS_PRECONDITION(aSnapshot, "Got null snapshot.");
699 0 : mOpQueue.ElementAt(mOpQueue.Length() - 1).SetSnapshot(aSnapshot, aLine);
700 0 : }
701 :
702 : void
703 234 : nsHtml5TreeBuilder::DropHandles()
704 : {
705 234 : mOldHandles.Clear();
706 234 : mHandlesUsed = 0;
707 234 : }
708 :
709 : void
710 0 : nsHtml5TreeBuilder::MarkAsBroken()
711 : {
712 0 : mOpQueue.Clear(); // Previous ops don't matter anymore
713 0 : mOpQueue.AppendElement()->Init(eTreeOpMarkAsBroken);
714 0 : }
715 :
716 : void
717 0 : nsHtml5TreeBuilder::StartPlainTextViewSource(const nsAutoString& aTitle)
718 : {
719 : startTag(nsHtml5ElementName::ELT_TITLE,
720 : nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES,
721 0 : false);
722 :
723 : // XUL will add the "Source of: " prefix.
724 0 : PRUint32 length = aTitle.Length();
725 0 : if (length > PR_INT32_MAX) {
726 0 : length = PR_INT32_MAX;
727 : }
728 0 : characters(aTitle.get(), 0, (PRInt32)length);
729 0 : endTag(nsHtml5ElementName::ELT_TITLE);
730 :
731 : startTag(nsHtml5ElementName::ELT_LINK,
732 : nsHtml5ViewSourceUtils::NewLinkAttributes(),
733 0 : false);
734 :
735 : startTag(nsHtml5ElementName::ELT_BODY,
736 : nsHtml5ViewSourceUtils::NewBodyAttributes(),
737 0 : false);
738 :
739 0 : StartPlainText();
740 0 : }
741 :
742 : void
743 0 : nsHtml5TreeBuilder::StartPlainText()
744 : {
745 : startTag(nsHtml5ElementName::ELT_PRE,
746 : nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES,
747 0 : false);
748 0 : needToDropLF = false;
749 0 : }
750 :
751 : // DocumentModeHandler
752 : void
753 234 : nsHtml5TreeBuilder::documentMode(nsHtml5DocumentMode m)
754 : {
755 234 : nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
756 234 : NS_ASSERTION(treeOp, "Tree op allocation failed.");
757 234 : treeOp->Init(m);
758 234 : }
759 :
760 : // Error reporting
761 :
762 : void
763 0 : nsHtml5TreeBuilder::EnableViewSource(nsHtml5Highlighter* aHighlighter)
764 : {
765 0 : mViewSource = aHighlighter;
766 0 : }
767 :
768 : void
769 1 : nsHtml5TreeBuilder::errStrayStartTag(nsIAtom* aName)
770 : {
771 1 : if (NS_UNLIKELY(mViewSource)) {
772 0 : mViewSource->AddErrorToCurrentRun("errStrayStartTag2", aName);
773 : }
774 1 : }
775 :
776 : void
777 2 : nsHtml5TreeBuilder::errStrayEndTag(nsIAtom* aName)
778 : {
779 2 : if (NS_UNLIKELY(mViewSource)) {
780 0 : mViewSource->AddErrorToCurrentRun("errStrayEndTag", aName);
781 : }
782 2 : }
783 :
784 : void
785 0 : nsHtml5TreeBuilder::errUnclosedElements(PRInt32 aIndex, nsIAtom* aName)
786 : {
787 0 : if (NS_UNLIKELY(mViewSource)) {
788 0 : mViewSource->AddErrorToCurrentRun("errUnclosedElements", aName);
789 : }
790 0 : }
791 :
792 : void
793 0 : nsHtml5TreeBuilder::errUnclosedElementsImplied(PRInt32 aIndex, nsIAtom* aName)
794 : {
795 0 : if (NS_UNLIKELY(mViewSource)) {
796 : mViewSource->AddErrorToCurrentRun("errUnclosedElementsImplied",
797 0 : aName);
798 : }
799 0 : }
800 :
801 : void
802 0 : nsHtml5TreeBuilder::errUnclosedElementsCell(PRInt32 aIndex)
803 : {
804 0 : if (NS_UNLIKELY(mViewSource)) {
805 0 : mViewSource->AddErrorToCurrentRun("errUnclosedElementsCell");
806 : }
807 0 : }
808 :
809 : void
810 0 : nsHtml5TreeBuilder::errStrayDoctype()
811 : {
812 0 : if (NS_UNLIKELY(mViewSource)) {
813 0 : mViewSource->AddErrorToCurrentRun("errStrayDoctype");
814 : }
815 0 : }
816 :
817 : void
818 0 : nsHtml5TreeBuilder::errAlmostStandardsDoctype()
819 : {
820 0 : if (NS_UNLIKELY(mViewSource)) {
821 0 : mViewSource->AddErrorToCurrentRun("errAlmostStandardsDoctype");
822 : }
823 0 : }
824 :
825 : void
826 0 : nsHtml5TreeBuilder::errQuirkyDoctype()
827 : {
828 0 : if (NS_UNLIKELY(mViewSource)) {
829 0 : mViewSource->AddErrorToCurrentRun("errQuirkyDoctype");
830 : }
831 0 : }
832 :
833 : void
834 0 : nsHtml5TreeBuilder::errNonSpaceInTrailer()
835 : {
836 0 : if (NS_UNLIKELY(mViewSource)) {
837 0 : mViewSource->AddErrorToCurrentRun("errNonSpaceInTrailer");
838 : }
839 0 : }
840 :
841 : void
842 0 : nsHtml5TreeBuilder::errNonSpaceAfterFrameset()
843 : {
844 0 : if (NS_UNLIKELY(mViewSource)) {
845 0 : mViewSource->AddErrorToCurrentRun("errNonSpaceAfterFrameset");
846 : }
847 0 : }
848 :
849 : void
850 0 : nsHtml5TreeBuilder::errNonSpaceInFrameset()
851 : {
852 0 : if (NS_UNLIKELY(mViewSource)) {
853 0 : mViewSource->AddErrorToCurrentRun("errNonSpaceInFrameset");
854 : }
855 0 : }
856 :
857 : void
858 0 : nsHtml5TreeBuilder::errNonSpaceAfterBody()
859 : {
860 0 : if (NS_UNLIKELY(mViewSource)) {
861 0 : mViewSource->AddErrorToCurrentRun("errNonSpaceAfterBody");
862 : }
863 0 : }
864 :
865 : void
866 0 : nsHtml5TreeBuilder::errNonSpaceInColgroupInFragment()
867 : {
868 0 : if (NS_UNLIKELY(mViewSource)) {
869 0 : mViewSource->AddErrorToCurrentRun("errNonSpaceInColgroupInFragment");
870 : }
871 0 : }
872 :
873 : void
874 0 : nsHtml5TreeBuilder::errNonSpaceInNoscriptInHead()
875 : {
876 0 : if (NS_UNLIKELY(mViewSource)) {
877 0 : mViewSource->AddErrorToCurrentRun("errNonSpaceInNoscriptInHead");
878 : }
879 0 : }
880 :
881 : void
882 0 : nsHtml5TreeBuilder::errFooBetweenHeadAndBody(nsIAtom* aName)
883 : {
884 0 : if (NS_UNLIKELY(mViewSource)) {
885 0 : mViewSource->AddErrorToCurrentRun("errFooBetweenHeadAndBody", aName);
886 : }
887 0 : }
888 :
889 : void
890 22 : nsHtml5TreeBuilder::errStartTagWithoutDoctype()
891 : {
892 22 : if (NS_UNLIKELY(mViewSource)) {
893 0 : mViewSource->AddErrorToCurrentRun("errStartTagWithoutDoctype");
894 : }
895 22 : }
896 :
897 : void
898 0 : nsHtml5TreeBuilder::errNoSelectInTableScope()
899 : {
900 0 : if (NS_UNLIKELY(mViewSource)) {
901 0 : mViewSource->AddErrorToCurrentRun("errNoSelectInTableScope");
902 : }
903 0 : }
904 :
905 : void
906 0 : nsHtml5TreeBuilder::errStartSelectWhereEndSelectExpected()
907 : {
908 0 : if (NS_UNLIKELY(mViewSource)) {
909 : mViewSource->AddErrorToCurrentRun(
910 0 : "errStartSelectWhereEndSelectExpected");
911 : }
912 0 : }
913 :
914 : void
915 0 : nsHtml5TreeBuilder::errStartTagWithSelectOpen(nsIAtom* aName)
916 : {
917 0 : if (NS_UNLIKELY(mViewSource)) {
918 0 : mViewSource->AddErrorToCurrentRun("errStartTagWithSelectOpen", aName);
919 : }
920 0 : }
921 :
922 : void
923 0 : nsHtml5TreeBuilder::errBadStartTagInHead(nsIAtom* aName)
924 : {
925 0 : if (NS_UNLIKELY(mViewSource)) {
926 0 : mViewSource->AddErrorToCurrentRun("errBadStartTagInHead2", aName);
927 : }
928 0 : }
929 :
930 : void
931 0 : nsHtml5TreeBuilder::errImage()
932 : {
933 0 : if (NS_UNLIKELY(mViewSource)) {
934 0 : mViewSource->AddErrorToCurrentRun("errImage");
935 : }
936 0 : }
937 :
938 : void
939 0 : nsHtml5TreeBuilder::errIsindex()
940 : {
941 0 : if (NS_UNLIKELY(mViewSource)) {
942 0 : mViewSource->AddErrorToCurrentRun("errIsindex");
943 : }
944 0 : }
945 :
946 : void
947 1 : nsHtml5TreeBuilder::errFooSeenWhenFooOpen(nsIAtom* aName)
948 : {
949 1 : if (NS_UNLIKELY(mViewSource)) {
950 0 : mViewSource->AddErrorToCurrentRun("errFooSeenWhenFooOpen", aName);
951 : }
952 1 : }
953 :
954 : void
955 0 : nsHtml5TreeBuilder::errHeadingWhenHeadingOpen()
956 : {
957 0 : if (NS_UNLIKELY(mViewSource)) {
958 0 : mViewSource->AddErrorToCurrentRun("errHeadingWhenHeadingOpen");
959 : }
960 0 : }
961 :
962 : void
963 0 : nsHtml5TreeBuilder::errFramesetStart()
964 : {
965 0 : if (NS_UNLIKELY(mViewSource)) {
966 0 : mViewSource->AddErrorToCurrentRun("errFramesetStart");
967 : }
968 0 : }
969 :
970 : void
971 0 : nsHtml5TreeBuilder::errNoCellToClose()
972 : {
973 0 : if (NS_UNLIKELY(mViewSource)) {
974 0 : mViewSource->AddErrorToCurrentRun("errNoCellToClose");
975 : }
976 0 : }
977 :
978 : void
979 0 : nsHtml5TreeBuilder::errStartTagInTable(nsIAtom* aName)
980 : {
981 0 : if (NS_UNLIKELY(mViewSource)) {
982 0 : mViewSource->AddErrorToCurrentRun("errStartTagInTable", aName);
983 : }
984 0 : }
985 :
986 : void
987 0 : nsHtml5TreeBuilder::errFormWhenFormOpen()
988 : {
989 0 : if (NS_UNLIKELY(mViewSource)) {
990 0 : mViewSource->AddErrorToCurrentRun("errFormWhenFormOpen");
991 : }
992 0 : }
993 :
994 : void
995 0 : nsHtml5TreeBuilder::errTableSeenWhileTableOpen()
996 : {
997 0 : if (NS_UNLIKELY(mViewSource)) {
998 0 : mViewSource->AddErrorToCurrentRun("errTableSeenWhileTableOpen");
999 : }
1000 0 : }
1001 :
1002 : void
1003 0 : nsHtml5TreeBuilder::errStartTagInTableBody(nsIAtom* aName)
1004 : {
1005 0 : if (NS_UNLIKELY(mViewSource)) {
1006 0 : mViewSource->AddErrorToCurrentRun("errStartTagInTableBody", aName);
1007 : }
1008 0 : }
1009 :
1010 : void
1011 0 : nsHtml5TreeBuilder::errEndTagSeenWithoutDoctype()
1012 : {
1013 0 : if (NS_UNLIKELY(mViewSource)) {
1014 0 : mViewSource->AddErrorToCurrentRun("errEndTagSeenWithoutDoctype");
1015 : }
1016 0 : }
1017 :
1018 : void
1019 0 : nsHtml5TreeBuilder::errEndTagAfterBody()
1020 : {
1021 0 : if (NS_UNLIKELY(mViewSource)) {
1022 0 : mViewSource->AddErrorToCurrentRun("errEndTagAfterBody");
1023 : }
1024 0 : }
1025 :
1026 : void
1027 0 : nsHtml5TreeBuilder::errEndTagSeenWithSelectOpen(nsIAtom* aName)
1028 : {
1029 0 : if (NS_UNLIKELY(mViewSource)) {
1030 : mViewSource->AddErrorToCurrentRun("errEndTagSeenWithSelectOpen",
1031 0 : aName);
1032 : }
1033 0 : }
1034 :
1035 : void
1036 0 : nsHtml5TreeBuilder::errGarbageInColgroup()
1037 : {
1038 0 : if (NS_UNLIKELY(mViewSource)) {
1039 0 : mViewSource->AddErrorToCurrentRun("errGarbageInColgroup");
1040 : }
1041 0 : }
1042 :
1043 : void
1044 0 : nsHtml5TreeBuilder::errEndTagBr()
1045 : {
1046 0 : if (NS_UNLIKELY(mViewSource)) {
1047 0 : mViewSource->AddErrorToCurrentRun("errEndTagBr");
1048 : }
1049 0 : }
1050 :
1051 : void
1052 0 : nsHtml5TreeBuilder::errNoElementToCloseButEndTagSeen(nsIAtom* aName)
1053 : {
1054 0 : if (NS_UNLIKELY(mViewSource)) {
1055 : mViewSource->AddErrorToCurrentRun(
1056 0 : "errNoElementToCloseButEndTagSeen", aName);
1057 : }
1058 0 : }
1059 :
1060 : void
1061 0 : nsHtml5TreeBuilder::errHtmlStartTagInForeignContext(nsIAtom* aName)
1062 : {
1063 0 : if (NS_UNLIKELY(mViewSource)) {
1064 : mViewSource->AddErrorToCurrentRun("errHtmlStartTagInForeignContext",
1065 0 : aName);
1066 : }
1067 0 : }
1068 :
1069 : void
1070 0 : nsHtml5TreeBuilder::errTableClosedWhileCaptionOpen()
1071 : {
1072 0 : if (NS_UNLIKELY(mViewSource)) {
1073 0 : mViewSource->AddErrorToCurrentRun("errTableClosedWhileCaptionOpen");
1074 : }
1075 0 : }
1076 :
1077 : void
1078 0 : nsHtml5TreeBuilder::errNoTableRowToClose()
1079 : {
1080 0 : if (NS_UNLIKELY(mViewSource)) {
1081 0 : mViewSource->AddErrorToCurrentRun("errNoTableRowToClose");
1082 : }
1083 0 : }
1084 :
1085 : void
1086 0 : nsHtml5TreeBuilder::errNonSpaceInTable()
1087 : {
1088 0 : if (NS_UNLIKELY(mViewSource)) {
1089 0 : mViewSource->AddErrorToCurrentRun("errNonSpaceInTable");
1090 : }
1091 0 : }
1092 :
1093 : void
1094 0 : nsHtml5TreeBuilder::errUnclosedChildrenInRuby()
1095 : {
1096 0 : if (NS_UNLIKELY(mViewSource)) {
1097 0 : mViewSource->AddErrorToCurrentRun("errUnclosedChildrenInRuby");
1098 : }
1099 0 : }
1100 :
1101 : void
1102 0 : nsHtml5TreeBuilder::errStartTagSeenWithoutRuby(nsIAtom* aName)
1103 : {
1104 0 : if (NS_UNLIKELY(mViewSource)) {
1105 : mViewSource->AddErrorToCurrentRun("errStartTagSeenWithoutRuby",
1106 0 : aName);
1107 : }
1108 0 : }
1109 :
1110 : void
1111 0 : nsHtml5TreeBuilder::errSelfClosing()
1112 : {
1113 0 : if (NS_UNLIKELY(mViewSource)) {
1114 0 : mViewSource->AddErrorToCurrentSlash("errSelfClosing");
1115 : }
1116 0 : }
1117 :
1118 : void
1119 0 : nsHtml5TreeBuilder::errNoCheckUnclosedElementsOnStack()
1120 : {
1121 0 : if (NS_UNLIKELY(mViewSource)) {
1122 : mViewSource->AddErrorToCurrentRun(
1123 0 : "errNoCheckUnclosedElementsOnStack");
1124 : }
1125 0 : }
1126 :
1127 : void
1128 0 : nsHtml5TreeBuilder::errEndTagDidNotMatchCurrentOpenElement(nsIAtom* aName,
1129 : nsIAtom* aOther)
1130 : {
1131 0 : if (NS_UNLIKELY(mViewSource)) {
1132 : mViewSource->AddErrorToCurrentRun(
1133 0 : "errEndTagDidNotMatchCurrentOpenElement", aName, aOther);
1134 : }
1135 0 : }
1136 :
1137 : void
1138 0 : nsHtml5TreeBuilder::errEndTagViolatesNestingRules(nsIAtom* aName)
1139 : {
1140 0 : if (NS_UNLIKELY(mViewSource)) {
1141 0 : mViewSource->AddErrorToCurrentRun("errEndTagViolatesNestingRules", aName);
1142 : }
1143 0 : }
1144 :
1145 : void
1146 0 : nsHtml5TreeBuilder::errEndWithUnclosedElements(nsIAtom* aName)
1147 : {
1148 0 : if (NS_UNLIKELY(mViewSource)) {
1149 0 : mViewSource->AddErrorToCurrentRun("errEndWithUnclosedElements", aName);
1150 : }
1151 0 : }
|