1 : /* ***** BEGIN LICENSE BLOCK *****
2 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 : *
4 : * The contents of this file are subject to the Mozilla Public License Version
5 : * 1.1 (the "License"); you may not use this file except in compliance with
6 : * the License. You may obtain a copy of the License at
7 : * http://www.mozilla.org/MPL/
8 : *
9 : * Software distributed under the License is distributed on an "AS IS" basis,
10 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 : * for the specific language governing rights and limitations under the
12 : * License.
13 : *
14 : * The Original Code is HTML Parser C++ Translator code.
15 : *
16 : * The Initial Developer of the Original Code is
17 : * Mozilla Foundation.
18 : * Portions created by the Initial Developer are Copyright (C) 2008-2009
19 : * the Initial Developer. All Rights Reserved.
20 : *
21 : * Contributor(s):
22 : * Henri Sivonen <hsivonen@iki.fi>
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either the GNU General Public License Version 2 or later (the "GPL"), or
26 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #define NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH 512
39 :
40 : private:
41 : nsHtml5Highlighter* mViewSource;
42 : nsTArray<nsHtml5TreeOperation> mOpQueue;
43 : nsTArray<nsHtml5SpeculativeLoad> mSpeculativeLoadQueue;
44 : nsAHtml5TreeOpSink* mOpSink;
45 : nsAutoArrayPtr<nsIContent*> mHandles;
46 : PRInt32 mHandlesUsed;
47 : nsTArray<nsAutoArrayPtr<nsIContent*> > mOldHandles;
48 : nsHtml5TreeOpStage* mSpeculativeLoadStage;
49 : nsIContent** mDeepTreeSurrogateParent;
50 : bool mCurrentHtmlScriptIsAsyncOrDefer;
51 : #ifdef DEBUG
52 : bool mActive;
53 : #endif
54 :
55 : // DocumentModeHandler
56 : /**
57 : * Tree builder uses this to report quirkiness of the document
58 : */
59 : void documentMode(nsHtml5DocumentMode m);
60 :
61 : /**
62 : * Using nsIContent** instead of nsIContent* is the parser deals with DOM
63 : * nodes in a way that works off the main thread. Non-main-thread code
64 : * can't refcount or otherwise touch nsIContent objects in any way.
65 : * Yet, the off-the-main-thread code needs to have a way to hold onto a
66 : * particular node and repeatedly operate on the same node.
67 : *
68 : * The way this works is that the off-the-main-thread code has an
69 : * nsIContent** for each DOM node and a given nsIContent** is only ever
70 : * actually dereferenced into an actual nsIContent* on the main thread.
71 : * When the off-the-main-thread code requests a new node, it gets an
72 : * nsIContent** immediately and a tree op is enqueued for later allocating
73 : * an actual nsIContent object and writing a pointer to it into the memory
74 : * location pointed to by the nsIContent**.
75 : *
76 : * Since tree ops are in a queue, the node creating tree op will always
77 : * run before tree ops that try to further operate on the node that the
78 : * nsIContent** is a handle to.
79 : *
80 : * On-the-main-thread parts of the parser use the same mechanism in order
81 : * to avoid having to have duplicate code paths for on-the-main-thread and
82 : * off-the-main-thread tree builder instances.)
83 : */
84 : nsIContent** AllocateContentHandle();
85 :
86 0 : void accumulateCharactersForced(const PRUnichar* aBuf, PRInt32 aStart, PRInt32 aLength)
87 : {
88 0 : accumulateCharacters(aBuf, aStart, aLength);
89 0 : }
90 :
91 : public:
92 :
93 : nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
94 : nsHtml5TreeOpStage* aStage);
95 :
96 : ~nsHtml5TreeBuilder();
97 :
98 : void StartPlainTextViewSource(const nsAutoString& aTitle);
99 :
100 : void StartPlainText();
101 :
102 : bool HasScript();
103 :
104 0 : void SetOpSink(nsAHtml5TreeOpSink* aOpSink) {
105 0 : mOpSink = aOpSink;
106 0 : }
107 :
108 0 : void ClearOps() {
109 0 : mOpQueue.Clear();
110 0 : }
111 :
112 : bool Flush(bool aDiscretionary = false);
113 :
114 : void FlushLoads();
115 :
116 : void SetDocumentCharset(nsACString& aCharset, PRInt32 aCharsetSource);
117 :
118 : void StreamEnded();
119 :
120 : void NeedsCharsetSwitchTo(const nsACString& aEncoding, PRInt32 aSource);
121 :
122 : void AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, PRInt32 aLine);
123 :
124 : void DropHandles();
125 :
126 : void EnableViewSource(nsHtml5Highlighter* aHighlighter);
127 :
128 : void errStrayStartTag(nsIAtom* aName);
129 :
130 : void errStrayEndTag(nsIAtom* aName);
131 :
132 : void errUnclosedElements(PRInt32 aIndex, nsIAtom* aName);
133 :
134 : void errUnclosedElementsImplied(PRInt32 aIndex, nsIAtom* aName);
135 :
136 : void errUnclosedElementsCell(PRInt32 aIndex);
137 :
138 : void errStrayDoctype();
139 :
140 : void errAlmostStandardsDoctype();
141 :
142 : void errQuirkyDoctype();
143 :
144 : void errNonSpaceInTrailer();
145 :
146 : void errNonSpaceAfterFrameset();
147 :
148 : void errNonSpaceInFrameset();
149 :
150 : void errNonSpaceAfterBody();
151 :
152 : void errNonSpaceInColgroupInFragment();
153 :
154 : void errNonSpaceInNoscriptInHead();
155 :
156 : void errFooBetweenHeadAndBody(nsIAtom* aName);
157 :
158 : void errStartTagWithoutDoctype();
159 :
160 : void errNoSelectInTableScope();
161 :
162 : void errStartSelectWhereEndSelectExpected();
163 :
164 : void errStartTagWithSelectOpen(nsIAtom* aName);
165 :
166 : void errBadStartTagInHead(nsIAtom* aName);
167 :
168 : void errImage();
169 :
170 : void errIsindex();
171 :
172 : void errFooSeenWhenFooOpen(nsIAtom* aName);
173 :
174 : void errHeadingWhenHeadingOpen();
175 :
176 : void errFramesetStart();
177 :
178 : void errNoCellToClose();
179 :
180 : void errStartTagInTable(nsIAtom* aName);
181 :
182 : void errFormWhenFormOpen();
183 :
184 : void errTableSeenWhileTableOpen();
185 :
186 : void errStartTagInTableBody(nsIAtom* aName);
187 :
188 : void errEndTagSeenWithoutDoctype();
189 :
190 : void errEndTagAfterBody();
191 :
192 : void errEndTagSeenWithSelectOpen(nsIAtom* aName);
193 :
194 : void errGarbageInColgroup();
195 :
196 : void errEndTagBr();
197 :
198 : void errNoElementToCloseButEndTagSeen(nsIAtom* aName);
199 :
200 : void errHtmlStartTagInForeignContext(nsIAtom* aName);
201 :
202 : void errTableClosedWhileCaptionOpen();
203 :
204 : void errNoTableRowToClose();
205 :
206 : void errNonSpaceInTable();
207 :
208 : void errUnclosedChildrenInRuby();
209 :
210 : void errStartTagSeenWithoutRuby(nsIAtom* aName);
211 :
212 : void errSelfClosing();
213 :
214 : void errNoCheckUnclosedElementsOnStack();
215 :
216 : void errEndTagDidNotMatchCurrentOpenElement(nsIAtom* aName, nsIAtom* aOther);
217 :
218 : void errEndTagViolatesNestingRules(nsIAtom* aName);
219 :
220 : void errEndWithUnclosedElements(nsIAtom* aName);
221 :
222 : void MarkAsBroken();
|