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 #include "nsHtml5Highlighter.h"
7 #include "nsHtml5AttributeName.h"
8 #include "nsHtml5Tokenizer.h"
9 #include "nsHtml5ViewSourceUtils.h"
11 #include "nsThreadUtils.h"
13 #include "mozilla/Attributes.h"
14 #include "mozilla/Preferences.h"
16 using namespace mozilla
;
18 // The old code had a limit of 16 tokens. 1300 is a number picked my measuring
19 // the size of 16 tokens on cnn.com.
20 #define NS_HTML5_HIGHLIGHTER_PRE_BREAK_THRESHOLD 1300
22 char16_t
nsHtml5Highlighter::sComment
[] = {
23 'c', 'o', 'm', 'm', 'e', 'n', 't', 0
26 char16_t
nsHtml5Highlighter::sCdata
[] = { 'c', 'd', 'a', 't', 'a', 0 };
28 char16_t
nsHtml5Highlighter::sEntity
[] = { 'e', 'n', 't', 'i', 't', 'y', 0 };
30 char16_t
nsHtml5Highlighter::sEndTag
[] = {
31 'e', 'n', 'd', '-', 't', 'a', 'g', 0
34 char16_t
nsHtml5Highlighter::sStartTag
[] = { 's', 't', 'a', 'r', 't',
35 '-', 't', 'a', 'g', 0 };
37 char16_t
nsHtml5Highlighter::sAttributeName
[] = { 'a', 't', 't', 'r', 'i',
38 'b', 'u', 't', 'e', '-',
39 'n', 'a', 'm', 'e', 0 };
41 char16_t
nsHtml5Highlighter::sAttributeValue
[] = { 'a', 't', 't', 'r', 'i', 'b',
42 'u', 't', 'e', '-', 'v', 'a',
45 char16_t
nsHtml5Highlighter::sDoctype
[] = {
46 'd', 'o', 'c', 't', 'y', 'p', 'e', 0
49 char16_t
nsHtml5Highlighter::sPi
[] = { 'p', 'i', 0 };
51 nsHtml5Highlighter::nsHtml5Highlighter(nsAHtml5TreeOpSink
* aOpSink
)
52 : mState(nsHtml5Tokenizer::DATA
)
57 , mInCharacters(false)
60 , mCurrentRun(nullptr)
64 MakeUnique
<nsIContent
* []>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH
))
68 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
71 nsHtml5Highlighter::~nsHtml5Highlighter()
73 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
77 nsHtml5Highlighter::Start(const nsAutoString
& aTitle
)
80 mOpQueue
.AppendElement()->Init(nsGkAtoms::html
, EmptyString(), EmptyString());
82 mOpQueue
.AppendElement()->Init(STANDARDS_MODE
);
84 // <html> uses NS_NewHTMLSharedElement creator
86 CreateElement(nsGkAtoms::html
, nullptr, nullptr, NS_NewHTMLSharedElement
);
87 mOpQueue
.AppendElement()->Init(eTreeOpAppendToDocument
, root
);
88 mStack
.AppendElement(root
);
90 // <head> uses NS_NewHTMLSharedElement creator
91 Push(nsGkAtoms::head
, nullptr, NS_NewHTMLSharedElement
);
94 nsHtml5ViewSourceUtils::NewMetaViewportAttributes(),
95 NS_NewHTMLMetaElement
);
98 Push(nsGkAtoms::title
, nullptr, NS_NewHTMLTitleElement
);
99 // XUL will add the "Source of: " prefix.
100 uint32_t length
= aTitle
.Length();
101 if (length
> INT32_MAX
) {
104 AppendCharacters(aTitle
.BeginReading(), 0, (int32_t)length
);
107 Push(nsGkAtoms::link
,
108 nsHtml5ViewSourceUtils::NewLinkAttributes(),
109 NS_NewHTMLLinkElement
);
111 mOpQueue
.AppendElement()->Init(eTreeOpUpdateStyleSheet
, CurrentNode());
117 Push(nsGkAtoms::body
,
118 nsHtml5ViewSourceUtils::NewBodyAttributes(),
119 NS_NewHTMLBodyElement
);
121 nsHtml5HtmlAttributes
* preAttrs
= new nsHtml5HtmlAttributes(0);
122 nsHtml5String preId
= nsHtml5Portability::newStringFromLiteral("line1");
123 preAttrs
->addAttribute(nsHtml5AttributeName::ATTR_ID
, preId
, -1);
124 Push(nsGkAtoms::pre
, preAttrs
, NS_NewHTMLPreElement
);
128 mOpQueue
.AppendElement()->Init(eTreeOpStartLayout
);
132 nsHtml5Highlighter::Transition(int32_t aState
, bool aReconsume
, int32_t aPos
)
136 case nsHtml5Tokenizer::SCRIPT_DATA
:
137 case nsHtml5Tokenizer::RAWTEXT
:
138 case nsHtml5Tokenizer::RCDATA
:
139 case nsHtml5Tokenizer::DATA
:
140 // We can transition on < and on &. Either way, we don't yet know the
141 // role of the token, so open a span without class.
142 if (aState
== nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE
) {
144 // Start another span for highlighting the ampersand
146 mAmpersand
= CurrentNode();
148 EndCharactersAndStartMarkupRun();
151 case nsHtml5Tokenizer::TAG_OPEN
:
153 case nsHtml5Tokenizer::TAG_NAME
:
154 StartSpan(sStartTag
);
156 case nsHtml5Tokenizer::DATA
:
159 case nsHtml5Tokenizer::PROCESSING_INSTRUCTION
:
164 case nsHtml5Tokenizer::TAG_NAME
:
166 case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME
:
167 EndSpanOrA(); // nsHtml5Tokenizer::TAG_NAME
169 case nsHtml5Tokenizer::SELF_CLOSING_START_TAG
:
170 EndSpanOrA(); // nsHtml5Tokenizer::TAG_NAME
171 StartSpan(); // for highlighting the slash
172 mSlash
= CurrentNode();
179 case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME
:
181 case nsHtml5Tokenizer::ATTRIBUTE_NAME
:
182 StartSpan(sAttributeName
);
184 case nsHtml5Tokenizer::SELF_CLOSING_START_TAG
:
185 StartSpan(); // for highlighting the slash
186 mSlash
= CurrentNode();
193 case nsHtml5Tokenizer::ATTRIBUTE_NAME
:
195 case nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME
:
196 case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE
:
197 EndSpanOrA(); // nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME
199 case nsHtml5Tokenizer::SELF_CLOSING_START_TAG
:
200 EndSpanOrA(); // nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME
201 StartSpan(); // for highlighting the slash
202 mSlash
= CurrentNode();
209 case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE
:
211 case nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED
:
212 case nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED
:
216 case nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED
:
224 case nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED
:
225 case nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED
:
227 case nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED
:
230 case nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE
:
232 StartSpan(); // for ampersand itself
233 mAmpersand
= CurrentNode();
236 MOZ_ASSERT_UNREACHABLE("Impossible transition.");
240 case nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED
:
242 case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME
:
244 case nsHtml5Tokenizer::SELF_CLOSING_START_TAG
:
245 StartSpan(); // for highlighting the slash
246 mSlash
= CurrentNode();
253 case nsHtml5Tokenizer::SELF_CLOSING_START_TAG
:
254 EndSpanOrA(); // end the slash highlight
256 case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME
:
263 case nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED
:
265 case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME
:
268 case nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE
:
270 StartSpan(); // for ampersand itself
271 mAmpersand
= CurrentNode();
278 case nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME
:
280 case nsHtml5Tokenizer::SELF_CLOSING_START_TAG
:
281 StartSpan(); // for highlighting the slash
282 mSlash
= CurrentNode();
284 case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE
:
286 case nsHtml5Tokenizer::ATTRIBUTE_NAME
:
287 StartSpan(sAttributeName
);
294 // most comment states are omitted, because they don't matter to
296 case nsHtml5Tokenizer::COMMENT_START
:
297 case nsHtml5Tokenizer::COMMENT_END
:
298 case nsHtml5Tokenizer::COMMENT_END_BANG
:
299 case nsHtml5Tokenizer::COMMENT_START_DASH
:
300 case nsHtml5Tokenizer::BOGUS_COMMENT
:
301 case nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN
:
302 if (aState
== nsHtml5Tokenizer::DATA
) {
307 // most cdata states are omitted, because they don't matter to
309 case nsHtml5Tokenizer::CDATA_RSQB_RSQB
:
310 if (aState
== nsHtml5Tokenizer::DATA
) {
315 case nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE
:
316 EndSpanOrA(); // the span for the ampersand
318 case nsHtml5Tokenizer::CONSUME_NCR
:
319 case nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP
:
322 // not actually a character reference
327 case nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP
:
328 if (aState
== nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL
) {
331 // not actually a character reference
334 case nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL
:
340 case nsHtml5Tokenizer::DECIMAL_NRC_LOOP
:
341 case nsHtml5Tokenizer::HEX_NCR_LOOP
:
343 case nsHtml5Tokenizer::HANDLE_NCR_VALUE
:
347 case nsHtml5Tokenizer::HANDLE_NCR_VALUE_RECONSUME
:
353 case nsHtml5Tokenizer::CLOSE_TAG_OPEN
:
355 case nsHtml5Tokenizer::DATA
:
358 case nsHtml5Tokenizer::TAG_NAME
:
363 case nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN
:
364 if (aState
== nsHtml5Tokenizer::NON_DATA_END_TAG_NAME
) {
366 StartSpan(); // don't know if it is "end-tag" yet :-(
372 case nsHtml5Tokenizer::NON_DATA_END_TAG_NAME
:
374 case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME
:
378 case nsHtml5Tokenizer::SELF_CLOSING_START_TAG
:
381 StartSpan(); // for highlighting the slash
382 mSlash
= CurrentNode();
384 case nsHtml5Tokenizer::DATA
: // yes, as a result of emitting the token
393 case nsHtml5Tokenizer::SCRIPT_DATA_LESS_THAN_SIGN
:
394 case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN
:
395 if (aState
== nsHtml5Tokenizer::NON_DATA_END_TAG_NAME
) {
397 StartSpan(); // don't know if it is "end-tag" yet :-(
402 case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH
:
403 case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED
:
404 case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH
:
405 if (aState
== nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN
) {
406 EndCharactersAndStartMarkupRun();
409 // Lots of double escape states omitted, because they don't highlight.
410 // Likewise, only doctype states that can emit the doctype are of
411 // interest. Otherwise, the transition out of bogus comment deals.
412 case nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME
:
413 case nsHtml5Tokenizer::DOCTYPE_NAME
:
414 case nsHtml5Tokenizer::AFTER_DOCTYPE_NAME
:
415 case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD
:
416 case nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER
:
417 case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED
:
418 case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER
:
419 case nsHtml5Tokenizer::BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS
:
420 case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED
:
421 case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER
:
422 case nsHtml5Tokenizer::BOGUS_DOCTYPE
:
423 case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD
:
424 case nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER
:
425 case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED
:
426 case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED
:
427 if (aState
== nsHtml5Tokenizer::DATA
) {
432 case nsHtml5Tokenizer::PROCESSING_INSTRUCTION_QUESTION_MARK
:
433 if (aState
== nsHtml5Tokenizer::DATA
) {
445 nsHtml5Highlighter::End()
448 case nsHtml5Tokenizer::COMMENT_END
:
449 case nsHtml5Tokenizer::COMMENT_END_BANG
:
450 case nsHtml5Tokenizer::COMMENT_START_DASH
:
451 case nsHtml5Tokenizer::BOGUS_COMMENT
:
452 case nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN
:
455 case nsHtml5Tokenizer::CDATA_RSQB_RSQB
:
458 case nsHtml5Tokenizer::DECIMAL_NRC_LOOP
:
459 case nsHtml5Tokenizer::HEX_NCR_LOOP
:
460 // XXX need tokenizer help here
462 case nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME
:
463 case nsHtml5Tokenizer::DOCTYPE_NAME
:
464 case nsHtml5Tokenizer::AFTER_DOCTYPE_NAME
:
465 case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD
:
466 case nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER
:
467 case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED
:
468 case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER
:
469 case nsHtml5Tokenizer::BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS
:
470 case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED
:
471 case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER
:
472 case nsHtml5Tokenizer::BOGUS_DOCTYPE
:
473 case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD
:
474 case nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER
:
475 case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED
:
476 case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED
:
482 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
483 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
484 treeOp
->Init(eTreeOpStreamEnded
);
489 nsHtml5Highlighter::SetBuffer(nsHtml5UTF16Buffer
* aBuffer
)
491 MOZ_ASSERT(!mBuffer
, "Old buffer still here!");
493 mCStart
= aBuffer
->getStart();
497 nsHtml5Highlighter::DropBuffer(int32_t aPos
)
499 MOZ_ASSERT(mBuffer
, "No buffer to drop!");
506 nsHtml5Highlighter::StartSpan()
509 Push(nsGkAtoms::span
, nullptr, NS_NewHTMLSpanElement
);
514 nsHtml5Highlighter::StartSpan(const char16_t
* aClass
)
521 nsHtml5Highlighter::EndSpanOrA()
529 nsHtml5Highlighter::StartCharacters()
531 MOZ_ASSERT(!mInCharacters
, "Already in characters!");
533 Push(nsGkAtoms::span
, nullptr, NS_NewHTMLSpanElement
);
534 mCurrentRun
= CurrentNode();
535 mInCharacters
= true;
539 nsHtml5Highlighter::EndCharactersAndStartMarkupRun()
541 MOZ_ASSERT(mInCharacters
, "Not in characters!");
544 mInCharacters
= false;
545 // Now start markup run
547 mCurrentRun
= CurrentNode();
551 nsHtml5Highlighter::StartA()
554 Push(nsGkAtoms::a
, nullptr, NS_NewHTMLAnchorElement
);
555 AddClass(sAttributeValue
);
560 nsHtml5Highlighter::FinishTag()
562 while (mInlinesOpen
> 1) {
566 EndSpanOrA(); // DATA
567 NS_ASSERTION(!mInlinesOpen
, "mInlinesOpen got out of sync!");
572 nsHtml5Highlighter::FlushChars()
574 if (mCStart
< mPos
) {
575 char16_t
* buf
= mBuffer
->getBuffer();
581 // The input this code sees has been normalized so that there are
582 // CR breaks and LF breaks but no CRLF breaks. Overwrite CR with LF
583 // to show consistent LF line breaks to layout. It is OK to mutate
584 // the input data, because there are no reparses in the View Source
585 // case, so we won't need the original data in the buffer anymore.
591 int32_t len
= i
- mCStart
;
592 AppendCharacters(buf
, mCStart
, len
);
596 Push(nsGkAtoms::span
, nullptr, NS_NewHTMLSpanElement
);
597 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
598 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
599 treeOp
->InitAddLineNumberId(CurrentNode(), mLineNumber
);
608 if (mCStart
< mPos
) {
609 int32_t len
= mPos
- mCStart
;
610 AppendCharacters(buf
, mCStart
, len
);
617 nsHtml5Highlighter::FlushCurrent()
624 nsHtml5Highlighter::FlushOps()
626 bool hasOps
= !mOpQueue
.IsEmpty();
628 mOpSink
->MoveOpsFrom(mOpQueue
);
634 nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName
* aName
,
635 nsHtml5String aValue
)
637 if (!(nsHtml5AttributeName::ATTR_HREF
== aName
||
638 nsHtml5AttributeName::ATTR_SRC
== aName
||
639 nsHtml5AttributeName::ATTR_ACTION
== aName
||
640 nsHtml5AttributeName::ATTR_CITE
== aName
||
641 nsHtml5AttributeName::ATTR_BACKGROUND
== aName
||
642 nsHtml5AttributeName::ATTR_LONGDESC
== aName
||
643 nsHtml5AttributeName::ATTR_XLINK_HREF
== aName
||
644 nsHtml5AttributeName::ATTR_DEFINITIONURL
== aName
)) {
647 AddViewSourceHref(aValue
);
651 nsHtml5Highlighter::CompletedNamedCharacterReference()
657 nsHtml5Highlighter::AllocateContentHandle()
659 if (mHandlesUsed
== NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH
) {
660 mOldHandles
.AppendElement(std::move(mHandles
));
662 MakeUnique
<nsIContent
* []>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH
);
666 mHandles
[mHandlesUsed
] = reinterpret_cast<nsIContent
*>(uintptr_t(0xC0DEDBAD));
668 return &mHandles
[mHandlesUsed
++];
672 nsHtml5Highlighter::CreateElement(
674 nsHtml5HtmlAttributes
* aAttributes
,
675 nsIContent
** aIntendedParent
,
676 mozilla::dom::HTMLContentCreatorFunction aCreator
)
678 MOZ_ASSERT(aName
, "Got null name.");
679 nsHtml5ContentCreatorFunction creator
;
680 creator
.html
= aCreator
;
681 nsIContent
** content
= AllocateContentHandle();
682 mOpQueue
.AppendElement()->Init(kNameSpaceID_XHTML
,
693 nsHtml5Highlighter::CurrentNode()
695 MOZ_ASSERT(mStack
.Length() >= 1, "Must have something on stack.");
696 return mStack
[mStack
.Length() - 1];
700 nsHtml5Highlighter::Push(nsAtom
* aName
,
701 nsHtml5HtmlAttributes
* aAttributes
,
702 mozilla::dom::HTMLContentCreatorFunction aCreator
)
704 MOZ_ASSERT(mStack
.Length() >= 1, "Pushing without root.");
705 nsIContent
** elt
= CreateElement(aName
,
708 aCreator
); // Don't inline below!
709 mOpQueue
.AppendElement()->Init(eTreeOpAppend
, elt
, CurrentNode());
710 mStack
.AppendElement(elt
);
714 nsHtml5Highlighter::Pop()
716 MOZ_ASSERT(mStack
.Length() >= 2, "Popping when stack too short.");
717 mStack
.RemoveLastElement();
721 nsHtml5Highlighter::AppendCharacters(const char16_t
* aBuffer
,
725 MOZ_ASSERT(aBuffer
, "Null buffer");
727 char16_t
* bufferCopy
= new char16_t
[aLength
];
728 memcpy(bufferCopy
, aBuffer
+ aStart
, aLength
* sizeof(char16_t
));
730 mOpQueue
.AppendElement()->Init(
731 eTreeOpAppendText
, bufferCopy
, aLength
, CurrentNode());
735 nsHtml5Highlighter::AddClass(const char16_t
* aClass
)
737 mOpQueue
.AppendElement()->InitAddClass(CurrentNode(), aClass
);
741 nsHtml5Highlighter::AddViewSourceHref(nsHtml5String aValue
)
743 char16_t
* bufferCopy
= new char16_t
[aValue
.Length() + 1];
744 aValue
.CopyToBuffer(bufferCopy
);
745 bufferCopy
[aValue
.Length()] = 0;
747 mOpQueue
.AppendElement()->Init(
748 eTreeOpAddViewSourceHref
, bufferCopy
, aValue
.Length(), CurrentNode());
752 nsHtml5Highlighter::AddBase(nsHtml5String aValue
)
758 char16_t
* bufferCopy
= new char16_t
[aValue
.Length() + 1];
759 aValue
.CopyToBuffer(bufferCopy
);
760 bufferCopy
[aValue
.Length()] = 0;
762 mOpQueue
.AppendElement()->Init(
763 eTreeOpAddViewSourceBase
, bufferCopy
, aValue
.Length());
767 nsHtml5Highlighter::AddErrorToCurrentNode(const char* aMsgId
)
769 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
770 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
771 treeOp
->Init(CurrentNode(), aMsgId
);
775 nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId
)
777 MOZ_ASSERT(mCurrentRun
, "Adding error to run without one!");
778 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
779 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
780 treeOp
->Init(mCurrentRun
, aMsgId
);
784 nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId
, nsAtom
* aName
)
786 MOZ_ASSERT(mCurrentRun
, "Adding error to run without one!");
787 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
788 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
789 treeOp
->Init(mCurrentRun
, aMsgId
, aName
);
793 nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId
,
797 MOZ_ASSERT(mCurrentRun
, "Adding error to run without one!");
798 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
799 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
800 treeOp
->Init(mCurrentRun
, aMsgId
, aName
, aOther
);
804 nsHtml5Highlighter::AddErrorToCurrentAmpersand(const char* aMsgId
)
806 MOZ_ASSERT(mAmpersand
, "Adding error to ampersand without one!");
807 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
808 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
809 treeOp
->Init(mAmpersand
, aMsgId
);
813 nsHtml5Highlighter::AddErrorToCurrentSlash(const char* aMsgId
)
815 MOZ_ASSERT(mSlash
, "Adding error to slash without one!");
816 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
817 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
818 treeOp
->Init(mSlash
, aMsgId
);