initial import
[vuplus_webkit] / Source / WebCore / html / parser / HTMLTreeBuilder.h
1 /*
2  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3  * Copyright (C) 2011 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #ifndef HTMLTreeBuilder_h
28 #define HTMLTreeBuilder_h
29
30 #include "Element.h"
31 #include "FragmentScriptingPermission.h"
32 #include "HTMLConstructionSite.h"
33 #include "HTMLElementStack.h"
34 #include "HTMLFormattingElementList.h"
35 #include "HTMLTokenizer.h"
36 #include <wtf/Noncopyable.h>
37 #include <wtf/OwnPtr.h>
38 #include <wtf/PassOwnPtr.h>
39 #include <wtf/PassRefPtr.h>
40 #include <wtf/RefPtr.h>
41 #include <wtf/text/StringBuilder.h>
42 #include <wtf/text/TextPosition.h>
43 #include <wtf/unicode/Unicode.h>
44
45 namespace WebCore {
46
47 class AtomicHTMLToken;
48 class Document;
49 class DocumentFragment;
50 class Frame;
51 class HTMLToken;
52 class HTMLDocument;
53 class Node;
54 class HTMLDocumentParser;
55
56 class HTMLTreeBuilder {
57     WTF_MAKE_NONCOPYABLE(HTMLTreeBuilder); WTF_MAKE_FAST_ALLOCATED;
58 public:
59     static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth)
60     {
61         return adoptPtr(new HTMLTreeBuilder(parser, document, reportErrors, usePreHTML5ParserQuirks, maximumDOMTreeDepth));
62     }
63     static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth)
64     {
65         return adoptPtr(new HTMLTreeBuilder(parser, fragment, contextElement, scriptingPermission, usePreHTML5ParserQuirks, maximumDOMTreeDepth));
66     }
67     ~HTMLTreeBuilder();
68
69     bool isParsingFragment() const { return !!m_fragmentContext.fragment(); }
70
71     void detach();
72
73     void setPaused(bool paused) { m_isPaused = paused; }
74     bool isPaused() const { return m_isPaused; }
75
76     // The token really should be passed as a const& since it's never modified.
77     void constructTreeFromToken(HTMLToken&);
78     void constructTreeFromAtomicToken(AtomicHTMLToken&);
79
80     // Must be called when parser is paused before calling the parser again.
81     PassRefPtr<Element> takeScriptToProcess(TextPosition1& scriptStartPosition);
82
83     // Done, close any open tags, etc.
84     void finished();
85
86     static bool scriptEnabled(Frame*);
87     static bool pluginsEnabled(Frame*);
88
89 private:
90     class FakeInsertionMode;
91     class ExternalCharacterTokenBuffer;
92     // Represents HTML5 "insertion mode"
93     // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode
94     enum InsertionMode {
95         InitialMode,
96         BeforeHTMLMode,
97         BeforeHeadMode,
98         InHeadMode,
99         InHeadNoscriptMode,
100         AfterHeadMode,
101         InBodyMode,
102         TextMode,
103         InTableMode,
104         InTableTextMode,
105         InCaptionMode,
106         InColumnGroupMode,
107         InTableBodyMode,
108         InRowMode,
109         InCellMode,
110         InSelectMode,
111         InSelectInTableMode,
112         InForeignContentMode,
113         AfterBodyMode,
114         InFramesetMode,
115         AfterFramesetMode,
116         AfterAfterBodyMode,
117         AfterAfterFramesetMode,
118     };
119
120     HTMLTreeBuilder(HTMLDocumentParser*, HTMLDocument*, bool reportErrors, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth);
121     HTMLTreeBuilder(HTMLDocumentParser*, DocumentFragment*, Element* contextElement, FragmentScriptingPermission, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth);
122
123     void processToken(AtomicHTMLToken&);
124
125     void processDoctypeToken(AtomicHTMLToken&);
126     void processStartTag(AtomicHTMLToken&);
127     void processEndTag(AtomicHTMLToken&);
128     void processComment(AtomicHTMLToken&);
129     void processCharacter(AtomicHTMLToken&);
130     void processEndOfFile(AtomicHTMLToken&);
131
132     bool processStartTagForInHead(AtomicHTMLToken&);
133     void processStartTagForInBody(AtomicHTMLToken&);
134     void processStartTagForInTable(AtomicHTMLToken&);
135     void processEndTagForInBody(AtomicHTMLToken&);
136     void processEndTagForInTable(AtomicHTMLToken&);
137     void processEndTagForInTableBody(AtomicHTMLToken&);
138     void processEndTagForInRow(AtomicHTMLToken&);
139     void processEndTagForInCell(AtomicHTMLToken&);
140
141     void processIsindexStartTagForInBody(AtomicHTMLToken&);
142     bool processBodyEndTagForInBody(AtomicHTMLToken&);
143     bool processTableEndTagForInTable();
144     bool processCaptionEndTagForInCaption();
145     bool processColgroupEndTagForInColumnGroup();
146     bool processTrEndTagForInRow();
147     // FIXME: This function should be inlined into its one call site or it
148     // needs to assert which tokens it can be called with.
149     void processAnyOtherEndTagForInBody(AtomicHTMLToken&);
150
151     void processCharacterBuffer(ExternalCharacterTokenBuffer&);
152
153     void processFakeStartTag(const QualifiedName&, PassRefPtr<NamedNodeMap> attributes = 0);
154     void processFakeEndTag(const QualifiedName&);
155     void processFakeCharacters(const String&);
156     void processFakePEndTagIfPInButtonScope();
157
158     void processGenericRCDATAStartTag(AtomicHTMLToken&);
159     void processGenericRawTextStartTag(AtomicHTMLToken&);
160     void processScriptStartTag(AtomicHTMLToken&);
161
162     // Default processing for the different insertion modes.
163     void defaultForInitial();
164     void defaultForBeforeHTML();
165     void defaultForBeforeHead();
166     void defaultForInHead();
167     void defaultForInHeadNoscript();
168     void defaultForAfterHead();
169     void defaultForInTableText();
170
171     void prepareToReprocessToken();
172
173     void reprocessStartTag(AtomicHTMLToken&);
174     void reprocessEndTag(AtomicHTMLToken&);
175
176     PassRefPtr<NamedNodeMap> attributesForIsindexInput(AtomicHTMLToken&);
177
178     HTMLElementStack::ElementRecord* furthestBlockForFormattingElement(Element*);
179     void callTheAdoptionAgency(AtomicHTMLToken&);
180
181     void closeTheCell();
182
183     template <bool shouldClose(const ContainerNode*)>
184     void processCloseWhenNestedTag(AtomicHTMLToken&);
185
186     bool m_framesetOk;
187
188     void parseError(AtomicHTMLToken&);
189
190     InsertionMode insertionMode() const { return m_insertionMode; }
191     void setInsertionMode(InsertionMode mode)
192     {
193         m_insertionMode = mode;
194         m_isFakeInsertionMode = false;
195     }
196
197     bool isFakeInsertionMode() { return m_isFakeInsertionMode; }
198     void setFakeInsertionMode(InsertionMode mode)
199     {
200         m_insertionMode = mode;
201         m_isFakeInsertionMode = true;
202     }
203
204     void resetInsertionModeAppropriately();
205
206     void processForeignContentUsingInBodyModeAndResetMode(AtomicHTMLToken& token);
207     void resetForeignInsertionMode();
208
209     class FragmentParsingContext {
210         WTF_MAKE_NONCOPYABLE(FragmentParsingContext);
211     public:
212         FragmentParsingContext();
213         FragmentParsingContext(DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
214         ~FragmentParsingContext();
215
216         DocumentFragment* fragment() const { return m_fragment; }
217         Element* contextElement() const { ASSERT(m_fragment); return m_contextElement; }
218         FragmentScriptingPermission scriptingPermission() const { ASSERT(m_fragment); return m_scriptingPermission; }
219
220     private:
221         DocumentFragment* m_fragment;
222         Element* m_contextElement;
223
224         // FragmentScriptingNotAllowed causes the Parser to remove children
225         // from <script> tags (so javascript doesn't show up in pastes).
226         FragmentScriptingPermission m_scriptingPermission;
227     };
228
229     FragmentParsingContext m_fragmentContext;
230
231     Document* m_document;
232     HTMLConstructionSite m_tree;
233
234     bool m_reportErrors;
235     bool m_isPaused;
236     bool m_isFakeInsertionMode;
237
238     // FIXME: InsertionModes should be a separate object to prevent direct
239     // manipulation of these variables.  For now, be careful to always use
240     // setInsertionMode and never set m_insertionMode directly.
241     InsertionMode m_insertionMode;
242     InsertionMode m_originalInsertionMode;
243
244     // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#pending-table-character-tokens
245     StringBuilder m_pendingTableCharacters;
246
247     // We access parser because HTML5 spec requires that we be able to change the state of the tokenizer
248     // from within parser actions. We also need it to track the current position.
249     HTMLDocumentParser* m_parser;
250
251     RefPtr<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
252     TextPosition1 m_scriptToProcessStartPosition; // Starting line number of the script tag needing processing.
253
254     // FIXME: We probably want to remove this member.  Originally, it was
255     // created to service the legacy tree builder, but it seems to be used for
256     // some other things now.
257     TextPosition0 m_lastScriptElementStartPosition;
258
259     bool m_usePreHTML5ParserQuirks;
260
261     bool m_hasPendingForeignInsertionModeSteps;
262 };
263
264 }
265
266 #endif