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