18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Copyright (C) 1997 Martin Jones (mjones@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              (C) 1997 Torben Weis (weis@kde.org)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              (C) 1999,2001 Lars Knoll (knoll@kde.org)
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project              (C) 2000,2001 Dirk Mueller (mueller@kde.org)
65f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
75f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    This library is free software; you can redistribute it and/or
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    modify it under the terms of the GNU Library General Public
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    License as published by the Free Software Foundation; either
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    version 2 of the License, or (at your option) any later version.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    This library is distributed in the hope that it will be useful,
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    but WITHOUT ANY WARRANTY; without even the implied warranty of
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Library General Public License for more details.
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    You should have received a copy of the GNU Library General Public License
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    along with this library; see the file COPYING.LIB.  If not, write to
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Boston, MA 02110-1301, USA.
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project*/
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLParser.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CharacterNames.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSPropertyNames.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSValueKeywords.h"
31d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "Chrome.h"
325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "ChromeClient.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Comment.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Console.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DOMWindow.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocumentFragment.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "DocumentType.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLBodyElement.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLDocument.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLDivElement.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLDListElement.h"
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLElementFactory.h"
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLFormElement.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLHeadElement.h"
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLHRElement.h"
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLHtmlElement.h"
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLIsIndexElement.h"
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLMapElement.h"
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "HTMLParserQuirks.h"
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLTableCellElement.h"
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLTableRowElement.h"
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLTableSectionElement.h"
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLTokenizer.h"
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "LocalizedStrings.h"
575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "Page.h"
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Settings.h"
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Text.h"
60635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/StdLibExtras.h>
615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const unsigned cMaxRedundantTagDepth = 20;
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const unsigned cResidualStyleMaxDepth = 200;
68d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic const unsigned cResidualStyleIterationLimit = 5;
69d0825bca7fe65beaee391d30da42e937db621564Steve Block
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic const int minBlockLevelTagPriority = 3;
728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// A cap on the number of tags with priority minBlockLevelTagPriority or higher
748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// allowed in m_blockStack. The cap is enforced by adding such new elements as
758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// siblings instead of children once it is reached.
768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic const size_t cMaxBlockDepth = 4096;
778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct HTMLStackElem : Noncopyable {
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLStackElem(const AtomicString& t, int lvl, Node* n, bool r, HTMLStackElem* nx)
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        : tagName(t)
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        , level(lvl)
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        , strayTableContent(false)
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        , node(n)
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        , didRefNode(r)
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        , next(nx)
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void derefNode()
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (didRefNode)
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            node->deref();
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    AtomicString tagName;
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int level;
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool strayTableContent;
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* node;
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool didRefNode;
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLStackElem* next;
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/**
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * The parser parses tokenized input into the document, building up the
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * document tree. If the document is well-formed, parsing it is straightforward.
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Unfortunately, we have to handle many HTML documents that are not well-formed,
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * so the parser has to be tolerant about errors.
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * We have to take care of at least the following error conditions:
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. The element being added is explicitly forbidden inside some outer tag.
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    In this case we should close all tags up to the one, which forbids
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    the element, and add it afterwards.
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. We are not allowed to add the element directly. It could be that
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    the person writing the document forgot some tag in between (or that the
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    tag in between is optional). This could be the case with the following
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    tags: HTML HEAD BODY TBODY TR TD LI (did I forget any?).
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3. We want to add a block element inside to an inline element. Close all
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    inline elements up to the next higher block element.
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 4. If this doesn't help, close elements until we are allowed to add the
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    element or ignore the tag.
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLParser::HTMLParser(HTMLDocument* doc, bool reportErrors)
1308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    : m_document(doc)
1318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_current(doc)
1328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_didRefCurrent(false)
1338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_blockStack(0)
1348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_blocksInStack(0)
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_hasPElementInScope(NotInScope)
1368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_inBody(false)
1378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_haveContent(false)
1388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_haveFrameSet(false)
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_isParsingFragment(false)
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_reportErrors(reportErrors)
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_handlingResidualStyleAcrossBlocks(false)
1428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_inStrayTableContent(0)
143d0825bca7fe65beaee391d30da42e937db621564Steve Block    , m_scriptingPermission(FragmentScriptingAllowed)
1445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_parserQuirks(m_document->page() ? m_document->page()->chrome()->client()->createHTMLParserQuirks() : 0)
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
148d0825bca7fe65beaee391d30da42e937db621564Steve BlockHTMLParser::HTMLParser(DocumentFragment* frag, FragmentScriptingPermission scriptingPermission)
1498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    : m_document(frag->document())
1508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_current(frag)
1518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_didRefCurrent(true)
1528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_blockStack(0)
1538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_blocksInStack(0)
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_hasPElementInScope(NotInScope)
1558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_inBody(true)
1568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_haveContent(false)
1578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_haveFrameSet(false)
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_isParsingFragment(true)
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_reportErrors(false)
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_handlingResidualStyleAcrossBlocks(false)
1618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    , m_inStrayTableContent(0)
162d0825bca7fe65beaee391d30da42e937db621564Steve Block    , m_scriptingPermission(scriptingPermission)
1635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_parserQuirks(m_document->page() ? m_document->page()->chrome()->client()->createHTMLParserQuirks() : 0)
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (frag)
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        frag->ref();
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLParser::~HTMLParser()
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    freeBlock();
1728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_didRefCurrent)
1735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_current->deref();
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::reset()
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_isParsingFragment);
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    setCurrent(m_document);
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    freeBlock();
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_inBody = false;
1858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_haveFrameSet = false;
1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_haveContent = false;
1878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_inStrayTableContent = 0;
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_currentFormElement = 0;
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_currentMapElement = 0;
1918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_head = 0;
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_isindexElement = 0;
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_skipModeTag = nullAtom;
1955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_parserQuirks)
1975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_parserQuirks->reset();
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::setCurrent(Node* newCurrent)
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool didRefNewCurrent = newCurrent && newCurrent != m_document;
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (didRefNewCurrent)
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        newCurrent->ref();
2058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_didRefCurrent)
2068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_current->deref();
2078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_current = newCurrent;
2088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_didRefCurrent = didRefNewCurrent;
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
211643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockinline static int tagPriorityOfNode(Node* n)
212643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
213643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return n->isHTMLElement() ? static_cast<HTMLElement*>(n)->tagPriority() : 0;
214643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
215643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
216643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockinline void HTMLParser::limitBlockDepth(int tagPriority)
217643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
218643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (tagPriority >= minBlockLevelTagPriority) {
219643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        while (m_blocksInStack >= cMaxBlockDepth)
220643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            popBlock(m_blockStack->tagName);
221643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
222643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
223643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
224643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockinline bool HTMLParser::insertNodeAfterLimitBlockDepth(Node* n, bool flat)
225643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
226643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    limitBlockDepth(tagPriorityOfNode(n));
227643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return insertNode(n, flat);
228643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
229643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Node> HTMLParser::parseToken(Token* t)
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_skipModeTag.isNull()) {
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!t->beginTag && t->tagName == m_skipModeTag)
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Found the end tag for the current skip mode, so we're done skipping.
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_skipModeTag = nullAtom;
2368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else if (m_current->localName() == t->tagName)
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Do not skip </iframe>.
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // FIXME: What does that comment mean? How can it be right to parse a token without clearing m_skipModeTag?
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ;
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return 0;
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Apparently some sites use </br> instead of <br>. Be compatible with IE and Firefox and treat this like <br>.
2458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (t->isCloseTag(brTag) && m_document->inCompatMode()) {
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        reportError(MalformedBRError);
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        t->beginTag = true;
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!t->beginTag) {
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        processCloseTag(t);
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Ignore spaces, if we're not inside a paragraph or other inline code.
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Do not alter the text if it is part of a scriptTag.
2578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (t->tagName == textAtom && t->text && m_current->localName() != scriptTag) {
2588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (m_inBody && !skipMode() && m_current->localName() != styleTag &&
2598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            m_current->localName() != titleTag && !t->text->containsOnlyWhitespace())
2608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            m_haveContent = true;
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<Node> n;
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String text = t->text.get();
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unsigned charsLeft = text.length();
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (charsLeft) {
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // split large blocks of text to nodes of manageable size
2678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            n = Text::createWithLengthLimit(m_document, text, charsLeft);
268643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (!insertNodeAfterLimitBlockDepth(n.get(), t->selfClosingTag))
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return 0;
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return n;
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> n = getNode(t);
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // just to be sure, and to catch currently unimplemented stuff
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!n)
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // set attributes
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (n->isHTMLElement()) {
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLElement* e = static_cast<HTMLElement*>(n.get());
282d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (m_scriptingPermission == FragmentScriptingAllowed || t->tagName != scriptTag)
283d0825bca7fe65beaee391d30da42e937db621564Steve Block            e->setAttributeMap(t->attrs.get(), m_scriptingPermission);
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // take care of optional close tags
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (e->endTagRequirement() == TagStatusOptional)
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            popBlock(t->tagName);
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If the node does not have a forbidden end tag requirement, and if the broken XML self-closing
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // syntax was used, report an error.
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (t->brokenXMLStyle && e->endTagRequirement() != TagStatusForbidden) {
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (t->tagName == scriptTag)
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                reportError(IncorrectXMLCloseScriptWarning);
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                reportError(IncorrectXMLSelfCloseError, &t->tagName);
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
299643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!insertNodeAfterLimitBlockDepth(n.get(), t->selfClosingTag)) {
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // we couldn't insert the node
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n->isElementNode()) {
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Element* e = static_cast<Element*>(n.get());
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e->setAttributeMap(0);
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_currentMapElement == n)
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_currentMapElement = 0;
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_currentFormElement == n)
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_currentFormElement = 0;
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (m_head == n)
3148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            m_head = 0;
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return n;
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::parseDoctypeToken(DoctypeToken* t)
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Ignore any doctype after the first.  Ignore doctypes in fragments.
3248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_document->doctype() || m_isParsingFragment || m_current != m_document)
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Make a new doctype node and set it as our doctype.
3288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_document->addChild(DocumentType::create(m_document, String::adopt(t->m_name), String::adopt(t->m_publicID), String::adopt(t->m_systemID)));
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic bool isTableSection(const Node* n)
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return n->hasTagName(tbodyTag) || n->hasTagName(tfootTag) || n->hasTagName(theadTag);
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic bool isTablePart(const Node* n)
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return n->hasTagName(trTag) || n->hasTagName(tdTag) || n->hasTagName(thTag) ||
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project           isTableSection(n);
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic bool isTableRelated(const Node* n)
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return n->hasTagName(tableTag) || isTablePart(n);
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool isScopingTag(const AtomicString& tagName)
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return tagName == appletTag || tagName == captionTag || tagName == tdTag || tagName == thTag || tagName == buttonTag || tagName == marqueeTag || tagName == objectTag || tagName == tableTag || tagName == htmlTag;
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::insertNode(Node* n, bool flat)
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> protectNode(n);
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const AtomicString& localName = n->localName();
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // <table> is never allowed inside stray table content.  Always pop out of the stray table content
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // and close up the first table, and then start the second table as a sibling.
3608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_inStrayTableContent && localName == tableTag)
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        popBlock(tableTag);
3628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_parserQuirks && !m_parserQuirks->shouldInsertNode(m_current, n))
3645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return false;
3655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
366643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    int tagPriority = tagPriorityOfNode(n);
367643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // let's be stupid and just try to insert it.
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // this should work if the document is well-formed
3708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node* newNode = m_current->addChild(n);
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!newNode)
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return handleError(n, flat, localName, tagPriority); // Try to handle the error.
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // don't push elements without end tags (e.g., <img>) on the stack
3758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool parentAttached = m_current->attached();
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (tagPriority > 0 && !flat) {
3778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (newNode == m_current) {
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // This case should only be hit when a demoted <form> is placed inside a table.
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(localName == formTag);
3808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            reportError(FormInsideTablePartError, &m_current->localName());
3815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            HTMLFormElement* form = static_cast<HTMLFormElement*>(n);
3825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            form->setDemoted(true);
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // The pushBlock function transfers ownership of current to the block stack
3858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // so we're guaranteed that m_didRefCurrent is false. The code below is an
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // optimized version of setCurrent that takes advantage of that fact and also
3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // assumes that newNode is neither 0 nor a pointer to the document.
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            pushBlock(localName, tagPriority);
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            newNode->beginParsingChildren();
3908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            ASSERT(!m_didRefCurrent);
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            newNode->ref();
3928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            m_current = newNode;
3938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            m_didRefCurrent = true;
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (parentAttached && !n->attached() && !m_isParsingFragment)
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            n->attach();
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (parentAttached && !n->attached() && !m_isParsingFragment)
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            n->attach();
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        n->finishParsingChildren();
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (localName == htmlTag && m_document->frame())
4048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_document->frame()->loader()->dispatchDocumentElementAvailable();
4058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName, int tagPriority)
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Error handling code.  This is just ad hoc handling of specific parent/child combinations.
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement* e;
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool handled = false;
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 1. Check out the element's tag name to decide how to deal with errors.
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (n->isHTMLElement()) {
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLElement* h = static_cast<HTMLElement*>(n);
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (h->hasLocalName(trTag) || h->hasLocalName(thTag) || h->hasLocalName(tdTag)) {
4198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (m_inStrayTableContent && !isTableRelated(m_current)) {
4208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                reportError(MisplacedTablePartError, &localName, &m_current->localName());
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // pop out to the nearest enclosing table-related tag.
4228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                while (m_blockStack && !isTableRelated(m_current))
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    popOneBlock();
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return insertNode(n);
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(headTag)) {
4278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!m_current->isDocumentNode() && !m_current->hasTagName(htmlTag)) {
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                reportError(MisplacedHeadError);
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(metaTag) || h->hasLocalName(linkTag) || h->hasLocalName(baseTag)) {
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bool createdHead = false;
4338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!m_head) {
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                createHead();
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                createdHead = true;
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (m_head) {
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!createdHead)
4398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    reportError(MisplacedHeadContentError, &localName, &m_current->localName());
4408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (m_head->addChild(n)) {
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!n->attached() && !m_isParsingFragment)
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        n->attach();
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return true;
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return false;
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(htmlTag)) {
4488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!m_current->isDocumentNode() ) {
4498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (m_document->documentElement() && m_document->documentElement()->hasTagName(htmlTag)) {
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    reportError(RedundantHTMLBodyError, &localName);
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // we have another <HTML> element.... apply attributes to existing one
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // make sure we don't overwrite already existing attributes
4535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    NamedNodeMap* map = static_cast<Element*>(n)->attributes(true);
4548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    Element* existingHTML = static_cast<Element*>(m_document->documentElement());
4555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    NamedNodeMap* bmap = existingHTML->attributes(false);
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    for (unsigned l = 0; map && l < map->length(); ++l) {
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        Attribute* it = map->attributeItem(l);
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (!bmap->getAttributeItem(it->name()))
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            existingHTML->setAttribute(it->name(), it->value());
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } else if (h->hasLocalName(titleTag) || h->hasLocalName(styleTag) || h->hasLocalName(scriptTag)) {
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            bool createdHead = false;
4668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!m_head) {
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                createHead();
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                createdHead = true;
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (m_head) {
4718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                Node* newNode = m_head->addChild(n);
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!newNode) {
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    setSkipMode(h->tagQName());
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return false;
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!createdHead)
4788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    reportError(MisplacedHeadContentError, &localName, &m_current->localName());
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                pushBlock(localName, tagPriority);
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                newNode->beginParsingChildren();
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                setCurrent(newNode);
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!n->attached() && !m_isParsingFragment)
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    n->attach();
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (m_inBody) {
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                setSkipMode(h->tagQName());
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(bodyTag)) {
4928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (m_inBody && m_document->body()) {
4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // we have another <BODY> element.... apply attributes to existing one
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // make sure we don't overwrite already existing attributes
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // some sites use <body bgcolor=rightcolor>...<body bgcolor=wrongcolor>
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                reportError(RedundantHTMLBodyError, &localName);
4975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                NamedNodeMap* map = static_cast<Element*>(n)->attributes(true);
4988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                Element* existingBody = m_document->body();
4995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                NamedNodeMap* bmap = existingBody->attributes(false);
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                for (unsigned l = 0; map && l < map->length(); ++l) {
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    Attribute* it = map->attributeItem(l);
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!bmap->getAttributeItem(it->name()))
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        existingBody->setAttribute(it->name(), it->value());
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            else if (!m_current->isDocumentNode())
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
5098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(areaTag)) {
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_currentMapElement) {
5118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                reportError(MisplacedAreaError, &m_current->localName());
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_currentMapElement->addChild(n);
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!n->attached() && !m_isParsingFragment)
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    n->attach();
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                handled = true;
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(colgroupTag) || h->hasLocalName(captionTag)) {
5208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (isTableRelated(m_current)) {
5218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                while (m_blockStack && isTablePart(m_current))
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    popOneBlock();
5238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return insertNode(n);
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else if (n->isCommentNode() && !m_head)
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 2. Next we examine our currently active element to do some further error handling.
5308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_current->isHTMLElement()) {
5318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        HTMLElement* h = static_cast<HTMLElement*>(m_current);
5328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const AtomicString& currentTagName = h->localName();
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (h->hasLocalName(htmlTag)) {
5348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            HTMLElement* elt = n->isHTMLElement() ? static_cast<HTMLElement*>(n) : 0;
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (elt && (elt->hasLocalName(scriptTag) || elt->hasLocalName(styleTag) ||
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                elt->hasLocalName(metaTag) || elt->hasLocalName(linkTag) ||
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                elt->hasLocalName(objectTag) || elt->hasLocalName(embedTag) ||
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                elt->hasLocalName(titleTag) || elt->hasLocalName(isindexTag) ||
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                elt->hasLocalName(baseTag))) {
5408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (!m_head) {
5418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    m_head = new HTMLHeadElement(headTag, m_document);
5425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    insertNode(m_head.get());
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    handled = true;
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (n->isTextNode()) {
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    Text* t = static_cast<Text*>(n);
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (t->containsOnlyWhitespace())
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        return false;
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (!m_haveFrameSet) {
5525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    // Ensure that head exists.
5535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    // But not for older versions of Mail, where the implicit <head> isn't expected - <rdar://problem/6863795>
5545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    if (shouldCreateImplicitHead(m_document))
5555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                        createHead();
5565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    popBlock(headTag);
5588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    e = new HTMLBodyElement(bodyTag, m_document);
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    startBody();
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    insertNode(e);
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    handled = true;
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
5638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    reportError(MisplacedFramesetContentError, &localName);
5648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(headTag)) {
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (n->hasTagName(htmlTag))
5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else {
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // This means the body starts here...
5708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (!m_haveFrameSet) {
5715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    ASSERT(currentTagName == headTag);
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    popBlock(currentTagName);
5738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    e = new HTMLBodyElement(bodyTag, m_document);
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    startBody();
5758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    insertNode(e);
5768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    handled = true;
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    reportError(MisplacedFramesetContentError, &localName);
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(addressTag) || h->hasLocalName(fontTag)
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                   || h->hasLocalName(styleTag) || h->hasLocalName(titleTag)) {
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            reportError(MisplacedContentRetryError, &localName, &currentTagName);
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            popBlock(currentTagName);
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            handled = true;
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(captionTag)) {
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Illegal content in a caption. Close the caption and try again.
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            reportError(MisplacedCaptionContentError, &localName);
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            popBlock(currentTagName);
5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (isTablePart(n))
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return insertNode(n, flat);
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(tableTag) || h->hasLocalName(trTag) || isTableSection(h)) {
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (n->hasTagName(tableTag)) {
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                reportError(MisplacedTableError, &currentTagName);
5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (m_isParsingFragment && !h->hasLocalName(tableTag))
5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // fragment may contain table parts without <table> ancestor, pop them one by one
5968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    popBlock(h->localName());
5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                popBlock(localName); // end the table
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                handled = true;      // ...and start a new one
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                ExceptionCode ec = 0;
6018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                Node* node = m_current;
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                Node* parent = node->parentNode();
6038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // A script may have removed the current node's parent from the DOM
6048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // http://bugs.webkit.org/show_bug.cgi?id=7137
6058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // FIXME: we should do real recovery here and re-parent with the correct node.
6068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!parent)
6078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return false;
6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                Node* grandparent = parent->parentNode();
6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (n->isTextNode() ||
6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    (h->hasLocalName(trTag) &&
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                     isTableSection(parent) && grandparent && grandparent->hasTagName(tableTag)) ||
6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                     ((!n->hasTagName(tdTag) && !n->hasTagName(thTag) &&
6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                       !n->hasTagName(formTag) && !n->hasTagName(scriptTag)) && isTableSection(node) &&
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                     parent->hasTagName(tableTag))) {
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    node = (node->hasTagName(tableTag)) ? node :
6178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            ((node->hasTagName(trTag)) ? grandparent : parent);
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // This can happen with fragments
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!node)
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        return false;
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    Node* parent = node->parentNode();
6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!parent)
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        return false;
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    parent->insertBefore(n, node, ec);
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!ec) {
6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        reportError(StrayTableContentError, &localName, &currentTagName);
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (n->isHTMLElement() && tagPriority > 0 &&
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            !flat && static_cast<HTMLElement*>(n)->endTagRequirement() != TagStatusForbidden)
6298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        {
6308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            pushBlock(localName, tagPriority);
6318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            n->beginParsingChildren();
6328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            setCurrent(n);
6338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            m_inStrayTableContent++;
6348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            m_blockStack->strayTableContent = true;
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
6368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        return true;
6378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
6388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
6398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!ec) {
6418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    if (m_current->hasTagName(trTag)) {
6428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        reportError(TablePartRequiredError, &localName, &tdTag.localName());
6438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        e = new HTMLTableCellElement(tdTag, m_document);
6448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    } else if (m_current->hasTagName(tableTag)) {
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // Don't report an error in this case, since making a <tbody> happens all the time when you have <table><tr>,
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // and it isn't really a parse error per se.
6478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        e = new HTMLTableSectionElement(tbodyTag, m_document);
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } else {
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        reportError(TablePartRequiredError, &localName, &trTag.localName());
6508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        e = new HTMLTableRowElement(trTag, m_document);
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    insertNode(e);
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    handled = true;
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(objectTag)) {
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            reportError(MisplacedContentRetryError, &localName, &currentTagName);
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            popBlock(objectTag);
6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            handled = true;
661d0825bca7fe65beaee391d30da42e937db621564Steve Block        } else if (h->hasLocalName(pTag) || isHeadingTag(currentTagName)) {
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!isInline(n)) {
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                popBlock(currentTagName);
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                handled = true;
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(optionTag) || h->hasLocalName(optgroupTag)) {
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (localName == optgroupTag) {
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                popBlock(currentTagName);
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                handled = true;
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else if (localName == selectTag) {
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // IE treats a nested select as </select>. Let's do the same
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                popBlock(localName);
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(selectTag)) {
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (localName == inputTag || localName == textareaTag) {
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                reportError(MisplacedContentRetryError, &localName, &currentTagName);
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                popBlock(currentTagName);
6788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                handled = true;
6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (h->hasLocalName(colgroupTag)) {
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            popBlock(currentTagName);
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            handled = true;
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (!h->hasLocalName(bodyTag)) {
6848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (isInline(m_current)) {
6858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                popInlineBlocks();
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                handled = true;
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    } else if (m_current->isDocumentNode()) {
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n->isTextNode()) {
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Text* t = static_cast<Text*>(n);
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (t->containsOnlyWhitespace())
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!m_document->documentElement()) {
6978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            e = new HTMLHtmlElement(htmlTag, m_document);
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            insertNode(e);
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            handled = true;
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // 3. If we couldn't handle the error, just return false and attempt to error-correct again.
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!handled) {
7058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        reportError(IgnoredContentError, &localName, &m_current->localName());
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return insertNode(n);
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef bool (HTMLParser::*CreateErrorCheckFunc)(Token* t, RefPtr<Node>&);
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef HashMap<AtomicStringImpl*, CreateErrorCheckFunc> FunctionMap;
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::textCreateErrorCheck(Token* t, RefPtr<Node>& result)
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
716231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    result = Text::create(m_document, t->text.get());
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::commentCreateErrorCheck(Token* t, RefPtr<Node>& result)
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
722231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    result = Comment::create(m_document, t->text.get());
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
726635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::headCreateErrorCheck(Token*, RefPtr<Node>& result)
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!m_head || m_current->localName() == htmlTag) {
7298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_head = new HTMLHeadElement(headTag, m_document);
7308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        result = m_head;
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else
7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        reportError(MisplacedHeadError);
7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
736635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::bodyCreateErrorCheck(Token*, RefPtr<Node>&)
7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // body no longer allowed if we have a frameset
7398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_haveFrameSet)
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
7415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Ensure that head exists (unless parsing a fragment).
7435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // But not for older versions of Mail, where the implicit <head> isn't expected - <rdar://problem/6863795>
7445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!m_isParsingFragment && shouldCreateImplicitHead(m_document))
7455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        createHead();
7465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(headTag);
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    startBody();
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
752635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::framesetCreateErrorCheck(Token*, RefPtr<Node>&)
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(headTag);
7558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_inBody && !m_haveFrameSet && !m_haveContent) {
7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        popBlock(bodyTag);
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // ### actually for IE document.body returns the now hidden "body" element
7588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // we can't implement that behaviour now because it could cause too many
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // regressions and the headaches are not worth the work as long as there is
7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // no site actually relying on that detail (Dirk)
7618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (m_document->body())
7628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            m_document->body()->setAttribute(styleAttr, "display:none");
7638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_inBody = false;
7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if ((m_haveContent || m_haveFrameSet) && m_current->localName() == htmlTag)
7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
7678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_haveFrameSet = true;
7688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    startBody();
7698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
7708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::formCreateErrorCheck(Token* t, RefPtr<Node>& result)
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Only create a new form if we're not already inside one.
7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This is consistent with other browsers' behavior.
7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_currentFormElement) {
7778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_currentFormElement = new HTMLFormElement(formTag, m_document);
7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = m_currentFormElement;
7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pCloserCreateErrorCheck(t, result);
7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::isindexCreateErrorCheck(Token* t, RefPtr<Node>& result)
7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> n = handleIsindex(t);
7878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!m_inBody)
7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_isindexElement = n.release();
789635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    else {
790635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        t->selfClosingTag = true;
7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = n.release();
7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
796635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::selectCreateErrorCheck(Token*, RefPtr<Node>&)
7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::ddCreateErrorCheck(Token* t, RefPtr<Node>& result)
8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    pCloserCreateErrorCheck(t, result);
8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(dtTag);
8058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(ddTag);
8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::dtCreateErrorCheck(Token* t, RefPtr<Node>& result)
8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    pCloserCreateErrorCheck(t, result);
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(ddTag);
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(dtTag);
8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool HTMLParser::rpCreateErrorCheck(Token*, RefPtr<Node>&)
8180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
8190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    popBlock(rpTag);
8200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    popBlock(rtTag);
8210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return true;
8220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
8230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool HTMLParser::rtCreateErrorCheck(Token*, RefPtr<Node>&)
8250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
8260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    popBlock(rpTag);
8270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    popBlock(rtTag);
8280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return true;
8290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
8300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
831635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::nestedCreateErrorCheck(Token* t, RefPtr<Node>&)
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(t->tagName);
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::nestedPCloserCreateErrorCheck(Token* t, RefPtr<Node>& result)
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    pCloserCreateErrorCheck(t, result);
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(t->tagName);
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
844635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::nestedStyleCreateErrorCheck(Token* t, RefPtr<Node>&)
8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return allowNestedRedundantTag(t->tagName);
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
849635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::tableCellCreateErrorCheck(Token*, RefPtr<Node>&)
8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(tdTag);
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(thTag);
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
856635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::tableSectionCreateErrorCheck(Token*, RefPtr<Node>&)
8578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(theadTag);
8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(tbodyTag);
8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(tfootTag);
8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
864635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::noembedCreateErrorCheck(Token*, RefPtr<Node>&)
8658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setSkipMode(noembedTag);
8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
870635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::noframesCreateErrorCheck(Token*, RefPtr<Node>&)
8718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setSkipMode(noframesTag);
8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
876635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::noscriptCreateErrorCheck(Token*, RefPtr<Node>&)
8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_isParsingFragment) {
8798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Settings* settings = m_document->settings();
8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (settings && settings->isJavaScriptEnabled())
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            setSkipMode(noscriptTag);
8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
886635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::pCloserCreateErrorCheck(Token*, RefPtr<Node>&)
8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasPElementInScope())
8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        popBlock(pTag);
8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
8918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
893635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::pCloserStrictCreateErrorCheck(Token*, RefPtr<Node>&)
8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_document->inCompatMode())
8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasPElementInScope())
8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        popBlock(pTag);
8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
9008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
902635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool HTMLParser::mapCreateErrorCheck(Token*, RefPtr<Node>& result)
9038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_currentMapElement = new HTMLMapElement(mapTag, m_document);
9058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    result = m_currentMapElement;
9068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
9078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Node> HTMLParser::getNode(Token* t)
9108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Init our error handling table.
912635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(FunctionMap, gFunctionMap, ());
9138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (gFunctionMap.isEmpty()) {
9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(aTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
9158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(addressTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
916d0825bca7fe65beaee391d30da42e937db621564Steve Block        gFunctionMap.set(articleTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
917d0825bca7fe65beaee391d30da42e937db621564Steve Block        gFunctionMap.set(asideTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(bTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(bigTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(blockquoteTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(bodyTag.localName().impl(), &HTMLParser::bodyCreateErrorCheck);
9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(buttonTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(centerTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(commentAtom.impl(), &HTMLParser::commentCreateErrorCheck);
9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(ddTag.localName().impl(), &HTMLParser::ddCreateErrorCheck);
9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(dirTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(divTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(dlTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(dtTag.localName().impl(), &HTMLParser::dtCreateErrorCheck);
9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(formTag.localName().impl(), &HTMLParser::formCreateErrorCheck);
9318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(fieldsetTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
932d0825bca7fe65beaee391d30da42e937db621564Steve Block        gFunctionMap.set(footerTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(framesetTag.localName().impl(), &HTMLParser::framesetCreateErrorCheck);
9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(h1Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(h2Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(h3Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(h4Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(h5Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(h6Tag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(headTag.localName().impl(), &HTMLParser::headCreateErrorCheck);
941d0825bca7fe65beaee391d30da42e937db621564Steve Block        gFunctionMap.set(headerTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(hrTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(iTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(isindexTag.localName().impl(), &HTMLParser::isindexCreateErrorCheck);
9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(liTag.localName().impl(), &HTMLParser::nestedPCloserCreateErrorCheck);
9468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(listingTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(mapTag.localName().impl(), &HTMLParser::mapCreateErrorCheck);
9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(menuTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
949231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        gFunctionMap.set(navTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(nobrTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(noembedTag.localName().impl(), &HTMLParser::noembedCreateErrorCheck);
9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(noframesTag.localName().impl(), &HTMLParser::noframesCreateErrorCheck);
9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(noscriptTag.localName().impl(), &HTMLParser::noscriptCreateErrorCheck);
9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(olTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(pTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(plaintextTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(preTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        gFunctionMap.set(rpTag.localName().impl(), &HTMLParser::rpCreateErrorCheck);
9590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        gFunctionMap.set(rtTag.localName().impl(), &HTMLParser::rtCreateErrorCheck);
9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(sTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
961d0825bca7fe65beaee391d30da42e937db621564Steve Block        gFunctionMap.set(sectionTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(selectTag.localName().impl(), &HTMLParser::selectCreateErrorCheck);
9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(smallTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(strikeTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(tableTag.localName().impl(), &HTMLParser::pCloserStrictCreateErrorCheck);
9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(tbodyTag.localName().impl(), &HTMLParser::tableSectionCreateErrorCheck);
9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(tdTag.localName().impl(), &HTMLParser::tableCellCreateErrorCheck);
9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(textAtom.impl(), &HTMLParser::textCreateErrorCheck);
9698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(tfootTag.localName().impl(), &HTMLParser::tableSectionCreateErrorCheck);
9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(thTag.localName().impl(), &HTMLParser::tableCellCreateErrorCheck);
9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(theadTag.localName().impl(), &HTMLParser::tableSectionCreateErrorCheck);
9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(trTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(ttTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(uTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gFunctionMap.set(ulTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool proceed = true;
9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Node> result;
9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (CreateErrorCheckFunc errorCheckFunc = gFunctionMap.get(t->tagName.impl()))
9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        proceed = (this->*errorCheckFunc)(t, result);
9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (proceed)
9838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        result = HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, t->tagName, xhtmlNamespaceURI), m_document, m_currentFormElement.get());
9848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result.release();
9858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::allowNestedRedundantTag(const AtomicString& tagName)
9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // www.liceo.edu.mx is an example of a site that achieves a level of nesting of
9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // about 1500 tags, all from a bunch of <b>s.  We will only allow at most 20
9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // nested tags of the same type before just ignoring them all together.
9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned i = 0;
9938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    for (HTMLStackElem* curr = m_blockStack;
9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         i < cMaxRedundantTagDepth && curr && curr->tagName == tagName;
9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project         curr = curr->next, i++) { }
9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return i != cMaxRedundantTagDepth;
9978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::processCloseTag(Token* t)
10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Support for really broken html.
10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we never close the body tag, since some stupid web pages close it before the actual end of the doc.
10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // let's rely on the end() call to close things.
10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (t->tagName == htmlTag || t->tagName == bodyTag || t->tagName == commentAtom)
10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool checkForCloseTagErrors = true;
10088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (t->tagName == formTag && m_currentFormElement) {
10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_currentFormElement = 0;
10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        checkForCloseTagErrors = false;
10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (t->tagName == mapTag)
10128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_currentMapElement = 0;
10138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (t->tagName == pTag)
10148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        checkForCloseTagErrors = false;
10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HTMLStackElem* oldElem = m_blockStack;
10178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    popBlock(t->tagName, checkForCloseTagErrors);
10188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (oldElem == m_blockStack && t->tagName == pTag) {
10198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We encountered a stray </p>.  Amazingly Gecko, WinIE, and MacIE all treat
10208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // this as a valid break, i.e., <p></p>.  So go ahead and make the empty
10218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // paragraph.
10228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        t->beginTag = true;
10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        parseToken(t);
10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        popBlock(t->tagName);
10258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        reportError(StrayParagraphCloseError);
10268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1029d0825bca7fe65beaee391d30da42e937db621564Steve Blockbool HTMLParser::isHeadingTag(const AtomicString& tagName)
10308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1031d0825bca7fe65beaee391d30da42e937db621564Steve Block    DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, headingTags, ());
1032d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (headingTags.isEmpty()) {
1033d0825bca7fe65beaee391d30da42e937db621564Steve Block        headingTags.add(h1Tag.localName().impl());
1034d0825bca7fe65beaee391d30da42e937db621564Steve Block        headingTags.add(h2Tag.localName().impl());
1035d0825bca7fe65beaee391d30da42e937db621564Steve Block        headingTags.add(h3Tag.localName().impl());
1036d0825bca7fe65beaee391d30da42e937db621564Steve Block        headingTags.add(h4Tag.localName().impl());
1037d0825bca7fe65beaee391d30da42e937db621564Steve Block        headingTags.add(h5Tag.localName().impl());
1038d0825bca7fe65beaee391d30da42e937db621564Steve Block        headingTags.add(h6Tag.localName().impl());
10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1041d0825bca7fe65beaee391d30da42e937db621564Steve Block    return headingTags.contains(tagName.impl());
10428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::isInline(Node* node) const
10458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node->isTextNode())
10478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
10488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (node->isHTMLElement()) {
10508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLElement* e = static_cast<HTMLElement*>(node);
10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (e->hasLocalName(aTag) || e->hasLocalName(fontTag) || e->hasLocalName(ttTag) ||
10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e->hasLocalName(uTag) || e->hasLocalName(bTag) || e->hasLocalName(iTag) ||
10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e->hasLocalName(sTag) || e->hasLocalName(strikeTag) || e->hasLocalName(bigTag) ||
10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e->hasLocalName(smallTag) || e->hasLocalName(emTag) || e->hasLocalName(strongTag) ||
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e->hasLocalName(dfnTag) || e->hasLocalName(codeTag) || e->hasLocalName(sampTag) ||
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e->hasLocalName(kbdTag) || e->hasLocalName(varTag) || e->hasLocalName(citeTag) ||
10578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e->hasLocalName(abbrTag) || e->hasLocalName(acronymTag) || e->hasLocalName(subTag) ||
10588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e->hasLocalName(supTag) || e->hasLocalName(spanTag) || e->hasLocalName(nobrTag) ||
10598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e->hasLocalName(noframesTag) || e->hasLocalName(nolayerTag) ||
10608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            e->hasLocalName(noembedTag))
10618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
10625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if !ENABLE(XHTMLMP)
10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (e->hasLocalName(noscriptTag) && !m_isParsingFragment) {
10648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            Settings* settings = m_document->settings();
10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (settings && settings->isJavaScriptEnabled())
10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
10685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
10698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::isResidualStyleTag(const AtomicString& tagName)
10758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1076635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, residualStyleTags, ());
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (residualStyleTags.isEmpty()) {
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(aTag.localName().impl());
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(fontTag.localName().impl());
10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(ttTag.localName().impl());
10818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(uTag.localName().impl());
10828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(bTag.localName().impl());
10838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(iTag.localName().impl());
10848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(sTag.localName().impl());
10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(strikeTag.localName().impl());
10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(bigTag.localName().impl());
10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(smallTag.localName().impl());
10888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(emTag.localName().impl());
10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(strongTag.localName().impl());
10908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(dfnTag.localName().impl());
10918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(codeTag.localName().impl());
10928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(sampTag.localName().impl());
10938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(kbdTag.localName().impl());
10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(varTag.localName().impl());
10958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        residualStyleTags.add(nobrTag.localName().impl());
10968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return residualStyleTags.contains(tagName.impl());
10998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLParser::isAffectedByResidualStyle(const AtomicString& tagName)
11028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, unaffectedTags, ());
11048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (unaffectedTags.isEmpty()) {
11058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(bodyTag.localName().impl());
11068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(tableTag.localName().impl());
11078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(theadTag.localName().impl());
11088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(tbodyTag.localName().impl());
11098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(tfootTag.localName().impl());
11108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(trTag.localName().impl());
11118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(thTag.localName().impl());
11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(tdTag.localName().impl());
11138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(captionTag.localName().impl());
11148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(colgroupTag.localName().impl());
11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(colTag.localName().impl());
11168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(optionTag.localName().impl());
11178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(optgroupTag.localName().impl());
11188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(selectTag.localName().impl());
11198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        unaffectedTags.add(objectTag.localName().impl());
11200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        unaffectedTags.add(datagridTag.localName().impl());
1121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        unaffectedTags.add(datalistTag.localName().impl());
11228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
11238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return !unaffectedTags.contains(tagName.impl());
11258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLStackElem* maxElem = 0;
11308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool finished = false;
11318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool strayTableContent = elem->strayTableContent;
11328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1133d0825bca7fe65beaee391d30da42e937db621564Steve Block    unsigned iterationCount = 0;
1134d0825bca7fe65beaee391d30da42e937db621564Steve Block
11358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_handlingResidualStyleAcrossBlocks = true;
1136d0825bca7fe65beaee391d30da42e937db621564Steve Block    while (!finished && (iterationCount++ < cResidualStyleIterationLimit)) {
11378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Find the outermost element that crosses over to a higher level. If there exists another higher-level
11388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // element, we will do another pass, until we have corrected the innermost one.
11398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ExceptionCode ec = 0;
11408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        HTMLStackElem* curr = m_blockStack;
11418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLStackElem* prev = 0;
11428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLStackElem* prevMaxElem = 0;
11438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        maxElem = 0;
11448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        finished = true;
11458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (curr && curr != elem) {
11468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (curr->level > elem->level) {
11478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!isAffectedByResidualStyle(curr->tagName))
11488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    return;
11498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (maxElem)
11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // We will need another pass.
11518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    finished = false;
11528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                maxElem = curr;
11538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                prevMaxElem = prev;
11548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
11558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            prev = curr;
11578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            curr = curr->next;
11588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
11598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!curr || !maxElem)
11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* residualElem = prev->node;
11648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        Node* blockElem = prevMaxElem ? prevMaxElem->node : m_current;
11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* parentElem = elem->node;
11668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check to see if the reparenting that is going to occur is allowed according to the DOM.
11688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: We should either always allow it or perform an additional fixup instead of
11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // just bailing here.
11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Example: <p><font><center>blah</font></center></p> isn't doing a fixup right now.
11718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!parentElem->childAllowed(blockElem))
11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_hasPElementInScope = Unknown;
11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (maxElem->node->parentNode() != elem->node) {
11778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Walk the stack and remove any elements that aren't residual style tags.  These
11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // are basically just being closed up.  Example:
11798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // <font><span>Moo<p>Goo</font></p>.
11808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // In the above example, the <span> doesn't need to be reopened.  It can just close.
11818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            HTMLStackElem* currElem = maxElem->next;
11828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            HTMLStackElem* prevElem = maxElem;
11838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (currElem != elem) {
11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                HTMLStackElem* nextElem = currElem->next;
11858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!isResidualStyleTag(currElem->tagName)) {
11868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    prevElem->next = nextElem;
11878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    prevElem->derefNode();
11888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    prevElem->node = currElem->node;
11898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    prevElem->didRefNode = currElem->didRefNode;
11908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    delete currElem;
11918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
11928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
11938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    prevElem = currElem;
11948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currElem = nextElem;
11958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
11968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We have to reopen residual tags in between maxElem and elem.  An example of this case is:
11988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // <font><i>Moo<p>Foo</font>.
11998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // In this case, we need to transform the part before the <p> into:
12008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // <font><i>Moo</i></font><i>
12018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // so that the <i> will remain open.  This involves the modification of elements
12028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // in the block stack.
12038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // This will also affect how we ultimately reparent the block, since we want it to end up
12048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // under the reopened residual tags (e.g., the <i> in the above example.)
12058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RefPtr<Node> prevNode = 0;
12068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currElem = maxElem;
12078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (currElem->node != residualElem) {
12088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (isResidualStyleTag(currElem->node->localName())) {
12098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Create a clone of this element.
12108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // We call releaseRef to get a raw pointer since we plan to hand over ownership to currElem.
12118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    Node* currNode = currElem->node->cloneNode(false).releaseRef();
12128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    reportError(ResidualStyleError, &currNode->localName());
12138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Change the stack element's node to point to the clone.
12158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // The stack element adopts the reference we obtained above by calling release().
12168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    currElem->derefNode();
12178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    currElem->node = currNode;
12188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    currElem->didRefNode = true;
12198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Attach the previous node as a child of this new node.
12218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (prevNode)
12228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        currNode->appendChild(prevNode, ec);
12238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    else // The new parent for the block element is going to be the innermost clone.
12248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        parentElem = currNode;  // FIXME: We shifted parentElem to be a residual inline.  We never checked to see if blockElem could be legally placed inside the inline though.
12258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    prevNode = currNode;
12278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
12288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currElem = currElem->next;
12308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
12318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Now append the chain of new residual style elements if one exists.
12338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (prevNode)
12348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                elem->node->appendChild(prevNode, ec);  // FIXME: This append can result in weird stuff happening, like an inline chain being put into a table section.
12358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
12368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Check if the block is still in the tree. If it isn't, then we don't
12388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // want to remove it from its parent (that would crash) or insert it into
12398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // a new parent later. See http://bugs.webkit.org/show_bug.cgi?id=6778
12408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool isBlockStillInTree = blockElem->parentNode();
12418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We need to make a clone of |residualElem| and place it just inside |blockElem|.
12438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // All content of |blockElem| is reparented to be under this clone.  We then
12448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // reparent |blockElem| using real DOM calls so that attachment/detachment will
12458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // be performed to fix up the rendering tree.
12468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // So for this example: <b>...<p>Foo</b>Goo</p>
12478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // The end result will be: <b>...</b><p><b>Foo</b>Goo</p>
12488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        //
12498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Step 1: Remove |blockElem| from its parent, doing a batch detach of all the kids.
12508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isBlockStillInTree)
12518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            blockElem->parentNode()->removeChild(blockElem, ec);
12528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Node* newNodePtr = 0;
12548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (blockElem->firstChild()) {
12558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Step 2: Clone |residualElem|.
12568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RefPtr<Node> newNode = residualElem->cloneNode(false); // Shallow clone. We don't pick up the same kids.
12578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            newNodePtr = newNode.get();
12588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            reportError(ResidualStyleError, &newNode->localName());
12598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Step 3: Place |blockElem|'s children under |newNode|.  Remove all of the children of |blockElem|
12618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // before we've put |newElem| into the document.  That way we'll only do one attachment of all
12628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the new content (instead of a bunch of individual attachments).
12638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Node* currNode = blockElem->firstChild();
12648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (currNode) {
12658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                Node* nextNode = currNode->nextSibling();
12668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                newNode->appendChild(currNode, ec);
12678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                currNode = nextNode;
12688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
12698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Step 4: Place |newNode| under |blockElem|.  |blockElem| is still out of the document, so no
12718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // attachment can occur yet.
12728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            blockElem->appendChild(newNode.release(), ec);
12738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
12748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            finished = true;
12758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Step 5: Reparent |blockElem|.  Now the full attachment of the fixed up tree takes place.
12778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isBlockStillInTree)
12788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            parentElem->appendChild(blockElem, ec);
12798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Step 6: Pull |elem| out of the stack, since it is no longer enclosing us.  Also update
12818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the node associated with the previous stack element so that when it gets popped,
12828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // it doesn't make the residual element the next current node.
12838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLStackElem* currElem = maxElem;
12848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLStackElem* prevElem = 0;
12858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (currElem != elem) {
12868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            prevElem = currElem;
12878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            currElem = currElem->next;
12888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
12898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        prevElem->next = elem->next;
12908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        prevElem->derefNode();
12918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        prevElem->node = elem->node;
12928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        prevElem->didRefNode = elem->didRefNode;
12938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!finished) {
12948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Repurpose |elem| to represent |newNode| and insert it at the appropriate position
12958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // in the stack. We do not do this for the innermost block, because in that case the new
12968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // node is effectively no longer open.
12978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            elem->next = maxElem;
12988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            elem->node = prevMaxElem->node;
12998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            elem->didRefNode = prevMaxElem->didRefNode;
13008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            elem->strayTableContent = false;
13018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            prevMaxElem->next = elem;
13028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(newNodePtr);
13038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            prevMaxElem->node = newNodePtr;
1304d0825bca7fe65beaee391d30da42e937db621564Steve Block            newNodePtr->ref();
1305d0825bca7fe65beaee391d30da42e937db621564Steve Block            prevMaxElem->didRefNode = true;
13068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
13078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            delete elem;
13088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // FIXME: If we ever make a case like this work:
13118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // <table><b><i><form></b></form></i></table>
13128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Then this check will be too simplistic.  Right now the <i><form> chain will end up inside the <tbody>, which is pretty crazy.
13138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (strayTableContent)
13148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_inStrayTableContent--;
13158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Step 7: Reopen intermediate inlines, e.g., <b><p><i>Foo</b>Goo</p>.
13178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // In the above example, Goo should stay italic.
13188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We cap the number of tags we're willing to reopen based off cResidualStyleMaxDepth.
13198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HTMLStackElem* curr = m_blockStack;
13218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLStackElem* residualStyleStack = 0;
13228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned stackDepth = 1;
13238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned redundantStyleCount = 0;
13248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (curr && curr != maxElem) {
13258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We will actually schedule this tag for reopening
13268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // after we complete the close of this entire block.
13278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isResidualStyleTag(curr->tagName) && stackDepth++ < cResidualStyleMaxDepth) {
13288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We've overloaded the use of stack elements and are just reusing the
13298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // struct with a slightly different meaning to the variables.  Instead of chaining
13308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // from innermost to outermost, we build up a list of all the tags we need to reopen
13318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // from the outermost to the innermost, i.e., residualStyleStack will end up pointing
13328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // to the outermost tag we need to reopen.
13338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We also set curr->node to be the actual element that corresponds to the ID stored in
13348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // curr->id rather than the node that you should pop to when the element gets pulled off
13358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // the stack.
13368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (residualStyleStack && curr->tagName == residualStyleStack->tagName && curr->node->attributes()->mapsEquivalent(residualStyleStack->node->attributes()))
13378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                redundantStyleCount++;
13388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
13398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                redundantStyleCount = 0;
13408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (redundantStyleCount < cMaxRedundantTagDepth)
13428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                moveOneBlockToStack(residualStyleStack);
13438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            else
13448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                popOneBlock();
13458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
13468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            popOneBlock();
13478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        curr = m_blockStack;
13498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    reopenResidualStyleTags(residualStyleStack, 0); // Stray table content can't be an issue here, since some element above will always become the root of new stray table content.
13528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_handlingResidualStyleAcrossBlocks = false;
13548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::reopenResidualStyleTags(HTMLStackElem* elem, Node* malformedTableParent)
13578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Loop for each tag that needs to be reopened.
13598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (elem) {
13608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Create a shallow clone of the DOM node for this element.
13618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<Node> newNode = elem->node->cloneNode(false);
13628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        reportError(ResidualStyleError, &newNode->localName());
13638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Append the new node. In the malformed table case, we need to insert before the table,
13658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // which will be the last child.
13668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ExceptionCode ec = 0;
13678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (malformedTableParent)
13688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            malformedTableParent->insertBefore(newNode, malformedTableParent->lastChild(), ec);
13698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
13708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            m_current->appendChild(newNode, ec);
13718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: Is it really OK to ignore the exceptions here?
13728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Now push a new stack element for this node we just created.
13748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        pushBlock(elem->tagName, elem->level);
13758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        newNode->beginParsingChildren();
13768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Set our strayTableContent boolean if needed, so that the reopened tag also knows
13788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // that it is inside a malformed table.
13798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_blockStack->strayTableContent = malformedTableParent != 0;
13808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (m_blockStack->strayTableContent)
13818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            m_inStrayTableContent++;
13828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Clear our malformed table parent variable.
13848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        malformedTableParent = 0;
13858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Update |current| manually to point to the new node.
13878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setCurrent(newNode.get());
13888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Advance to the next tag that needs to be reopened.
13908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLStackElem* next = elem->next;
13918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        elem->derefNode();
13928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        delete elem;
13938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        elem = next;
13948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
13958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
13968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::pushBlock(const AtomicString& tagName, int level)
13988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_blockStack = new HTMLStackElem(tagName, level, m_current, m_didRefCurrent, m_blockStack);
14008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (level >= minBlockLevelTagPriority)
14018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_blocksInStack++;
14028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_didRefCurrent = false;
14038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (tagName == pTag)
14048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_hasPElementInScope = InScope;
14058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (isScopingTag(tagName))
14068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_hasPElementInScope = NotInScope;
14078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::popBlock(const AtomicString& tagName, bool reportErrors)
14108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HTMLStackElem* elem = m_blockStack;
14125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
14135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_parserQuirks && elem && !m_parserQuirks->shouldPopBlock(elem->tagName, tagName))
14145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return;
14155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
14168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int maxLevel = 0;
14178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (elem && (elem->tagName != tagName)) {
14198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (maxLevel < elem->level)
14208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            maxLevel = elem->level;
14218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        elem = elem->next;
14228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!elem) {
14258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (reportErrors)
14268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            reportError(StrayCloseTagError, &tagName, 0, true);
14278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
14288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (maxLevel > elem->level) {
14318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // We didn't match because the tag is in a different scope, e.g.,
14328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // <b><p>Foo</b>.  Try to correct the problem.
14338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!isResidualStyleTag(tagName))
14348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
14358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return handleResidualStyleCloseTagAcrossBlocks(elem);
14368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isAffectedByStyle = isAffectedByResidualStyle(elem->tagName);
14398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLStackElem* residualStyleStack = 0;
14408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* malformedTableParent = 0;
14418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    elem = m_blockStack;
14438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned stackDepth = 1;
14448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned redundantStyleCount = 0;
14458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (elem) {
14468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (elem->tagName == tagName) {
14478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            int strayTable = m_inStrayTableContent;
14488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            popOneBlock();
14498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            elem = 0;
14508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // This element was the root of some malformed content just inside an implicit or
14528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // explicit <tbody> or <tr>.
14538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If we end up needing to reopen residual style tags, the root of the reopened chain
14548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // must also know that it is the root of malformed content inside a <tbody>/<tr>.
14558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (strayTable && (m_inStrayTableContent < strayTable) && residualStyleStack) {
14568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                Node* curr = m_current;
14578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                while (curr && !curr->hasTagName(tableTag))
14588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    curr = curr->parentNode();
14598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                malformedTableParent = curr ? curr->parentNode() : 0;
14608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
14618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
14628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
14638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (m_currentFormElement && elem->tagName == formTag)
14648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // A <form> is being closed prematurely (and this is
14658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // malformed HTML).  Set an attribute on the form to clear out its
14668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // bottom margin.
14678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                m_currentFormElement->setMalformed(true);
14688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Schedule this tag for reopening
14708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // after we complete the close of this entire block.
14718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (isAffectedByStyle && isResidualStyleTag(elem->tagName) && stackDepth++ < cResidualStyleMaxDepth) {
14728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // We've overloaded the use of stack elements and are just reusing the
14738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // struct with a slightly different meaning to the variables.  Instead of chaining
14748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // from innermost to outermost, we build up a list of all the tags we need to reopen
14758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // from the outermost to the innermost, i.e., residualStyleStack will end up pointing
14768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // to the outermost tag we need to reopen.
14778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // We also set elem->node to be the actual element that corresponds to the ID stored in
14788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // elem->id rather than the node that you should pop to when the element gets pulled off
14798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // the stack.
14808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (residualStyleStack && elem->tagName == residualStyleStack->tagName && elem->node->attributes()->mapsEquivalent(residualStyleStack->node->attributes()))
14818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    redundantStyleCount++;
14828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
14838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    redundantStyleCount = 0;
14848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (redundantStyleCount < cMaxRedundantTagDepth)
14868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    moveOneBlockToStack(residualStyleStack);
14878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                else
14888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    popOneBlock();
14898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else
14908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                popOneBlock();
14918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            elem = m_blockStack;
14928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
14938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
14948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    reopenResidualStyleTags(residualStyleStack, malformedTableParent);
14968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
14978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline HTMLStackElem* HTMLParser::popOneBlockCommon()
14998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HTMLStackElem* elem = m_blockStack;
15018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Form elements restore their state during the parsing process.
15038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Also, a few elements (<applet>, <object>) need to know when all child elements (<param>s) are available.
15048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_current && elem->node != m_current)
15058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_current->finishParsingChildren();
15068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_blockStack->level >= minBlockLevelTagPriority) {
15088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        ASSERT(m_blocksInStack > 0);
15098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_blocksInStack--;
15108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
15118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_blockStack = elem->next;
15128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_current = elem->node;
15138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_didRefCurrent = elem->didRefNode;
15148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (elem->strayTableContent)
15168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_inStrayTableContent--;
15178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (elem->tagName == pTag)
15198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_hasPElementInScope = NotInScope;
15208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (isScopingTag(elem->tagName))
15218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_hasPElementInScope = Unknown;
15228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return elem;
15248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::popOneBlock()
15278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Store the current node before popOneBlockCommon overwrites it.
15298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node* lastCurrent = m_current;
15308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool didRefLastCurrent = m_didRefCurrent;
15318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete popOneBlockCommon();
15338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (didRefLastCurrent)
15358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        lastCurrent->deref();
15368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::moveOneBlockToStack(HTMLStackElem*& head)
15398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We'll be using the stack element we're popping, but for the current node.
15418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // See the two callers for details.
15428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Store the current node before popOneBlockCommon overwrites it.
15448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Node* lastCurrent = m_current;
15458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool didRefLastCurrent = m_didRefCurrent;
15468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Pop the block, but don't deref the current node as popOneBlock does because
15488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // we'll be using the pointer in the new stack element.
15498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLStackElem* elem = popOneBlockCommon();
15508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Transfer the current node into the stack element.
15528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // No need to deref the old elem->node because popOneBlockCommon transferred
15538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // it into the m_current/m_didRefCurrent fields.
15548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    elem->node = lastCurrent;
15558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    elem->didRefNode = didRefLastCurrent;
15568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    elem->next = head;
15578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    head = elem;
15588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::checkIfHasPElementInScope()
15618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_hasPElementInScope = NotInScope;
15638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HTMLStackElem* elem = m_blockStack;
15648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (elem) {
15658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const AtomicString& tagName = elem->tagName;
15668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (tagName == pTag) {
15678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_hasPElementInScope = InScope;
15688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
15698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (isScopingTag(tagName))
15708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
15718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        elem = elem->next;
15728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
15738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::popInlineBlocks()
15768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (m_blockStack && isInline(m_current))
15788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        popOneBlock();
15798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::freeBlock()
15828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    while (m_blockStack)
15848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        popOneBlock();
15858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ASSERT(!m_blocksInStack);
15868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
15878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::createHead()
15898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (m_head)
15918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
15928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!m_document->documentElement()) {
15945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        insertNode(new HTMLHtmlElement(htmlTag, m_document));
15955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ASSERT(m_document->documentElement());
15965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
15975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
15988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_head = new HTMLHeadElement(headTag, m_document);
15998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HTMLElement* body = m_document->body();
16008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
16015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_document->documentElement()->insertBefore(m_head.get(), body, ec);
16028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ec)
16038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_head = 0;
16048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the body does not exist yet, then the <head> should be pushed as the current block.
16068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_head && !body) {
16078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        pushBlock(m_head->localName(), m_head->tagPriority());
16085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        setCurrent(m_head.get());
16098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<Node> HTMLParser::handleIsindex(Token* t)
16138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RefPtr<Node> n = new HTMLDivElement(divTag, m_document);
16158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NamedMappedAttrMap* attrs = t->attrs.get();
16178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RefPtr<HTMLIsIndexElement> isIndex = new HTMLIsIndexElement(isindexTag, m_document, m_currentFormElement.get());
16198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    isIndex->setAttributeMap(attrs);
16208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    isIndex->setAttribute(typeAttr, "khtml_isindex");
16218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String text = searchableIndexIntroduction();
16238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (attrs) {
16248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (Attribute* a = attrs->getAttributeItem(promptAttr))
16258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            text = a->value().string() + " ";
16268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        t->attrs = 0;
16278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    n->addChild(new HTMLHRElement(hrTag, m_document));
1630231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    n->addChild(Text::create(m_document, text));
16318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    n->addChild(isIndex.release());
16328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    n->addChild(new HTMLHRElement(hrTag, m_document));
16338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return n.release();
16358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::startBody()
16388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_inBody)
16408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
16418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    m_inBody = true;
16438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_isindexElement) {
16458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        insertNode(m_isindexElement.get(), true /* don't descend into this node */);
16468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_isindexElement = 0;
16478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::finished()
16518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // In the case of a completely empty document, here's the place to create the HTML element.
16538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (m_current && m_current->isDocumentNode() && !m_document->documentElement())
16548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        insertNode(new HTMLHtmlElement(htmlTag, m_document));
16558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This ensures that "current" is not left pointing to a node when the document is destroyed.
16578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    freeBlock();
16588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setCurrent(0);
16598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Warning, this may delete the tokenizer and parser, so don't try to do anything else after this.
16618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_isParsingFragment)
16628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        m_document->finishedParsing();
16638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
16648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLParser::reportErrorToConsole(HTMLParserErrorCode errorCode, const AtomicString* tagName1, const AtomicString* tagName2, bool closeTags)
16668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Frame* frame = m_document->frame();
16688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frame)
16698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
16708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HTMLTokenizer* htmlTokenizer = static_cast<HTMLTokenizer*>(m_document->tokenizer());
16728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int lineNumber = htmlTokenizer->lineNumber() + 1;
16738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    AtomicString tag1;
16758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    AtomicString tag2;
16768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (tagName1) {
16778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (*tagName1 == "#text")
16788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tag1 = "Text";
16798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (*tagName1 == "#comment")
16808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tag1 = "<!-- comment -->";
16818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
16828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tag1 = (closeTags ? "</" : "<") + *tagName1 + ">";
16838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (tagName2) {
16858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (*tagName2 == "#text")
16868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tag2 = "Text";
16878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (*tagName2 == "#comment")
16888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tag2 = "<!-- comment -->";
16898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
16908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            tag2 = (closeTags ? "</" : "<") + *tagName2 + ">";
16918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
16928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const char* errorMsg = htmlParserErrorMessageTemplate(errorCode);
16948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!errorMsg)
16958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
16968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String message;
16988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (htmlTokenizer->processingContentWrittenByScript())
16998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        message += htmlParserDocumentWriteMessage();
17008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    message += errorMsg;
17018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    message.replace("%tag1", tag1);
17028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    message.replace("%tag2", tag2);
17038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType,
17058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        isWarning(errorCode) ? WarningMessageLevel : ErrorMessageLevel,
17068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        message, lineNumber, m_document->url().string());
17078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
17088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
17095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#ifdef BUILDING_ON_LEOPARD
17105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool shouldCreateImplicitHead(Document* document)
17115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
17125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(document);
17135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
17145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Settings* settings = document->page() ? document->page()->settings() : 0;
17155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return settings ? !settings->needsLeopardMailQuirks() : true;
17165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
17175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#elif defined(BUILDING_ON_TIGER)
17185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianbool shouldCreateImplicitHead(Document* document)
17195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
17205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(document);
17215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
17225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Settings* settings = document->page() ? document->page()->settings() : 0;
17235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return settings ? !settings->needsTigerMailQuirks() : true;
17245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
17255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif
17265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
17278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1728