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/dom/ShadowRootBinding.h"
12 #include "mozilla/NotNull.h"
13 #include "mozilla/Variant.h"
14 #include "nsCharsetSource.h"
17 class nsHtml5TreeOpExecutor
;
18 class nsHtml5DocumentBuilder
;
25 } // namespace mozilla
27 struct uninitialized
{};
31 nsIContent
** mElement
;
33 explicit opDetach(nsIContentHandle
* aElement
) {
34 mElement
= static_cast<nsIContent
**>(aElement
);
41 mozilla::dom::FromParser mFromNetwork
;
43 explicit opAppend(nsIContentHandle
* aChild
, nsIContentHandle
* aParent
,
44 mozilla::dom::FromParser aFromNetwork
)
45 : mFromNetwork(aFromNetwork
) {
46 mChild
= static_cast<nsIContent
**>(aChild
);
47 mParent
= static_cast<nsIContent
**>(aParent
);
51 struct opAppendChildrenToNewParent
{
52 nsIContent
** mOldParent
;
53 nsIContent
** mNewParent
;
55 explicit opAppendChildrenToNewParent(nsIContentHandle
* aOldParent
,
56 nsIContentHandle
* aNewParent
) {
57 mOldParent
= static_cast<nsIContent
**>(aOldParent
);
58 mNewParent
= static_cast<nsIContent
**>(aNewParent
);
62 struct opFosterParent
{
64 nsIContent
** mStackParent
;
67 explicit opFosterParent(nsIContentHandle
* aChild
,
68 nsIContentHandle
* aStackParent
,
69 nsIContentHandle
* aTable
) {
70 mChild
= static_cast<nsIContent
**>(aChild
);
71 mStackParent
= static_cast<nsIContent
**>(aStackParent
);
72 mTable
= static_cast<nsIContent
**>(aTable
);
76 struct opAppendToDocument
{
77 nsIContent
** mContent
;
79 explicit opAppendToDocument(nsIContentHandle
* aContent
) {
80 mContent
= static_cast<nsIContent
**>(aContent
);
84 struct opAddAttributes
{
85 nsIContent
** mElement
;
86 nsHtml5HtmlAttributes
* mAttributes
;
88 explicit opAddAttributes(nsIContentHandle
* aElement
,
89 nsHtml5HtmlAttributes
* aAttributes
)
90 : mAttributes(aAttributes
) {
91 mElement
= static_cast<nsIContent
**>(aElement
);
95 struct opCreateHTMLElement
{
96 nsIContent
** mContent
;
98 nsHtml5HtmlAttributes
* mAttributes
;
99 mozilla::dom::HTMLContentCreatorFunction mCreator
;
100 nsIContent
** mIntendedParent
;
101 mozilla::dom::FromParser mFromNetwork
;
103 explicit opCreateHTMLElement(
104 nsIContentHandle
* aContent
, nsAtom
* aName
,
105 nsHtml5HtmlAttributes
* aAttributes
,
106 mozilla::dom::HTMLContentCreatorFunction aCreator
,
107 nsIContentHandle
* aIntendedParent
, mozilla::dom::FromParser mFromNetwork
)
109 mAttributes(aAttributes
),
111 mFromNetwork(mFromNetwork
) {
112 mContent
= static_cast<nsIContent
**>(aContent
);
113 mIntendedParent
= static_cast<nsIContent
**>(aIntendedParent
);
115 if (mAttributes
== nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
) {
116 mAttributes
= nullptr;
121 struct opCreateSVGElement
{
122 nsIContent
** mContent
;
124 nsHtml5HtmlAttributes
* mAttributes
;
125 mozilla::dom::SVGContentCreatorFunction mCreator
;
126 nsIContent
** mIntendedParent
;
127 mozilla::dom::FromParser mFromNetwork
;
129 explicit opCreateSVGElement(nsIContentHandle
* aContent
, nsAtom
* aName
,
130 nsHtml5HtmlAttributes
* aAttributes
,
131 mozilla::dom::SVGContentCreatorFunction aCreator
,
132 nsIContentHandle
* aIntendedParent
,
133 mozilla::dom::FromParser mFromNetwork
)
135 mAttributes(aAttributes
),
137 mFromNetwork(mFromNetwork
) {
138 mContent
= static_cast<nsIContent
**>(aContent
);
139 mIntendedParent
= static_cast<nsIContent
**>(aIntendedParent
);
141 if (mAttributes
== nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
) {
142 mAttributes
= nullptr;
147 struct opCreateMathMLElement
{
148 nsIContent
** mContent
;
150 nsHtml5HtmlAttributes
* mAttributes
;
151 nsIContent
** mIntendedParent
;
153 explicit opCreateMathMLElement(nsIContentHandle
* aContent
, nsAtom
* aName
,
154 nsHtml5HtmlAttributes
* aAttributes
,
155 nsIContentHandle
* aIntendedParent
)
156 : mName(aName
), mAttributes(aAttributes
) {
157 mContent
= static_cast<nsIContent
**>(aContent
);
158 mIntendedParent
= static_cast<nsIContent
**>(aIntendedParent
);
160 if (mAttributes
== nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES
) {
161 mAttributes
= nullptr;
166 struct opSetFormElement
{
167 nsIContent
** mContent
;
168 nsIContent
** mFormElement
;
170 explicit opSetFormElement(nsIContentHandle
* aContent
,
171 nsIContentHandle
* aFormElement
) {
172 mContent
= static_cast<nsIContent
**>(aContent
);
173 mFormElement
= static_cast<nsIContent
**>(aFormElement
);
177 struct opAppendText
{
178 nsIContent
** mParent
;
182 explicit opAppendText(nsIContentHandle
* aParent
, char16_t
* aBuffer
,
184 : mBuffer(aBuffer
), mLength(aLength
) {
185 mParent
= static_cast<nsIContent
**>(aParent
);
189 struct opFosterParentText
{
190 nsIContent
** mStackParent
;
195 explicit opFosterParentText(nsIContentHandle
* aStackParent
, char16_t
* aBuffer
,
196 nsIContentHandle
* aTable
, int32_t aLength
)
197 : mBuffer(aBuffer
), mLength(aLength
) {
198 mStackParent
= static_cast<nsIContent
**>(aStackParent
);
199 mTable
= static_cast<nsIContent
**>(aTable
);
203 struct opAppendComment
{
204 nsIContent
** mParent
;
208 explicit opAppendComment(nsIContentHandle
* aParent
, char16_t
* aBuffer
,
210 : mBuffer(aBuffer
), mLength(aLength
) {
211 mParent
= static_cast<nsIContent
**>(aParent
);
215 struct opAppendCommentToDocument
{
219 explicit opAppendCommentToDocument(char16_t
* aBuffer
, int32_t aLength
)
220 : mBuffer(aBuffer
), mLength(aLength
){};
223 class nsHtml5TreeOperationStringPair
{
229 nsHtml5TreeOperationStringPair(const nsAString
& aPublicId
,
230 const nsAString
& aSystemId
)
231 : mPublicId(aPublicId
), mSystemId(aSystemId
) {
232 MOZ_COUNT_CTOR(nsHtml5TreeOperationStringPair
);
235 ~nsHtml5TreeOperationStringPair() {
236 MOZ_COUNT_DTOR(nsHtml5TreeOperationStringPair
);
239 inline void Get(nsAString
& aPublicId
, nsAString
& aSystemId
) {
240 aPublicId
.Assign(mPublicId
);
241 aSystemId
.Assign(mSystemId
);
245 struct opAppendDoctypeToDocument
{
247 nsHtml5TreeOperationStringPair
* mStringPair
;
249 explicit opAppendDoctypeToDocument(nsAtom
* aName
, const nsAString
& aPublicId
,
250 const nsAString
& aSystemId
) {
253 mStringPair
= new nsHtml5TreeOperationStringPair(aPublicId
, aSystemId
);
257 struct opGetDocumentFragmentForTemplate
{
258 nsIContent
** mTemplate
;
259 nsIContent
** mFragHandle
;
261 explicit opGetDocumentFragmentForTemplate(nsIContentHandle
* aTemplate
,
262 nsIContentHandle
* aFragHandle
) {
263 mTemplate
= static_cast<nsIContent
**>(aTemplate
);
264 mFragHandle
= static_cast<nsIContent
**>(aFragHandle
);
268 struct opSetDocumentFragmentForTemplate
{
269 nsIContent
** mTemplate
;
270 nsIContent
** mFragment
;
272 explicit opSetDocumentFragmentForTemplate(nsIContentHandle
* aTemplate
,
273 nsIContentHandle
* aFragment
) {
274 mTemplate
= static_cast<nsIContent
**>(aTemplate
);
275 mFragment
= static_cast<nsIContent
**>(aFragment
);
279 struct opGetShadowRootFromHost
{
281 nsIContent
** mFragHandle
;
282 nsIContent
** mTemplateNode
;
283 mozilla::dom::ShadowRootMode mShadowRootMode
;
284 bool mShadowRootIsClonable
;
285 bool mShadowRootDelegatesFocus
;
287 explicit opGetShadowRootFromHost(nsIContentHandle
* aHost
,
288 nsIContentHandle
* aFragHandle
,
289 nsIContentHandle
* aTemplateNode
,
290 mozilla::dom::ShadowRootMode aShadowRootMode
,
291 bool aShadowRootIsClonable
,
292 bool aShadowRootDelegatesFocus
) {
293 mHost
= static_cast<nsIContent
**>(aHost
);
294 mFragHandle
= static_cast<nsIContent
**>(aFragHandle
);
295 mTemplateNode
= static_cast<nsIContent
**>(aTemplateNode
);
296 mShadowRootMode
= aShadowRootMode
;
297 mShadowRootIsClonable
= aShadowRootIsClonable
;
298 mShadowRootDelegatesFocus
= aShadowRootDelegatesFocus
;
302 struct opGetFosterParent
{
304 nsIContent
** mStackParent
;
305 nsIContent
** mParentHandle
;
307 explicit opGetFosterParent(nsIContentHandle
* aTable
,
308 nsIContentHandle
* aStackParent
,
309 nsIContentHandle
* aParentHandle
) {
310 mTable
= static_cast<nsIContent
**>(aTable
);
311 mStackParent
= static_cast<nsIContent
**>(aStackParent
);
312 mParentHandle
= static_cast<nsIContent
**>(aParentHandle
);
316 // Gecko-specific on-pop ops
317 struct opMarkAsBroken
{
320 explicit opMarkAsBroken(nsresult aResult
) : mResult(aResult
){};
323 struct opRunScriptThatMayDocumentWriteOrBlock
{
324 nsIContent
** mElement
;
325 nsAHtml5TreeBuilderState
* mBuilderState
;
328 explicit opRunScriptThatMayDocumentWriteOrBlock(
329 nsIContentHandle
* aElement
, nsAHtml5TreeBuilderState
* aBuilderState
)
330 : mBuilderState(aBuilderState
), mLineNumber(0) {
331 mElement
= static_cast<nsIContent
**>(aElement
);
335 struct opRunScriptThatCannotDocumentWriteOrBlock
{
336 nsIContent
** mElement
;
338 explicit opRunScriptThatCannotDocumentWriteOrBlock(
339 nsIContentHandle
* aElement
) {
340 mElement
= static_cast<nsIContent
**>(aElement
);
344 struct opPreventScriptExecution
{
345 nsIContent
** mElement
;
347 explicit opPreventScriptExecution(nsIContentHandle
* aElement
) {
348 mElement
= static_cast<nsIContent
**>(aElement
);
352 struct opDoneAddingChildren
{
353 nsIContent
** mElement
;
355 explicit opDoneAddingChildren(nsIContentHandle
* aElement
) {
356 mElement
= static_cast<nsIContent
**>(aElement
);
360 struct opDoneCreatingElement
{
361 nsIContent
** mElement
;
363 explicit opDoneCreatingElement(nsIContentHandle
* aElement
) {
364 mElement
= static_cast<nsIContent
**>(aElement
);
368 struct opUpdateCharsetSource
{
369 nsCharsetSource mCharsetSource
;
371 explicit opUpdateCharsetSource(nsCharsetSource aCharsetSource
)
372 : mCharsetSource(aCharsetSource
){};
375 struct opCharsetSwitchTo
{
376 const mozilla::Encoding
* mEncoding
;
377 int32_t mCharsetSource
;
380 explicit opCharsetSwitchTo(const mozilla::Encoding
* aEncoding
,
381 int32_t aCharsetSource
, int32_t aLineNumber
)
382 : mEncoding(aEncoding
),
383 mCharsetSource(aCharsetSource
),
384 mLineNumber(aLineNumber
){};
387 struct opUpdateStyleSheet
{
388 nsIContent
** mElement
;
390 explicit opUpdateStyleSheet(nsIContentHandle
* aElement
) {
391 mElement
= static_cast<nsIContent
**>(aElement
);
395 struct opProcessOfflineManifest
{
398 explicit opProcessOfflineManifest(char16_t
* aUrl
) : mUrl(aUrl
){};
401 struct opMarkMalformedIfScript
{
402 nsIContent
** mElement
;
404 explicit opMarkMalformedIfScript(nsIContentHandle
* aElement
) {
405 mElement
= static_cast<nsIContent
**>(aElement
);
409 struct opStreamEnded
{};
411 struct opSetStyleLineNumber
{
412 nsIContent
** mContent
;
415 explicit opSetStyleLineNumber(nsIContentHandle
* aContent
, int32_t aLineNumber
)
416 : mLineNumber(aLineNumber
) {
417 mContent
= static_cast<nsIContent
**>(aContent
);
421 struct opSetScriptLineAndColumnNumberAndFreeze
{
422 nsIContent
** mContent
;
424 int32_t mColumnNumber
;
426 explicit opSetScriptLineAndColumnNumberAndFreeze(nsIContentHandle
* aContent
,
428 int32_t aColumnNumber
)
429 : mLineNumber(aLineNumber
), mColumnNumber(aColumnNumber
) {
430 mContent
= static_cast<nsIContent
**>(aContent
);
435 nsIContent
** mElement
;
437 explicit opSvgLoad(nsIContentHandle
* aElement
) {
438 mElement
= static_cast<nsIContent
**>(aElement
);
442 struct opMaybeComplainAboutCharset
{
447 explicit opMaybeComplainAboutCharset(char* aMsgId
, bool aError
,
449 : mMsgId(aMsgId
), mError(aError
), mLineNumber(aLineNumber
){};
452 struct opMaybeComplainAboutDeepTree
{
455 explicit opMaybeComplainAboutDeepTree(int32_t aLineNumber
)
456 : mLineNumber(aLineNumber
){};
460 nsIContent
** mElement
;
463 explicit opAddClass(nsIContentHandle
* aElement
, char16_t
* aClass
)
465 mElement
= static_cast<nsIContent
**>(aElement
);
469 struct opAddViewSourceHref
{
470 nsIContent
** mElement
;
474 explicit opAddViewSourceHref(nsIContentHandle
* aElement
, char16_t
* aBuffer
,
476 : mBuffer(aBuffer
), mLength(aLength
) {
477 mElement
= static_cast<nsIContent
**>(aElement
);
481 struct opAddViewSourceBase
{
485 explicit opAddViewSourceBase(char16_t
* aBuffer
, int32_t aLength
)
486 : mBuffer(aBuffer
), mLength(aLength
){};
489 struct opAddErrorType
{
490 nsIContent
** mElement
;
495 explicit opAddErrorType(nsIContentHandle
* aElement
, char* aMsgId
,
496 nsAtom
* aName
= nullptr, nsAtom
* aOther
= nullptr)
497 : mMsgId(aMsgId
), mName(aName
), mOther(aOther
) {
498 mElement
= static_cast<nsIContent
**>(aElement
);
508 struct opAddLineNumberId
{
509 nsIContent
** mElement
;
512 explicit opAddLineNumberId(nsIContentHandle
* aElement
, int32_t aLineNumber
)
513 : mLineNumber(aLineNumber
) {
514 mElement
= static_cast<nsIContent
**>(aElement
);
518 struct opStartLayout
{};
520 struct opEnableEncodingMenu
{};
522 typedef mozilla::Variant
<
525 opAppend
, opDetach
, opAppendChildrenToNewParent
, opFosterParent
,
526 opAppendToDocument
, opAddAttributes
, nsHtml5DocumentMode
,
527 opCreateHTMLElement
, opCreateSVGElement
, opCreateMathMLElement
,
528 opSetFormElement
, opAppendText
, opFosterParentText
, opAppendComment
,
529 opAppendCommentToDocument
, opAppendDoctypeToDocument
,
530 opGetDocumentFragmentForTemplate
, opSetDocumentFragmentForTemplate
,
531 opGetShadowRootFromHost
, opGetFosterParent
,
532 // Gecko-specific on-pop ops
533 opMarkAsBroken
, opRunScriptThatMayDocumentWriteOrBlock
,
534 opRunScriptThatCannotDocumentWriteOrBlock
, opPreventScriptExecution
,
535 opDoneAddingChildren
, opDoneCreatingElement
, opUpdateCharsetSource
,
536 opCharsetSwitchTo
, opUpdateStyleSheet
, opProcessOfflineManifest
,
537 opMarkMalformedIfScript
, opStreamEnded
, opSetStyleLineNumber
,
538 opSetScriptLineAndColumnNumberAndFreeze
, opSvgLoad
,
539 opMaybeComplainAboutCharset
, opMaybeComplainAboutDeepTree
, opAddClass
,
540 opAddViewSourceHref
, opAddViewSourceBase
, opAddErrorType
, opAddLineNumberId
,
541 opStartLayout
, opEnableEncodingMenu
>
544 class nsHtml5TreeOperation final
{
545 template <typename T
>
546 using NotNull
= mozilla::NotNull
<T
>;
547 using Encoding
= mozilla::Encoding
;
550 static nsresult
AppendTextToTextNode(const char16_t
* aBuffer
,
552 mozilla::dom::Text
* aTextNode
,
553 nsHtml5DocumentBuilder
* aBuilder
);
555 static nsresult
AppendText(const char16_t
* aBuffer
, uint32_t aLength
,
557 nsHtml5DocumentBuilder
* aBuilder
);
559 static nsresult
Append(nsIContent
* aNode
, nsIContent
* aParent
,
560 nsHtml5DocumentBuilder
* aBuilder
);
562 static nsresult
Append(nsIContent
* aNode
, nsIContent
* aParent
,
563 mozilla::dom::FromParser aFromParser
,
564 nsHtml5DocumentBuilder
* aBuilder
);
566 static nsresult
AppendToDocument(nsIContent
* aNode
,
567 nsHtml5DocumentBuilder
* aBuilder
);
569 static void Detach(nsIContent
* aNode
, nsHtml5DocumentBuilder
* aBuilder
);
571 static nsresult
AppendChildrenToNewParent(nsIContent
* aNode
,
573 nsHtml5DocumentBuilder
* aBuilder
);
575 static nsresult
FosterParent(nsIContent
* aNode
, nsIContent
* aParent
,
577 nsHtml5DocumentBuilder
* aBuilder
);
579 static nsresult
AddAttributes(nsIContent
* aNode
,
580 nsHtml5HtmlAttributes
* aAttributes
,
581 nsHtml5DocumentBuilder
* aBuilder
);
583 static void SetHTMLElementAttributes(mozilla::dom::Element
* aElement
,
585 nsHtml5HtmlAttributes
* aAttributes
);
587 static nsIContent
* CreateHTMLElement(
588 nsAtom
* aName
, nsHtml5HtmlAttributes
* aAttributes
,
589 mozilla::dom::FromParser aFromParser
, nsNodeInfoManager
* aNodeInfoManager
,
590 nsHtml5DocumentBuilder
* aBuilder
,
591 mozilla::dom::HTMLContentCreatorFunction aCreator
);
593 static nsIContent
* CreateSVGElement(
594 nsAtom
* aName
, nsHtml5HtmlAttributes
* aAttributes
,
595 mozilla::dom::FromParser aFromParser
, nsNodeInfoManager
* aNodeInfoManager
,
596 nsHtml5DocumentBuilder
* aBuilder
,
597 mozilla::dom::SVGContentCreatorFunction aCreator
);
599 static nsIContent
* CreateMathMLElement(nsAtom
* aName
,
600 nsHtml5HtmlAttributes
* aAttributes
,
601 nsNodeInfoManager
* aNodeInfoManager
,
602 nsHtml5DocumentBuilder
* aBuilder
);
604 static void SetFormElement(nsIContent
* aNode
, nsIContent
* aParent
);
606 static nsresult
AppendIsindexPrompt(nsIContent
* parent
,
607 nsHtml5DocumentBuilder
* aBuilder
);
609 static nsresult
FosterParentText(nsIContent
* aStackParent
, char16_t
* aBuffer
,
610 uint32_t aLength
, nsIContent
* aTable
,
611 nsHtml5DocumentBuilder
* aBuilder
);
613 static nsresult
AppendComment(nsIContent
* aParent
, char16_t
* aBuffer
,
615 nsHtml5DocumentBuilder
* aBuilder
);
617 static nsresult
AppendCommentToDocument(char16_t
* aBuffer
, int32_t aLength
,
618 nsHtml5DocumentBuilder
* aBuilder
);
620 static nsresult
AppendDoctypeToDocument(nsAtom
* aName
,
621 const nsAString
& aPublicId
,
622 const nsAString
& aSystemId
,
623 nsHtml5DocumentBuilder
* aBuilder
);
625 static nsIContent
* GetDocumentFragmentForTemplate(nsIContent
* aNode
);
626 static void SetDocumentFragmentForTemplate(nsIContent
* aNode
,
627 nsIContent
* aDocumentFragment
);
629 static nsIContent
* GetFosterParent(nsIContent
* aTable
,
630 nsIContent
* aStackParent
);
632 static void PreventScriptExecution(nsIContent
* aNode
);
634 static void DoneAddingChildren(nsIContent
* aNode
);
636 static void DoneCreatingElement(nsIContent
* aNode
);
638 static void SvgLoad(nsIContent
* aNode
);
640 static void MarkMalformedIfScript(nsIContent
* aNode
);
642 nsHtml5TreeOperation();
644 ~nsHtml5TreeOperation();
646 inline void Init(const treeOperation
& aOperation
) {
647 NS_ASSERTION(mOperation
.is
<uninitialized
>(),
648 "Op code must be uninitialized when initializing.");
649 mOperation
= aOperation
;
652 inline bool IsRunScriptThatMayDocumentWriteOrBlock() {
653 return mOperation
.is
<opRunScriptThatMayDocumentWriteOrBlock
>();
656 inline bool IsMarkAsBroken() { return mOperation
.is
<opMarkAsBroken
>(); }
658 inline void SetSnapshot(nsAHtml5TreeBuilderState
* aSnapshot
, int32_t aLine
) {
660 IsRunScriptThatMayDocumentWriteOrBlock(),
661 "Setting a snapshot for a tree operation other than eTreeOpRunScript!");
662 MOZ_ASSERT(aSnapshot
, "Initialized tree op with null snapshot.");
663 opRunScriptThatMayDocumentWriteOrBlock data
=
664 mOperation
.as
<opRunScriptThatMayDocumentWriteOrBlock
>();
665 data
.mBuilderState
= aSnapshot
;
666 data
.mLineNumber
= aLine
;
667 mOperation
= mozilla::AsVariant(data
);
670 nsresult
Perform(nsHtml5TreeOpExecutor
* aBuilder
, nsIContent
** aScriptElement
,
671 bool* aInterrupted
, bool* aStreamEnded
);
674 nsHtml5TreeOperation(const nsHtml5TreeOperation
&) = delete;
675 nsHtml5TreeOperation
& operator=(const nsHtml5TreeOperation
&) = delete;
677 treeOperation mOperation
;
680 #endif // nsHtml5TreeOperation_h