Bumping gaia.json for 1 gaia revision(s) a=gaia-bump
[gecko.git] / parser / html / nsHtml5TreeOperation.h
blobcd9aafd7c36fe96c1d0b6b8273c13f1314cb8a7f
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/. */
5 #ifndef nsHtml5TreeOperation_h
6 #define nsHtml5TreeOperation_h
8 #include "nsHtml5DocumentMode.h"
9 #include "nsHtml5HtmlAttributes.h"
10 #include "nsXPCOMStrings.h"
11 #include "mozilla/dom/FromParser.h"
13 class nsIContent;
14 class nsHtml5TreeOpExecutor;
15 class nsHtml5StateSnapshot;
16 class nsHtml5DocumentBuilder;
18 enum eHtml5TreeOperation {
19 #ifdef DEBUG
20 eTreeOpUninitialized,
21 #endif
22 // main HTML5 ops
23 eTreeOpAppend,
24 eTreeOpDetach,
25 eTreeOpAppendChildrenToNewParent,
26 eTreeOpFosterParent,
27 eTreeOpAppendToDocument,
28 eTreeOpAddAttributes,
29 eTreeOpDocumentMode,
30 eTreeOpCreateElementNetwork,
31 eTreeOpCreateElementNotNetwork,
32 eTreeOpSetFormElement,
33 eTreeOpAppendText,
34 eTreeOpAppendIsindexPrompt,
35 eTreeOpFosterParentText,
36 eTreeOpAppendComment,
37 eTreeOpAppendCommentToDocument,
38 eTreeOpAppendDoctypeToDocument,
39 eTreeOpGetDocumentFragmentForTemplate,
40 // Gecko-specific on-pop ops
41 eTreeOpMarkAsBroken,
42 eTreeOpRunScript,
43 eTreeOpRunScriptAsyncDefer,
44 eTreeOpPreventScriptExecution,
45 eTreeOpDoneAddingChildren,
46 eTreeOpDoneCreatingElement,
47 eTreeOpSetDocumentCharset,
48 eTreeOpNeedsCharsetSwitchTo,
49 eTreeOpUpdateStyleSheet,
50 eTreeOpProcessMeta,
51 eTreeOpProcessOfflineManifest,
52 eTreeOpMarkMalformedIfScript,
53 eTreeOpStreamEnded,
54 eTreeOpSetStyleLineNumber,
55 eTreeOpSetScriptLineNumberAndFreeze,
56 eTreeOpSvgLoad,
57 eTreeOpMaybeComplainAboutCharset,
58 eTreeOpAddClass,
59 eTreeOpAddViewSourceHref,
60 eTreeOpAddError,
61 eTreeOpAddLineNumberId,
62 eTreeOpAddErrorAtom,
63 eTreeOpAddErrorTwoAtoms,
64 eTreeOpStartLayout
67 class nsHtml5TreeOperationStringPair {
68 private:
69 nsString mPublicId;
70 nsString mSystemId;
71 public:
72 nsHtml5TreeOperationStringPair(const nsAString& aPublicId,
73 const nsAString& aSystemId)
74 : mPublicId(aPublicId)
75 , mSystemId(aSystemId)
77 MOZ_COUNT_CTOR(nsHtml5TreeOperationStringPair);
80 ~nsHtml5TreeOperationStringPair()
82 MOZ_COUNT_DTOR(nsHtml5TreeOperationStringPair);
85 inline void Get(nsAString& aPublicId, nsAString& aSystemId)
87 aPublicId.Assign(mPublicId);
88 aSystemId.Assign(mSystemId);
92 class nsHtml5TreeOperation {
94 public:
95 /**
96 * Atom is used inside the parser core are either static atoms that are
97 * the same as Gecko-wide static atoms or they are dynamic atoms scoped by
98 * both thread and parser to a particular nsHtml5AtomTable. In order to
99 * such scoped atoms coming into contact with the rest of Gecko, atoms
100 * that are about to exit the parser must go through this method which
101 * reobtains dynamic atoms from the Gecko-global atom table.
103 * @param aAtom a potentially parser-scoped atom
104 * @return an nsIAtom that's pointer comparable on the main thread with
105 * other not-parser atoms.
107 static inline already_AddRefed<nsIAtom> Reget(nsIAtom* aAtom)
109 if (!aAtom || aAtom->IsStaticAtom()) {
110 return dont_AddRef(aAtom);
112 nsAutoString str;
113 aAtom->ToString(str);
114 return do_GetAtom(str);
117 static nsresult AppendTextToTextNode(const char16_t* aBuffer,
118 uint32_t aLength,
119 nsIContent* aTextNode,
120 nsHtml5DocumentBuilder* aBuilder);
122 static nsresult AppendText(const char16_t* aBuffer,
123 uint32_t aLength,
124 nsIContent* aParent,
125 nsHtml5DocumentBuilder* aBuilder);
127 static nsresult Append(nsIContent* aNode,
128 nsIContent* aParent,
129 nsHtml5DocumentBuilder* aBuilder);
131 static nsresult AppendToDocument(nsIContent* aNode,
132 nsHtml5DocumentBuilder* aBuilder);
134 static void Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder);
136 static nsresult AppendChildrenToNewParent(nsIContent* aNode,
137 nsIContent* aParent,
138 nsHtml5DocumentBuilder* aBuilder);
140 static nsresult FosterParent(nsIContent* aNode,
141 nsIContent* aParent,
142 nsIContent* aTable,
143 nsHtml5DocumentBuilder* aBuilder);
145 static nsresult AddAttributes(nsIContent* aNode,
146 nsHtml5HtmlAttributes* aAttributes,
147 nsHtml5DocumentBuilder* aBuilder);
149 static nsIContent* CreateElement(int32_t aNs,
150 nsIAtom* aName,
151 nsHtml5HtmlAttributes* aAttributes,
152 mozilla::dom::FromParser aFromParser,
153 nsHtml5DocumentBuilder* aBuilder);
155 static void SetFormElement(nsIContent* aNode, nsIContent* aParent);
157 static nsresult AppendIsindexPrompt(nsIContent* parent,
158 nsHtml5DocumentBuilder* aBuilder);
160 static nsresult FosterParentText(nsIContent* aStackParent,
161 char16_t* aBuffer,
162 uint32_t aLength,
163 nsIContent* aTable,
164 nsHtml5DocumentBuilder* aBuilder);
166 static nsresult AppendComment(nsIContent* aParent,
167 char16_t* aBuffer,
168 int32_t aLength,
169 nsHtml5DocumentBuilder* aBuilder);
171 static nsresult AppendCommentToDocument(char16_t* aBuffer,
172 int32_t aLength,
173 nsHtml5DocumentBuilder* aBuilder);
175 static nsresult AppendDoctypeToDocument(nsIAtom* aName,
176 const nsAString& aPublicId,
177 const nsAString& aSystemId,
178 nsHtml5DocumentBuilder* aBuilder);
180 static nsIContent* GetDocumentFragmentForTemplate(nsIContent* aNode);
182 static void PreventScriptExecution(nsIContent* aNode);
184 static void DoneAddingChildren(nsIContent* aNode);
186 static void DoneCreatingElement(nsIContent* aNode);
188 static void SvgLoad(nsIContent* aNode);
190 static void MarkMalformedIfScript(nsIContent* aNode);
192 nsHtml5TreeOperation();
194 ~nsHtml5TreeOperation();
196 inline void Init(eHtml5TreeOperation aOpCode)
198 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
199 "Op code must be uninitialized when initializing.");
200 mOpCode = aOpCode;
203 inline void Init(eHtml5TreeOperation aOpCode, nsIContentHandle* aNode)
205 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
206 "Op code must be uninitialized when initializing.");
207 NS_PRECONDITION(aNode, "Initialized tree op with null node.");
208 mOpCode = aOpCode;
209 mOne.node = static_cast<nsIContent**>(aNode);
212 inline void Init(eHtml5TreeOperation aOpCode,
213 nsIContentHandle* aNode,
214 nsIContentHandle* aParent)
216 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
217 "Op code must be uninitialized when initializing.");
218 NS_PRECONDITION(aNode, "Initialized tree op with null node.");
219 NS_PRECONDITION(aParent, "Initialized tree op with null parent.");
220 mOpCode = aOpCode;
221 mOne.node = static_cast<nsIContent**>(aNode);
222 mTwo.node = static_cast<nsIContent**>(aParent);
225 inline void Init(eHtml5TreeOperation aOpCode,
226 const nsACString& aString,
227 int32_t aInt32)
229 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
230 "Op code must be uninitialized when initializing.");
232 int32_t len = aString.Length();
233 char* str = new char[len + 1];
234 const char* start = aString.BeginReading();
235 for (int32_t i = 0; i < len; ++i) {
236 str[i] = start[i];
238 str[len] = '\0';
240 mOpCode = aOpCode;
241 mOne.charPtr = str;
242 mFour.integer = aInt32;
245 inline void Init(eHtml5TreeOperation aOpCode,
246 const nsACString& aString,
247 int32_t aInt32,
248 int32_t aLineNumber)
250 Init(aOpCode, aString, aInt32);
251 mTwo.integer = aLineNumber;
254 inline void Init(eHtml5TreeOperation aOpCode,
255 nsIContentHandle* aNode,
256 nsIContentHandle* aParent,
257 nsIContentHandle* aTable)
259 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
260 "Op code must be uninitialized when initializing.");
261 NS_PRECONDITION(aNode, "Initialized tree op with null node.");
262 NS_PRECONDITION(aParent, "Initialized tree op with null parent.");
263 NS_PRECONDITION(aTable, "Initialized tree op with null table.");
264 mOpCode = aOpCode;
265 mOne.node = static_cast<nsIContent**>(aNode);
266 mTwo.node = static_cast<nsIContent**>(aParent);
267 mThree.node = static_cast<nsIContent**>(aTable);
270 inline void Init(nsHtml5DocumentMode aMode)
272 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
273 "Op code must be uninitialized when initializing.");
274 mOpCode = eTreeOpDocumentMode;
275 mOne.mode = aMode;
278 inline void InitScript(nsIContentHandle* aNode)
280 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
281 "Op code must be uninitialized when initializing.");
282 NS_PRECONDITION(aNode, "Initialized tree op with null node.");
283 mOpCode = eTreeOpRunScript;
284 mOne.node = static_cast<nsIContent**>(aNode);
285 mTwo.state = nullptr;
288 inline void Init(int32_t aNamespace,
289 nsIAtom* aName,
290 nsHtml5HtmlAttributes* aAttributes,
291 nsIContentHandle* aTarget,
292 bool aFromNetwork)
294 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
295 "Op code must be uninitialized when initializing.");
296 NS_PRECONDITION(aName, "Initialized tree op with null name.");
297 NS_PRECONDITION(aTarget, "Initialized tree op with null target node.");
298 mOpCode = aFromNetwork ?
299 eTreeOpCreateElementNetwork :
300 eTreeOpCreateElementNotNetwork;
301 mFour.integer = aNamespace;
302 mOne.node = static_cast<nsIContent**>(aTarget);
303 mTwo.atom = aName;
304 if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
305 mThree.attributes = nullptr;
306 } else {
307 mThree.attributes = aAttributes;
311 inline void Init(eHtml5TreeOperation aOpCode,
312 char16_t* aBuffer,
313 int32_t aLength,
314 nsIContentHandle* aStackParent,
315 nsIContentHandle* aTable)
317 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
318 "Op code must be uninitialized when initializing.");
319 NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
320 mOpCode = aOpCode;
321 mOne.node = static_cast<nsIContent**>(aStackParent);
322 mTwo.unicharPtr = aBuffer;
323 mThree.node = static_cast<nsIContent**>(aTable);
324 mFour.integer = aLength;
327 inline void Init(eHtml5TreeOperation aOpCode,
328 char16_t* aBuffer,
329 int32_t aLength,
330 nsIContentHandle* aParent)
332 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
333 "Op code must be uninitialized when initializing.");
334 NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
335 mOpCode = aOpCode;
336 mOne.node = static_cast<nsIContent**>(aParent);
337 mTwo.unicharPtr = aBuffer;
338 mFour.integer = aLength;
341 inline void Init(eHtml5TreeOperation aOpCode,
342 char16_t* aBuffer,
343 int32_t aLength)
345 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
346 "Op code must be uninitialized when initializing.");
347 NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
348 mOpCode = aOpCode;
349 mTwo.unicharPtr = aBuffer;
350 mFour.integer = aLength;
353 inline void Init(nsIContentHandle* aElement,
354 nsHtml5HtmlAttributes* aAttributes)
356 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
357 "Op code must be uninitialized when initializing.");
358 NS_PRECONDITION(aElement, "Initialized tree op with null element.");
359 mOpCode = eTreeOpAddAttributes;
360 mOne.node = static_cast<nsIContent**>(aElement);
361 mTwo.attributes = aAttributes;
364 inline void Init(nsIAtom* aName,
365 const nsAString& aPublicId,
366 const nsAString& aSystemId)
368 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
369 "Op code must be uninitialized when initializing.");
370 mOpCode = eTreeOpAppendDoctypeToDocument;
371 mOne.atom = aName;
372 mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId);
375 inline void Init(nsIContentHandle* aElement,
376 const char* aMsgId,
377 nsIAtom* aAtom,
378 nsIAtom* aOtherAtom)
380 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
381 "Op code must be uninitialized when initializing.");
382 mOpCode = eTreeOpAddError;
383 mOne.node = static_cast<nsIContent**>(aElement);
384 mTwo.charPtr = (char*)aMsgId;
385 mThree.atom = aAtom;
386 mFour.atom = aOtherAtom;
389 inline void Init(nsIContentHandle* aElement,
390 const char* aMsgId,
391 nsIAtom* aAtom)
393 Init(aElement, aMsgId, aAtom, nullptr);
396 inline void Init(nsIContentHandle* aElement,
397 const char* aMsgId)
399 Init(aElement, aMsgId, nullptr, nullptr);
402 inline void Init(const char* aMsgId,
403 bool aError,
404 int32_t aLineNumber)
406 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
407 "Op code must be uninitialized when initializing.");
408 mOpCode = eTreeOpMaybeComplainAboutCharset;
409 mOne.charPtr = const_cast<char*>(aMsgId);
410 mTwo.integer = aError;
411 mThree.integer = aLineNumber;
414 inline void Init(eHtml5TreeOperation aOpCode, const nsAString& aString)
416 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
417 "Op code must be uninitialized when initializing.");
419 char16_t* str = NS_StringCloneData(aString);
420 mOpCode = aOpCode;
421 mOne.unicharPtr = str;
424 inline void Init(eHtml5TreeOperation aOpCode,
425 nsIContentHandle* aNode,
426 int32_t aInt)
428 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
429 "Op code must be uninitialized when initializing.");
430 NS_PRECONDITION(aNode, "Initialized tree op with null node.");
431 mOpCode = aOpCode;
432 mOne.node = static_cast<nsIContent**>(aNode);
433 mFour.integer = aInt;
436 inline void Init(nsresult aRv)
438 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
439 "Op code must be uninitialized when initializing.");
440 NS_PRECONDITION(NS_FAILED(aRv), "Initialized tree op with non-failure.");
441 mOpCode = eTreeOpMarkAsBroken;
442 mOne.result = aRv;
445 inline void InitAddClass(nsIContentHandle* aNode, const char16_t* aClass)
447 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
448 "Op code must be uninitialized when initializing.");
449 NS_PRECONDITION(aNode, "Initialized tree op with null node.");
450 NS_PRECONDITION(aClass, "Initialized tree op with null string.");
451 // aClass must be a literal string that does not need freeing
452 mOpCode = eTreeOpAddClass;
453 mOne.node = static_cast<nsIContent**>(aNode);
454 mTwo.unicharPtr = (char16_t*)aClass;
457 inline void InitAddLineNumberId(nsIContentHandle* aNode,
458 const int32_t aLineNumber)
460 NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
461 "Op code must be uninitialized when initializing.");
462 NS_PRECONDITION(aNode, "Initialized tree op with null node.");
463 NS_PRECONDITION(aLineNumber > 0, "Initialized tree op with line number.");
464 // aClass must be a literal string that does not need freeing
465 mOpCode = eTreeOpAddLineNumberId;
466 mOne.node = static_cast<nsIContent**>(aNode);
467 mFour.integer = aLineNumber;
470 inline bool IsRunScript()
472 return mOpCode == eTreeOpRunScript;
475 inline void SetSnapshot(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine)
477 NS_ASSERTION(IsRunScript(),
478 "Setting a snapshot for a tree operation other than eTreeOpRunScript!");
479 NS_PRECONDITION(aSnapshot, "Initialized tree op with null snapshot.");
480 mTwo.state = aSnapshot;
481 mFour.integer = aLine;
484 nsresult Perform(nsHtml5TreeOpExecutor* aBuilder,
485 nsIContent** aScriptElement);
487 private:
488 // possible optimization:
489 // Make the queue take items the size of pointer and make the op code
490 // decide how many operands it dequeues after it.
491 eHtml5TreeOperation mOpCode;
492 union {
493 nsIContent** node;
494 nsIAtom* atom;
495 nsHtml5HtmlAttributes* attributes;
496 nsHtml5DocumentMode mode;
497 char16_t* unicharPtr;
498 char* charPtr;
499 nsHtml5TreeOperationStringPair* stringPair;
500 nsAHtml5TreeBuilderState* state;
501 int32_t integer;
502 nsresult result;
503 } mOne, mTwo, mThree, mFour;
506 #endif // nsHtml5TreeOperation_h