2011-01-29 Sheriff Bot <webkit.review.bot@gmail.com>
[WebKit-https.git] / Source / 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/text/TextPosition.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/unicode/Unicode.h>
42
43 namespace WebCore {
44
45 class AtomicHTMLToken;
46 class Document;
47 class DocumentFragment;
48 class Frame;
49 class HTMLToken;
50 class HTMLDocument;
51 class Node;
52 class HTMLDocumentParser;
53
54 class HTMLTreeBuilder {
55     WTF_MAKE_NONCOPYABLE(HTMLTreeBuilder); WTF_MAKE_FAST_ALLOCATED;
56 public:
57     static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, bool usePreHTML5ParserQuirks)
58     {
59         return adoptPtr(new HTMLTreeBuilder(parser, document, reportErrors, usePreHTML5ParserQuirks));
60     }
61     static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, bool usePreHTML5ParserQuirks)
62     {
63         return adoptPtr(new HTMLTreeBuilder(parser, fragment, contextElement, scriptingPermission, usePreHTML5ParserQuirks));
64     }
65     ~HTMLTreeBuilder();
66
67     bool isParsingFragment() const { return !!m_fragmentContext.fragment(); }
68
69     void detach();
70
71     void setPaused(bool paused) { m_isPaused = paused; }
72     bool isPaused() const { return m_isPaused; }
73
74     // The token really should be passed as a const& since it's never modified.
75     void constructTreeFromToken(HTMLToken&);
76     void constructTreeFromAtomicToken(AtomicHTMLToken&);
77
78     // Must be called when parser is paused before calling the parser again.
79     PassRefPtr<Element> takeScriptToProcess(TextPosition1& scriptStartPosition);
80
81     // Done, close any open tags, etc.
82     void finished();
83
84     static bool scriptEnabled(Frame*);
85     static bool pluginsEnabled(Frame*);
86
87 private:
88     class FakeInsertionMode;
89     class ExternalCharacterTokenBuffer;
90     // Represents HTML5 "insertion mode"
91     // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode
92     enum InsertionMode {
93         InitialMode,
94         BeforeHTMLMode,
95         BeforeHeadMode,
96         InHeadMode,
97         InHeadNoscriptMode,
98         AfterHeadMode,
99         InBodyMode,
100         TextMode,
101         InTableMode,
102         InTableTextMode,
103         InCaptionMode,
104         InColumnGroupMode,
105         InTableBodyMode,
106         InRowMode,
107         InCellMode,
108         InSelectMode,
109         InSelectInTableMode,
110         InForeignContentMode,
111         AfterBodyMode,
112         InFramesetMode,
113         AfterFramesetMode,
114         AfterAfterBodyMode,
115         AfterAfterFramesetMode,
116     };
117
118     HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument*, bool reportErrors, bool usePreHTML5ParserQuirks);
119     HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment*, Element* contextElement, FragmentScriptingPermission, bool usePreHTML5ParserQuirks);
120
121     void processToken(AtomicHTMLToken&);
122
123     void processDoctypeToken(AtomicHTMLToken&);
124     void processStartTag(AtomicHTMLToken&);
125     void processEndTag(AtomicHTMLToken&);
126     void processComment(AtomicHTMLToken&);
127     void processCharacter(AtomicHTMLToken&);
128     void processEndOfFile(AtomicHTMLToken&);
129
130     bool processStartTagForInHead(AtomicHTMLToken&);
131     void processStartTagForInBody(AtomicHTMLToken&);
132     void processStartTagForInTable(AtomicHTMLToken&);
133     void processEndTagForInBody(AtomicHTMLToken&);
134     void processEndTagForInTable(AtomicHTMLToken&);
135     void processEndTagForInTableBody(AtomicHTMLToken&);
136     void processEndTagForInRow(AtomicHTMLToken&);
137     void processEndTagForInCell(AtomicHTMLToken&);
138
139     void processIsindexStartTagForInBody(AtomicHTMLToken&);
140     bool processBodyEndTagForInBody(AtomicHTMLToken&);
141     bool processTableEndTagForInTable();
142     bool processCaptionEndTagForInCaption();
143     bool processColgroupEndTagForInColumnGroup();
144     bool processTrEndTagForInRow();
145     // FIXME: This function should be inlined into its one call site or it
146     // needs to assert which tokens it can be called with.
147     void processAnyOtherEndTagForInBody(AtomicHTMLToken&);
148
149     void processCharacterBuffer(ExternalCharacterTokenBuffer&);
150
151     void processFakeStartTag(const QualifiedName&, PassRefPtr<NamedNodeMap> attributes = 0);
152     void processFakeEndTag(const QualifiedName&);
153     void processFakeCharacters(const String&);
154     void processFakePEndTagIfPInButtonScope();
155
156     void processGenericRCDATAStartTag(AtomicHTMLToken&);
157     void processGenericRawTextStartTag(AtomicHTMLToken&);
158     void processScriptStartTag(AtomicHTMLToken&);
159
160     // Default processing for the different insertion modes.
161     void defaultForInitial();
162     void defaultForBeforeHTML();
163     void defaultForBeforeHead();
164     void defaultForInHead();
165     void defaultForInHeadNoscript();
166     void defaultForAfterHead();
167     void defaultForInTableText();
168
169     void prepareToReprocessToken();
170
171     void reprocessStartTag(AtomicHTMLToken&);
172     void reprocessEndTag(AtomicHTMLToken&);
173
174     PassRefPtr<NamedNodeMap> attributesForIsindexInput(AtomicHTMLToken&);
175
176     HTMLElementStack::ElementRecord* furthestBlockForFormattingElement(Element*);
177     void callTheAdoptionAgency(AtomicHTMLToken&);
178
179     void closeTheCell();
180
181     template <bool shouldClose(const Element*)>
182     void processCloseWhenNestedTag(AtomicHTMLToken&);
183
184     bool m_framesetOk;
185
186     // FIXME: Implement error reporting.
187     void parseError(AtomicHTMLToken&) { }
188
189     InsertionMode insertionMode() const { return m_insertionMode; }
190     void setInsertionMode(InsertionMode mode)
191     {
192         m_insertionMode = mode;
193         m_isFakeInsertionMode = false;
194     }
195
196     bool isFakeInsertionMode() { return m_isFakeInsertionMode; }
197     void setFakeInsertionMode(InsertionMode mode)
198     {
199         m_insertionMode = mode;
200         m_isFakeInsertionMode = true;
201     }
202
203     void resetInsertionModeAppropriately();
204
205     void processForeignContentUsingInBodyModeAndResetMode(AtomicHTMLToken& token);
206     void resetForeignInsertionMode();
207
208     class FragmentParsingContext {
209         WTF_MAKE_NONCOPYABLE(FragmentParsingContext);
210     public:
211         FragmentParsingContext();
212         FragmentParsingContext(DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
213         ~FragmentParsingContext();
214
215         Document* document() const;
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         void finished();
221
222     private:
223         RefPtr<Document> m_dummyDocumentForFragmentParsing;
224         DocumentFragment* m_fragment;
225         Element* m_contextElement;
226
227         // FragmentScriptingNotAllowed causes the Parser to remove children
228         // from <script> tags (so javascript doesn't show up in pastes).
229         FragmentScriptingPermission m_scriptingPermission;
230     };
231
232     FragmentParsingContext m_fragmentContext;
233
234     Document* m_document;
235     HTMLConstructionSite m_tree;
236
237     bool m_reportErrors;
238     bool m_isPaused;
239     bool m_isFakeInsertionMode;
240
241     // FIXME: InsertionModes should be a separate object to prevent direct
242     // manipulation of these variables.  For now, be careful to always use
243     // setInsertionMode and never set m_insertionMode directly.
244     InsertionMode m_insertionMode;
245     InsertionMode m_originalInsertionMode;
246
247     // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#pending-table-character-tokens
248     Vector<UChar> m_pendingTableCharacters;
249
250     // We access parser because HTML5 spec requires that we be able to change the state of the tokenizer
251     // from within parser actions. We also need it to track the current position.
252     HTMLDocumentParser* m_parser;
253
254     RefPtr<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
255     TextPosition1 m_scriptToProcessStartPosition; // Starting line number of the script tag needing processing.
256
257     // FIXME: We probably want to remove this member.  Originally, it was
258     // created to service the legacy tree builder, but it seems to be used for
259     // some other things now.
260     TextPosition0 m_lastScriptElementStartPosition;
261
262     bool m_usePreHTML5ParserQuirks;
263
264     bool m_hasPendingForeignInsertionModeSteps;
265 };
266
267 }
268
269 #endif