106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen/*
206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * Copyright (C) 2010 Google, Inc. All Rights Reserved.
381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Copyright (C) 2011 Apple Inc. All rights reserved.
406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen *
506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * Redistribution and use in source and binary forms, with or without
606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * modification, are permitted provided that the following conditions
706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * are met:
806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * 1. Redistributions of source code must retain the above copyright
906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen *    notice, this list of conditions and the following disclaimer.
1006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * 2. Redistributions in binary form must reproduce the above copyright
1106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen *    notice, this list of conditions and the following disclaimer in the
1206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen *    documentation and/or other materials provided with the distribution.
1306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen *
1406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
1506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
1806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
2206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen */
2606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
2706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "config.h"
2806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "HTMLTreeBuilder.h"
2906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
30ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "Comment.h"
312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "DOMWindow.h"
3206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "DocumentFragment.h"
33ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "DocumentType.h"
3406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "Frame.h"
3506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "HTMLDocument.h"
36cad810f21b803229eb11403f9209855525a25d57Steve Block#include "HTMLDocumentParser.h"
37ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "HTMLElementFactory.h"
38967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "HTMLFormElement.h"
39ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "HTMLHtmlElement.h"
4006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "HTMLNames.h"
4168513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "HTMLParserIdioms.h"
42ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "HTMLScriptElement.h"
43ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "HTMLToken.h"
44ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "HTMLTokenizer.h"
45e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "LocalizedStrings.h"
46e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "MathMLNames.h"
4706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "NotImplemented.h"
48ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "SVGNames.h"
4906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "ScriptController.h"
50ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "Text.h"
51e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "XLinkNames.h"
52e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "XMLNSNames.h"
53e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "XMLNames.h"
542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/unicode/CharacterNames.h>
5506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
5606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsennamespace WebCore {
5706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
5806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenusing namespace HTMLNames;
5906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
6006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenstatic const int uninitializedLineNumberValue = -1;
6106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennerstatic TextPosition1 uninitializedPositionValue1()
636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{
646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    return TextPosition1(WTF::OneBasedNumber::fromOneBasedInt(-1), WTF::OneBasedNumber::base());
656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}
666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
6706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsennamespace {
6806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
6968513a70bcd92384395513322f1b801e7bf9c729Steve Blockinline bool isHTMLSpaceOrReplacementCharacter(UChar character)
7006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
7168513a70bcd92384395513322f1b801e7bf9c729Steve Block    return isHTMLSpace(character) || character == replacementCharacter;
72dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
73dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
74dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochinline bool isAllWhitespace(const String& string)
75dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
7668513a70bcd92384395513322f1b801e7bf9c729Steve Block    return string.isAllSpecialCharacters<isHTMLSpace>();
77dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
78dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
79dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochinline bool isAllWhitespaceOrReplacementCharacters(const String& string)
80dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
8168513a70bcd92384395513322f1b801e7bf9c729Steve Block    return string.isAllSpecialCharacters<isHTMLSpaceOrReplacementCharacter>();
82e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
83e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
84ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockbool isNumberedHeaderTag(const AtomicString& tagName)
85ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
86ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return tagName == h1Tag
87ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == h2Tag
88ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == h3Tag
89ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == h4Tag
90ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == h5Tag
91ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == h6Tag;
92ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
93ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
94e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool isCaptionColOrColgroupTag(const AtomicString& tagName)
95e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
96e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return tagName == captionTag
97e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || tagName == colTag
98e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || tagName == colgroupTag;
99e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
100e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
101e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool isTableCellContextTag(const AtomicString& tagName)
102e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
103e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return tagName == thTag || tagName == tdTag;
104e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
105e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
106ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockbool isTableBodyContextTag(const AtomicString& tagName)
107ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
108ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return tagName == tbodyTag
109ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == tfootTag
110ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == theadTag;
111ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
112ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
113ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#special
114e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockbool isSpecialNode(Node* node)
115ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
116e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (node->hasTagName(MathMLNames::miTag)
117e14391e94c850b8bd03680c23b38978db68687a8John Reck        || node->hasTagName(MathMLNames::moTag)
118e14391e94c850b8bd03680c23b38978db68687a8John Reck        || node->hasTagName(MathMLNames::mnTag)
119e14391e94c850b8bd03680c23b38978db68687a8John Reck        || node->hasTagName(MathMLNames::msTag)
120e14391e94c850b8bd03680c23b38978db68687a8John Reck        || node->hasTagName(MathMLNames::mtextTag)
121e14391e94c850b8bd03680c23b38978db68687a8John Reck        || node->hasTagName(MathMLNames::annotation_xmlTag)
122e14391e94c850b8bd03680c23b38978db68687a8John Reck        || node->hasTagName(SVGNames::foreignObjectTag)
123e14391e94c850b8bd03680c23b38978db68687a8John Reck        || node->hasTagName(SVGNames::descTag)
124e14391e94c850b8bd03680c23b38978db68687a8John Reck        || node->hasTagName(SVGNames::titleTag))
12568513a70bcd92384395513322f1b801e7bf9c729Steve Block        return true;
12681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (node->nodeType() == Node::DOCUMENT_FRAGMENT_NODE)
12781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return true;
1282bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!isInHTMLNamespace(node))
129e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        return false;
130e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    const AtomicString& tagName = node->localName();
131ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return tagName == addressTag
13268513a70bcd92384395513322f1b801e7bf9c729Steve Block        || tagName == appletTag
13368513a70bcd92384395513322f1b801e7bf9c729Steve Block        || tagName == areaTag
134ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == articleTag
135ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == asideTag
136ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == baseTag
137ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == basefontTag
1380617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || tagName == bgsoundTag
139ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == blockquoteTag
140ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == bodyTag
141ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == brTag
142ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == buttonTag
14368513a70bcd92384395513322f1b801e7bf9c729Steve Block        || tagName == captionTag
144ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == centerTag
145ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == colTag
146ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == colgroupTag
1470617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || tagName == commandTag
148ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == ddTag
1490617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || tagName == detailsTag
150ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == dirTag
151ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == divTag
152ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == dlTag
153ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == dtTag
154ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == embedTag
155ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == fieldsetTag
15668513a70bcd92384395513322f1b801e7bf9c729Steve Block        || tagName == figcaptionTag
1570617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || tagName == figureTag
158ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == footerTag
159ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == formTag
160ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == frameTag
161ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == framesetTag
162ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || isNumberedHeaderTag(tagName)
163ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == headTag
164ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == headerTag
165ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == hgroupTag
166ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == hrTag
167e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        || tagName == htmlTag
168ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == iframeTag
169ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == imgTag
170ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == inputTag
171ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == isindexTag
172ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == liTag
173ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == linkTag
174ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == listingTag
17568513a70bcd92384395513322f1b801e7bf9c729Steve Block        || tagName == marqueeTag
176ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == menuTag
177ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == metaTag
178ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == navTag
179ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == noembedTag
180ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == noframesTag
181ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == noscriptTag
18268513a70bcd92384395513322f1b801e7bf9c729Steve Block        || tagName == objectTag
183ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == olTag
184ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == pTag
185ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == paramTag
186ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == plaintextTag
187ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == preTag
188ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == scriptTag
189ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == sectionTag
190ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == selectTag
191ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == styleTag
19268513a70bcd92384395513322f1b801e7bf9c729Steve Block        || tagName == summaryTag
19368513a70bcd92384395513322f1b801e7bf9c729Steve Block        || tagName == tableTag
194ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || isTableBodyContextTag(tagName)
19568513a70bcd92384395513322f1b801e7bf9c729Steve Block        || tagName == tdTag
196ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == textareaTag
19768513a70bcd92384395513322f1b801e7bf9c729Steve Block        || tagName == thTag
198ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == titleTag
199ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == trTag
200ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == ulTag
201ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == wbrTag
202ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == xmpTag;
203ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
204ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
205e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool isNonAnchorNonNobrFormattingTag(const AtomicString& tagName)
206ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
207ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return tagName == bTag
208ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == bigTag
209ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == codeTag
210ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == emTag
211ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == fontTag
212ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == iTag
213ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == sTag
214ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == smallTag
215ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == strikeTag
216ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == strongTag
217ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == ttTag
218ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        || tagName == uTag;
219ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
220ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
221e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool isNonAnchorFormattingTag(const AtomicString& tagName)
222e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
223e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return tagName == nobrTag
224e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isNonAnchorNonNobrFormattingTag(tagName);
225e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
226e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
227ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#formatting
228ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockbool isFormattingTag(const AtomicString& tagName)
229ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
230ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return tagName == aTag || isNonAnchorFormattingTag(tagName);
231ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
232ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
233dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochHTMLFormElement* closestFormAncestor(Element* element)
234dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
235dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    while (element) {
236dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        if (element->hasTagName(formTag))
237dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            return static_cast<HTMLFormElement*>(element);
2386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        ContainerNode* parent = element->parentNode();
239dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        if (!parent || !parent->isElementNode())
240dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            return 0;
241dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        element = static_cast<Element*>(parent);
242dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
243dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    return 0;
244dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
245dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
24606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen} // namespace
24706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
248ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochclass HTMLTreeBuilder::ExternalCharacterTokenBuffer {
249ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    WTF_MAKE_NONCOPYABLE(ExternalCharacterTokenBuffer);
250967717af5423377c967781471ee106e2bb4e11c8Ben Murdochpublic:
251967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    explicit ExternalCharacterTokenBuffer(AtomicHTMLToken& token)
252967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        : m_current(token.characters().data())
253967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        , m_end(m_current + token.characters().size())
254967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    {
255967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        ASSERT(!isEmpty());
256967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
257967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
258967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    explicit ExternalCharacterTokenBuffer(const String& string)
259967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        : m_current(string.characters())
260967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        , m_end(m_current + string.length())
261967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    {
262967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        ASSERT(!isEmpty());
263967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
264967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
265967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ~ExternalCharacterTokenBuffer()
266967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    {
267967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        ASSERT(isEmpty());
268967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
269967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
270967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    bool isEmpty() const { return m_current == m_end; }
271967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
272967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    void skipLeadingWhitespace()
273967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    {
27468513a70bcd92384395513322f1b801e7bf9c729Steve Block        skipLeading<isHTMLSpace>();
275967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
276967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
277967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    String takeLeadingWhitespace()
278967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    {
27968513a70bcd92384395513322f1b801e7bf9c729Steve Block        return takeLeading<isHTMLSpace>();
280f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
281f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
282f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    String takeLeadingNonWhitespace()
283f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    {
28468513a70bcd92384395513322f1b801e7bf9c729Steve Block        return takeLeading<isNotHTMLSpace>();
285967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
286967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
287967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    String takeRemaining()
288967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    {
289967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        ASSERT(!isEmpty());
290967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        const UChar* start = m_current;
291967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        m_current = m_end;
292967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return String(start, m_current - start);
293967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
294967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
295967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    void giveRemainingTo(Vector<UChar>& recipient)
296967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    {
297967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        recipient.append(m_current, m_end - m_current);
298967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        m_current = m_end;
299967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
300967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
301967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    String takeRemainingWhitespace()
302967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    {
303967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        ASSERT(!isEmpty());
304967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        Vector<UChar> whitespace;
305967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        do {
306967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            UChar cc = *m_current++;
30768513a70bcd92384395513322f1b801e7bf9c729Steve Block            if (isHTMLSpace(cc))
308967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch                whitespace.append(cc);
309967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        } while (m_current < m_end);
310967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        // Returning the null string when there aren't any whitespace
311967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        // characters is slightly cleaner semantically because we don't want
312967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        // to insert a text node (as opposed to inserting an empty text node).
313967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (whitespace.isEmpty())
314967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            return String();
315967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return String::adopt(whitespace);
316967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
317967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
318967717af5423377c967781471ee106e2bb4e11c8Ben Murdochprivate:
319f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<bool characterPredicate(UChar)>
320f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    void skipLeading()
321f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    {
322f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        ASSERT(!isEmpty());
323f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        while (characterPredicate(*m_current)) {
324f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (++m_current == m_end)
325f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                return;
326f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        }
327f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
328f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
329f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<bool characterPredicate(UChar)>
330f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    String takeLeading()
331f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    {
332f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        ASSERT(!isEmpty());
333f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        const UChar* start = m_current;
334f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        skipLeading<characterPredicate>();
335f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        if (start == m_current)
336f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            return String();
337f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return String(start, m_current - start);
338f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
339f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
340967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    const UChar* m_current;
341967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    const UChar* m_end;
342967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch};
343967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
344967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
345cad810f21b803229eb11403f9209855525a25d57Steve BlockHTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, bool usePreHTML5ParserQuirks)
34606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    : m_framesetOk(true)
34706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    , m_document(document)
3482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    , m_tree(document)
34906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    , m_reportErrors(reportErrors)
35006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    , m_isPaused(false)
35106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    , m_insertionMode(InitialMode)
352ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    , m_originalInsertionMode(InitialMode)
353cad810f21b803229eb11403f9209855525a25d57Steve Block    , m_parser(parser)
3546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    , m_scriptToProcessStartPosition(uninitializedPositionValue1())
3556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    , m_lastScriptElementStartPosition(TextPosition0::belowRangePosition())
356bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_usePreHTML5ParserQuirks(usePreHTML5ParserQuirks)
357e14391e94c850b8bd03680c23b38978db68687a8John Reck    , m_hasPendingForeignInsertionModeSteps(false)
35806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
35906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
36006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
36106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen// FIXME: Member variables should be grouped into self-initializing structs to
36206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen// minimize code duplication between these constructors.
363cad810f21b803229eb11403f9209855525a25d57Steve BlockHTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, bool usePreHTML5ParserQuirks)
36406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    : m_framesetOk(true)
365e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    , m_fragmentContext(fragment, contextElement, scriptingPermission)
3662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    , m_document(fragment->document())
3672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    , m_tree(fragment, scriptingPermission)
36806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    , m_reportErrors(false) // FIXME: Why not report errors in fragments?
36906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    , m_isPaused(false)
37006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    , m_insertionMode(InitialMode)
371ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    , m_originalInsertionMode(InitialMode)
372cad810f21b803229eb11403f9209855525a25d57Steve Block    , m_parser(parser)
3736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    , m_scriptToProcessStartPosition(uninitializedPositionValue1())
3746b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    , m_lastScriptElementStartPosition(TextPosition0::belowRangePosition())
375bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    , m_usePreHTML5ParserQuirks(usePreHTML5ParserQuirks)
376e14391e94c850b8bd03680c23b38978db68687a8John Reck    , m_hasPendingForeignInsertionModeSteps(false)
37706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
378f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (contextElement) {
379f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm:
380f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
38181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // For efficiency, we skip step 4.2 ("Let root be a new html element with no attributes")
38281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // and instead use the DocumentFragment as a root node.
38381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_tree.openElements()->pushRootNode(fragment);
384f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        resetInsertionModeAppropriately();
385f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        m_tree.setForm(closestFormAncestor(contextElement));
386f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
38706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
38806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
38906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian MonsenHTMLTreeBuilder::~HTMLTreeBuilder()
39006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
39106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
39206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
393e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid HTMLTreeBuilder::detach()
394e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{
395e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // This call makes little sense in fragment mode, but for consistency
396e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // DocumentParser expects detach() to always be called before it's destroyed.
397e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    m_document = 0;
398e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // HTMLConstructionSite might be on the callstack when detach() is called
399e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // otherwise we'd just call m_tree.clear() here instead.
400e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    m_tree.detach();
401e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block}
402e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
403dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochHTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext()
404dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    : m_fragment(0)
405dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    , m_contextElement(0)
406dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    , m_scriptingPermission(FragmentScriptingAllowed)
407dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
408dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
409dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
410e8b154fd68f9b33be40a3590e58347f353835f5cSteve BlockHTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
4112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    : m_fragment(fragment)
412dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    , m_contextElement(contextElement)
413dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    , m_scriptingPermission(scriptingPermission)
414dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
4152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(!fragment->hasChildNodes());
416dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
417dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
418dd8bb3de4f353a81954234999f1fea748aee2ea9Ben MurdochHTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext()
419dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
420dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
421dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
4226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell BrennerPassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition1& scriptStartPosition)
42306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
42406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // Unpause ourselves, callers may pause us again when processing the script.
42506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // The HTML5 spec is written as though scripts are executed inside the tree
42606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // builder.  We pause the parser to exit the tree builder, and then resume
42706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    // before running scripts.
42806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    m_isPaused = false;
4296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    scriptStartPosition = m_scriptToProcessStartPosition;
4306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    m_scriptToProcessStartPosition = uninitializedPositionValue1();
43106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return m_scriptToProcess.release();
43206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
43306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
434ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid HTMLTreeBuilder::constructTreeFromToken(HTMLToken& rawToken)
43506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
43606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    AtomicHTMLToken token(rawToken);
437d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch
438d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // We clear the rawToken in case constructTreeFromAtomicToken
439d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // synchronously re-enters the parser. We don't clear the token immedately
440d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // for Character tokens because the AtomicHTMLToken avoids copying the
441d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // characters by keeping a pointer to the underlying buffer in the
442d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // HTMLToken. Fortuantely, Character tokens can't cause use to re-enter
443d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // the parser.
444d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    //
445d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // FIXME: Top clearing the rawToken once we start running the parser off
446d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // the main thread or once we stop allowing synchronous JavaScript
447d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // execution from parseMappedAttribute.
448d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    if (rawToken.type() != HTMLToken::Character)
449d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch        rawToken.clear();
450d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch
4515abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    constructTreeFromAtomicToken(token);
452d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch
453d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    if (!rawToken.isUninitialized()) {
454d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch        ASSERT(rawToken.type() == HTMLToken::Character);
455d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch        rawToken.clear();
456d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    }
4575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick}
4585abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick
4595abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickvoid HTMLTreeBuilder::constructTreeFromAtomicToken(AtomicHTMLToken& token)
4605abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick{
461ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    processToken(token);
462dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
463dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // Swallowing U+0000 characters isn't in the HTML5 spec, but turning all
464dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // the U+0000 characters into replacement characters has compatibility
465dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // problems.
466cad810f21b803229eb11403f9209855525a25d57Steve Block    m_parser->tokenizer()->setForceNullCharacterReplacement(m_insertionMode == TextMode || m_insertionMode == InForeignContentMode);
4672bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_parser->tokenizer()->setShouldAllowCDATA(m_insertionMode == InForeignContentMode && !isInHTMLNamespace(m_tree.currentNode()));
468ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
469ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
470ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid HTMLTreeBuilder::processToken(AtomicHTMLToken& token)
471ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
472ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    switch (token.type()) {
473ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case HTMLToken::Uninitialized:
474ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT_NOT_REACHED();
475ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
476ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case HTMLToken::DOCTYPE:
477ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        processDoctypeToken(token);
478ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
479ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case HTMLToken::StartTag:
480ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        processStartTag(token);
481ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
482ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case HTMLToken::EndTag:
483ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        processEndTag(token);
484ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
485ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case HTMLToken::Comment:
486ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        processComment(token);
487ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return;
488ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case HTMLToken::Character:
489ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        processCharacter(token);
490ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
491ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case HTMLToken::EndOfFile:
492ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        processEndOfFile(token);
493ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
494ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
495ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
496ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
497ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid HTMLTreeBuilder::processDoctypeToken(AtomicHTMLToken& token)
498ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
499e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::DOCTYPE);
500e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (m_insertionMode == InitialMode) {
501e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertDoctype(token);
5025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        setInsertionMode(BeforeHTMLMode);
503e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
504e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
505e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (m_insertionMode == InTableTextMode) {
506967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInTableText();
507e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processDoctypeToken(token);
508ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return;
509ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
510ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    parseError(token);
511ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
51206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
513e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processFakeStartTag(const QualifiedName& tagName, PassRefPtr<NamedNodeMap> attributes)
514e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
515e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // FIXME: We'll need a fancier conversion than just "localName" for SVG/MathML tags.
516e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    AtomicHTMLToken fakeToken(HTMLToken::StartTag, tagName.localName(), attributes);
517e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processStartTag(fakeToken);
518e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
519e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
520e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processFakeEndTag(const QualifiedName& tagName)
521ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
522e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // FIXME: We'll need a fancier conversion than just "localName" for SVG/MathML tags.
523e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    AtomicHTMLToken fakeToken(HTMLToken::EndTag, tagName.localName());
524e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processEndTag(fakeToken);
525ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
526ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
527e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processFakeCharacters(const String& characters)
528e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
529967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ASSERT(!characters.isEmpty());
530967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ExternalCharacterTokenBuffer buffer(characters);
531967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    processCharacterBuffer(buffer);
532e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
533e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
5340617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenvoid HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
535ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
5360617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    if (!m_tree.openElements()->inButtonScope(pTag.localName()))
537ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return;
538e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    AtomicHTMLToken endP(HTMLToken::EndTag, pTag.localName());
539e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processEndTag(endP);
540e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
541ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
542e458d70a0d18538346f41b503114c9ebe6b2ce12Leon ClarkePassRefPtr<NamedNodeMap> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken& token)
543e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
544e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    RefPtr<NamedNodeMap> attributes = token.takeAtributes();
545e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!attributes)
546e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        attributes = NamedNodeMap::create();
547e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    else {
548e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        attributes->removeAttribute(nameAttr);
549e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        attributes->removeAttribute(actionAttr);
550e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        attributes->removeAttribute(promptAttr);
55106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    }
552e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
553e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    RefPtr<Attribute> mappedAttribute = Attribute::createMapped(nameAttr, isindexTag.localName());
554e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    attributes->insertAttribute(mappedAttribute.release(), false);
555e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return attributes.release();
55606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
55706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
558e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken& token)
559ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
560e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::StartTag);
561e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.name() == isindexTag);
562ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    parseError(token);
563e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (m_tree.form())
564e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
565e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    notImplemented(); // Acknowledge self-closing flag
566e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processFakeStartTag(formTag);
5676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    RefPtr<Attribute> actionAttribute = token.getAttributeItem(actionAttr);
568e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (actionAttribute) {
569e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(m_tree.currentElement()->hasTagName(formTag));
570e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.currentElement()->setAttribute(actionAttr, actionAttribute->value());
571e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
572e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processFakeStartTag(hrTag);
573e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processFakeStartTag(labelTag);
5746b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    RefPtr<Attribute> promptAttribute = token.getAttributeItem(promptAttr);
575e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (promptAttribute)
576e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processFakeCharacters(promptAttribute->value());
577e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    else
578e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processFakeCharacters(searchableIndexIntroduction());
579e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processFakeStartTag(inputTag, attributesForIsindexInput(token));
580e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    notImplemented(); // This second set of characters may be needed by non-english locales.
581e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processFakeEndTag(labelTag);
582e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processFakeStartTag(hrTag);
583e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processFakeEndTag(formTag);
584ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
585ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
586e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkenamespace {
587e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
58881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool isLi(const ContainerNode* element)
589e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
590e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return element->hasTagName(liTag);
591e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
592e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
59381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool isDdOrDt(const ContainerNode* element)
594e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
595e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return element->hasTagName(ddTag)
596e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || element->hasTagName(dtTag);
597e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
598e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
599e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
600e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
60181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochtemplate <bool shouldClose(const ContainerNode*)>
602e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken& token)
603e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
604e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_framesetOk = false;
605e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
606e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    while (1) {
60781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ContainerNode* node = nodeRecord->node();
608e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (shouldClose(node)) {
60981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            ASSERT(node->isElementNode());
61081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            processFakeEndTag(toElement(node)->tagQName());
611e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            break;
612e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
613e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        if (isSpecialNode(node) && !node->hasTagName(addressTag) && !node->hasTagName(divTag) && !node->hasTagName(pTag))
614e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            break;
615e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        nodeRecord = nodeRecord->next();
616e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
6170617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    processFakePEndTagIfPInButtonScope();
618e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.insertHTMLElement(token);
619e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
620e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
621e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkenamespace {
622e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
623e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarketypedef HashMap<AtomicString, QualifiedName> PrefixedNameToQualifiedNameMap;
624e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
625e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid mapLoweredLocalNameToName(PrefixedNameToQualifiedNameMap* map, QualifiedName** names, size_t length)
626e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
627e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    for (size_t i = 0; i < length; ++i) {
628e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        const QualifiedName& name = *names[i];
629e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        const AtomicString& localName = name.localName();
630e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        AtomicString loweredLocalName = localName.lower();
631e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (loweredLocalName != localName)
632e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            map->add(loweredLocalName, name);
633e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
634e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
635e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
636e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid adjustSVGTagNameCase(AtomicHTMLToken& token)
637e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
638e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    static PrefixedNameToQualifiedNameMap* caseMap = 0;
639e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!caseMap) {
640e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        caseMap = new PrefixedNameToQualifiedNameMap;
641e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        size_t length = 0;
642e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QualifiedName** svgTags = SVGNames::getSVGTags(&length);
643e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        mapLoweredLocalNameToName(caseMap, svgTags, length);
644e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
645e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
646e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    const QualifiedName& casedName = caseMap->get(token.name());
647e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (casedName.localName().isNull())
648ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return;
649e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    token.setName(casedName.localName());
650ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
651ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
6520617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsentemplate<QualifiedName** getAttrs(size_t* length)>
6530617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenvoid adjustAttributes(AtomicHTMLToken& token)
65406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
655e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    static PrefixedNameToQualifiedNameMap* caseMap = 0;
656e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!caseMap) {
657e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        caseMap = new PrefixedNameToQualifiedNameMap;
658e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        size_t length = 0;
6590617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QualifiedName** attrs = getAttrs(&length);
6600617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        mapLoweredLocalNameToName(caseMap, attrs, length);
661e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
662e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
663e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    NamedNodeMap* attributes = token.attributes();
664e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!attributes)
665e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
666e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
667e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    for (unsigned x = 0; x < attributes->length(); ++x) {
668e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        Attribute* attribute = attributes->attributeItem(x);
669e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        const QualifiedName& casedName = caseMap->get(attribute->localName());
670e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!casedName.localName().isNull())
671e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            attribute->parserSetName(casedName);
672e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
673e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
674e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
6750617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenvoid adjustSVGAttributes(AtomicHTMLToken& token)
6760617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
6770617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    adjustAttributes<SVGNames::getSVGAttrs>(token);
6780617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
6790617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
6800617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenvoid adjustMathMLAttributes(AtomicHTMLToken& token)
681e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
6820617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    adjustAttributes<MathMLNames::getMathMLAttrs>(token);
683e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
684e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
685e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid addNamesWithPrefix(PrefixedNameToQualifiedNameMap* map, const AtomicString& prefix, QualifiedName** names, size_t length)
686e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
687e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    for (size_t i = 0; i < length; ++i) {
688e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QualifiedName* name = names[i];
689e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        const AtomicString& localName = name->localName();
690e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        AtomicString prefixColonLocalName(prefix + ":" + localName);
691e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QualifiedName nameWithPrefix(prefix, localName, name->namespaceURI());
692e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        map->add(prefixColonLocalName, nameWithPrefix);
693e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
694e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
695e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
696e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid adjustForeignAttributes(AtomicHTMLToken& token)
697e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
698e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    static PrefixedNameToQualifiedNameMap* map = 0;
699e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!map) {
700e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        map = new PrefixedNameToQualifiedNameMap;
701e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        size_t length = 0;
702e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QualifiedName** attrs = XLinkNames::getXLinkAttrs(&length);
703e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        addNamesWithPrefix(map, "xlink", attrs, length);
704e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
705e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        attrs = XMLNames::getXMLAttrs(&length);
706e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        addNamesWithPrefix(map, "xml", attrs, length);
707e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
708e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        map->add("xmlns", XMLNSNames::xmlnsAttr);
709e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        map->add("xmlns:xlink", QualifiedName("xmlns", "xlink", XMLNSNames::xmlnsNamespaceURI));
710e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
711e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
712e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    NamedNodeMap* attributes = token.attributes();
713e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!attributes)
714e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
715e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
716e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    for (unsigned x = 0; x < attributes->length(); ++x) {
717e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        Attribute* attribute = attributes->attributeItem(x);
718e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        const QualifiedName& name = map->get(attribute->localName());
719e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!name.localName().isNull())
720e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            attribute->parserSetName(name);
721e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
722e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
723e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
724e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
725e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
726e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
727e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
728e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::StartTag);
729e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == htmlTag) {
730e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLHtmlStartTagInBody(token);
731e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
732e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
733e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == baseTag
7340617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == basefontTag
7350617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == bgsoundTag
7360617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == commandTag
737e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == linkTag
738e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == metaTag
739e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == noframesTag
740e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == scriptTag
741e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == styleTag
742e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == titleTag) {
743e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        bool didProcess = processStartTagForInHead(token);
744e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT_UNUSED(didProcess, didProcess);
745e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
746e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
747e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == bodyTag) {
748dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        if (!m_tree.openElements()->secondElementIsHTMLBodyElement() || m_tree.openElements()->hasOnlyOneElement()) {
749dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
750dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            return;
751dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        }
752e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLBodyStartTagInBody(token);
753e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
754e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
755e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == framesetTag) {
756e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        parseError(token);
757dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        if (!m_tree.openElements()->secondElementIsHTMLBodyElement() || m_tree.openElements()->hasOnlyOneElement()) {
758dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
759dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            return;
760dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        }
761e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!m_framesetOk)
762ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
763e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ExceptionCode ec = 0;
764e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->bodyElement()->remove(ec);
765e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(!ec);
766e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntil(m_tree.openElements()->bodyElement());
767e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popHTMLBodyElement();
768e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(m_tree.openElements()->top() == m_tree.openElements()->htmlElement());
769e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
770e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(InFramesetMode);
771e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
772e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
773e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == addressTag
774e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == articleTag
775e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == asideTag
776e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == blockquoteTag
777e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == centerTag
7780617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == detailsTag
779e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == dirTag
780e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == divTag
781e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == dlTag
782e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == fieldsetTag
7830617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == figcaptionTag
7840617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == figureTag
785e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == footerTag
786e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == headerTag
787e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == hgroupTag
788e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == menuTag
789e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == navTag
790e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == olTag
791e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == pTag
792e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == sectionTag
7930617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == summaryTag
794e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == ulTag) {
7950617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        processFakePEndTagIfPInButtonScope();
796e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
797e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
798e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
799e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (isNumberedHeaderTag(token.name())) {
8000617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        processFakePEndTagIfPInButtonScope();
80181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (isNumberedHeaderTag(m_tree.currentNode()->localName())) {
80206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            parseError(token);
803e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->pop();
804ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
805e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
806e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
807e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
808e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == preTag || token.name() == listingTag) {
8090617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        processFakePEndTagIfPInButtonScope();
810e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
811cad810f21b803229eb11403f9209855525a25d57Steve Block        m_parser->tokenizer()->setSkipLeadingNewLineForListing(true);
812e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_framesetOk = false;
813e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
814e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
815e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == formTag) {
816e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (m_tree.form()) {
81706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            parseError(token);
818ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
81906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        }
8200617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        processFakePEndTagIfPInButtonScope();
821967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        m_tree.insertHTMLFormElement(token);
822e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
823e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
824e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == liTag) {
825e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processCloseWhenNestedTag<isLi>(token);
826e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
827e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
828e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == ddTag || token.name() == dtTag) {
829e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processCloseWhenNestedTag<isDdOrDt>(token);
830e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
831e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
832e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == plaintextTag) {
8330617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        processFakePEndTagIfPInButtonScope();
834e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
835cad810f21b803229eb11403f9209855525a25d57Steve Block        m_parser->tokenizer()->setState(HTMLTokenizer::PLAINTEXTState);
836e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
837e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
838e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == buttonTag) {
839e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (m_tree.openElements()->inScope(buttonTag)) {
840e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
841e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processFakeEndTag(buttonTag);
842e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessStartTag(token); // FIXME: Could we just fall through here?
843ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
844ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
845e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
846e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
847e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_framesetOk = false;
848e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
849e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
850e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == aTag) {
851e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        Element* activeATag = m_tree.activeFormattingElements()->closestElementInScopeWithName(aTag.localName());
852e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (activeATag) {
85306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            parseError(token);
854e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processFakeEndTag(aTag);
855e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.activeFormattingElements()->remove(activeATag);
856e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (m_tree.openElements()->contains(activeATag))
857e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                m_tree.openElements()->remove(activeATag);
858ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
859e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
860e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertFormattingElement(token);
861e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
862e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
863e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (isNonAnchorNonNobrFormattingTag(token.name())) {
864e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
865e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertFormattingElement(token);
866e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
867e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
868e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == nobrTag) {
869e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
870e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (m_tree.openElements()->inScope(nobrTag)) {
871ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            parseError(token);
872e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processFakeEndTag(nobrTag);
873e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.reconstructTheActiveFormattingElements();
874ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
875e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertFormattingElement(token);
876e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
877e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
878e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == appletTag
879e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == marqueeTag
880e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == objectTag) {
881e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
882e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
883e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.activeFormattingElements()->appendMarker();
884e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_framesetOk = false;
885e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
886e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
887e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == tableTag) {
8885ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        if (!m_document->inQuirksMode() && m_tree.openElements()->inButtonScope(pTag))
889e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processFakeEndTag(pTag);
890e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
891e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_framesetOk = false;
892e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(InTableMode);
893e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
894e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
895e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == imageTag) {
896e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        parseError(token);
897e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Apparently we're not supposed to ask.
898e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        token.setName(imgTag.localName());
899e14391e94c850b8bd03680c23b38978db68687a8John Reck        prepareToReprocessToken();
900e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Note the fall through to the imgTag handling below!
901e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
902e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == areaTag
903e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == brTag
904e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == embedTag
905e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == imgTag
906e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == keygenTag
907e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == wbrTag) {
908e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
909e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertSelfClosingHTMLElement(token);
910e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_framesetOk = false;
911e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
912e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
913cad810f21b803229eb11403f9209855525a25d57Steve Block    if (token.name() == inputTag) {
914cad810f21b803229eb11403f9209855525a25d57Steve Block        RefPtr<Attribute> typeAttribute = token.getAttributeItem(typeAttr);
915cad810f21b803229eb11403f9209855525a25d57Steve Block        m_tree.reconstructTheActiveFormattingElements();
916cad810f21b803229eb11403f9209855525a25d57Steve Block        m_tree.insertSelfClosingHTMLElement(token);
917cad810f21b803229eb11403f9209855525a25d57Steve Block        if (!typeAttribute || !equalIgnoringCase(typeAttribute->value(), "hidden"))
918cad810f21b803229eb11403f9209855525a25d57Steve Block            m_framesetOk = false;
919cad810f21b803229eb11403f9209855525a25d57Steve Block        return;
920cad810f21b803229eb11403f9209855525a25d57Steve Block    }
921e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == paramTag
922e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == sourceTag
9230617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == trackTag) {
924e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertSelfClosingHTMLElement(token);
925e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
926e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
927e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == hrTag) {
9280617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        processFakePEndTagIfPInButtonScope();
929e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertSelfClosingHTMLElement(token);
930e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_framesetOk = false;
931e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
932e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
933e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == isindexTag) {
934e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processIsindexStartTagForInBody(token);
935e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
936e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
937e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == textareaTag) {
938e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
939cad810f21b803229eb11403f9209855525a25d57Steve Block        m_parser->tokenizer()->setSkipLeadingNewLineForListing(true);
940cad810f21b803229eb11403f9209855525a25d57Steve Block        m_parser->tokenizer()->setState(HTMLTokenizer::RCDATAState);
941e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_originalInsertionMode = m_insertionMode;
942e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_framesetOk = false;
943e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(TextMode);
944e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
945e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
946e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == xmpTag) {
9470617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        processFakePEndTagIfPInButtonScope();
948e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
949e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_framesetOk = false;
950e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processGenericRawTextStartTag(token);
951e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
952e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
953e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == iframeTag) {
954e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_framesetOk = false;
955e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processGenericRawTextStartTag(token);
956e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
957e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
958dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    if (token.name() == noembedTag && pluginsEnabled(m_document->frame())) {
959e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processGenericRawTextStartTag(token);
960e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
961e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
962dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    if (token.name() == noscriptTag && scriptEnabled(m_document->frame())) {
963e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processGenericRawTextStartTag(token);
964e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
965e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
966e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == selectTag) {
967e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
968e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
969e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_framesetOk = false;
970e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (m_insertionMode == InTableMode
971e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke             || m_insertionMode == InCaptionMode
972e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke             || m_insertionMode == InColumnGroupMode
973e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke             || m_insertionMode == InTableBodyMode
974e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke             || m_insertionMode == InRowMode
975e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke             || m_insertionMode == InCellMode)
976e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(InSelectInTableMode);
977e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        else
978e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(InSelectMode);
979e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
980e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
981e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == optgroupTag || token.name() == optionTag) {
982e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (m_tree.openElements()->inScope(optionTag.localName())) {
983e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
984e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processEndTag(endOption);
985ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
986e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
987e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
988e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
989e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
990e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == rpTag || token.name() == rtTag) {
991e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (m_tree.openElements()->inScope(rubyTag.localName())) {
992e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.generateImpliedEndTags();
99381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (!m_tree.currentNode()->hasTagName(rubyTag)) {
994e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                parseError(token);
995e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                m_tree.openElements()->popUntil(rubyTag.localName());
996e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
997ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
998e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
999e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1000e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1001e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == MathMLNames::mathTag.localName()) {
1002e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
1003e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        adjustMathMLAttributes(token);
1004e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        adjustForeignAttributes(token);
1005e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertForeignElement(token, MathMLNames::mathmlNamespaceURI);
10062bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (m_insertionMode != InForeignContentMode && !token.selfClosing())
1007e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(InForeignContentMode);
1008e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1009e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1010e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == SVGNames::svgTag.localName()) {
1011e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
1012e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        adjustSVGAttributes(token);
1013e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        adjustForeignAttributes(token);
1014e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertForeignElement(token, SVGNames::svgNamespaceURI);
10152bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (m_insertionMode != InForeignContentMode && !token.selfClosing())
1016e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(InForeignContentMode);
1017e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1018e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1019e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (isCaptionColOrColgroupTag(token.name())
1020e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == frameTag
1021e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == headTag
1022e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isTableBodyContextTag(token.name())
1023e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isTableCellContextTag(token.name())
1024e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == trTag) {
1025e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        parseError(token);
1026e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1027e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1028e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.reconstructTheActiveFormattingElements();
1029e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.insertHTMLElement(token);
1030e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1031e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1032e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
1033e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
103481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_tree.currentNode() == m_tree.openElements()->rootNode()) {
1035dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        ASSERT(isParsingFragment());
1036e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // FIXME: parse error
1037e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return false;
1038e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1039e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.openElements()->pop();
1040e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    setInsertionMode(InTableMode);
1041e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return true;
1042e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1043e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1044e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#close-the-cell
1045e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::closeTheCell()
1046e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
1047e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(insertionMode() == InCellMode);
1048967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (m_tree.openElements()->inTableScope(tdTag)) {
1049967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        ASSERT(!m_tree.openElements()->inTableScope(thTag));
1050e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processFakeEndTag(tdTag);
1051e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1052e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1053967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ASSERT(m_tree.openElements()->inTableScope(thTag));
1054e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processFakeEndTag(thTag);
1055e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(insertionMode() == InRowMode);
1056e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1057e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1058e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
1059e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
1060e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::StartTag);
1061e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == captionTag) {
1062e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntilTableScopeMarker();
1063e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.activeFormattingElements()->appendMarker();
1064e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
1065e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(InCaptionMode);
1066e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1067e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1068e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == colgroupTag) {
1069e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntilTableScopeMarker();
1070e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
1071e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(InColumnGroupMode);
1072e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1073e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1074e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == colTag) {
1075e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processFakeStartTag(colgroupTag);
1076e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(InColumnGroupMode);
1077e14391e94c850b8bd03680c23b38978db68687a8John Reck        reprocessStartTag(token);
1078e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1079e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1080e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (isTableBodyContextTag(token.name())) {
1081e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntilTableScopeMarker();
1082e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
1083e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(InTableBodyMode);
1084e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1085e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1086e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (isTableCellContextTag(token.name())
1087e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == trTag) {
1088e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processFakeStartTag(tbodyTag);
1089e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InTableBodyMode);
1090e14391e94c850b8bd03680c23b38978db68687a8John Reck        reprocessStartTag(token);
1091e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1092e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1093e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == tableTag) {
1094e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        parseError(token);
1095e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!processTableEndTagForInTable()) {
1096dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
1097ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1098ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1099e14391e94c850b8bd03680c23b38978db68687a8John Reck        reprocessStartTag(token);
1100e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1101e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1102e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == styleTag || token.name() == scriptTag) {
1103e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processStartTagForInHead(token);
1104e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1105e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1106e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == inputTag) {
1107e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        Attribute* typeAttribute = token.getAttributeItem(typeAttr);
1108967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (typeAttribute && equalIgnoringCase(typeAttribute->value(), "hidden")) {
1109ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            parseError(token);
1110e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertSelfClosingHTMLElement(token);
1111ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1112ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1113e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through to "anything else" case.
1114e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1115e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == formTag) {
1116e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        parseError(token);
1117e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (m_tree.form())
1118ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
11195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        m_tree.insertHTMLFormElement(token, true);
1120967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        m_tree.openElements()->pop();
1121e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1122e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1123e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    parseError(token);
1124967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree);
1125e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processStartTagForInBody(token);
1126e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1127e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1128e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkenamespace {
1129e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
113081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool shouldProcessForeignContentUsingInBodyInsertionMode(AtomicHTMLToken& token, ContainerNode* currentElement)
1131e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
1132e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::StartTag);
1133e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (currentElement->hasTagName(MathMLNames::miTag)
1134e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || currentElement->hasTagName(MathMLNames::moTag)
1135e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || currentElement->hasTagName(MathMLNames::mnTag)
1136e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || currentElement->hasTagName(MathMLNames::msTag)
1137e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || currentElement->hasTagName(MathMLNames::mtextTag)) {
1138e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return token.name() != MathMLNames::mglyphTag
1139e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            && token.name() != MathMLNames::malignmarkTag;
1140e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1141e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (currentElement->hasTagName(MathMLNames::annotation_xmlTag))
1142e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return token.name() == SVGNames::svgTag;
1143e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (currentElement->hasTagName(SVGNames::foreignObjectTag)
1144e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || currentElement->hasTagName(SVGNames::descTag)
1145e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || currentElement->hasTagName(SVGNames::titleTag))
1146e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return true;
11472bde8e466a4451c7319e3a072d118917957d6554Steve Block    return isInHTMLNamespace(currentElement);
1148e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1149e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1150e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1151e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1152e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
1153e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
1154e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::StartTag);
1155e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    switch (insertionMode()) {
1156e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InitialMode:
1157e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InitialMode);
1158967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInitial();
1159e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through.
1160e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case BeforeHTMLMode:
1161e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == BeforeHTMLMode);
1162e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == htmlTag) {
1163e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLHtmlStartTagBeforeHTML(token);
1164e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(BeforeHeadMode);
1165ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1166ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1167967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForBeforeHTML();
1168e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through.
1169e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case BeforeHeadMode:
1170e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == BeforeHeadMode);
1171e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == htmlTag) {
1172e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLHtmlStartTagInBody(token);
1173ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1174ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1175e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == headTag) {
1176e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLHeadElement(token);
1177e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(InHeadMode);
1178ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1179ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1180967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForBeforeHead();
1181e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through.
1182e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InHeadMode:
1183e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InHeadMode);
1184e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (processStartTagForInHead(token))
1185ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1186967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInHead();
1187e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through.
1188e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case AfterHeadMode:
1189e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == AfterHeadMode);
1190e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == htmlTag) {
1191e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLHtmlStartTagInBody(token);
1192ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1193ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1194e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == bodyTag) {
1195ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            m_framesetOk = false;
1196e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLBodyElement(token);
1197e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(InBodyMode);
1198ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1199ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1200e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == framesetTag) {
1201e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLElement(token);
1202e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(InFramesetMode);
1203ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1204ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1205e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == baseTag
12060617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            || token.name() == basefontTag
12070617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            || token.name() == bgsoundTag
1208e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == linkTag
1209e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == metaTag
1210e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == noframesTag
1211e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == scriptTag
1212e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == styleTag
1213e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == titleTag) {
1214e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1215e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            ASSERT(m_tree.head());
1216e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->pushHTMLHeadElement(m_tree.head());
1217e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processStartTagForInHead(token);
1218e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->removeHTMLHeadElement(m_tree.head());
1219ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1220ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1221e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == headTag) {
1222ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            parseError(token);
1223ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1224ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1225967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForAfterHead();
1226e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through
1227e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InBodyMode:
1228e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InBodyMode);
1229e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processStartTagForInBody(token);
1230ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
1231ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InTableMode:
1232ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InTableMode);
1233e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processStartTagForInTable(token);
1234e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
1235e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InCaptionMode:
1236e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InCaptionMode);
1237e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (isCaptionColOrColgroupTag(token.name())
1238e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isTableBodyContextTag(token.name())
1239e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isTableCellContextTag(token.name())
1240e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == trTag) {
1241e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1242e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (!processCaptionEndTagForInCaption()) {
1243dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch                ASSERT(isParsingFragment());
1244e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                return;
1245e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
1246e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessStartTag(token);
1247ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1248ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1249e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processStartTagForInBody(token);
1250e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
1251e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InColumnGroupMode:
1252e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InColumnGroupMode);
1253e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == htmlTag) {
1254e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLHtmlStartTagInBody(token);
1255ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1256ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1257ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == colTag) {
1258e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertSelfClosingHTMLElement(token);
1259ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1260ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1261e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!processColgroupEndTagForInColumnGroup()) {
1262dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
1263ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1264ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1265e14391e94c850b8bd03680c23b38978db68687a8John Reck        reprocessStartTag(token);
1266ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
1267ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InTableBodyMode:
1268ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InTableBodyMode);
1269ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == trTag) {
1270e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->popUntilTableBodyScopeMarker(); // How is there ever anything to pop?
1271e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLElement(token);
1272e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(InRowMode);
1273ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1274ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1275e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (isTableCellContextTag(token.name())) {
1276ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            parseError(token);
1277e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processFakeStartTag(trTag);
1278ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            ASSERT(insertionMode() == InRowMode);
1279e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessStartTag(token);
1280ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1281ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1282e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (isCaptionColOrColgroupTag(token.name()) || isTableBodyContextTag(token.name())) {
1283e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            // FIXME: This is slow.
1284e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (!m_tree.openElements()->inTableScope(tbodyTag.localName()) && !m_tree.openElements()->inTableScope(theadTag.localName()) && !m_tree.openElements()->inTableScope(tfootTag.localName())) {
1285dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch                ASSERT(isParsingFragment());
1286e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                parseError(token);
1287e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                return;
1288e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
1289e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->popUntilTableBodyScopeMarker();
1290e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            ASSERT(isTableBodyContextTag(m_tree.currentElement()->localName()));
1291e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processFakeEndTag(m_tree.currentElement()->tagQName());
1292e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessStartTag(token);
1293e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1294e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1295e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processStartTagForInTable(token);
1296e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
1297e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InRowMode:
1298e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InRowMode);
1299e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (isTableCellContextTag(token.name())) {
1300e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->popUntilTableRowScopeMarker();
1301e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLElement(token);
1302e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(InCellMode);
1303e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.activeFormattingElements()->appendMarker();
1304e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1305e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1306e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == trTag
1307e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isCaptionColOrColgroupTag(token.name())
1308e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isTableBodyContextTag(token.name())) {
1309e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (!processTrEndTagForInRow()) {
1310dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch                ASSERT(isParsingFragment());
1311e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                return;
1312e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
1313e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            ASSERT(insertionMode() == InTableBodyMode);
1314e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessStartTag(token);
1315ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1316ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1317e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processStartTagForInTable(token);
1318e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
1319e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InCellMode:
1320e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InCellMode);
1321e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (isCaptionColOrColgroupTag(token.name())
1322e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isTableCellContextTag(token.name())
1323e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == trTag
1324e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isTableBodyContextTag(token.name())) {
1325e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            // FIXME: This could be more efficient.
1326e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (!m_tree.openElements()->inTableScope(tdTag) && !m_tree.openElements()->inTableScope(thTag)) {
1327dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch                ASSERT(isParsingFragment());
1328e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                parseError(token);
1329e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                return;
1330e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
1331e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            closeTheCell();
1332e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessStartTag(token);
1333e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1334e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1335e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processStartTagForInBody(token);
1336ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
1337ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case AfterBodyMode:
1338ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case AfterAfterBodyMode:
1339ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
1340ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == htmlTag) {
1341e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLHtmlStartTagInBody(token);
1342ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1343ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1344e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(InBodyMode);
1345e14391e94c850b8bd03680c23b38978db68687a8John Reck        reprocessStartTag(token);
1346ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
1347ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InHeadNoscriptMode:
1348ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InHeadNoscriptMode);
1349ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == htmlTag) {
1350e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLHtmlStartTagInBody(token);
1351ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1352ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
13530617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        if (token.name() == basefontTag
13540617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            || token.name() == bgsoundTag
13550617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            || token.name() == linkTag
1356e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == metaTag
1357e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == noframesTag
1358e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == styleTag) {
1359ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            bool didProcess = processStartTagForInHead(token);
1360ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            ASSERT_UNUSED(didProcess, didProcess);
1361ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1362ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1363ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == htmlTag || token.name() == noscriptTag) {
136406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            parseError(token);
1365ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1366ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1367967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInHeadNoscript();
1368ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        processToken(token);
1369ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
1370ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InFramesetMode:
1371ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InFramesetMode);
1372ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == htmlTag) {
1373e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLHtmlStartTagInBody(token);
1374ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1375ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1376ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == framesetTag) {
1377e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLElement(token);
1378ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1379ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1380ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == frameTag) {
1381e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertSelfClosingHTMLElement(token);
1382ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1383ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1384ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == noframesTag) {
1385ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            processStartTagForInHead(token);
1386ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
138706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        }
1388ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        parseError(token);
1389ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
1390ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case AfterFramesetMode:
1391ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case AfterAfterFramesetMode:
1392ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode);
1393ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == htmlTag) {
1394e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLHtmlStartTagInBody(token);
1395ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1396ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1397ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == noframesTag) {
1398ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            processStartTagForInHead(token);
1399ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1400ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1401ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        parseError(token);
1402ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
1403e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InSelectInTableMode:
1404e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InSelectInTableMode);
1405e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == captionTag
1406e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == tableTag
1407e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isTableBodyContextTag(token.name())
1408e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == trTag
1409e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isTableCellContextTag(token.name())) {
1410e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1411e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
1412e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processEndTag(endSelect);
1413e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessStartTag(token);
1414e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1415e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1416e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through
1417e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InSelectMode:
1418e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode);
1419e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == htmlTag) {
1420e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLHtmlStartTagInBody(token);
1421e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1422e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1423e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == optionTag) {
142481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (m_tree.currentNode()->hasTagName(optionTag)) {
1425e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
1426e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                processEndTag(endOption);
1427e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
1428e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLElement(token);
1429e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1430e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1431e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == optgroupTag) {
143281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (m_tree.currentNode()->hasTagName(optionTag)) {
1433e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
1434e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                processEndTag(endOption);
1435e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
143681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (m_tree.currentNode()->hasTagName(optgroupTag)) {
1437e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                AtomicHTMLToken endOptgroup(HTMLToken::EndTag, optgroupTag.localName());
1438e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                processEndTag(endOptgroup);
1439e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
1440e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertHTMLElement(token);
1441e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1442e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1443e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == selectTag) {
1444e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1445e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
1446e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processEndTag(endSelect);
1447e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1448e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1449e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == inputTag
1450e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == keygenTag
1451e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == textareaTag) {
1452e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1453a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!m_tree.openElements()->inSelectScope(selectTag)) {
14545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                ASSERT(isParsingFragment());
14555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                return;
14565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            }
1457e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
1458e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processEndTag(endSelect);
1459e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessStartTag(token);
1460e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1461e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1462e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == scriptTag) {
1463e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            bool didProcess = processStartTagForInHead(token);
1464e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            ASSERT_UNUSED(didProcess, didProcess);
1465e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1466e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1467e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
1468e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InTableTextMode:
1469967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInTableText();
1470e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processStartTag(token);
1471e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
1472e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InForeignContentMode: {
14732bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (shouldProcessForeignContentUsingInBodyInsertionMode(token, m_tree.currentNode())) {
1474e14391e94c850b8bd03680c23b38978db68687a8John Reck            processForeignContentUsingInBodyModeAndResetMode(token);
1475e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1476e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1477e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == bTag
1478e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == bigTag
1479e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == blockquoteTag
1480e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == bodyTag
1481e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == brTag
1482e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == centerTag
1483e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == codeTag
1484e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == ddTag
1485e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == divTag
1486e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == dlTag
1487e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == dtTag
1488e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == emTag
1489e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == embedTag
1490e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isNumberedHeaderTag(token.name())
1491e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == headTag
1492e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == hrTag
1493e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == iTag
1494e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == imgTag
1495e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == liTag
1496e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == listingTag
1497e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == menuTag
1498e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == metaTag
1499e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == nobrTag
1500e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == olTag
1501e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == pTag
1502e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == preTag
1503e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == rubyTag
1504e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == sTag
1505e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == smallTag
1506e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == spanTag
1507e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == strongTag
1508e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == strikeTag
1509e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == subTag
1510e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == supTag
1511e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == tableTag
1512e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == ttTag
1513e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == uTag
1514e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == ulTag
1515e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == varTag
1516e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || (token.name() == fontTag && (token.getAttributeItem(colorAttr) || token.getAttributeItem(faceAttr) || token.getAttributeItem(sizeAttr)))) {
151768513a70bcd92384395513322f1b801e7bf9c729Steve Block            parseError(token);
151868513a70bcd92384395513322f1b801e7bf9c729Steve Block            m_tree.openElements()->popUntilForeignContentScopeMarker();
1519e14391e94c850b8bd03680c23b38978db68687a8John Reck            resetInsertionModeAppropriately();
1520e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessStartTag(token);
1521e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1522e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1523e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        const AtomicString& currentNamespace = m_tree.currentElement()->namespaceURI();
1524e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (currentNamespace == MathMLNames::mathmlNamespaceURI)
1525e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            adjustMathMLAttributes(token);
1526e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (currentNamespace == SVGNames::svgNamespaceURI) {
1527e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            adjustSVGTagNameCase(token);
1528e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            adjustSVGAttributes(token);
1529e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1530e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        adjustForeignAttributes(token);
1531e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertForeignElement(token, currentNamespace);
1532e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
1533e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1534e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case TextMode:
153568513a70bcd92384395513322f1b801e7bf9c729Steve Block        ASSERT_NOT_REACHED();
1536e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
1537ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
1538ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
1539ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
1540ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockbool HTMLTreeBuilder::processBodyEndTagForInBody(AtomicHTMLToken& token)
1541ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
1542e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::EndTag);
1543e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.name() == bodyTag);
1544e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!m_tree.openElements()->inScope(bodyTag.localName())) {
1545ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        parseError(token);
1546ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return false;
154706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    }
1548967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    notImplemented(); // Emit a more specific parse error based on stack contents.
1549e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    setInsertionMode(AfterBodyMode);
1550ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return true;
1551ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
1552ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
1553e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken& token)
1554e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
1555e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::EndTag);
1556e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord();
1557e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    while (1) {
155881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ContainerNode* node = record->node();
1559e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->hasLocalName(token.name())) {
1560e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.generateImpliedEndTags();
156181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // FIXME: The ElementRecord pointed to by record might be deleted by
156281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // the preceding call. Perhaps we should hold a RefPtr so that it
156381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // stays alive for the duration of record's scope.
156481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            record = 0;
156581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (!m_tree.currentNode()->hasLocalName(token.name())) {
1566e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                parseError(token);
1567e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                // FIXME: This is either a bug in the spec, or a bug in our
1568e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                // implementation.  Filed a bug with HTML5:
1569e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10080
1570e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                // We might have already popped the node for the token in
1571e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                // generateImpliedEndTags, just abort.
157281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (!m_tree.openElements()->contains(toElement(node)))
1573e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                    return;
1574e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
157581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            m_tree.openElements()->popUntilPopped(toElement(node));
1576e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1577e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1578e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        if (isSpecialNode(node)) {
1579e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1580e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1581e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1582e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        record = record->next();
1583e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1584e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1585e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1586ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block// FIXME: This probably belongs on HTMLElementStack.
1587ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve BlockHTMLElementStack::ElementRecord* HTMLTreeBuilder::furthestBlockForFormattingElement(Element* formattingElement)
1588ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
1589ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    HTMLElementStack::ElementRecord* furthestBlock = 0;
1590e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord();
1591ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    for (; record; record = record->next()) {
1592ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (record->element() == formattingElement)
1593ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return furthestBlock;
1594e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        if (isSpecialNode(record->element()))
1595ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            furthestBlock = record;
1596ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
1597ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    ASSERT_NOT_REACHED();
1598ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return 0;
1599ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
1600ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
1601ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-inbody
1602ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
1603ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
1604dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // The adoption agency algorithm is N^2.  We limit the number of iterations
1605dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // to stop from hanging the whole browser.  This limit is copied from the
1606dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // legacy tree builder and might need to be tweaked in the future.
1607dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    static const int adoptionAgencyIterationLimit = 10;
1608dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
1609dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    for (int i = 0; i < adoptionAgencyIterationLimit; ++i) {
1610ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 1.
1611e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        Element* formattingElement = m_tree.activeFormattingElements()->closestElementInScopeWithName(token.name());
1612967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        if (!formattingElement || ((m_tree.openElements()->contains(formattingElement)) && !m_tree.openElements()->inScope(formattingElement))) {
161306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            parseError(token);
1614ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            notImplemented(); // Check the stack of open elements for a more specific parse error.
1615ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1616ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1617e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        HTMLElementStack::ElementRecord* formattingElementRecord = m_tree.openElements()->find(formattingElement);
1618ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (!formattingElementRecord) {
1619ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            parseError(token);
1620e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.activeFormattingElements()->remove(formattingElement);
1621ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1622ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1623e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (formattingElement != m_tree.currentElement())
1624ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            parseError(token);
1625ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 2.
1626ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        HTMLElementStack::ElementRecord* furthestBlock = furthestBlockForFormattingElement(formattingElement);
1627ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 3.
1628ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (!furthestBlock) {
1629e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->popUntilPopped(formattingElement);
1630e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.activeFormattingElements()->remove(formattingElement);
1631ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
1632ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1633ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 4.
1634ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(furthestBlock->isAbove(formattingElementRecord));
163581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ContainerNode* commonAncestor = formattingElementRecord->next()->node();
1636ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 5.
1637e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        HTMLFormattingElementList::Bookmark bookmark = m_tree.activeFormattingElements()->bookmarkFor(formattingElement);
1638ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 6.
1639ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        HTMLElementStack::ElementRecord* node = furthestBlock;
1640ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        HTMLElementStack::ElementRecord* nextNode = node->next();
1641ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        HTMLElementStack::ElementRecord* lastNode = furthestBlock;
1642dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        for (int i = 0; i < adoptionAgencyIterationLimit; ++i) {
1643ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            // 6.1
1644ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            node = nextNode;
1645ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            ASSERT(node);
1646ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            nextNode = node->next(); // Save node->next() for the next iteration in case node is deleted in 6.2.
1647ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            // 6.2
1648e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (!m_tree.activeFormattingElements()->contains(node->element())) {
1649e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                m_tree.openElements()->remove(node->element());
1650ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block                node = 0;
1651ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block                continue;
165206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            }
1653ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            // 6.3
1654ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            if (node == formattingElementRecord)
165506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen                break;
1656ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            // 6.5
1657967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            RefPtr<Element> newElement = m_tree.createHTMLElementFromElementRecord(node);
1658e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattingElements()->find(node->element());
1659ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            nodeEntry->replaceElement(newElement.get());
1660ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            node->replaceElement(newElement.release());
1661e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            // 6.4 -- Intentionally out of order to handle the case where node
1662e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            // was replaced in 6.5.
1663e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10096
1664e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (lastNode == furthestBlock)
1665967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch                bookmark.moveToAfter(nodeEntry);
1666ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            // 6.6
1667e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            if (Element* parent = lastNode->element()->parentElement())
1668e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block                parent->parserRemoveChild(lastNode->element());
1669e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            node->element()->parserAddChild(lastNode->element());
1670e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            if (lastNode->element()->parentElement()->attached() && !lastNode->element()->attached())
1671e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block                lastNode->element()->lazyAttach();
1672ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            // 6.7
1673ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            lastNode = node;
1674ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1675ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 7
1676ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        const AtomicString& commonAncestorTag = commonAncestor->localName();
1677e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        if (Element* parent = lastNode->element()->parentElement())
1678e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            parent->parserRemoveChild(lastNode->element());
1679967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        // FIXME: If this moves to HTMLConstructionSite, this check should use
1680967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        // causesFosterParenting(tagName) instead.
1681ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (commonAncestorTag == tableTag
1682ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            || commonAncestorTag == trTag
1683ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            || isTableBodyContextTag(commonAncestorTag))
1684e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.fosterParent(lastNode->element());
1685ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        else {
1686e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            commonAncestor->parserAddChild(lastNode->element());
168781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            ASSERT(lastNode->node()->isElementNode());
168881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            ASSERT(lastNode->element()->parentNode());
168981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (lastNode->element()->parentNode()->attached() && !lastNode->element()->attached())
1690e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block                lastNode->element()->lazyAttach();
1691ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
1692ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 8
1693967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        RefPtr<Element> newElement = m_tree.createHTMLElementFromElementRecord(formattingElementRecord);
1694ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 9
169568513a70bcd92384395513322f1b801e7bf9c729Steve Block        newElement->takeAllChildrenFrom(furthestBlock->element());
1696ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 10
1697967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        Element* furthestBlockElement = furthestBlock->element();
1698967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        // FIXME: All this creation / parserAddChild / attach business should
1699967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        //        be in HTMLConstructionSite.  My guess is that steps 8--12
1700967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        //        should all be in some HTMLConstructionSite function.
1701967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        furthestBlockElement->parserAddChild(newElement);
1702dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        if (furthestBlockElement->attached() && !newElement->attached()) {
1703dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            // Notice that newElement might already be attached if, for example, one of the reparented
1704dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            // children is a style element, which attaches itself automatically.
1705967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch            newElement->attach();
1706967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        }
1707ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 11
1708967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        m_tree.activeFormattingElements()->swapTo(formattingElement, newElement.get(), bookmark);
1709ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // 12
1710e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->remove(formattingElement);
1711e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->insertAbove(newElement, furthestBlock);
1712e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1713e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1714e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1715e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::resetInsertionModeAppropriately()
1716e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
1717e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#reset-the-insertion-mode-appropriately
1718e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    bool last = false;
1719e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
1720e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    while (1) {
172181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ContainerNode* node = nodeRecord->node();
172281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (node == m_tree.openElements()->rootNode()) {
1723dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
1724e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            last = true;
1725dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            node = m_fragmentContext.contextElement();
1726e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1727e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->hasTagName(selectTag)) {
1728dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
1729e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InSelectMode);
1730e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1731e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->hasTagName(tdTag) || node->hasTagName(thTag))
1732e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InCellMode);
1733e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->hasTagName(trTag))
1734e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InRowMode);
1735e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (node->hasTagName(tbodyTag) || node->hasTagName(theadTag) || node->hasTagName(tfootTag))
1736e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InTableBodyMode);
1737e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->hasTagName(captionTag))
1738e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InCaptionMode);
1739e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->hasTagName(colgroupTag)) {
1740dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
1741e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InColumnGroupMode);
1742e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1743e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->hasTagName(tableTag))
1744e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InTableMode);
1745e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->hasTagName(headTag)) {
1746dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
1747e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InBodyMode);
1748e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1749e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->hasTagName(bodyTag))
1750e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InBodyMode);
1751e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->hasTagName(framesetTag)) {
1752dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
1753e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InFramesetMode);
1754e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1755e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->hasTagName(htmlTag)) {
1756dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
1757e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(BeforeHeadMode);
1758e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1759e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (node->namespaceURI() == SVGNames::svgNamespaceURI
1760e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || node->namespaceURI() == MathMLNames::mathmlNamespaceURI)
1761e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InForeignContentMode);
1762e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (last) {
1763dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
1764e14391e94c850b8bd03680c23b38978db68687a8John Reck            return setInsertionMode(InBodyMode);
1765e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1766e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        nodeRecord = nodeRecord->next();
1767e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1768e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1769e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1770e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processEndTagForInTableBody(AtomicHTMLToken& token)
1771e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
1772e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::EndTag);
1773e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (isTableBodyContextTag(token.name())) {
1774e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!m_tree.openElements()->inTableScope(token.name())) {
1775e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1776e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1777e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1778e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntilTableBodyScopeMarker();
1779e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->pop();
1780e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(InTableMode);
1781e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1782e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1783e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == tableTag) {
1784e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // FIXME: This is slow.
1785e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!m_tree.openElements()->inTableScope(tbodyTag.localName()) && !m_tree.openElements()->inTableScope(theadTag.localName()) && !m_tree.openElements()->inTableScope(tfootTag.localName())) {
1786dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
1787e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1788e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1789e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1790e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntilTableBodyScopeMarker();
1791e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(isTableBodyContextTag(m_tree.currentElement()->localName()));
1792e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processFakeEndTag(m_tree.currentElement()->tagQName());
1793e14391e94c850b8bd03680c23b38978db68687a8John Reck        reprocessEndTag(token);
1794e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1795e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1796e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == bodyTag
1797e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isCaptionColOrColgroupTag(token.name())
1798e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == htmlTag
1799e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isTableCellContextTag(token.name())
1800e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == trTag) {
1801e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        parseError(token);
1802e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1803e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1804e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processEndTagForInTable(token);
1805e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1806e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1807e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processEndTagForInRow(AtomicHTMLToken& token)
1808e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
1809e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::EndTag);
1810e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == trTag) {
1811e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processTrEndTagForInRow();
1812e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1813e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1814e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == tableTag) {
1815e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!processTrEndTagForInRow()) {
1816dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
1817e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1818e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1819e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InTableBodyMode);
1820e14391e94c850b8bd03680c23b38978db68687a8John Reck        reprocessEndTag(token);
1821e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1822e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1823e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (isTableBodyContextTag(token.name())) {
1824e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!m_tree.openElements()->inTableScope(token.name())) {
1825e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1826e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1827e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1828e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processFakeEndTag(trTag);
1829e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InTableBodyMode);
1830e14391e94c850b8bd03680c23b38978db68687a8John Reck        reprocessEndTag(token);
1831e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1832e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1833e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == bodyTag
1834e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isCaptionColOrColgroupTag(token.name())
1835e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == htmlTag
1836e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isTableCellContextTag(token.name())) {
1837e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        parseError(token);
1838e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1839e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1840e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processEndTagForInTable(token);
1841e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1842e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1843e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken& token)
1844e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
1845e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::EndTag);
1846e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (isTableCellContextTag(token.name())) {
1847e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!m_tree.openElements()->inTableScope(token.name())) {
1848e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1849e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1850e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1851e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.generateImpliedEndTags();
185281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!m_tree.currentNode()->hasLocalName(token.name()))
1853e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1854e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntilPopped(token.name());
1855e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.activeFormattingElements()->clearToLastMarker();
1856e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(InRowMode);
1857e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1858e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1859e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == bodyTag
1860e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isCaptionColOrColgroupTag(token.name())
1861e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == htmlTag) {
1862e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        parseError(token);
1863e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1864e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1865e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == tableTag
1866e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == trTag
1867e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isTableBodyContextTag(token.name())) {
1868e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!m_tree.openElements()->inTableScope(token.name())) {
1869a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            ASSERT(isTableBodyContextTag(token.name()) || isParsingFragment());
1870e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1871e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1872e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1873e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        closeTheCell();
1874e14391e94c850b8bd03680c23b38978db68687a8John Reck        reprocessEndTag(token);
1875e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1876e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1877e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processEndTagForInBody(token);
1878e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
1879e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1880e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken& token)
1881e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
1882e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::EndTag);
1883e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == bodyTag) {
1884e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processBodyEndTagForInBody(token);
1885e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1886e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1887e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == htmlTag) {
1888e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        AtomicHTMLToken endBody(HTMLToken::EndTag, bodyTag.localName());
1889e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (processBodyEndTagForInBody(endBody))
1890e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessEndTag(token);
1891e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1892e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1893e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == addressTag
1894e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == articleTag
1895e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == asideTag
1896e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == blockquoteTag
1897e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == buttonTag
1898e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == centerTag
18990617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == detailsTag
1900e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == dirTag
1901e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == divTag
1902e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == dlTag
1903e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == fieldsetTag
1904dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        || token.name() == figcaptionTag
19050617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == figureTag
1906e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == footerTag
1907e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == headerTag
1908e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == hgroupTag
1909e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == listingTag
1910e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == menuTag
1911e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == navTag
1912e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == olTag
1913e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == preTag
1914e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == sectionTag
1915dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        || token.name() == summaryTag
1916e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == ulTag) {
1917e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!m_tree.openElements()->inScope(token.name())) {
1918e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1919e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1920e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1921e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.generateImpliedEndTags();
192281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!m_tree.currentNode()->hasLocalName(token.name()))
1923e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1924e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntilPopped(token.name());
1925e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1926e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1927e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == formTag) {
1928e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        RefPtr<Element> node = m_tree.takeForm();
1929e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!node || !m_tree.openElements()->inScope(node.get())) {
1930e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1931e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1932e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1933e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.generateImpliedEndTags();
1934e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (m_tree.currentElement() != node.get())
1935e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1936e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->remove(node.get());
1937e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1938e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == pTag) {
19390617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        if (!m_tree.openElements()->inButtonScope(token.name())) {
1940e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1941e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processFakeStartTag(pTag);
1942e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            ASSERT(m_tree.openElements()->inScope(token.name()));
1943e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessEndTag(token);
1944e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1945e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1946e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.generateImpliedEndTagsWithExclusion(token.name());
194781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!m_tree.currentNode()->hasLocalName(token.name()))
1948e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1949e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntilPopped(token.name());
1950e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1951e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1952e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == liTag) {
1953e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!m_tree.openElements()->inListItemScope(token.name())) {
1954e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1955e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1956e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1957e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.generateImpliedEndTagsWithExclusion(token.name());
195881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!m_tree.currentNode()->hasLocalName(token.name()))
1959e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1960e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntilPopped(token.name());
1961e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1962e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1963e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == ddTag
1964e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == dtTag) {
1965e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!m_tree.openElements()->inScope(token.name())) {
1966e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1967e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1968e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1969e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.generateImpliedEndTagsWithExclusion(token.name());
197081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!m_tree.currentNode()->hasLocalName(token.name()))
1971e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1972e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntilPopped(token.name());
1973e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1974e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1975e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (isNumberedHeaderTag(token.name())) {
19760617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        if (!m_tree.openElements()->hasNumberedHeaderElementInScope()) {
1977e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1978e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1979e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1980e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.generateImpliedEndTags();
198181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!m_tree.currentNode()->hasLocalName(token.name()))
1982e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
19830617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        m_tree.openElements()->popUntilNumberedHeaderElementPopped();
1984e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1985e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1986e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (isFormattingTag(token.name())) {
1987e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        callTheAdoptionAgency(token);
1988e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
1989e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
1990e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == appletTag
1991e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == marqueeTag
1992e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == objectTag) {
1993e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!m_tree.openElements()->inScope(token.name())) {
1994e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
1995e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
1996e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
1997e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.generateImpliedEndTags();
199881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!m_tree.currentNode()->hasLocalName(token.name()))
1999e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
2000e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->popUntilPopped(token.name());
2001e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.activeFormattingElements()->clearToLastMarker();
2002e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
2003e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2004e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == brTag) {
2005e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        parseError(token);
2006e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processFakeStartTag(brTag);
2007e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
2008e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2009e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processAnyOtherEndTagForInBody(token);
2010e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
2011e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2012e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool HTMLTreeBuilder::processCaptionEndTagForInCaption()
2013e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
2014e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!m_tree.openElements()->inTableScope(captionTag.localName())) {
2015dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        ASSERT(isParsingFragment());
2016e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // FIXME: parse error
2017e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return false;
2018e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2019e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.generateImpliedEndTags();
2020e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // FIXME: parse error if (!m_tree.currentElement()->hasTagName(captionTag))
2021e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.openElements()->popUntilPopped(captionTag.localName());
2022e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.activeFormattingElements()->clearToLastMarker();
2023e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    setInsertionMode(InTableMode);
2024e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return true;
2025e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
2026e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2027e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool HTMLTreeBuilder::processTrEndTagForInRow()
2028e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
2029e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!m_tree.openElements()->inTableScope(trTag.localName())) {
2030dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        ASSERT(isParsingFragment());
2031e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // FIXME: parse error
2032e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return false;
203306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    }
2034e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.openElements()->popUntilTableRowScopeMarker();
2035e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(m_tree.currentElement()->hasTagName(trTag));
2036e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.openElements()->pop();
2037e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    setInsertionMode(InTableBodyMode);
2038e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return true;
2039e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
2040e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2041e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool HTMLTreeBuilder::processTableEndTagForInTable()
2042e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
2043e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!m_tree.openElements()->inTableScope(tableTag)) {
2044dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        ASSERT(isParsingFragment());
2045e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // FIXME: parse error.
2046e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return false;
2047e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2048e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.openElements()->popUntilPopped(tableTag.localName());
2049e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    resetInsertionModeAppropriately();
2050e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return true;
2051e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
2052e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2053e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processEndTagForInTable(AtomicHTMLToken& token)
2054e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
2055e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::EndTag);
2056e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == tableTag) {
2057e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processTableEndTagForInTable();
2058e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
2059e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2060e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == bodyTag
2061e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isCaptionColOrColgroupTag(token.name())
2062e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == htmlTag
2063e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isTableBodyContextTag(token.name())
2064e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || isTableCellContextTag(token.name())
2065e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == trTag) {
2066e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        parseError(token);
2067e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
2068e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2069e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // Is this redirection necessary here?
2070967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree);
2071e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    processEndTagForInBody(token);
2072ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
2073ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
2074ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
2075ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
2076e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::EndTag);
2077ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    switch (insertionMode()) {
2078ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InitialMode:
2079ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InitialMode);
2080967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInitial();
2081ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2082ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case BeforeHTMLMode:
2083ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == BeforeHTMLMode);
2084ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() != headTag && token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
208506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            parseError(token);
2086ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2087ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2088967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForBeforeHTML();
2089ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2090ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case BeforeHeadMode:
2091ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == BeforeHeadMode);
2092e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() != headTag && token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
2093ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            parseError(token);
2094ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2095ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2096967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForBeforeHead();
2097ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2098ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InHeadMode:
2099ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InHeadMode);
2100ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == headTag) {
2101e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->popHTMLHeadElement();
2102ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            setInsertionMode(AfterHeadMode);
2103ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2104ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2105e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
2106e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
2107ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2108ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2109967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInHead();
2110e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through.
2111e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case AfterHeadMode:
2112e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == AfterHeadMode);
2113e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
2114e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
2115ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2116ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2117967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForAfterHead();
2118e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through
2119e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InBodyMode:
2120e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InBodyMode);
2121e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processEndTagForInBody(token);
2122e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2123e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InTableMode:
2124e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InTableMode);
2125e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processEndTagForInTable(token);
2126e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2127e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InCaptionMode:
2128e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InCaptionMode);
2129e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == captionTag) {
2130e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processCaptionEndTagForInCaption();
2131ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2132ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2133e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == tableTag) {
2134e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
2135e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (!processCaptionEndTagForInCaption()) {
2136dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch                ASSERT(isParsingFragment());
2137ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block                return;
213806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            }
2139e14391e94c850b8bd03680c23b38978db68687a8John Reck            reprocessEndTag(token);
2140ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2141ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2142e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == bodyTag
2143e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == colTag
2144e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == colgroupTag
2145e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == htmlTag
2146e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isTableBodyContextTag(token.name())
2147e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isTableCellContextTag(token.name())
2148e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == trTag) {
2149ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            parseError(token);
2150ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2151ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2152e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processEndTagForInBody(token);
2153e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2154e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InColumnGroupMode:
2155e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InColumnGroupMode);
2156e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == colgroupTag) {
2157e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processColgroupEndTagForInColumnGroup();
2158e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2159e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2160e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == colTag) {
2161e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
2162e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2163e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2164e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!processColgroupEndTagForInColumnGroup()) {
2165dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
2166ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2167e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2168e14391e94c850b8bd03680c23b38978db68687a8John Reck        reprocessEndTag(token);
2169e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2170e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InRowMode:
2171e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InRowMode);
2172e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processEndTagForInRow(token);
2173e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2174e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InCellMode:
2175e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InCellMode);
2176e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processEndTagForInCell(token);
2177e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2178e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InTableBodyMode:
2179e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InTableBodyMode);
2180e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processEndTagForInTableBody(token);
2181ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2182ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case AfterBodyMode:
2183ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == AfterBodyMode);
2184ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == htmlTag) {
2185dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            if (isParsingFragment()) {
2186ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block                parseError(token);
2187ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block                return;
2188ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            }
2189e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(AfterAfterBodyMode);
2190ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2191ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2192e14391e94c850b8bd03680c23b38978db68687a8John Reck        prepareToReprocessToken();
2193ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2194ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case AfterAfterBodyMode:
2195ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
2196ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        parseError(token);
2197e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(InBodyMode);
2198e14391e94c850b8bd03680c23b38978db68687a8John Reck        reprocessEndTag(token);
2199ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2200ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InHeadNoscriptMode:
2201ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InHeadNoscriptMode);
2202ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == noscriptTag) {
2203e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            ASSERT(m_tree.currentElement()->hasTagName(noscriptTag));
2204e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->pop();
2205e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            ASSERT(m_tree.currentElement()->hasTagName(headTag));
2206ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            setInsertionMode(InHeadMode);
2207ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2208ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2209ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() != brTag) {
221006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen            parseError(token);
2211ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2212ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2213967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInHeadNoscript();
2214ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        processToken(token);
2215ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2216ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case TextMode:
2217ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == scriptTag) {
2218ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            // Pause ourselves so that parsing stops until the script can be processed by the caller.
2219ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            m_isPaused = true;
2220e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            ASSERT(m_tree.currentElement()->hasTagName(scriptTag));
2221e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_scriptToProcess = m_tree.currentElement();
22226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            m_scriptToProcessStartPosition = WTF::toOneBasedTextPosition(m_lastScriptElementStartPosition);
2223e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->pop();
2224e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            if (isParsingFragment() && m_fragmentContext.scriptingPermission() == FragmentScriptingNotAllowed)
2225e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block                m_scriptToProcess->removeAllChildren();
2226e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(m_originalInsertionMode);
2227bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
2228bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            // This token will not have been created by the tokenizer if a
2229bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            // self-closing script tag was encountered and pre-HTML5 parser
2230bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            // quirks are enabled. We must set the tokenizer's state to
2231bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            // DataState explicitly if the tokenizer didn't have a chance to.
2232cad810f21b803229eb11403f9209855525a25d57Steve Block            ASSERT(m_parser->tokenizer()->state() == HTMLTokenizer::DataState || m_usePreHTML5ParserQuirks);
2233cad810f21b803229eb11403f9209855525a25d57Steve Block            m_parser->tokenizer()->setState(HTMLTokenizer::DataState);
2234ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2235ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2236e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.openElements()->pop();
2237e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(m_originalInsertionMode);
2238ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2239ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InFramesetMode:
2240ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InFramesetMode);
2241ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == framesetTag) {
224281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (m_tree.currentNode() == m_tree.openElements()->rootNode()) {
2243ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block                parseError(token);
2244ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block                return;
2245ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            }
2246e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->pop();
2247dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            if (!isParsingFragment() && !m_tree.currentElement()->hasTagName(framesetTag))
2248e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                setInsertionMode(AfterFramesetMode);
2249ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2250ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2251ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2252ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case AfterFramesetMode:
2253ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == AfterFramesetMode);
2254ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        if (token.name() == htmlTag) {
2255e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            setInsertionMode(AfterAfterFramesetMode);
2256ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return;
2257ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2258ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2259ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case AfterAfterFramesetMode:
2260ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode);
2261ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        parseError(token);
2262ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2263e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InSelectInTableMode:
2264e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InSelectInTableMode);
2265e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == captionTag
2266e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == tableTag
2267e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isTableBodyContextTag(token.name())
2268e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || token.name() == trTag
2269e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            || isTableCellContextTag(token.name())) {
2270e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
2271e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            if (m_tree.openElements()->inTableScope(token.name())) {
2272e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
2273e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                processEndTag(endSelect);
2274e14391e94c850b8bd03680c23b38978db68687a8John Reck                reprocessEndTag(token);
2275e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
2276e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2277e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2278e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through.
2279e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InSelectMode:
2280e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode);
2281e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == optgroupTag) {
228281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (m_tree.currentNode()->hasTagName(optionTag) && m_tree.oneBelowTop()->hasTagName(optgroupTag))
2283e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                processFakeEndTag(optionTag);
228481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (m_tree.currentNode()->hasTagName(optgroupTag)) {
2285e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                m_tree.openElements()->pop();
2286e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                return;
2287e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
2288e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
2289e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2290e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2291e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == optionTag) {
229281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (m_tree.currentNode()->hasTagName(optionTag)) {
2293e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                m_tree.openElements()->pop();
2294e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                return;
2295e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
2296e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
2297e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2298e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2299e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (token.name() == selectTag) {
2300a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (!m_tree.openElements()->inSelectScope(token.name())) {
23015ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                ASSERT(isParsingFragment());
23025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                parseError(token);
23035ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen                return;
23045ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            }
2305e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.openElements()->popUntilPopped(selectTag.localName());
2306e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            resetInsertionModeAppropriately();
2307e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2308e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2309e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2310e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InTableTextMode:
2311967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInTableText();
2312e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processEndTag(token);
2313e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2314e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InForeignContentMode:
231581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (token.name() == SVGNames::scriptTag && m_tree.currentNode()->hasTagName(SVGNames::scriptTag)) {
2316e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            notImplemented();
2317e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2318e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
23192bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!isInHTMLNamespace(m_tree.currentNode())) {
2320e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            // FIXME: This code just wants an Element* iterator, instead of an ElementRecord*
2321e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
232281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (!nodeRecord->node()->hasLocalName(token.name()))
2323e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                parseError(token);
2324e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            while (1) {
232581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (nodeRecord->node()->hasLocalName(token.name())) {
2326e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                    m_tree.openElements()->popUntilPopped(nodeRecord->element());
232728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    resetForeignInsertionMode();
232828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu                    return;
2329e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                }
2330e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke                nodeRecord = nodeRecord->next();
233181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
23322bde8e466a4451c7319e3a072d118917957d6554Steve Block                if (isInHTMLNamespace(nodeRecord->node()))
2333e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block                    break;
2334e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            }
2335e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2336e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        // Any other end tag (also the last two steps of "An end tag, if the current node is not an element in the HTML namespace."
2337e14391e94c850b8bd03680c23b38978db68687a8John Reck        processForeignContentUsingInBodyModeAndResetMode(token);
2338e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2339e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2340e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
2341e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2342e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid HTMLTreeBuilder::prepareToReprocessToken()
2343e14391e94c850b8bd03680c23b38978db68687a8John Reck{
2344e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (m_hasPendingForeignInsertionModeSteps) {
2345e14391e94c850b8bd03680c23b38978db68687a8John Reck        resetForeignInsertionMode();
2346e14391e94c850b8bd03680c23b38978db68687a8John Reck        m_hasPendingForeignInsertionModeSteps = false;
2347e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
2348e14391e94c850b8bd03680c23b38978db68687a8John Reck}
2349e14391e94c850b8bd03680c23b38978db68687a8John Reck
2350e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid HTMLTreeBuilder::reprocessStartTag(AtomicHTMLToken& token)
2351e14391e94c850b8bd03680c23b38978db68687a8John Reck{
2352e14391e94c850b8bd03680c23b38978db68687a8John Reck    prepareToReprocessToken();
2353e14391e94c850b8bd03680c23b38978db68687a8John Reck    processStartTag(token);
2354e14391e94c850b8bd03680c23b38978db68687a8John Reck}
2355e14391e94c850b8bd03680c23b38978db68687a8John Reck
2356e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid HTMLTreeBuilder::reprocessEndTag(AtomicHTMLToken& token)
2357e14391e94c850b8bd03680c23b38978db68687a8John Reck{
2358e14391e94c850b8bd03680c23b38978db68687a8John Reck    prepareToReprocessToken();
2359e14391e94c850b8bd03680c23b38978db68687a8John Reck    processEndTag(token);
2360e14391e94c850b8bd03680c23b38978db68687a8John Reck}
2361e14391e94c850b8bd03680c23b38978db68687a8John Reck
2362ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochclass HTMLTreeBuilder::FakeInsertionMode {
2363ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    WTF_MAKE_NONCOPYABLE(FakeInsertionMode);
2364e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkepublic:
2365e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    FakeInsertionMode(HTMLTreeBuilder* treeBuilder, InsertionMode mode)
2366e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        : m_treeBuilder(treeBuilder)
2367e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        , m_originalMode(treeBuilder->insertionMode())
2368e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    {
2369e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_treeBuilder->setFakeInsertionMode(mode);
237006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    }
2371e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2372e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ~FakeInsertionMode()
2373e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    {
2374e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (m_treeBuilder->isFakeInsertionMode())
2375e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_treeBuilder->setInsertionMode(m_originalMode);
2376e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2377e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2378e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkeprivate:
2379e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    HTMLTreeBuilder* m_treeBuilder;
2380e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    InsertionMode m_originalMode;
2381e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke};
2382e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2383e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid HTMLTreeBuilder::processForeignContentUsingInBodyModeAndResetMode(AtomicHTMLToken& token)
2384e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
2385e14391e94c850b8bd03680c23b38978db68687a8John Reck    m_hasPendingForeignInsertionModeSteps = true;
2386e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    {
2387e14391e94c850b8bd03680c23b38978db68687a8John Reck        FakeInsertionMode fakeMode(this, InBodyMode);
2388e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processToken(token);
2389e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2390e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (m_hasPendingForeignInsertionModeSteps)
2391e14391e94c850b8bd03680c23b38978db68687a8John Reck        resetForeignInsertionMode();
2392e14391e94c850b8bd03680c23b38978db68687a8John Reck}
2393e14391e94c850b8bd03680c23b38978db68687a8John Reck
2394e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid HTMLTreeBuilder::resetForeignInsertionMode()
2395e14391e94c850b8bd03680c23b38978db68687a8John Reck{
2396e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (insertionMode() == InForeignContentMode)
2397e14391e94c850b8bd03680c23b38978db68687a8John Reck        resetInsertionModeAppropriately();
2398ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
2399ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
2400ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid HTMLTreeBuilder::processComment(AtomicHTMLToken& token)
2401ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
2402e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::Comment);
2403e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (m_insertionMode == InitialMode
2404e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || m_insertionMode == BeforeHTMLMode
2405e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || m_insertionMode == AfterAfterBodyMode
2406e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || m_insertionMode == AfterAfterFramesetMode) {
2407e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertCommentOnDocument(token);
2408ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return;
2409ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
2410ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (m_insertionMode == AfterBodyMode) {
2411e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertCommentOnHTMLHtmlElement(token);
2412ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return;
2413ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
2414e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (m_insertionMode == InTableTextMode) {
2415967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInTableText();
2416e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processComment(token);
2417e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
2418e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2419e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.insertComment(token);
2420ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
2421ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
2422ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid HTMLTreeBuilder::processCharacter(AtomicHTMLToken& token)
2423ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
2424e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::Character);
2425e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ExternalCharacterTokenBuffer buffer(token);
2426967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    processCharacterBuffer(buffer);
2427967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
2428e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2429967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid HTMLTreeBuilder::processCharacterBuffer(ExternalCharacterTokenBuffer& buffer)
2430967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
2431e458d70a0d18538346f41b503114c9ebe6b2ce12Leon ClarkeReprocessBuffer:
2432ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    switch (insertionMode()) {
2433e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InitialMode: {
2434ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InitialMode);
2435e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        buffer.skipLeadingWhitespace();
2436e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (buffer.isEmpty())
2437e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2438967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInitial();
2439ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2440e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2441e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case BeforeHTMLMode: {
2442ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == BeforeHTMLMode);
2443e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        buffer.skipLeadingWhitespace();
2444e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (buffer.isEmpty())
2445e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2446967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForBeforeHTML();
2447ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2448e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2449e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case BeforeHeadMode: {
2450ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == BeforeHeadMode);
2451e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        buffer.skipLeadingWhitespace();
2452e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (buffer.isEmpty())
2453e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2454967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForBeforeHead();
2455ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2456e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2457e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InHeadMode: {
2458ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InHeadMode);
2459e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        String leadingWhitespace = buffer.takeLeadingWhitespace();
2460e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!leadingWhitespace.isEmpty())
2461e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertTextNode(leadingWhitespace);
2462e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (buffer.isEmpty())
2463e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2464967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInHead();
2465ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2466e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2467e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case AfterHeadMode: {
2468ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == AfterHeadMode);
2469e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        String leadingWhitespace = buffer.takeLeadingWhitespace();
2470e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!leadingWhitespace.isEmpty())
2471e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertTextNode(leadingWhitespace);
2472e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (buffer.isEmpty())
2473e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2474967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForAfterHead();
2475e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through.
2476e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
247706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    case InBodyMode:
2478e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InCaptionMode:
2479e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InCellMode: {
2480e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InBodyMode || insertionMode() == InCaptionMode || insertionMode() == InCellMode);
2481e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
2482e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        String characters = buffer.takeRemaining();
2483e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertTextNode(characters);
2484dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
2485e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_framesetOk = false;
2486e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2487e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2488e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InTableMode:
2489e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InTableBodyMode:
2490e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InRowMode: {
2491e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InTableMode || insertionMode() == InTableBodyMode || insertionMode() == InRowMode);
2492e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(m_pendingTableCharacters.isEmpty());
2493e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_originalInsertionMode = m_insertionMode;
2494e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(InTableTextMode);
2495e14391e94c850b8bd03680c23b38978db68687a8John Reck        prepareToReprocessToken();
2496e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // Fall through.
2497e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2498e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InTableTextMode: {
2499e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        buffer.giveRemainingTo(m_pendingTableCharacters);
2500ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2501e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2502e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InColumnGroupMode: {
2503e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InColumnGroupMode);
2504e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        String leadingWhitespace = buffer.takeLeadingWhitespace();
2505e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!leadingWhitespace.isEmpty())
2506e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertTextNode(leadingWhitespace);
2507e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (buffer.isEmpty())
2508e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2509e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!processColgroupEndTagForInColumnGroup()) {
2510dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
2511f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            // The spec tells us to drop these characters on the floor.
2512f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            buffer.takeLeadingNonWhitespace();
2513f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            if (buffer.isEmpty())
2514f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                return;
2515e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2516e14391e94c850b8bd03680c23b38978db68687a8John Reck        prepareToReprocessToken();
2517e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        goto ReprocessBuffer;
2518e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
251906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    case AfterBodyMode:
2520e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case AfterAfterBodyMode: {
2521ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
2522967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        // FIXME: parse error
2523e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(InBodyMode);
2524e14391e94c850b8bd03680c23b38978db68687a8John Reck        prepareToReprocessToken();
2525e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        goto ReprocessBuffer;
2526ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2527e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2528e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case TextMode: {
2529e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == TextMode);
2530e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertTextNode(buffer.takeRemaining());
2531ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2532e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2533e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InHeadNoscriptMode: {
2534ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InHeadNoscriptMode);
2535e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        String leadingWhitespace = buffer.takeLeadingWhitespace();
2536e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!leadingWhitespace.isEmpty())
2537e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertTextNode(leadingWhitespace);
2538e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (buffer.isEmpty())
2539e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
2540967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInHeadNoscript();
2541e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        goto ReprocessBuffer;
2542ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2543e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
254406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    case InFramesetMode:
2545e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case AfterFramesetMode: {
2546ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InFramesetMode || insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode);
2547e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        String leadingWhitespace = buffer.takeRemainingWhitespace();
2548e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!leadingWhitespace.isEmpty())
2549e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertTextNode(leadingWhitespace);
2550e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // FIXME: We should generate a parse error if we skipped over any
2551e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // non-whitespace characters.
2552e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2553e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2554e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InSelectInTableMode:
2555e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InSelectMode: {
2556e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode);
2557e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertTextNode(buffer.takeRemaining());
2558e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2559e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2560e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InForeignContentMode: {
2561e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InForeignContentMode);
2562e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        String characters = buffer.takeRemaining();
2563e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertTextNode(characters);
2564dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        if (m_framesetOk && !isAllWhitespace(characters))
2565e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_framesetOk = false;
2566ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2567e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2568e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case AfterAfterFramesetMode: {
2569e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        String leadingWhitespace = buffer.takeRemainingWhitespace();
2570e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!leadingWhitespace.isEmpty()) {
2571e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.reconstructTheActiveFormattingElements();
2572e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            m_tree.insertTextNode(leadingWhitespace);
2573e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2574e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // FIXME: We should generate a parse error if we skipped over any
2575e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // non-whitespace characters.
2576e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2577e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2578ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
2579ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
2580ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
2581ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
2582ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
2583e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::EndOfFile);
2584ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    switch (insertionMode()) {
2585ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InitialMode:
2586ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InitialMode);
2587967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInitial();
2588ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2589ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case BeforeHTMLMode:
2590ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == BeforeHTMLMode);
2591967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForBeforeHTML();
2592ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2593ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case BeforeHeadMode:
2594ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == BeforeHeadMode);
2595967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForBeforeHead();
2596ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2597ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InHeadMode:
2598ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InHeadMode);
2599967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInHead();
2600ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through.
2601ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case AfterHeadMode:
2602ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == AfterHeadMode);
2603967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForAfterHead();
2604ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fall through
2605ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InBodyMode:
2606e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InCellMode:
260768513a70bcd92384395513322f1b801e7bf9c729Steve Block    case InCaptionMode:
260868513a70bcd92384395513322f1b801e7bf9c729Steve Block    case InRowMode:
260968513a70bcd92384395513322f1b801e7bf9c729Steve Block        ASSERT(insertionMode() == InBodyMode || insertionMode() == InCellMode || insertionMode() == InCaptionMode || insertionMode() == InRowMode);
261068513a70bcd92384395513322f1b801e7bf9c729Steve Block        notImplemented(); // Emit parse error based on what elements are still open.
2611ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2612ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case AfterBodyMode:
261306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    case AfterAfterBodyMode:
2614ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
261528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        break;
2616ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case InHeadNoscriptMode:
2617ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == InHeadNoscriptMode);
2618967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInHeadNoscript();
2619967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        processEndOfFile(token);
2620967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return;
2621ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    case AfterFramesetMode:
262206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    case AfterAfterFramesetMode:
2623ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT(insertionMode() == AfterFramesetMode || insertionMode() == AfterAfterFramesetMode);
2624ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        break;
2625e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InFramesetMode:
2626e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InTableMode:
2627e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InTableBodyMode:
2628e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InSelectInTableMode:
2629e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InSelectMode:
2630e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode || insertionMode() == InTableMode || insertionMode() == InFramesetMode || insertionMode() == InTableBodyMode);
263181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (m_tree.currentNode() != m_tree.openElements()->rootNode())
2632e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            parseError(token);
2633e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        break;
2634e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InColumnGroupMode:
263581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (m_tree.currentNode() == m_tree.openElements()->rootNode()) {
2636dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
263728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            return; // FIXME: Should we break here instead of returning?
2638e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2639e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!processColgroupEndTagForInColumnGroup()) {
2640dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch            ASSERT(isParsingFragment());
264128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            return; // FIXME: Should we break here instead of returning?
2642e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
2643e14391e94c850b8bd03680c23b38978db68687a8John Reck        prepareToReprocessToken();
2644e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processEndOfFile(token);
2645967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return;
2646e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InForeignContentMode:
2647e14391e94c850b8bd03680c23b38978db68687a8John Reck        setInsertionMode(InBodyMode);
2648e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processEndOfFile(token);
2649967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return;
2650e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case InTableTextMode:
2651967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        defaultForInTableText();
2652e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processEndOfFile(token);
2653967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return;
2654e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    case TextMode:
265568513a70bcd92384395513322f1b801e7bf9c729Steve Block        parseError(token);
265681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (m_tree.currentNode()->hasTagName(scriptTag))
265768513a70bcd92384395513322f1b801e7bf9c729Steve Block            notImplemented(); // mark the script element as "already started".
265868513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_tree.openElements()->pop();
265968513a70bcd92384395513322f1b801e7bf9c729Steve Block        setInsertionMode(m_originalInsertionMode);
2660e14391e94c850b8bd03680c23b38978db68687a8John Reck        prepareToReprocessToken();
266168513a70bcd92384395513322f1b801e7bf9c729Steve Block        processEndOfFile(token);
266268513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
266306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    }
266481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(m_tree.currentNode());
2665967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    m_tree.openElements()->popAll();
2666ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
266706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
2668967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid HTMLTreeBuilder::defaultForInitial()
2669ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
2670ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    notImplemented();
26715ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (!m_fragmentContext.fragment())
26725ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        m_document->setCompatibilityMode(Document::QuirksMode);
2673967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // FIXME: parse error
2674ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    setInsertionMode(BeforeHTMLMode);
2675e14391e94c850b8bd03680c23b38978db68687a8John Reck    prepareToReprocessToken();
267606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
267706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
2678967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid HTMLTreeBuilder::defaultForBeforeHTML()
267906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
2680ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    AtomicHTMLToken startHTML(HTMLToken::StartTag, htmlTag.localName());
2681e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.insertHTMLHtmlStartTagBeforeHTML(startHTML);
2682ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    setInsertionMode(BeforeHeadMode);
2683e14391e94c850b8bd03680c23b38978db68687a8John Reck    prepareToReprocessToken();
268406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
268506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
2686967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid HTMLTreeBuilder::defaultForBeforeHead()
268706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
2688ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    AtomicHTMLToken startHead(HTMLToken::StartTag, headTag.localName());
2689ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    processStartTag(startHead);
2690e14391e94c850b8bd03680c23b38978db68687a8John Reck    prepareToReprocessToken();
269106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
269206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
2693967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid HTMLTreeBuilder::defaultForInHead()
269406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
2695ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    AtomicHTMLToken endHead(HTMLToken::EndTag, headTag.localName());
2696ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    processEndTag(endHead);
2697e14391e94c850b8bd03680c23b38978db68687a8John Reck    prepareToReprocessToken();
269806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
269906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
2700967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid HTMLTreeBuilder::defaultForInHeadNoscript()
270106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
2702ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    AtomicHTMLToken endNoscript(HTMLToken::EndTag, noscriptTag.localName());
2703ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    processEndTag(endNoscript);
2704e14391e94c850b8bd03680c23b38978db68687a8John Reck    prepareToReprocessToken();
270506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
270606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
2707967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid HTMLTreeBuilder::defaultForAfterHead()
270806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
2709ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    AtomicHTMLToken startBody(HTMLToken::StartTag, bodyTag.localName());
2710ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    processStartTag(startBody);
2711ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    m_framesetOk = true;
2712e14391e94c850b8bd03680c23b38978db68687a8John Reck    prepareToReprocessToken();
271306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
271406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
2715967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid HTMLTreeBuilder::defaultForInTableText()
2716e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
2717e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    String characters = String::adopt(m_pendingTableCharacters);
2718dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    if (!isAllWhitespace(characters)) {
2719967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        // FIXME: parse error
2720967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree);
2721e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.reconstructTheActiveFormattingElements();
2722e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertTextNode(characters);
2723e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_framesetOk = false;
2724e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        setInsertionMode(m_originalInsertionMode);
2725e14391e94c850b8bd03680c23b38978db68687a8John Reck        prepareToReprocessToken();
2726e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
2727e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
2728e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.insertTextNode(characters);
2729e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    setInsertionMode(m_originalInsertionMode);
2730e14391e94c850b8bd03680c23b38978db68687a8John Reck    prepareToReprocessToken();
2731e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
2732e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
2733ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockbool HTMLTreeBuilder::processStartTagForInHead(AtomicHTMLToken& token)
273406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
2735e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::StartTag);
2736ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (token.name() == htmlTag) {
2737e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLHtmlStartTagInBody(token);
2738ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return true;
2739ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
2740e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.name() == baseTag
27410617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == basefontTag
27420617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == bgsoundTag
27430617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        || token.name() == commandTag
2744e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == linkTag
2745e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        || token.name() == metaTag) {
2746e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertSelfClosingHTMLElement(token);
2747ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Note: The custom processing for the <meta> tag is done in HTMLMetaElement::process().
2748ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return true;
2749ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
2750ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (token.name() == titleTag) {
2751e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processGenericRCDATAStartTag(token);
2752ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return true;
2753ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
2754ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (token.name() == noscriptTag) {
2755dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        if (scriptEnabled(m_document->frame())) {
2756e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            processGenericRawTextStartTag(token);
2757ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block            return true;
2758ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        }
2759e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_tree.insertHTMLElement(token);
2760ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        setInsertionMode(InHeadNoscriptMode);
2761ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return true;
2762ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
2763ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (token.name() == noframesTag || token.name() == styleTag) {
2764e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processGenericRawTextStartTag(token);
2765ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return true;
2766ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
2767ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (token.name() == scriptTag) {
2768e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        processScriptStartTag(token);
2769bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        if (m_usePreHTML5ParserQuirks && token.selfClosing())
2770bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen            processFakeEndTag(scriptTag);
2771ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return true;
2772ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
2773ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (token.name() == headTag) {
2774ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        parseError(token);
2775ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return true;
2776ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
2777ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    return false;
2778ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
2779ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
2780e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processGenericRCDATAStartTag(AtomicHTMLToken& token)
2781ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
2782ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    ASSERT(token.type() == HTMLToken::StartTag);
2783e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.insertHTMLElement(token);
2784cad810f21b803229eb11403f9209855525a25d57Steve Block    m_parser->tokenizer()->setState(HTMLTokenizer::RCDATAState);
2785ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    m_originalInsertionMode = m_insertionMode;
2786e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    setInsertionMode(TextMode);
2787ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
2788ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
2789e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processGenericRawTextStartTag(AtomicHTMLToken& token)
2790ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
2791e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::StartTag);
2792e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.insertHTMLElement(token);
2793cad810f21b803229eb11403f9209855525a25d57Steve Block    m_parser->tokenizer()->setState(HTMLTokenizer::RAWTEXTState);
2794ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    m_originalInsertionMode = m_insertionMode;
2795e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    setInsertionMode(TextMode);
2796ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
2797ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
2798e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken& token)
279906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
2800e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::StartTag);
2801e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_tree.insertScriptElement(token);
2802cad810f21b803229eb11403f9209855525a25d57Steve Block    m_parser->tokenizer()->setState(HTMLTokenizer::ScriptDataState);
2803ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    m_originalInsertionMode = m_insertionMode;
28046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
2805cad810f21b803229eb11403f9209855525a25d57Steve Block    TextPosition0 position = m_parser->textPosition();
2806cad810f21b803229eb11403f9209855525a25d57Steve Block
2807cad810f21b803229eb11403f9209855525a25d57Steve Block    ASSERT(position.m_line.zeroBasedInt() == m_parser->tokenizer()->lineNumber());
2808cad810f21b803229eb11403f9209855525a25d57Steve Block
28096b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    m_lastScriptElementStartPosition = position;
28106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
2811e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    setInsertionMode(TextMode);
281206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
281306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
281406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsenvoid HTMLTreeBuilder::finished()
281506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
281681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (isParsingFragment())
2817dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        return;
281881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
281981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(m_document);
2820e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    // Warning, this may detach the parser. Do not do anything else after this.
2821dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    m_document->finishedParsing();
282206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
282306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
28242fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid HTMLTreeBuilder::parseError(AtomicHTMLToken&)
28252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
28262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
28272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2828dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochbool HTMLTreeBuilder::scriptEnabled(Frame* frame)
282906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen{
283006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    if (!frame)
283106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        return false;
283268513a70bcd92384395513322f1b801e7bf9c729Steve Block    return frame->script()->canExecuteScripts(NotAboutToExecuteScript);
283306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
283406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
2835dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochbool HTMLTreeBuilder::pluginsEnabled(Frame* frame)
2836dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
2837dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    if (!frame)
2838dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        return false;
2839dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    return frame->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin);
2840dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
2841dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
284206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen}
2843