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 "mozilla/dom/FromParser.h"
11 #include "mozilla/NotNull.h"
12 #include "mozilla/Variant.h"
13 #include "nsCharsetSource.h"
16 class nsHtml5TreeOpExecutor
;
17 class nsHtml5DocumentBuilder
;
24 } // namespace mozilla
26 struct uninitialized
{};
30 nsIContent
** mElement
;
32 explicit opDetach(nsIContentHandle
* aElement
) {
33 mElement
= static_cast<nsIContent
**>(aElement
);
40 mozilla::dom::FromParser mFromNetwork
;
42 explicit opAppend(nsIContentHandle
* aChild
, nsIContentHandle
* aParent
,
43 mozilla::dom::FromParser aFromNetwork
)
44 : mFromNetwork(aFromNetwork
) {
45 mChild
= static_cast<nsIContent
**>(aChild
);
46 mParent
= static_cast<nsIContent
**>(aParent
);
50 struct opAppendChildrenToNewParent
{
51 nsIContent
** mOldParent
;
52 nsIContent
** mNewParent
;
54 explicit opAppendChildrenToNewParent(nsIContentHandle
* aOldParent
,
55 nsIContentHandle
* aNewParent
) {
56 mOldParent
= static_cast<nsIContent
**>(aOldParent
);
57 mNewParent
= static_cast<nsIContent
**>(aNewParent
);
61 struct opFosterParent
{
63 nsIContent
** mStackParent
;
66 explicit opFosterParent(nsIContentHandle
* aChild
,
67 nsIContentHandle
* aStackParent
,
68 nsIContentHandle
* aTable
) {
69 mChild
= static_cast<nsIContent
**>(aChild
);
70 mStackParent
= static_cast<nsIContent
**>(aStackParent
);
71 mTable
= static_cast<nsIContent
**>(aTable
);
75 struct opAppendToDocument
{
76 nsIContent
** mContent
;
78 explicit opAppendToDocument(nsIContentHandle
* aContent
) {
79 mContent
= static_cast<nsIContent
**>(aContent
);
83 struct opAddAttributes
{
84 nsIContent
** mElement
;
85 nsHtml5HtmlAttributes
* mAttributes
;
87 explicit opAddAttributes(nsIContentHandle
* aElement
,
88 nsHtml5HtmlAttributes
* aAttributes
)
89 : mAttributes(aAttributes
) {
90 mElement
= static_cast<nsIContent
**>(aElement
);
94 struct opCreateHTMLElement
{
95 nsIContent
** mContent
;
97 nsHtml5HtmlAttributes
* mAttributes
;
98 mozilla::dom::HTMLContentCreatorFunction mCreator
;
99 nsIContent
** mIntendedParent
;
100 mozilla::dom::FromParser mFromNetwork
;
102 explicit opCreateHTMLElement(
103 nsIContentHandle
* aContent
, nsAtom
* aName
,
104 nsHtml5HtmlAttributes
* aAttributes
,
105 mozilla::dom::HTMLContentCreatorFunction aCreator
,
106 nsIContentHandle
* aIntendedParent
, mozilla::dom::FromParser mFromNetwork
)
108 mAttributes(aAttributes
),
110 mFromNetwork(mFromNetwork
) {
111 mContent
= static_cast<nsIContent
**>(aContent
);
112 mIntendedParent
= static_cast<nsIContent
**>(aIntendedParent
);
114 if (mAttributes
== nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
) {
115 mAttributes
= nullptr;
120 struct opCreateSVGElement
{
121 nsIContent
** mContent
;
123 nsHtml5HtmlAttributes
* mAttributes
;
124 mozilla::dom::SVGContentCreatorFunction mCreator
;
125 nsIContent
** mIntendedParent
;
126 mozilla::dom::FromParser mFromNetwork
;
128 explicit opCreateSVGElement(nsIContentHandle
* aContent
, nsAtom
* aName
,
129 nsHtml5HtmlAttributes
* aAttributes
,
130 mozilla::dom::SVGContentCreatorFunction aCreator
,
131 nsIContentHandle
* aIntendedParent
,
132 mozilla::dom::FromParser mFromNetwork
)
134 mAttributes(aAttributes
),
136 mFromNetwork(mFromNetwork
) {
137 mContent
= static_cast<nsIContent
**>(aContent
);
138 mIntendedParent
= static_cast<nsIContent
**>(aIntendedParent
);
140 if (mAttributes
== nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
) {
141 mAttributes
= nullptr;
146 struct opCreateMathMLElement
{
147 nsIContent
** mContent
;
149 nsHtml5HtmlAttributes
* mAttributes
;
150 nsIContent
** mIntendedParent
;
152 explicit opCreateMathMLElement(nsIContentHandle
* aContent
, nsAtom
* aName
,
153 nsHtml5HtmlAttributes
* aAttributes
,
154 nsIContentHandle
* aIntendedParent
)
155 : mName(aName
), mAttributes(aAttributes
) {
156 mContent
= static_cast<nsIContent
**>(aContent
);
157 mIntendedParent
= static_cast<nsIContent
**>(aIntendedParent
);
159 if (mAttributes
== nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
) {
160 mAttributes
= nullptr;
165 struct opSetFormElement
{
166 nsIContent
** mContent
;
167 nsIContent
** mFormElement
;
169 explicit opSetFormElement(nsIContentHandle
* aContent
,
170 nsIContentHandle
* aFormElement
) {
171 mContent
= static_cast<nsIContent
**>(aContent
);
172 mFormElement
= static_cast<nsIContent
**>(aFormElement
);
176 struct opAppendText
{
177 nsIContent
** mParent
;
181 explicit opAppendText(nsIContentHandle
* aParent
, char16_t
* aBuffer
,
183 : mBuffer(aBuffer
), mLength(aLength
) {
184 mParent
= static_cast<nsIContent
**>(aParent
);
188 struct opFosterParentText
{
189 nsIContent
** mStackParent
;
194 explicit opFosterParentText(nsIContentHandle
* aStackParent
, char16_t
* aBuffer
,
195 nsIContentHandle
* aTable
, int32_t aLength
)
196 : mBuffer(aBuffer
), mLength(aLength
) {
197 mStackParent
= static_cast<nsIContent
**>(aStackParent
);
198 mTable
= static_cast<nsIContent
**>(aTable
);
202 struct opAppendComment
{
203 nsIContent
** mParent
;
207 explicit opAppendComment(nsIContentHandle
* aParent
, char16_t
* aBuffer
,
209 : mBuffer(aBuffer
), mLength(aLength
) {
210 mParent
= static_cast<nsIContent
**>(aParent
);
214 struct opAppendCommentToDocument
{
218 explicit opAppendCommentToDocument(char16_t
* aBuffer
, int32_t aLength
)
219 : mBuffer(aBuffer
), mLength(aLength
){};
222 class nsHtml5TreeOperationStringPair
{
228 nsHtml5TreeOperationStringPair(const nsAString
& aPublicId
,
229 const nsAString
& aSystemId
)
230 : mPublicId(aPublicId
), mSystemId(aSystemId
) {
231 MOZ_COUNT_CTOR(nsHtml5TreeOperationStringPair
);
234 ~nsHtml5TreeOperationStringPair() {
235 MOZ_COUNT_DTOR(nsHtml5TreeOperationStringPair
);
238 inline void Get(nsAString
& aPublicId
, nsAString
& aSystemId
) {
239 aPublicId
.Assign(mPublicId
);
240 aSystemId
.Assign(mSystemId
);
244 struct opAppendDoctypeToDocument
{
246 nsHtml5TreeOperationStringPair
* mStringPair
;
248 explicit opAppendDoctypeToDocument(nsAtom
* aName
, const nsAString
& aPublicId
,
249 const nsAString
& aSystemId
) {
252 mStringPair
= new nsHtml5TreeOperationStringPair(aPublicId
, aSystemId
);
256 struct opGetDocumentFragmentForTemplate
{
257 nsIContent
** mTemplate
;
258 nsIContent
** mFragHandle
;
260 explicit opGetDocumentFragmentForTemplate(nsIContentHandle
* aTemplate
,
261 nsIContentHandle
* aFragHandle
) {
262 mTemplate
= static_cast<nsIContent
**>(aTemplate
);
263 mFragHandle
= static_cast<nsIContent
**>(aFragHandle
);
267 struct opGetFosterParent
{
269 nsIContent
** mStackParent
;
270 nsIContent
** mParentHandle
;
272 explicit opGetFosterParent(nsIContentHandle
* aTable
,
273 nsIContentHandle
* aStackParent
,
274 nsIContentHandle
* aParentHandle
) {
275 mTable
= static_cast<nsIContent
**>(aTable
);
276 mStackParent
= static_cast<nsIContent
**>(aStackParent
);
277 mParentHandle
= static_cast<nsIContent
**>(aParentHandle
);
281 // Gecko-specific on-pop ops
282 struct opMarkAsBroken
{
285 explicit opMarkAsBroken(nsresult aResult
) : mResult(aResult
){};
289 nsIContent
** mElement
;
290 nsAHtml5TreeBuilderState
* mBuilderState
;
293 explicit opRunScript(nsIContentHandle
* aElement
,
294 nsAHtml5TreeBuilderState
* aBuilderState
)
295 : mBuilderState(aBuilderState
), mLineNumber(0) {
296 mElement
= static_cast<nsIContent
**>(aElement
);
300 struct opRunScriptAsyncDefer
{
301 nsIContent
** mElement
;
303 explicit opRunScriptAsyncDefer(nsIContentHandle
* aElement
) {
304 mElement
= static_cast<nsIContent
**>(aElement
);
308 struct opPreventScriptExecution
{
309 nsIContent
** mElement
;
311 explicit opPreventScriptExecution(nsIContentHandle
* aElement
) {
312 mElement
= static_cast<nsIContent
**>(aElement
);
316 struct opDoneAddingChildren
{
317 nsIContent
** mElement
;
319 explicit opDoneAddingChildren(nsIContentHandle
* aElement
) {
320 mElement
= static_cast<nsIContent
**>(aElement
);
324 struct opDoneCreatingElement
{
325 nsIContent
** mElement
;
327 explicit opDoneCreatingElement(nsIContentHandle
* aElement
) {
328 mElement
= static_cast<nsIContent
**>(aElement
);
332 struct opUpdateCharsetSource
{
333 nsCharsetSource mCharsetSource
;
335 explicit opUpdateCharsetSource(nsCharsetSource aCharsetSource
)
336 : mCharsetSource(aCharsetSource
){};
339 struct opCharsetSwitchTo
{
340 const mozilla::Encoding
* mEncoding
;
341 int32_t mCharsetSource
;
344 explicit opCharsetSwitchTo(const mozilla::Encoding
* aEncoding
,
345 int32_t aCharsetSource
, int32_t aLineNumber
)
346 : mEncoding(aEncoding
),
347 mCharsetSource(aCharsetSource
),
348 mLineNumber(aLineNumber
){};
351 struct opUpdateStyleSheet
{
352 nsIContent
** mElement
;
354 explicit opUpdateStyleSheet(nsIContentHandle
* aElement
) {
355 mElement
= static_cast<nsIContent
**>(aElement
);
359 struct opProcessOfflineManifest
{
362 explicit opProcessOfflineManifest(char16_t
* aUrl
) : mUrl(aUrl
){};
365 struct opMarkMalformedIfScript
{
366 nsIContent
** mElement
;
368 explicit opMarkMalformedIfScript(nsIContentHandle
* aElement
) {
369 mElement
= static_cast<nsIContent
**>(aElement
);
373 struct opStreamEnded
{};
375 struct opSetStyleLineNumber
{
376 nsIContent
** mContent
;
379 explicit opSetStyleLineNumber(nsIContentHandle
* aContent
, int32_t aLineNumber
)
380 : mLineNumber(aLineNumber
) {
381 mContent
= static_cast<nsIContent
**>(aContent
);
385 struct opSetScriptLineAndColumnNumberAndFreeze
{
386 nsIContent
** mContent
;
388 int32_t mColumnNumber
;
390 explicit opSetScriptLineAndColumnNumberAndFreeze(nsIContentHandle
* aContent
,
392 int32_t aColumnNumber
)
393 : mLineNumber(aLineNumber
), mColumnNumber(aColumnNumber
) {
394 mContent
= static_cast<nsIContent
**>(aContent
);
399 nsIContent
** mElement
;
401 explicit opSvgLoad(nsIContentHandle
* aElement
) {
402 mElement
= static_cast<nsIContent
**>(aElement
);
406 struct opMaybeComplainAboutCharset
{
411 explicit opMaybeComplainAboutCharset(char* aMsgId
, bool aError
,
413 : mMsgId(aMsgId
), mError(aError
), mLineNumber(aLineNumber
){};
416 struct opMaybeComplainAboutDeepTree
{
419 explicit opMaybeComplainAboutDeepTree(int32_t aLineNumber
)
420 : mLineNumber(aLineNumber
){};
424 nsIContent
** mElement
;
427 explicit opAddClass(nsIContentHandle
* aElement
, char16_t
* aClass
)
429 mElement
= static_cast<nsIContent
**>(aElement
);
433 struct opAddViewSourceHref
{
434 nsIContent
** mElement
;
438 explicit opAddViewSourceHref(nsIContentHandle
* aElement
, char16_t
* aBuffer
,
440 : mBuffer(aBuffer
), mLength(aLength
) {
441 mElement
= static_cast<nsIContent
**>(aElement
);
445 struct opAddViewSourceBase
{
449 explicit opAddViewSourceBase(char16_t
* aBuffer
, int32_t aLength
)
450 : mBuffer(aBuffer
), mLength(aLength
){};
453 struct opAddErrorType
{
454 nsIContent
** mElement
;
459 explicit opAddErrorType(nsIContentHandle
* aElement
, char* aMsgId
,
460 nsAtom
* aName
= nullptr, nsAtom
* aOther
= nullptr)
461 : mMsgId(aMsgId
), mName(aName
), mOther(aOther
) {
462 mElement
= static_cast<nsIContent
**>(aElement
);
472 struct opAddLineNumberId
{
473 nsIContent
** mElement
;
476 explicit opAddLineNumberId(nsIContentHandle
* aElement
, int32_t aLineNumber
)
477 : mLineNumber(aLineNumber
) {
478 mElement
= static_cast<nsIContent
**>(aElement
);
482 struct opStartLayout
{};
484 struct opEnableEncodingMenu
{};
486 typedef mozilla::Variant
<
489 opAppend
, opDetach
, opAppendChildrenToNewParent
, opFosterParent
,
490 opAppendToDocument
, opAddAttributes
, nsHtml5DocumentMode
,
491 opCreateHTMLElement
, opCreateSVGElement
, opCreateMathMLElement
,
492 opSetFormElement
, opAppendText
, opFosterParentText
, opAppendComment
,
493 opAppendCommentToDocument
, opAppendDoctypeToDocument
,
494 opGetDocumentFragmentForTemplate
, opGetFosterParent
,
495 // Gecko-specific on-pop ops
496 opMarkAsBroken
, opRunScript
, opRunScriptAsyncDefer
,
497 opPreventScriptExecution
, opDoneAddingChildren
, opDoneCreatingElement
,
498 opUpdateCharsetSource
, opCharsetSwitchTo
, opUpdateStyleSheet
,
499 opProcessOfflineManifest
, opMarkMalformedIfScript
, opStreamEnded
,
500 opSetStyleLineNumber
, opSetScriptLineAndColumnNumberAndFreeze
, opSvgLoad
,
501 opMaybeComplainAboutCharset
, opMaybeComplainAboutDeepTree
, opAddClass
,
502 opAddViewSourceHref
, opAddViewSourceBase
, opAddErrorType
, opAddLineNumberId
,
503 opStartLayout
, opEnableEncodingMenu
>
506 class nsHtml5TreeOperation final
{
507 template <typename T
>
508 using NotNull
= mozilla::NotNull
<T
>;
509 using Encoding
= mozilla::Encoding
;
512 static nsresult
AppendTextToTextNode(const char16_t
* aBuffer
,
514 mozilla::dom::Text
* aTextNode
,
515 nsHtml5DocumentBuilder
* aBuilder
);
517 static nsresult
AppendText(const char16_t
* aBuffer
, uint32_t aLength
,
519 nsHtml5DocumentBuilder
* aBuilder
);
521 static nsresult
Append(nsIContent
* aNode
, nsIContent
* aParent
,
522 nsHtml5DocumentBuilder
* aBuilder
);
524 static nsresult
Append(nsIContent
* aNode
, nsIContent
* aParent
,
525 mozilla::dom::FromParser aFromParser
,
526 nsHtml5DocumentBuilder
* aBuilder
);
528 static nsresult
AppendToDocument(nsIContent
* aNode
,
529 nsHtml5DocumentBuilder
* aBuilder
);
531 static void Detach(nsIContent
* aNode
, nsHtml5DocumentBuilder
* aBuilder
);
533 static nsresult
AppendChildrenToNewParent(nsIContent
* aNode
,
535 nsHtml5DocumentBuilder
* aBuilder
);
537 static nsresult
FosterParent(nsIContent
* aNode
, nsIContent
* aParent
,
539 nsHtml5DocumentBuilder
* aBuilder
);
541 static nsresult
AddAttributes(nsIContent
* aNode
,
542 nsHtml5HtmlAttributes
* aAttributes
,
543 nsHtml5DocumentBuilder
* aBuilder
);
545 static void SetHTMLElementAttributes(mozilla::dom::Element
* aElement
,
547 nsHtml5HtmlAttributes
* aAttributes
);
549 static nsIContent
* CreateHTMLElement(
550 nsAtom
* aName
, nsHtml5HtmlAttributes
* aAttributes
,
551 mozilla::dom::FromParser aFromParser
, nsNodeInfoManager
* aNodeInfoManager
,
552 nsHtml5DocumentBuilder
* aBuilder
,
553 mozilla::dom::HTMLContentCreatorFunction aCreator
);
555 static nsIContent
* CreateSVGElement(
556 nsAtom
* aName
, nsHtml5HtmlAttributes
* aAttributes
,
557 mozilla::dom::FromParser aFromParser
, nsNodeInfoManager
* aNodeInfoManager
,
558 nsHtml5DocumentBuilder
* aBuilder
,
559 mozilla::dom::SVGContentCreatorFunction aCreator
);
561 static nsIContent
* CreateMathMLElement(nsAtom
* aName
,
562 nsHtml5HtmlAttributes
* aAttributes
,
563 nsNodeInfoManager
* aNodeInfoManager
,
564 nsHtml5DocumentBuilder
* aBuilder
);
566 static void SetFormElement(nsIContent
* aNode
, nsIContent
* aParent
);
568 static nsresult
AppendIsindexPrompt(nsIContent
* parent
,
569 nsHtml5DocumentBuilder
* aBuilder
);
571 static nsresult
FosterParentText(nsIContent
* aStackParent
, char16_t
* aBuffer
,
572 uint32_t aLength
, nsIContent
* aTable
,
573 nsHtml5DocumentBuilder
* aBuilder
);
575 static nsresult
AppendComment(nsIContent
* aParent
, char16_t
* aBuffer
,
577 nsHtml5DocumentBuilder
* aBuilder
);
579 static nsresult
AppendCommentToDocument(char16_t
* aBuffer
, int32_t aLength
,
580 nsHtml5DocumentBuilder
* aBuilder
);
582 static nsresult
AppendDoctypeToDocument(nsAtom
* aName
,
583 const nsAString
& aPublicId
,
584 const nsAString
& aSystemId
,
585 nsHtml5DocumentBuilder
* aBuilder
);
587 static nsIContent
* GetDocumentFragmentForTemplate(nsIContent
* aNode
);
589 static nsIContent
* GetFosterParent(nsIContent
* aTable
,
590 nsIContent
* aStackParent
);
592 static void PreventScriptExecution(nsIContent
* aNode
);
594 static void DoneAddingChildren(nsIContent
* aNode
);
596 static void DoneCreatingElement(nsIContent
* aNode
);
598 static void SvgLoad(nsIContent
* aNode
);
600 static void MarkMalformedIfScript(nsIContent
* aNode
);
602 nsHtml5TreeOperation();
604 ~nsHtml5TreeOperation();
606 inline void Init(const treeOperation
& aOperation
) {
607 NS_ASSERTION(mOperation
.is
<uninitialized
>(),
608 "Op code must be uninitialized when initializing.");
609 mOperation
= aOperation
;
612 inline bool IsRunScript() { return mOperation
.is
<opRunScript
>(); }
614 inline bool IsMarkAsBroken() { return mOperation
.is
<opMarkAsBroken
>(); }
616 inline void SetSnapshot(nsAHtml5TreeBuilderState
* aSnapshot
, int32_t aLine
) {
619 "Setting a snapshot for a tree operation other than eTreeOpRunScript!");
620 MOZ_ASSERT(aSnapshot
, "Initialized tree op with null snapshot.");
621 opRunScript data
= mOperation
.as
<opRunScript
>();
622 data
.mBuilderState
= aSnapshot
;
623 data
.mLineNumber
= aLine
;
624 mOperation
= mozilla::AsVariant(data
);
627 nsresult
Perform(nsHtml5TreeOpExecutor
* aBuilder
, nsIContent
** aScriptElement
,
628 bool* aInterrupted
, bool* aStreamEnded
);
631 nsHtml5TreeOperation(const nsHtml5TreeOperation
&) = delete;
632 nsHtml5TreeOperation
& operator=(const nsHtml5TreeOperation
&) = delete;
634 treeOperation mOperation
;
637 #endif // nsHtml5TreeOperation_h