Implement HTMLTemplateElement
[WebKit-https.git] / 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 "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/text/StringBuilder.h>
41 #include <wtf/text/TextPosition.h>
42 #include <wtf/unicode/Unicode.h>
43
44 namespace WebCore {
45
46 class AtomicHTMLToken;
47 class Document;
48 class DocumentFragment;
49 class Element;
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 #if ENABLE(TEMPLATE_ELEMENT)
71     bool isParsingTemplateContents() const { return m_tree.openElements()->hasTemplateInHTMLScope(); }
72     bool isParsingFragmentOrTemplateContents() const { return isParsingFragment() || isParsingTemplateContents(); }
73 #else
74     bool isParsingFragmentOrTemplateContents() const { return isParsingFragment(); }
75 #endif
76
77     void detach();
78
79     // The token really should be passed as a const& since it's never modified.
80     void constructTreeFromToken(HTMLToken&);
81     void constructTreeFromAtomicToken(AtomicHTMLToken*);
82
83     bool hasParserBlockingScript() const { return !!m_scriptToProcess; }
84     // Must be called to take the parser-blocking script before calling the parser again.
85     PassRefPtr<Element> takeScriptToProcess(TextPosition& scriptStartPosition);
86
87     // Done, close any open tags, etc.
88     void finished();
89
90     void setShouldSkipLeadingNewline(bool shouldSkip) { m_shouldSkipLeadingNewline = shouldSkip; }
91
92     static bool scriptEnabled(Frame*);
93     static bool pluginsEnabled(Frame*);
94
95 private:
96     class ExternalCharacterTokenBuffer;
97     // Represents HTML5 "insertion mode"
98     // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode
99     enum InsertionMode {
100         InitialMode,
101         BeforeHTMLMode,
102         BeforeHeadMode,
103         InHeadMode,
104         InHeadNoscriptMode,
105         AfterHeadMode,
106         TemplateContentsMode,
107         InBodyMode,
108         TextMode,
109         InTableMode,
110         InTableTextMode,
111         InCaptionMode,
112         InColumnGroupMode,
113         InTableBodyMode,
114         InRowMode,
115         InCellMode,
116         InSelectMode,
117         InSelectInTableMode,
118         AfterBodyMode,
119         InFramesetMode,
120         AfterFramesetMode,
121         AfterAfterBodyMode,
122         AfterAfterFramesetMode,
123     };
124
125     HTMLTreeBuilder(HTMLDocumentParser*, HTMLDocument*, bool reportErrors, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth);
126     HTMLTreeBuilder(HTMLDocumentParser*, DocumentFragment*, Element* contextElement, FragmentScriptingPermission, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth);
127
128     void processToken(AtomicHTMLToken*);
129
130     void processDoctypeToken(AtomicHTMLToken*);
131     void processStartTag(AtomicHTMLToken*);
132     void processEndTag(AtomicHTMLToken*);
133     void processComment(AtomicHTMLToken*);
134     void processCharacter(AtomicHTMLToken*);
135     void processEndOfFile(AtomicHTMLToken*);
136
137     bool processStartTagForInHead(AtomicHTMLToken*);
138     void processStartTagForInBody(AtomicHTMLToken*);
139     void processStartTagForInTable(AtomicHTMLToken*);
140     void processEndTagForInBody(AtomicHTMLToken*);
141     void processEndTagForInTable(AtomicHTMLToken*);
142     void processEndTagForInTableBody(AtomicHTMLToken*);
143     void processEndTagForInRow(AtomicHTMLToken*);
144     void processEndTagForInCell(AtomicHTMLToken*);
145
146     void processIsindexStartTagForInBody(AtomicHTMLToken*);
147     void processHtmlStartTagForInBody(AtomicHTMLToken*);
148     bool processBodyEndTagForInBody(AtomicHTMLToken*);
149     bool processTableEndTagForInTable();
150     bool processCaptionEndTagForInCaption();
151     bool processColgroupEndTagForInColumnGroup();
152     bool processTrEndTagForInRow();
153     // FIXME: This function should be inlined into its one call site or it
154     // needs to assert which tokens it can be called with.
155     void processAnyOtherEndTagForInBody(AtomicHTMLToken*);
156
157     void processCharacterBuffer(ExternalCharacterTokenBuffer&);
158     inline void processCharacterBufferForInBody(ExternalCharacterTokenBuffer&);
159
160     void processFakeStartTag(const QualifiedName&, const Vector<Attribute>& attributes = Vector<Attribute>());
161     void processFakeEndTag(const QualifiedName&);
162     void processFakeEndTag(const AtomicString&);
163     void processFakeCharacters(const String&);
164     void processFakePEndTagIfPInButtonScope();
165
166     void processGenericRCDATAStartTag(AtomicHTMLToken*);
167     void processGenericRawTextStartTag(AtomicHTMLToken*);
168     void processScriptStartTag(AtomicHTMLToken*);
169
170     // Default processing for the different insertion modes.
171     void defaultForInitial();
172     void defaultForBeforeHTML();
173     void defaultForBeforeHead();
174     void defaultForInHead();
175     void defaultForInHeadNoscript();
176     void defaultForAfterHead();
177     void defaultForInTableText();
178
179     inline bool shouldProcessTokenInForeignContent(AtomicHTMLToken*);
180     void processTokenInForeignContent(AtomicHTMLToken*);
181
182     Vector<Attribute> attributesForIsindexInput(AtomicHTMLToken*);
183
184     void callTheAdoptionAgency(AtomicHTMLToken*);
185
186     void closeTheCell();
187
188     template <bool shouldClose(const HTMLStackItem*)>
189     void processCloseWhenNestedTag(AtomicHTMLToken*);
190
191     bool m_framesetOk;
192
193     void parseError(AtomicHTMLToken*);
194
195     InsertionMode insertionMode() const { return m_insertionMode; }
196     void setInsertionMode(InsertionMode mode) { m_insertionMode = mode; }
197
198     void resetInsertionModeAppropriately();
199
200 #if ENABLE(TEMPLATE_ELEMENT)
201     void processTemplateStartTag(AtomicHTMLToken*);
202     void processTemplateEndTag(AtomicHTMLToken*);
203 #endif
204
205     class FragmentParsingContext {
206         WTF_MAKE_NONCOPYABLE(FragmentParsingContext);
207     public:
208         FragmentParsingContext();
209         FragmentParsingContext(DocumentFragment*, Element* contextElement, FragmentScriptingPermission);
210         ~FragmentParsingContext();
211
212         DocumentFragment* fragment() const { return m_fragment; }
213         Element* contextElement() const { ASSERT(m_fragment); return m_contextElement; }
214         FragmentScriptingPermission scriptingPermission() const { ASSERT(m_fragment); return m_scriptingPermission; }
215
216     private:
217         DocumentFragment* m_fragment;
218         Element* m_contextElement;
219
220         // DisallowScriptingContent causes the Parser to remove children from <script> tags (so javascript doesn't show up in pastes).
221         FragmentScriptingPermission m_scriptingPermission;
222     };
223
224     FragmentParsingContext m_fragmentContext;
225
226     Document* m_document;
227     HTMLConstructionSite m_tree;
228
229     // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode
230     InsertionMode m_insertionMode;
231
232     // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#original-insertion-mode
233     InsertionMode m_originalInsertionMode;
234
235     // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#pending-table-character-tokens
236     StringBuilder m_pendingTableCharacters;
237
238     bool m_shouldSkipLeadingNewline;
239
240     // We access parser because HTML5 spec requires that we be able to change the state of the tokenizer
241     // from within parser actions. We also need it to track the current position.
242     HTMLDocumentParser* m_parser;
243
244     RefPtr<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
245     TextPosition m_scriptToProcessStartPosition; // Starting line number of the script tag needing processing.
246
247     bool m_usePreHTML5ParserQuirks;
248 };
249
250 }
251
252 #endif