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 "nsHtml5Tokenizer.h"
8 #include "nsHtml5AttributeName.h"
10 #include "nsThreadUtils.h"
11 #include "nsHtml5ViewSourceUtils.h"
12 #include "mozilla/Preferences.h"
14 using namespace mozilla
;
16 // The old code had a limit of 16 tokens. 1300 is a number picked my measuring
17 // the size of 16 tokens on cnn.com.
18 #define NS_HTML5_HIGHLIGHTER_PRE_BREAK_THRESHOLD 1300
20 char16_t
nsHtml5Highlighter::sComment
[] =
21 { 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
23 char16_t
nsHtml5Highlighter::sCdata
[] =
24 { 'c', 'd', 'a', 't', 'a', 0 };
26 char16_t
nsHtml5Highlighter::sEntity
[] =
27 { 'e', 'n', 't', 'i', 't', 'y', 0 };
29 char16_t
nsHtml5Highlighter::sEndTag
[] =
30 { 'e', 'n', 'd', '-', 't', 'a', 'g', 0 };
32 char16_t
nsHtml5Highlighter::sStartTag
[] =
33 { 's', 't', 'a', 'r', 't', '-', 't', 'a', 'g', 0 };
35 char16_t
nsHtml5Highlighter::sAttributeName
[] =
36 { 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-', 'n', 'a', 'm', 'e', 0 };
38 char16_t
nsHtml5Highlighter::sAttributeValue
[] =
39 { 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-',
40 'v', 'a', 'l', 'u', 'e', 0 };
42 char16_t
nsHtml5Highlighter::sDoctype
[] =
43 { 'd', 'o', 'c', 't', 'y', 'p', 'e', 0 };
45 char16_t
nsHtml5Highlighter::sPi
[] =
48 nsHtml5Highlighter::nsHtml5Highlighter(nsAHtml5TreeOpSink
* aOpSink
)
49 : mState(NS_HTML5TOKENIZER_DATA
)
54 , mInCharacters(false)
56 , mSyntaxHighlight(Preferences::GetBool("view_source.syntax_highlight",
59 , mCurrentRun(nullptr)
62 , mHandles(new nsIContent
*[NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH
])
66 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
69 nsHtml5Highlighter::~nsHtml5Highlighter()
71 NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
75 nsHtml5Highlighter::Start(const nsAutoString
& aTitle
)
78 mOpQueue
.AppendElement()->Init(nsGkAtoms::html
, EmptyString(), EmptyString());
80 mOpQueue
.AppendElement()->Init(STANDARDS_MODE
);
82 nsIContent
** root
= CreateElement(nsHtml5Atoms::html
, nullptr, nullptr);
83 mOpQueue
.AppendElement()->Init(eTreeOpAppendToDocument
, root
);
84 mStack
.AppendElement(root
);
86 Push(nsGkAtoms::head
, nullptr);
88 Push(nsGkAtoms::title
, nullptr);
89 // XUL will add the "Source of: " prefix.
90 uint32_t length
= aTitle
.Length();
91 if (length
> INT32_MAX
) {
94 AppendCharacters(aTitle
.get(), 0, (int32_t)length
);
97 Push(nsGkAtoms::link
, nsHtml5ViewSourceUtils::NewLinkAttributes());
99 mOpQueue
.AppendElement()->Init(eTreeOpUpdateStyleSheet
, CurrentNode());
105 Push(nsGkAtoms::body
, nsHtml5ViewSourceUtils::NewBodyAttributes());
107 nsHtml5HtmlAttributes
* preAttrs
= new nsHtml5HtmlAttributes(0);
108 nsString
* preId
= new nsString(NS_LITERAL_STRING("line1"));
109 preAttrs
->addAttribute(nsHtml5AttributeName::ATTR_ID
, preId
);
110 Push(nsGkAtoms::pre
, preAttrs
);
114 mOpQueue
.AppendElement()->Init(eTreeOpStartLayout
);
118 nsHtml5Highlighter::Transition(int32_t aState
, bool aReconsume
, int32_t aPos
)
122 case NS_HTML5TOKENIZER_SCRIPT_DATA
:
123 case NS_HTML5TOKENIZER_RAWTEXT
:
124 case NS_HTML5TOKENIZER_RCDATA
:
125 case NS_HTML5TOKENIZER_DATA
:
126 // We can transition on < and on &. Either way, we don't yet know the
127 // role of the token, so open a span without class.
128 if (aState
== NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE
) {
130 // Start another span for highlighting the ampersand
132 mAmpersand
= CurrentNode();
134 EndCharactersAndStartMarkupRun();
137 case NS_HTML5TOKENIZER_TAG_OPEN
:
139 case NS_HTML5TOKENIZER_TAG_NAME
:
140 StartSpan(sStartTag
);
142 case NS_HTML5TOKENIZER_DATA
:
145 case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION
:
150 case NS_HTML5TOKENIZER_TAG_NAME
:
152 case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
:
153 EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
155 case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG
:
156 EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
157 StartSpan(); // for highlighting the slash
158 mSlash
= CurrentNode();
165 case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
:
167 case NS_HTML5TOKENIZER_ATTRIBUTE_NAME
:
168 StartSpan(sAttributeName
);
170 case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG
:
171 StartSpan(); // for highlighting the slash
172 mSlash
= CurrentNode();
179 case NS_HTML5TOKENIZER_ATTRIBUTE_NAME
:
181 case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME
:
182 case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE
:
183 EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
185 case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG
:
186 EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
187 StartSpan(); // for highlighting the slash
188 mSlash
= CurrentNode();
195 case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE
:
197 case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED
:
198 case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED
:
202 case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED
:
210 case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED
:
211 case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED
:
213 case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED
:
216 case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE
:
218 StartSpan(); // for ampersand itself
219 mAmpersand
= CurrentNode();
222 NS_NOTREACHED("Impossible transition.");
226 case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED
:
228 case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
:
230 case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG
:
231 StartSpan(); // for highlighting the slash
232 mSlash
= CurrentNode();
239 case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG
:
240 EndSpanOrA(); // end the slash highlight
242 case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
:
249 case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED
:
251 case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
:
254 case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE
:
256 StartSpan(); // for ampersand itself
257 mAmpersand
= CurrentNode();
264 case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME
:
266 case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG
:
267 StartSpan(); // for highlighting the slash
268 mSlash
= CurrentNode();
270 case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE
:
272 case NS_HTML5TOKENIZER_ATTRIBUTE_NAME
:
273 StartSpan(sAttributeName
);
280 // most comment states are omitted, because they don't matter to
282 case NS_HTML5TOKENIZER_COMMENT_START
:
283 case NS_HTML5TOKENIZER_COMMENT_END
:
284 case NS_HTML5TOKENIZER_COMMENT_END_BANG
:
285 case NS_HTML5TOKENIZER_COMMENT_START_DASH
:
286 case NS_HTML5TOKENIZER_BOGUS_COMMENT
:
287 case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN
:
288 if (aState
== NS_HTML5TOKENIZER_DATA
) {
293 // most cdata states are omitted, because they don't matter to
295 case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB
:
296 if (aState
== NS_HTML5TOKENIZER_DATA
) {
301 case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE
:
302 EndSpanOrA(); // the span for the ampersand
304 case NS_HTML5TOKENIZER_CONSUME_NCR
:
305 case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP
:
308 // not actually a character reference
313 case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP
:
314 if (aState
== NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL
) {
317 // not actually a character reference
320 case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL
:
326 case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP
:
327 case NS_HTML5TOKENIZER_HEX_NCR_LOOP
:
329 case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE
:
333 case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE_RECONSUME
:
339 case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN
:
341 case NS_HTML5TOKENIZER_DATA
:
344 case NS_HTML5TOKENIZER_TAG_NAME
:
349 case NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN
:
350 if (aState
== NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME
) {
352 StartSpan(); // don't know if it is "end-tag" yet :-(
358 case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME
:
360 case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
:
364 case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG
:
367 StartSpan(); // for highlighting the slash
368 mSlash
= CurrentNode();
370 case NS_HTML5TOKENIZER_DATA
: // yes, as a result of emitting the token
379 case NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN
:
380 case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN
:
381 if (aState
== NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME
) {
383 StartSpan(); // don't know if it is "end-tag" yet :-(
388 case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH
:
389 case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED
:
390 case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH
:
391 if (aState
== NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN
) {
392 EndCharactersAndStartMarkupRun();
395 // Lots of double escape states omitted, because they don't highlight.
396 // Likewise, only doctype states that can emit the doctype are of
397 // interest. Otherwise, the transition out of bogus comment deals.
398 case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME
:
399 case NS_HTML5TOKENIZER_DOCTYPE_NAME
:
400 case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME
:
401 case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD
:
402 case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER
:
403 case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED
:
404 case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER
:
405 case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS
:
406 case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED
:
407 case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER
:
408 case NS_HTML5TOKENIZER_BOGUS_DOCTYPE
:
409 case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD
:
410 case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER
:
411 case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED
:
412 case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED
:
413 if (aState
== NS_HTML5TOKENIZER_DATA
) {
418 case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION_QUESTION_MARK
:
419 if (aState
== NS_HTML5TOKENIZER_DATA
) {
431 nsHtml5Highlighter::End()
434 case NS_HTML5TOKENIZER_COMMENT_END
:
435 case NS_HTML5TOKENIZER_COMMENT_END_BANG
:
436 case NS_HTML5TOKENIZER_COMMENT_START_DASH
:
437 case NS_HTML5TOKENIZER_BOGUS_COMMENT
:
438 case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN
:
441 case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB
:
444 case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP
:
445 case NS_HTML5TOKENIZER_HEX_NCR_LOOP
:
446 // XXX need tokenizer help here
448 case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME
:
449 case NS_HTML5TOKENIZER_DOCTYPE_NAME
:
450 case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME
:
451 case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD
:
452 case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER
:
453 case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED
:
454 case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER
:
455 case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS
:
456 case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED
:
457 case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER
:
458 case NS_HTML5TOKENIZER_BOGUS_DOCTYPE
:
459 case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD
:
460 case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER
:
461 case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED
:
462 case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED
:
468 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
469 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
470 treeOp
->Init(eTreeOpStreamEnded
);
475 nsHtml5Highlighter::SetBuffer(nsHtml5UTF16Buffer
* aBuffer
)
477 NS_PRECONDITION(!mBuffer
, "Old buffer still here!");
479 mCStart
= aBuffer
->getStart();
483 nsHtml5Highlighter::DropBuffer(int32_t aPos
)
485 NS_PRECONDITION(mBuffer
, "No buffer to drop!");
492 nsHtml5Highlighter::StartSpan()
495 Push(nsGkAtoms::span
, nullptr);
500 nsHtml5Highlighter::StartSpan(const char16_t
* aClass
)
507 nsHtml5Highlighter::EndSpanOrA()
515 nsHtml5Highlighter::StartCharacters()
517 NS_PRECONDITION(!mInCharacters
, "Already in characters!");
519 Push(nsGkAtoms::span
, nullptr);
520 mCurrentRun
= CurrentNode();
521 mInCharacters
= true;
525 nsHtml5Highlighter::EndCharactersAndStartMarkupRun()
527 NS_PRECONDITION(mInCharacters
, "Not in characters!");
530 mInCharacters
= false;
531 // Now start markup run
533 mCurrentRun
= CurrentNode();
537 nsHtml5Highlighter::StartA()
540 Push(nsGkAtoms::a
, nullptr);
541 AddClass(sAttributeValue
);
546 nsHtml5Highlighter::FinishTag()
548 while (mInlinesOpen
> 1) {
552 EndSpanOrA(); // DATA
553 NS_ASSERTION(!mInlinesOpen
, "mInlinesOpen got out of sync!");
558 nsHtml5Highlighter::FlushChars()
560 if (mCStart
< mPos
) {
561 char16_t
* buf
= mBuffer
->getBuffer();
567 // The input this code sees has been normalized so that there are
568 // CR breaks and LF breaks but no CRLF breaks. Overwrite CR with LF
569 // to show consistent LF line breaks to layout. It is OK to mutate
570 // the input data, because there are no reparses in the View Source
571 // case, so we won't need the original data in the buffer anymore.
577 int32_t len
= i
- mCStart
;
578 AppendCharacters(buf
, mCStart
, len
);
582 Push(nsGkAtoms::span
, nullptr);
583 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
584 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
585 treeOp
->InitAddLineNumberId(CurrentNode(), mLineNumber
);
594 if (mCStart
< mPos
) {
595 int32_t len
= mPos
- mCStart
;
596 AppendCharacters(buf
, mCStart
, len
);
603 nsHtml5Highlighter::FlushCurrent()
610 nsHtml5Highlighter::FlushOps()
612 bool hasOps
= !mOpQueue
.IsEmpty();
614 mOpSink
->MoveOpsFrom(mOpQueue
);
620 nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName
* aName
,
623 if (!(nsHtml5AttributeName::ATTR_HREF
== aName
||
624 nsHtml5AttributeName::ATTR_SRC
== aName
||
625 nsHtml5AttributeName::ATTR_ACTION
== aName
||
626 nsHtml5AttributeName::ATTR_CITE
== aName
||
627 nsHtml5AttributeName::ATTR_BACKGROUND
== aName
||
628 nsHtml5AttributeName::ATTR_LONGDESC
== aName
||
629 nsHtml5AttributeName::ATTR_XLINK_HREF
== aName
||
630 nsHtml5AttributeName::ATTR_DEFINITIONURL
== aName
)) {
633 AddViewSourceHref(*aValue
);
637 nsHtml5Highlighter::CompletedNamedCharacterReference()
643 nsHtml5Highlighter::AllocateContentHandle()
645 if (mHandlesUsed
== NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH
) {
646 mOldHandles
.AppendElement(mHandles
.forget());
647 mHandles
= new nsIContent
*[NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH
];
651 mHandles
[mHandlesUsed
] = (nsIContent
*)0xC0DEDBAD;
653 return &mHandles
[mHandlesUsed
++];
657 nsHtml5Highlighter::CreateElement(nsIAtom
* aName
,
658 nsHtml5HtmlAttributes
* aAttributes
,
659 nsIContent
** aIntendedParent
)
661 NS_PRECONDITION(aName
, "Got null name.");
662 nsIContent
** content
= AllocateContentHandle();
663 mOpQueue
.AppendElement()->Init(kNameSpaceID_XHTML
,
673 nsHtml5Highlighter::CurrentNode()
675 NS_PRECONDITION(mStack
.Length() >= 1, "Must have something on stack.");
676 return mStack
[mStack
.Length() - 1];
680 nsHtml5Highlighter::Push(nsIAtom
* aName
,
681 nsHtml5HtmlAttributes
* aAttributes
)
683 NS_PRECONDITION(mStack
.Length() >= 1, "Pushing without root.");
684 nsIContent
** elt
= CreateElement(aName
, aAttributes
, CurrentNode()); // Don't inline below!
685 mOpQueue
.AppendElement()->Init(eTreeOpAppend
, elt
, CurrentNode());
686 mStack
.AppendElement(elt
);
690 nsHtml5Highlighter::Pop()
692 NS_PRECONDITION(mStack
.Length() >= 2, "Popping when stack too short.");
693 mStack
.RemoveElementAt(mStack
.Length() - 1);
697 nsHtml5Highlighter::AppendCharacters(const char16_t
* aBuffer
,
701 NS_PRECONDITION(aBuffer
, "Null buffer");
703 char16_t
* bufferCopy
= new char16_t
[aLength
];
704 memcpy(bufferCopy
, aBuffer
+ aStart
, aLength
* sizeof(char16_t
));
706 mOpQueue
.AppendElement()->Init(eTreeOpAppendText
,
714 nsHtml5Highlighter::AddClass(const char16_t
* aClass
)
716 if (!mSyntaxHighlight
) {
719 mOpQueue
.AppendElement()->InitAddClass(CurrentNode(), aClass
);
723 nsHtml5Highlighter::AddViewSourceHref(const nsString
& aValue
)
725 char16_t
* bufferCopy
= new char16_t
[aValue
.Length() + 1];
726 memcpy(bufferCopy
, aValue
.get(), aValue
.Length() * sizeof(char16_t
));
727 bufferCopy
[aValue
.Length()] = 0;
729 mOpQueue
.AppendElement()->Init(eTreeOpAddViewSourceHref
,
736 nsHtml5Highlighter::AddBase(const nsString
& aValue
)
742 char16_t
* bufferCopy
= new char16_t
[aValue
.Length() + 1];
743 memcpy(bufferCopy
, aValue
.get(), aValue
.Length() * sizeof(char16_t
));
744 bufferCopy
[aValue
.Length()] = 0;
746 mOpQueue
.AppendElement()->Init(eTreeOpAddViewSourceBase
,
752 nsHtml5Highlighter::AddErrorToCurrentNode(const char* aMsgId
)
754 if (!mSyntaxHighlight
) {
757 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
758 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
759 treeOp
->Init(CurrentNode(), aMsgId
);
763 nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId
)
765 if (!mSyntaxHighlight
) {
768 NS_PRECONDITION(mCurrentRun
, "Adding error to run without one!");
769 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
770 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
771 treeOp
->Init(mCurrentRun
, aMsgId
);
775 nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId
,
778 if (!mSyntaxHighlight
) {
781 NS_PRECONDITION(mCurrentRun
, "Adding error to run without one!");
782 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
783 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
784 treeOp
->Init(mCurrentRun
, aMsgId
, aName
);
788 nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId
,
792 if (!mSyntaxHighlight
) {
795 NS_PRECONDITION(mCurrentRun
, "Adding error to run without one!");
796 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
797 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
798 treeOp
->Init(mCurrentRun
, aMsgId
, aName
, aOther
);
802 nsHtml5Highlighter::AddErrorToCurrentAmpersand(const char* aMsgId
)
804 if (!mSyntaxHighlight
) {
807 NS_PRECONDITION(mAmpersand
, "Adding error to ampersand without one!");
808 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
809 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
810 treeOp
->Init(mAmpersand
, aMsgId
);
814 nsHtml5Highlighter::AddErrorToCurrentSlash(const char* aMsgId
)
816 if (!mSyntaxHighlight
) {
819 NS_PRECONDITION(mSlash
, "Adding error to slash without one!");
820 nsHtml5TreeOperation
* treeOp
= mOpQueue
.AppendElement();
821 NS_ASSERTION(treeOp
, "Tree op allocation failed.");
822 treeOp
->Init(mSlash
, aMsgId
);