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