1e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke/*
2e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * Copyright (C) 2010 Google, Inc. All Rights Reserved.
381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Copyright (C) 2011 Apple Inc. All rights reserved.
4e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke *
5e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * Redistribution and use in source and binary forms, with or without
6e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * modification, are permitted provided that the following conditions
7e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * are met:
8e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * 1. Redistributions of source code must retain the above copyright
9e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke *    notice, this list of conditions and the following disclaimer.
10e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * 2. Redistributions in binary form must reproduce the above copyright
11e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke *    notice, this list of conditions and the following disclaimer in the
12e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke *    documentation and/or other materials provided with the distribution.
13e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke *
14e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
15e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
18e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke * (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.
25e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke */
26e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
27e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "config.h"
28e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "HTMLTreeBuilder.h"
29e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
30e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "Comment.h"
31e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "DocumentFragment.h"
32e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "DocumentType.h"
33e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "Element.h"
34e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "Frame.h"
35e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "HTMLDocument.h"
36967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "HTMLElementFactory.h"
37967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "HTMLFormElement.h"
38e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "HTMLHtmlElement.h"
39e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "HTMLNames.h"
40e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "HTMLScriptElement.h"
41e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "HTMLToken.h"
42e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "HTMLTokenizer.h"
43e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "LocalizedStrings.h"
44e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(MATHML)
45e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "MathMLNames.h"
46e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif
47e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "NotImplemented.h"
48e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if ENABLE(SVG)
49e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "SVGNames.h"
50e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif
51e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "ScriptController.h"
52e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "Settings.h"
53e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "Text.h"
54e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include <wtf/UnusedParam.h>
55e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
56e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkenamespace WebCore {
57e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
58e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkeusing namespace HTMLNames;
59e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
60e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkenamespace {
61e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
6281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochbool hasImpliedEndTag(ContainerNode* node)
63e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
6481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return node->hasTagName(ddTag)
6581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        || node->hasTagName(dtTag)
6681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        || node->hasTagName(liTag)
6781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        || node->hasTagName(optionTag)
6881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        || node->hasTagName(optgroupTag)
6981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        || node->hasTagName(pTag)
7081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        || node->hasTagName(rpTag)
7181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        || node->hasTagName(rtTag);
72e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
73e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
74967717af5423377c967781471ee106e2bb4e11c8Ben Murdochbool causesFosterParenting(const QualifiedName& tagName)
75967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
76967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return tagName == tableTag
77967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        || tagName == tbodyTag
78967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        || tagName == tfootTag
79967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        || tagName == theadTag
80967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        || tagName == trTag;
81967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
82967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
83e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} // namespace
84e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
85e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarketemplate<typename ChildType>
86d0147a863b872ecaa451ab0dce2a348760e99e2cBen MurdochPassRefPtr<ChildType> HTMLConstructionSite::attach(ContainerNode* rawParent, PassRefPtr<ChildType> prpChild)
87e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
88e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    RefPtr<ChildType> child = prpChild;
89d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    RefPtr<ContainerNode> parent = rawParent;
90e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
91e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // FIXME: It's confusing that HTMLConstructionSite::attach does the magic
92e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // redirection to the foster parent but HTMLConstructionSite::attachAtSite
93d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // doesn't. It feels like we're missing a concept somehow.
94967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (shouldFosterParent()) {
95e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        fosterParent(child.get());
966b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        ASSERT(child->attached() || !child->parentNode() || !child->parentNode()->attached());
97e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return child.release();
98e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
99e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
100e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    parent->parserAddChild(child);
101f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
102f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // An event handler (DOM Mutation, beforeload, et al.) could have removed
103f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // the child, in which case we shouldn't try attaching it.
104f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (!child->parentNode())
105f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return child.release();
106f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
1070617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    if (parent->attached() && !child->attached())
108967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        child->attach();
109e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return child.release();
110e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
111e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
112e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::attachAtSite(const AttachmentSite& site, PassRefPtr<Node> prpChild)
113e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
11468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // FIXME: It's unfortunate that we need to hold a reference to child
11568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // here to call attach().  We should investigate whether we can rely on
11668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // |site.parent| to hold a ref at this point.
117e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    RefPtr<Node> child = prpChild;
118e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
11968513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (site.nextChild)
120e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        site.parent->parserInsertBefore(child, site.nextChild);
12168513a70bcd92384395513322f1b801e7bf9c729Steve Block    else
12268513a70bcd92384395513322f1b801e7bf9c729Steve Block        site.parent->parserAddChild(child);
12368513a70bcd92384395513322f1b801e7bf9c729Steve Block
12468513a70bcd92384395513322f1b801e7bf9c729Steve Block    // JavaScript run from beforeload (or DOM Mutation or event handlers)
12568513a70bcd92384395513322f1b801e7bf9c729Steve Block    // might have removed the child, in which case we should not attach it.
12668513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (child->parentNode() && site.parent->attached() && !child->attached())
127e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        child->attach();
128e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
129e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
1302fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockHTMLConstructionSite::HTMLConstructionSite(Document* document)
131e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    : m_document(document)
1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    , m_attachmentRoot(document)
1332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    , m_fragmentScriptingPermission(FragmentScriptingAllowed)
1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    , m_isParsingFragment(false)
1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    , m_redirectAttachToFosterParent(false)
1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1392fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockHTMLConstructionSite::HTMLConstructionSite(DocumentFragment* fragment, FragmentScriptingPermission scriptingPermission)
1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    : m_document(fragment->document())
1412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    , m_attachmentRoot(fragment)
142e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    , m_fragmentScriptingPermission(scriptingPermission)
1432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    , m_isParsingFragment(true)
144e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    , m_redirectAttachToFosterParent(false)
145e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
146e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
147e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
148e458d70a0d18538346f41b503114c9ebe6b2ce12Leon ClarkeHTMLConstructionSite::~HTMLConstructionSite()
149e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
150e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
151e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
152e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockvoid HTMLConstructionSite::detach()
153e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block{
154e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    m_document = 0;
1552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_attachmentRoot = 0;
156e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block}
157e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
158dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochvoid HTMLConstructionSite::setForm(HTMLFormElement* form)
159dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch{
160dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    // This method should only be needed for HTMLTreeBuilder in the fragment case.
161dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    ASSERT(!m_form);
162dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    m_form = form;
163dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch}
164dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
165967717af5423377c967781471ee106e2bb4e11c8Ben MurdochPassRefPtr<HTMLFormElement> HTMLConstructionSite::takeForm()
166967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
167967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return m_form.release();
168967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
169967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
170967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded()
171967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
172e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    ASSERT(m_document);
173967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (m_document->frame() && !m_isParsingFragment)
174967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        m_document->frame()->loader()->dispatchDocumentElementAvailable();
175967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
176967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
177e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken& token)
178e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
179a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(m_document);
180e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
1812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_openElements.pushHTMLHtmlElement(attach<Element>(m_attachmentRoot, element.get()));
182a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#if ENABLE(OFFLINE_WEB_APPLICATIONS)
183a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    element->insertedByParser();
184a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif
185967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    dispatchDocumentElementAvailableIfNeeded();
186e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
187e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
188e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::mergeAttributesFromTokenIntoElement(AtomicHTMLToken& token, Element* element)
189e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
190e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!token.attributes())
191e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
192e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
193e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    NamedNodeMap* attributes = element->attributes(false);
194e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    for (unsigned i = 0; i < token.attributes()->length(); ++i) {
195e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        Attribute* attribute = token.attributes()->attributeItem(i);
196e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (!attributes->getAttributeItem(attribute->name()))
197e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            element->setAttribute(attribute->name(), attribute->value());
198e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
199e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
200e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
201e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertHTMLHtmlStartTagInBody(AtomicHTMLToken& token)
202e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
203e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // FIXME: parse error
20481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
20581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // Fragments do not have a root HTML element, so any additional HTML elements
20681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // encountered during fragment parsing should be ignored.
20781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_isParsingFragment)
20881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
20981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
210e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    mergeAttributesFromTokenIntoElement(token, m_openElements.htmlElement());
211e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
212e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
213e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertHTMLBodyStartTagInBody(AtomicHTMLToken& token)
214e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
215e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // FIXME: parse error
216e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    mergeAttributesFromTokenIntoElement(token, m_openElements.bodyElement());
217e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
218e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
219e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertDoctype(AtomicHTMLToken& token)
220e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
221e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::DOCTYPE);
2222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    attach(m_attachmentRoot, DocumentType::create(m_document, token.name(), String::adopt(token.publicIdentifier()), String::adopt(token.systemIdentifier())));
2232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // DOCTYPE nodes are only processed when parsing fragments w/o contextElements, which
2252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // never occurs.  However, if we ever chose to support such, this code is subtly wrong,
2262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // because context-less fragments can determine their own quirks mode, and thus change
2272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // parsing rules (like <p> inside <table>).  For now we ASSERT that we never hit this code
2282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // in a fragment, as changing the owning document's compatibility mode would be wrong.
2292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(!m_isParsingFragment);
2302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_isParsingFragment)
2312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
2325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
233e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (token.forceQuirks())
2345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        m_document->setCompatibilityMode(Document::QuirksMode);
2355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    else
2365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        m_document->setCompatibilityModeFromDoctype();
237e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
238e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
239e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertComment(AtomicHTMLToken& token)
240e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
241e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::Comment);
24281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    attach(currentNode(), Comment::create(currentNode()->document(), token.comment()));
243e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
244e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
245e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertCommentOnDocument(AtomicHTMLToken& token)
246e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
247e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::Comment);
2482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    attach(m_attachmentRoot, Comment::create(m_document, token.comment()));
249e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
250e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
251e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertCommentOnHTMLHtmlElement(AtomicHTMLToken& token)
252e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
253e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::Comment);
25481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ContainerNode* parent = m_openElements.rootNode();
2555abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    attach(parent, Comment::create(parent->document(), token.comment()));
256e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
257e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
258967717af5423377c967781471ee106e2bb4e11c8Ben MurdochPassRefPtr<Element> HTMLConstructionSite::attachToCurrent(PassRefPtr<Element> child)
259e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
26081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return attach(currentNode(), child);
261e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
262e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
263e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertHTMLHeadElement(AtomicHTMLToken& token)
264e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
265967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ASSERT(!shouldFosterParent());
266967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    m_head = attachToCurrent(createHTMLElement(token));
267e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_openElements.pushHTMLHeadElement(m_head);
268e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
269e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
270e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken& token)
271e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
272967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ASSERT(!shouldFosterParent());
273967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    m_openElements.pushHTMLBodyElement(attachToCurrent(createHTMLElement(token)));
274967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
275967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
2765ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken& token, bool isDemoted)
277967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
2785ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    RefPtr<Element> element = createHTMLElement(token);
2795ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    ASSERT(element->hasTagName(formTag));
2805ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    RefPtr<HTMLFormElement> form = static_pointer_cast<HTMLFormElement>(element.release());
2815ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    form->setDemoted(isDemoted);
2825ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_openElements.push(attachToCurrent(form.release()));
283967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ASSERT(currentElement()->isHTMLElement());
284967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ASSERT(currentElement()->hasTagName(formTag));
285967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    m_form = static_cast<HTMLFormElement*>(currentElement());
286e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
287e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
288e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken& token)
289e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
290967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    m_openElements.push(attachToCurrent(createHTMLElement(token)));
291e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
292e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
293e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertSelfClosingHTMLElement(AtomicHTMLToken& token)
294e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
295e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::StartTag);
296967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    RefPtr<Element> element = attachToCurrent(createHTMLElement(token));
297967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // Normally HTMLElementStack is responsible for calling finishParsingChildren,
298967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // but self-closing elements are never in the element stack so the stack
299967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // doesn't get a chance to tell them that we're done parsing their children.
300967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    element->finishParsingChildren();
301e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // FIXME: Do we want to acknowledge the token's self-closing flag?
302e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#acknowledge-self-closing-flag
303e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
304e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
305e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertFormattingElement(AtomicHTMLToken& token)
306e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
307e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#the-stack-of-open-elements
308e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // Possible active formatting elements include:
309e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // a, b, big, code, em, font, i, nobr, s, small, strike, strong, tt, and u.
310e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    insertHTMLElement(token);
311e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    m_activeFormattingElements.append(currentElement());
312e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
313e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
314e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertScriptElement(AtomicHTMLToken& token)
315e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
31681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, currentNode()->document(), true);
317e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block    if (m_fragmentScriptingPermission == FragmentScriptingAllowed)
318e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
319967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    m_openElements.push(attachToCurrent(element.release()));
320e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
321e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
322e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertForeignElement(AtomicHTMLToken& token, const AtomicString& namespaceURI)
323e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
324e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(token.type() == HTMLToken::StartTag);
325e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    notImplemented(); // parseError when xmlns or xmlns:xlink are wrong.
326e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
327967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    RefPtr<Element> element = attachToCurrent(createElement(token, namespaceURI));
328e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!token.selfClosing())
329e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_openElements.push(element);
330e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
331e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
332e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::insertTextNode(const String& characters)
333e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
334e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    AttachmentSite site;
33581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    site.parent = currentNode();
336e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    site.nextChild = 0;
337967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (shouldFosterParent())
338e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        findFosterSite(site);
339e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
34081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    unsigned currentPosition = 0;
34181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
34281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // FIXME: Splitting text nodes into smaller chunks contradicts HTML5 spec, but is currently necessary
34381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // for performance, see <https://bugs.webkit.org/show_bug.cgi?id=55898>.
34481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
345e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    Node* previousChild = site.nextChild ? site.nextChild->previousSibling() : site.parent->lastChild();
346e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (previousChild && previousChild->isTextNode()) {
347e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // FIXME: We're only supposed to append to this text node if it
348e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        // was the last text node inserted by the parser.
349e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        CharacterData* textNode = static_cast<CharacterData*>(previousChild);
35081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        currentPosition = textNode->parserAppendData(characters.characters(), characters.length(), Text::defaultLengthLimit);
351e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
352e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
35381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (currentPosition < characters.length()) {
35481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        RefPtr<Text> textNode = Text::createWithLengthLimit(site.parent->document(), characters, currentPosition);
35581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        // If we have a whole string of unbreakable characters the above could lead to an infinite loop. Exceeding the length limit is the lesser evil.
35681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!textNode->length())
35781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            textNode = Text::create(site.parent->document(), characters.substring(currentPosition));
35881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
35981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        currentPosition += textNode->length();
36081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(currentPosition <= characters.length());
36181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        attachAtSite(site, textNode.release());
36281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
363e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
364e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
365e458d70a0d18538346f41b503114c9ebe6b2ce12Leon ClarkePassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken& token, const AtomicString& namespaceURI)
366e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
367e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    QualifiedName tagName(nullAtom, token.name(), namespaceURI);
36881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RefPtr<Element> element = currentNode()->document()->createElement(tagName, true);
369e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
370e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return element.release();
371e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
372e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
373e458d70a0d18538346f41b503114c9ebe6b2ce12Leon ClarkePassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken& token)
374e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
375967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    QualifiedName tagName(nullAtom, token.name(), xhtmlNamespaceURI);
376967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // FIXME: This can't use HTMLConstructionSite::createElement because we
377967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // have to pass the current form element.  We should rework form association
378967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // to occur after construction to allow better code sharing here.
37981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    RefPtr<Element> element = HTMLElementFactory::createHTMLElement(tagName, currentNode()->document(), form(), true);
380967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    element->setAttributeMap(token.takeAtributes(), m_fragmentScriptingPermission);
381e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(element->isHTMLElement());
382e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return element.release();
383e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
384e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
385967717af5423377c967781471ee106e2bb4e11c8Ben MurdochPassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromElementRecord(HTMLElementStack::ElementRecord* record)
386967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
387967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return createHTMLElementFromSavedElement(record->element());
388967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
389967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
390967717af5423377c967781471ee106e2bb4e11c8Ben Murdochnamespace {
391967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
392967717af5423377c967781471ee106e2bb4e11c8Ben MurdochPassRefPtr<NamedNodeMap> cloneAttributes(Element* element)
393967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
394967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    NamedNodeMap* attributes = element->attributes(true);
395967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    if (!attributes)
396967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        return 0;
397967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
398967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    RefPtr<NamedNodeMap> newAttributes = NamedNodeMap::create();
399967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    for (size_t i = 0; i < attributes->length(); ++i) {
400967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        Attribute* attribute = attributes->attributeItem(i);
401967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        RefPtr<Attribute> clone = Attribute::createMapped(attribute->name(), attribute->value());
402967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        newAttributes->addAttribute(clone);
403967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    }
404967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return newAttributes.release();
405967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
406967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
407967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
408967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
409967717af5423377c967781471ee106e2bb4e11c8Ben MurdochPassRefPtr<Element> HTMLConstructionSite::createHTMLElementFromSavedElement(Element* element)
410967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
411967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // FIXME: This method is wrong.  We should be using the original token.
412967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // Using an Element* causes us to fail examples like this:
413967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // <b id="1"><p><script>document.getElementById("1").id = "2"</script></p>TEXT</b>
414967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // When reconstructTheActiveFormattingElements calls this method to open
415967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // a second <b> tag to wrap TEXT, it will have id "2", even though the HTML5
416967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    // spec implies it should be "1".  Minefield matches the HTML5 spec here.
417967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
418967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    ASSERT(element->isHTMLElement()); // otherwise localName() might be wrong.
419967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    AtomicHTMLToken fakeToken(HTMLToken::StartTag, element->localName(), cloneAttributes(element));
420967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return createHTMLElement(fakeToken);
421967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
422967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
423e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool HTMLConstructionSite::indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const
424e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
425e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (m_activeFormattingElements.isEmpty())
426e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return false;
427e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    unsigned index = m_activeFormattingElements.size();
428e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    do {
429e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        --index;
430e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        const HTMLFormattingElementList::Entry& entry = m_activeFormattingElements.at(index);
431e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (entry.isMarker() || m_openElements.contains(entry.element())) {
432e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            firstUnopenElementIndex = index + 1;
433e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return firstUnopenElementIndex < m_activeFormattingElements.size();
434e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
435e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    } while (index);
436e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    firstUnopenElementIndex = index;
437e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return true;
438e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
439e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
440e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::reconstructTheActiveFormattingElements()
441e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
442e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    unsigned firstUnopenElementIndex;
443e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (!indexOfFirstUnopenFormattingElement(firstUnopenElementIndex))
444e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
445e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
446e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    unsigned unopenEntryIndex = firstUnopenElementIndex;
447e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    ASSERT(unopenEntryIndex < m_activeFormattingElements.size());
448e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    for (; unopenEntryIndex < m_activeFormattingElements.size(); ++unopenEntryIndex) {
449e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        HTMLFormattingElementList::Entry& unopenedEntry = m_activeFormattingElements.at(unopenEntryIndex);
450967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        RefPtr<Element> reconstructed = createHTMLElementFromSavedElement(unopenedEntry.element());
451967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        m_openElements.push(attachToCurrent(reconstructed.release()));
452e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        unopenedEntry.replaceElement(currentElement());
453e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
454e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
455e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
456e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::generateImpliedEndTagsWithExclusion(const AtomicString& tagName)
457e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
45881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (hasImpliedEndTag(currentNode()) && !currentNode()->hasLocalName(tagName))
459e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_openElements.pop();
460e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
461e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
462e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::generateImpliedEndTags()
463e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
46481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (hasImpliedEndTag(currentNode()))
465e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_openElements.pop();
466e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
467e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
468e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::findFosterSite(AttachmentSite& site)
469e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
470e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    HTMLElementStack::ElementRecord* lastTableElementRecord = m_openElements.topmost(tableTag.localName());
471e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (lastTableElementRecord) {
472e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        Element* lastTableElement = lastTableElementRecord->element();
4736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (ContainerNode* parent = lastTableElement->parentNode()) {
474e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            site.parent = parent;
475e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            site.nextChild = lastTableElement;
476e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            return;
477e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        }
478e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        site.parent = lastTableElementRecord->next()->element();
479e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        site.nextChild = 0;
480e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        return;
481e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
482e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // Fragment case
48381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    site.parent = m_openElements.rootNode(); // DocumentFragment
484e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    site.nextChild = 0;
485e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
486e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
487967717af5423377c967781471ee106e2bb4e11c8Ben Murdochbool HTMLConstructionSite::shouldFosterParent() const
488967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{
489967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return m_redirectAttachToFosterParent
49081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        && currentNode()->isElementNode()
491967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch        && causesFosterParenting(currentElement()->tagQName());
492967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch}
493967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
494e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid HTMLConstructionSite::fosterParent(Node* node)
495e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
496e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    AttachmentSite site;
497e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    findFosterSite(site);
498e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    attachAtSite(site, node);
499e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
500e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
501e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
502