/src/mozilla-central/parser/html/nsHtml5TreeOperation.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | | |
5 | | #ifndef nsHtml5TreeOperation_h |
6 | | #define nsHtml5TreeOperation_h |
7 | | |
8 | | #include "nsHtml5DocumentMode.h" |
9 | | #include "nsHtml5HtmlAttributes.h" |
10 | | #include "mozilla/dom/FromParser.h" |
11 | | #include "mozilla/NotNull.h" |
12 | | |
13 | | class nsIContent; |
14 | | class nsHtml5TreeOpExecutor; |
15 | | class nsHtml5DocumentBuilder; |
16 | | namespace mozilla { |
17 | | class Encoding; |
18 | | |
19 | | namespace dom { |
20 | | class Text; |
21 | | } // namespace dom |
22 | | } // namespace mozilla |
23 | | |
24 | | enum eHtml5TreeOperation |
25 | | { |
26 | | eTreeOpUninitialized, |
27 | | // main HTML5 ops |
28 | | eTreeOpAppend, |
29 | | eTreeOpDetach, |
30 | | eTreeOpAppendChildrenToNewParent, |
31 | | eTreeOpFosterParent, |
32 | | eTreeOpAppendToDocument, |
33 | | eTreeOpAddAttributes, |
34 | | eTreeOpDocumentMode, |
35 | | eTreeOpCreateHTMLElementNetwork, |
36 | | eTreeOpCreateHTMLElementNotNetwork, |
37 | | eTreeOpCreateSVGElementNetwork, |
38 | | eTreeOpCreateSVGElementNotNetwork, |
39 | | eTreeOpCreateMathMLElement, |
40 | | eTreeOpSetFormElement, |
41 | | eTreeOpAppendText, |
42 | | eTreeOpFosterParentText, |
43 | | eTreeOpAppendComment, |
44 | | eTreeOpAppendCommentToDocument, |
45 | | eTreeOpAppendDoctypeToDocument, |
46 | | eTreeOpGetDocumentFragmentForTemplate, |
47 | | eTreeOpGetFosterParent, |
48 | | // Gecko-specific on-pop ops |
49 | | eTreeOpMarkAsBroken, |
50 | | eTreeOpRunScript, |
51 | | eTreeOpRunScriptAsyncDefer, |
52 | | eTreeOpPreventScriptExecution, |
53 | | eTreeOpDoneAddingChildren, |
54 | | eTreeOpDoneCreatingElement, |
55 | | eTreeOpSetDocumentCharset, |
56 | | eTreeOpNeedsCharsetSwitchTo, |
57 | | eTreeOpUpdateStyleSheet, |
58 | | eTreeOpProcessMeta, |
59 | | eTreeOpProcessOfflineManifest, |
60 | | eTreeOpMarkMalformedIfScript, |
61 | | eTreeOpStreamEnded, |
62 | | eTreeOpSetStyleLineNumber, |
63 | | eTreeOpSetScriptLineNumberAndFreeze, |
64 | | eTreeOpSvgLoad, |
65 | | eTreeOpMaybeComplainAboutCharset, |
66 | | eTreeOpAddClass, |
67 | | eTreeOpAddViewSourceHref, |
68 | | eTreeOpAddViewSourceBase, |
69 | | eTreeOpAddError, |
70 | | eTreeOpAddLineNumberId, |
71 | | eTreeOpStartLayout, |
72 | | eTreeOpEnableEncodingMenu |
73 | | }; |
74 | | |
75 | | class nsHtml5TreeOperationStringPair |
76 | | { |
77 | | private: |
78 | | nsString mPublicId; |
79 | | nsString mSystemId; |
80 | | |
81 | | public: |
82 | | nsHtml5TreeOperationStringPair(const nsAString& aPublicId, |
83 | | const nsAString& aSystemId) |
84 | | : mPublicId(aPublicId) |
85 | | , mSystemId(aSystemId) |
86 | 0 | { |
87 | 0 | MOZ_COUNT_CTOR(nsHtml5TreeOperationStringPair); |
88 | 0 | } |
89 | | |
90 | | ~nsHtml5TreeOperationStringPair() |
91 | 0 | { |
92 | 0 | MOZ_COUNT_DTOR(nsHtml5TreeOperationStringPair); |
93 | 0 | } |
94 | | |
95 | | inline void Get(nsAString& aPublicId, nsAString& aSystemId) |
96 | 0 | { |
97 | 0 | aPublicId.Assign(mPublicId); |
98 | 0 | aSystemId.Assign(mSystemId); |
99 | 0 | } |
100 | | }; |
101 | | |
102 | | class nsHtml5TreeOperation final |
103 | | { |
104 | | template<typename T> |
105 | | using NotNull = mozilla::NotNull<T>; |
106 | | using Encoding = mozilla::Encoding; |
107 | | |
108 | | public: |
109 | | /** |
110 | | * Atom is used inside the parser core are either static atoms that are |
111 | | * the same as Gecko-wide static atoms or they are dynamic atoms scoped by |
112 | | * both thread and parser to a particular nsHtml5AtomTable. In order to |
113 | | * such scoped atoms coming into contact with the rest of Gecko, atoms |
114 | | * that are about to exit the parser must go through this method which |
115 | | * reobtains dynamic atoms from the Gecko-global atom table. |
116 | | * |
117 | | * @param aAtom a potentially parser-scoped atom |
118 | | * @return an nsAtom that's pointer comparable on the main thread with |
119 | | * other not-parser atoms. |
120 | | */ |
121 | | static inline already_AddRefed<nsAtom> Reget(nsAtom* aAtom) |
122 | 0 | { |
123 | 0 | if (!aAtom || aAtom->IsStatic()) { |
124 | 0 | return dont_AddRef(aAtom); |
125 | 0 | } |
126 | 0 | nsAutoString str; |
127 | 0 | aAtom->ToString(str); |
128 | 0 | return NS_AtomizeMainThread(str); |
129 | 0 | } |
130 | | |
131 | | static nsresult AppendTextToTextNode(const char16_t* aBuffer, |
132 | | uint32_t aLength, |
133 | | mozilla::dom::Text* aTextNode, |
134 | | nsHtml5DocumentBuilder* aBuilder); |
135 | | |
136 | | static nsresult AppendText(const char16_t* aBuffer, |
137 | | uint32_t aLength, |
138 | | nsIContent* aParent, |
139 | | nsHtml5DocumentBuilder* aBuilder); |
140 | | |
141 | | static nsresult Append(nsIContent* aNode, |
142 | | nsIContent* aParent, |
143 | | nsHtml5DocumentBuilder* aBuilder); |
144 | | |
145 | | static nsresult AppendToDocument(nsIContent* aNode, |
146 | | nsHtml5DocumentBuilder* aBuilder); |
147 | | |
148 | | static void Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder); |
149 | | |
150 | | static nsresult AppendChildrenToNewParent(nsIContent* aNode, |
151 | | nsIContent* aParent, |
152 | | nsHtml5DocumentBuilder* aBuilder); |
153 | | |
154 | | static nsresult FosterParent(nsIContent* aNode, |
155 | | nsIContent* aParent, |
156 | | nsIContent* aTable, |
157 | | nsHtml5DocumentBuilder* aBuilder); |
158 | | |
159 | | static nsresult AddAttributes(nsIContent* aNode, |
160 | | nsHtml5HtmlAttributes* aAttributes, |
161 | | nsHtml5DocumentBuilder* aBuilder); |
162 | | |
163 | | static void SetHTMLElementAttributes(mozilla::dom::Element* aElement, |
164 | | nsAtom* aName, |
165 | | nsHtml5HtmlAttributes* aAttributes); |
166 | | |
167 | | static nsIContent* CreateHTMLElement( |
168 | | nsAtom* aName, |
169 | | nsHtml5HtmlAttributes* aAttributes, |
170 | | mozilla::dom::FromParser aFromParser, |
171 | | nsNodeInfoManager* aNodeInfoManager, |
172 | | nsHtml5DocumentBuilder* aBuilder, |
173 | | mozilla::dom::HTMLContentCreatorFunction aCreator); |
174 | | |
175 | | static nsIContent* CreateSVGElement( |
176 | | nsAtom* aName, |
177 | | nsHtml5HtmlAttributes* aAttributes, |
178 | | mozilla::dom::FromParser aFromParser, |
179 | | nsNodeInfoManager* aNodeInfoManager, |
180 | | nsHtml5DocumentBuilder* aBuilder, |
181 | | mozilla::dom::SVGContentCreatorFunction aCreator); |
182 | | |
183 | | static nsIContent* CreateMathMLElement(nsAtom* aName, |
184 | | nsHtml5HtmlAttributes* aAttributes, |
185 | | nsNodeInfoManager* aNodeInfoManager, |
186 | | nsHtml5DocumentBuilder* aBuilder); |
187 | | |
188 | | static void SetFormElement(nsIContent* aNode, nsIContent* aParent); |
189 | | |
190 | | static nsresult AppendIsindexPrompt(nsIContent* parent, |
191 | | nsHtml5DocumentBuilder* aBuilder); |
192 | | |
193 | | static nsresult FosterParentText(nsIContent* aStackParent, |
194 | | char16_t* aBuffer, |
195 | | uint32_t aLength, |
196 | | nsIContent* aTable, |
197 | | nsHtml5DocumentBuilder* aBuilder); |
198 | | |
199 | | static nsresult AppendComment(nsIContent* aParent, |
200 | | char16_t* aBuffer, |
201 | | int32_t aLength, |
202 | | nsHtml5DocumentBuilder* aBuilder); |
203 | | |
204 | | static nsresult AppendCommentToDocument(char16_t* aBuffer, |
205 | | int32_t aLength, |
206 | | nsHtml5DocumentBuilder* aBuilder); |
207 | | |
208 | | static nsresult AppendDoctypeToDocument(nsAtom* aName, |
209 | | const nsAString& aPublicId, |
210 | | const nsAString& aSystemId, |
211 | | nsHtml5DocumentBuilder* aBuilder); |
212 | | |
213 | | static nsIContent* GetDocumentFragmentForTemplate(nsIContent* aNode); |
214 | | |
215 | | static nsIContent* GetFosterParent(nsIContent* aTable, |
216 | | nsIContent* aStackParent); |
217 | | |
218 | | static void PreventScriptExecution(nsIContent* aNode); |
219 | | |
220 | | static void DoneAddingChildren(nsIContent* aNode); |
221 | | |
222 | | static void DoneCreatingElement(nsIContent* aNode); |
223 | | |
224 | | static void SvgLoad(nsIContent* aNode); |
225 | | |
226 | | static void MarkMalformedIfScript(nsIContent* aNode); |
227 | | |
228 | | nsHtml5TreeOperation(); |
229 | | |
230 | | ~nsHtml5TreeOperation(); |
231 | | |
232 | | inline void Init(eHtml5TreeOperation aOpCode) |
233 | 0 | { |
234 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
235 | 0 | "Op code must be uninitialized when initializing."); |
236 | 0 | mOpCode = aOpCode; |
237 | 0 | } |
238 | | |
239 | | inline void Init(eHtml5TreeOperation aOpCode, nsIContentHandle* aNode) |
240 | 0 | { |
241 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
242 | 0 | "Op code must be uninitialized when initializing."); |
243 | 0 | MOZ_ASSERT(aNode, "Initialized tree op with null node."); |
244 | 0 | mOpCode = aOpCode; |
245 | 0 | mOne.node = static_cast<nsIContent**>(aNode); |
246 | 0 | } |
247 | | |
248 | | inline void Init(eHtml5TreeOperation aOpCode, |
249 | | nsIContentHandle* aNode, |
250 | | nsIContentHandle* aParent) |
251 | 0 | { |
252 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
253 | 0 | "Op code must be uninitialized when initializing."); |
254 | 0 | MOZ_ASSERT(aNode, "Initialized tree op with null node."); |
255 | 0 | MOZ_ASSERT(aParent, "Initialized tree op with null parent."); |
256 | 0 | mOpCode = aOpCode; |
257 | 0 | mOne.node = static_cast<nsIContent**>(aNode); |
258 | 0 | mTwo.node = static_cast<nsIContent**>(aParent); |
259 | 0 | } |
260 | | |
261 | | inline void Init(eHtml5TreeOperation aOpCode, |
262 | | const nsACString& aString, |
263 | | int32_t aInt32) |
264 | 0 | { |
265 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
266 | 0 | "Op code must be uninitialized when initializing."); |
267 | 0 |
|
268 | 0 | int32_t len = aString.Length(); |
269 | 0 | char* str = new char[len + 1]; |
270 | 0 | const char* start = aString.BeginReading(); |
271 | 0 | for (int32_t i = 0; i < len; ++i) { |
272 | 0 | str[i] = start[i]; |
273 | 0 | } |
274 | 0 | str[len] = '\0'; |
275 | 0 |
|
276 | 0 | mOpCode = aOpCode; |
277 | 0 | mOne.charPtr = str; |
278 | 0 | mFour.integer = aInt32; |
279 | 0 | } |
280 | | |
281 | | inline void Init(eHtml5TreeOperation aOpCode, |
282 | | const nsACString& aString, |
283 | | int32_t aInt32, |
284 | | int32_t aLineNumber) |
285 | 0 | { |
286 | 0 | Init(aOpCode, aString, aInt32); |
287 | 0 | mTwo.integer = aLineNumber; |
288 | 0 | } |
289 | | |
290 | | inline void Init(eHtml5TreeOperation aOpCode, |
291 | | NotNull<const Encoding*> aEncoding, |
292 | | int32_t aInt32) |
293 | 0 | { |
294 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
295 | 0 | "Op code must be uninitialized when initializing."); |
296 | 0 |
|
297 | 0 | mOpCode = aOpCode; |
298 | 0 | mOne.encoding = aEncoding; |
299 | 0 | mFour.integer = aInt32; |
300 | 0 | } |
301 | | |
302 | | inline void Init(eHtml5TreeOperation aOpCode, |
303 | | NotNull<const Encoding*> aEncoding, |
304 | | int32_t aInt32, |
305 | | int32_t aLineNumber) |
306 | 0 | { |
307 | 0 | Init(aOpCode, aEncoding, aInt32); |
308 | 0 | mTwo.integer = aLineNumber; |
309 | 0 | } |
310 | | |
311 | | inline void Init(eHtml5TreeOperation aOpCode, |
312 | | nsIContentHandle* aNode, |
313 | | nsIContentHandle* aParent, |
314 | | nsIContentHandle* aTable) |
315 | 0 | { |
316 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
317 | 0 | "Op code must be uninitialized when initializing."); |
318 | 0 | MOZ_ASSERT(aNode, "Initialized tree op with null node."); |
319 | 0 | MOZ_ASSERT(aParent, "Initialized tree op with null parent."); |
320 | 0 | MOZ_ASSERT(aTable, "Initialized tree op with null table."); |
321 | 0 | mOpCode = aOpCode; |
322 | 0 | mOne.node = static_cast<nsIContent**>(aNode); |
323 | 0 | mTwo.node = static_cast<nsIContent**>(aParent); |
324 | 0 | mThree.node = static_cast<nsIContent**>(aTable); |
325 | 0 | } |
326 | | |
327 | | inline void Init(nsHtml5DocumentMode aMode) |
328 | 0 | { |
329 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
330 | 0 | "Op code must be uninitialized when initializing."); |
331 | 0 | mOpCode = eTreeOpDocumentMode; |
332 | 0 | mOne.mode = aMode; |
333 | 0 | } |
334 | | |
335 | | inline void InitScript(nsIContentHandle* aNode) |
336 | 0 | { |
337 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
338 | 0 | "Op code must be uninitialized when initializing."); |
339 | 0 | MOZ_ASSERT(aNode, "Initialized tree op with null node."); |
340 | 0 | mOpCode = eTreeOpRunScript; |
341 | 0 | mOne.node = static_cast<nsIContent**>(aNode); |
342 | 0 | mTwo.state = nullptr; |
343 | 0 | } |
344 | | |
345 | | inline void Init(int32_t aNamespace, |
346 | | nsAtom* aName, |
347 | | nsHtml5HtmlAttributes* aAttributes, |
348 | | nsIContentHandle* aTarget, |
349 | | nsIContentHandle* aIntendedParent, |
350 | | bool aFromNetwork, |
351 | | nsHtml5ContentCreatorFunction aCreator) |
352 | 0 | { |
353 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
354 | 0 | "Op code must be uninitialized when initializing."); |
355 | 0 | MOZ_ASSERT(aName, "Initialized tree op with null name."); |
356 | 0 | MOZ_ASSERT(aTarget, "Initialized tree op with null target node."); |
357 | 0 |
|
358 | 0 | if (aNamespace == kNameSpaceID_XHTML) { |
359 | 0 | mOpCode = aFromNetwork ? eTreeOpCreateHTMLElementNetwork |
360 | 0 | : eTreeOpCreateHTMLElementNotNetwork; |
361 | 0 | mFour.htmlCreator = aCreator.html; |
362 | 0 | } else if (aNamespace == kNameSpaceID_SVG) { |
363 | 0 | mOpCode = aFromNetwork ? eTreeOpCreateSVGElementNetwork |
364 | 0 | : eTreeOpCreateSVGElementNotNetwork; |
365 | 0 | mFour.svgCreator = aCreator.svg; |
366 | 0 | } else { |
367 | 0 | MOZ_ASSERT(aNamespace == kNameSpaceID_MathML); |
368 | 0 | mOpCode = eTreeOpCreateMathMLElement; |
369 | 0 | } |
370 | 0 | mFive.node = static_cast<nsIContent**>(aIntendedParent); |
371 | 0 | mOne.node = static_cast<nsIContent**>(aTarget); |
372 | 0 | mTwo.atom = aName; |
373 | 0 | if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) { |
374 | 0 | mThree.attributes = nullptr; |
375 | 0 | } else { |
376 | 0 | mThree.attributes = aAttributes; |
377 | 0 | } |
378 | 0 | } |
379 | | |
380 | | inline void Init(eHtml5TreeOperation aOpCode, |
381 | | char16_t* aBuffer, |
382 | | int32_t aLength, |
383 | | nsIContentHandle* aStackParent, |
384 | | nsIContentHandle* aTable) |
385 | 0 | { |
386 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
387 | 0 | "Op code must be uninitialized when initializing."); |
388 | 0 | MOZ_ASSERT(aBuffer, "Initialized tree op with null buffer."); |
389 | 0 | mOpCode = aOpCode; |
390 | 0 | mOne.node = static_cast<nsIContent**>(aStackParent); |
391 | 0 | mTwo.unicharPtr = aBuffer; |
392 | 0 | mThree.node = static_cast<nsIContent**>(aTable); |
393 | 0 | mFour.integer = aLength; |
394 | 0 | } |
395 | | |
396 | | inline void Init(eHtml5TreeOperation aOpCode, |
397 | | char16_t* aBuffer, |
398 | | int32_t aLength, |
399 | | nsIContentHandle* aParent) |
400 | 0 | { |
401 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
402 | 0 | "Op code must be uninitialized when initializing."); |
403 | 0 | MOZ_ASSERT(aBuffer, "Initialized tree op with null buffer."); |
404 | 0 | mOpCode = aOpCode; |
405 | 0 | mOne.node = static_cast<nsIContent**>(aParent); |
406 | 0 | mTwo.unicharPtr = aBuffer; |
407 | 0 | mFour.integer = aLength; |
408 | 0 | } |
409 | | |
410 | | inline void Init(eHtml5TreeOperation aOpCode, |
411 | | char16_t* aBuffer, |
412 | | int32_t aLength) |
413 | 0 | { |
414 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
415 | 0 | "Op code must be uninitialized when initializing."); |
416 | 0 | MOZ_ASSERT(aBuffer, "Initialized tree op with null buffer."); |
417 | 0 | mOpCode = aOpCode; |
418 | 0 | mTwo.unicharPtr = aBuffer; |
419 | 0 | mFour.integer = aLength; |
420 | 0 | } |
421 | | |
422 | | inline void Init(nsIContentHandle* aElement, |
423 | | nsHtml5HtmlAttributes* aAttributes) |
424 | 0 | { |
425 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
426 | 0 | "Op code must be uninitialized when initializing."); |
427 | 0 | MOZ_ASSERT(aElement, "Initialized tree op with null element."); |
428 | 0 | mOpCode = eTreeOpAddAttributes; |
429 | 0 | mOne.node = static_cast<nsIContent**>(aElement); |
430 | 0 | mTwo.attributes = aAttributes; |
431 | 0 | } |
432 | | |
433 | | inline void Init(nsAtom* aName, |
434 | | const nsAString& aPublicId, |
435 | | const nsAString& aSystemId) |
436 | 0 | { |
437 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
438 | 0 | "Op code must be uninitialized when initializing."); |
439 | 0 | mOpCode = eTreeOpAppendDoctypeToDocument; |
440 | 0 | mOne.atom = aName; |
441 | 0 | mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId); |
442 | 0 | } |
443 | | |
444 | | inline void Init(nsIContentHandle* aElement, |
445 | | const char* aMsgId, |
446 | | nsAtom* aAtom, |
447 | | nsAtom* aOtherAtom) |
448 | 0 | { |
449 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
450 | 0 | "Op code must be uninitialized when initializing."); |
451 | 0 | mOpCode = eTreeOpAddError; |
452 | 0 | mOne.node = static_cast<nsIContent**>(aElement); |
453 | 0 | mTwo.charPtr = (char*)aMsgId; |
454 | 0 | mThree.atom = aAtom; |
455 | 0 | mFour.atom = aOtherAtom; |
456 | 0 | } |
457 | | |
458 | | inline void Init(nsIContentHandle* aElement, |
459 | | const char* aMsgId, |
460 | | nsAtom* aAtom) |
461 | 0 | { |
462 | 0 | Init(aElement, aMsgId, aAtom, nullptr); |
463 | 0 | } |
464 | | |
465 | | inline void Init(nsIContentHandle* aElement, const char* aMsgId) |
466 | 0 | { |
467 | 0 | Init(aElement, aMsgId, nullptr, nullptr); |
468 | 0 | } |
469 | | |
470 | | inline void Init(const char* aMsgId, bool aError, int32_t aLineNumber) |
471 | 0 | { |
472 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
473 | 0 | "Op code must be uninitialized when initializing."); |
474 | 0 | mOpCode = eTreeOpMaybeComplainAboutCharset; |
475 | 0 | mOne.charPtr = const_cast<char*>(aMsgId); |
476 | 0 | mTwo.integer = aError; |
477 | 0 | mThree.integer = aLineNumber; |
478 | 0 | } |
479 | | |
480 | | inline void Init(eHtml5TreeOperation aOpCode, const nsAString& aString) |
481 | 0 | { |
482 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
483 | 0 | "Op code must be uninitialized when initializing."); |
484 | 0 |
|
485 | 0 | char16_t* str = ToNewUnicode(aString); |
486 | 0 | mOpCode = aOpCode; |
487 | 0 | mOne.unicharPtr = str; |
488 | 0 | } |
489 | | |
490 | | inline void Init(eHtml5TreeOperation aOpCode, |
491 | | nsIContentHandle* aNode, |
492 | | int32_t aInt) |
493 | 0 | { |
494 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
495 | 0 | "Op code must be uninitialized when initializing."); |
496 | 0 | MOZ_ASSERT(aNode, "Initialized tree op with null node."); |
497 | 0 | mOpCode = aOpCode; |
498 | 0 | mOne.node = static_cast<nsIContent**>(aNode); |
499 | 0 | mFour.integer = aInt; |
500 | 0 | } |
501 | | |
502 | | inline void Init(nsresult aRv) |
503 | 0 | { |
504 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
505 | 0 | "Op code must be uninitialized when initializing."); |
506 | 0 | MOZ_ASSERT(NS_FAILED(aRv), "Initialized tree op with non-failure."); |
507 | 0 | mOpCode = eTreeOpMarkAsBroken; |
508 | 0 | mOne.result = aRv; |
509 | 0 | } |
510 | | |
511 | | inline void InitAddClass(nsIContentHandle* aNode, const char16_t* aClass) |
512 | 0 | { |
513 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
514 | 0 | "Op code must be uninitialized when initializing."); |
515 | 0 | MOZ_ASSERT(aNode, "Initialized tree op with null node."); |
516 | 0 | MOZ_ASSERT(aClass, "Initialized tree op with null string."); |
517 | 0 | // aClass must be a literal string that does not need freeing |
518 | 0 | mOpCode = eTreeOpAddClass; |
519 | 0 | mOne.node = static_cast<nsIContent**>(aNode); |
520 | 0 | mTwo.unicharPtr = (char16_t*)aClass; |
521 | 0 | } |
522 | | |
523 | | inline void InitAddLineNumberId(nsIContentHandle* aNode, |
524 | | const int32_t aLineNumber) |
525 | 0 | { |
526 | 0 | MOZ_ASSERT(mOpCode == eTreeOpUninitialized, |
527 | 0 | "Op code must be uninitialized when initializing."); |
528 | 0 | MOZ_ASSERT(aNode, "Initialized tree op with null node."); |
529 | 0 | MOZ_ASSERT(aLineNumber > 0, "Initialized tree op with line number."); |
530 | 0 | // aClass must be a literal string that does not need freeing |
531 | 0 | mOpCode = eTreeOpAddLineNumberId; |
532 | 0 | mOne.node = static_cast<nsIContent**>(aNode); |
533 | 0 | mFour.integer = aLineNumber; |
534 | 0 | } |
535 | | |
536 | 0 | inline bool IsRunScript() { return mOpCode == eTreeOpRunScript; } |
537 | | |
538 | 0 | inline bool IsMarkAsBroken() { return mOpCode == eTreeOpMarkAsBroken; } |
539 | | |
540 | | inline void SetSnapshot(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine) |
541 | 0 | { |
542 | 0 | NS_ASSERTION( |
543 | 0 | IsRunScript(), |
544 | 0 | "Setting a snapshot for a tree operation other than eTreeOpRunScript!"); |
545 | 0 | MOZ_ASSERT(aSnapshot, "Initialized tree op with null snapshot."); |
546 | 0 | mTwo.state = aSnapshot; |
547 | 0 | mFour.integer = aLine; |
548 | 0 | } |
549 | | |
550 | | nsresult Perform(nsHtml5TreeOpExecutor* aBuilder, |
551 | | nsIContent** aScriptElement, |
552 | | bool* aInterrupted, |
553 | | bool* aStreamEnded); |
554 | | |
555 | | private: |
556 | | nsHtml5TreeOperation(const nsHtml5TreeOperation&) = delete; |
557 | | nsHtml5TreeOperation& operator=(const nsHtml5TreeOperation&) = delete; |
558 | | |
559 | | // possible optimization: |
560 | | // Make the queue take items the size of pointer and make the op code |
561 | | // decide how many operands it dequeues after it. |
562 | | eHtml5TreeOperation mOpCode; |
563 | | union { |
564 | | nsIContent** node; |
565 | | nsAtom* atom; |
566 | | nsHtml5HtmlAttributes* attributes; |
567 | | nsHtml5DocumentMode mode; |
568 | | char16_t* unicharPtr; |
569 | | char* charPtr; |
570 | | nsHtml5TreeOperationStringPair* stringPair; |
571 | | nsAHtml5TreeBuilderState* state; |
572 | | int32_t integer; |
573 | | nsresult result; |
574 | | const Encoding* encoding; |
575 | | mozilla::dom::HTMLContentCreatorFunction htmlCreator; |
576 | | mozilla::dom::SVGContentCreatorFunction svgCreator; |
577 | | } mOne, mTwo, mThree, mFour, mFive; |
578 | | }; |
579 | | |
580 | | #endif // nsHtml5TreeOperation_h |