LCOV - code coverage report
Current view: top level - parser/html - nsHtml5Highlighter.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 415 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 34 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       4             : 
       5             : #include "nsHtml5Highlighter.h"
       6             : #include "nsDebug.h"
       7             : #include "nsHtml5Tokenizer.h"
       8             : #include "nsHtml5AttributeName.h"
       9             : #include "nsString.h"
      10             : #include "nsThreadUtils.h"
      11             : #include "nsHtml5ViewSourceUtils.h"
      12             : 
      13             : #include "mozilla/Attributes.h"
      14             : #include "mozilla/Preferences.h"
      15             : 
      16             : using namespace mozilla;
      17             : 
      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
      21             : 
      22             : char16_t nsHtml5Highlighter::sComment[] =
      23             :   { 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
      24             : 
      25             : char16_t nsHtml5Highlighter::sCdata[] =
      26             :   { 'c', 'd', 'a', 't', 'a', 0 };
      27             : 
      28             : char16_t nsHtml5Highlighter::sEntity[] =
      29             :   { 'e', 'n', 't', 'i', 't', 'y', 0 };
      30             : 
      31             : char16_t nsHtml5Highlighter::sEndTag[] =
      32             :   { 'e', 'n', 'd', '-', 't', 'a', 'g', 0 };
      33             : 
      34             : char16_t nsHtml5Highlighter::sStartTag[] =
      35             :   { 's', 't', 'a', 'r', 't', '-', 't', 'a', 'g', 0 };
      36             : 
      37             : char16_t nsHtml5Highlighter::sAttributeName[] =
      38             :   { 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-', 'n', 'a', 'm', 'e', 0 };
      39             : 
      40             : char16_t nsHtml5Highlighter::sAttributeValue[] =
      41             :   { 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-',
      42             :     'v', 'a', 'l', 'u', 'e', 0 };
      43             : 
      44             : char16_t nsHtml5Highlighter::sDoctype[] =
      45             :   { 'd', 'o', 'c', 't', 'y', 'p', 'e', 0 };
      46             : 
      47             : char16_t nsHtml5Highlighter::sPi[] =
      48             :   { 'p', 'i', 0 };
      49             : 
      50           0 : nsHtml5Highlighter::nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink)
      51             :   : mState(nsHtml5Tokenizer::DATA)
      52             :   , mCStart(INT32_MAX)
      53             :   , mPos(0)
      54             :   , mLineNumber(1)
      55             :   , mInlinesOpen(0)
      56             :   , mInCharacters(false)
      57             :   , mBuffer(nullptr)
      58             :   , mOpSink(aOpSink)
      59             :   , mCurrentRun(nullptr)
      60             :   , mAmpersand(nullptr)
      61             :   , mSlash(nullptr)
      62             :   , mHandles(
      63             :       MakeUnique<nsIContent* []>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH))
      64             :   , mHandlesUsed(0)
      65           0 :   , mSeenBase(false)
      66             : {
      67           0 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
      68           0 : }
      69             : 
      70           0 : nsHtml5Highlighter::~nsHtml5Highlighter()
      71             : {
      72           0 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
      73           0 : }
      74             : 
      75             : void
      76           0 : nsHtml5Highlighter::Start(const nsAutoString& aTitle)
      77             : {
      78             :   // Doctype
      79           0 :   mOpQueue.AppendElement()->Init(nsGkAtoms::html, EmptyString(), EmptyString());
      80             : 
      81           0 :   mOpQueue.AppendElement()->Init(STANDARDS_MODE);
      82             : 
      83           0 :   nsIContent** root = CreateElement(nsGkAtoms::html, nullptr, nullptr);
      84           0 :   mOpQueue.AppendElement()->Init(eTreeOpAppendToDocument, root);
      85           0 :   mStack.AppendElement(root);
      86             : 
      87           0 :   Push(nsGkAtoms::head, nullptr);
      88             : 
      89           0 :   Push(nsGkAtoms::title, nullptr);
      90             :   // XUL will add the "Source of: " prefix.
      91           0 :   uint32_t length = aTitle.Length();
      92           0 :   if (length > INT32_MAX) {
      93           0 :     length = INT32_MAX;
      94             :   }
      95           0 :   AppendCharacters(aTitle.BeginReading(), 0, (int32_t)length);
      96           0 :   Pop(); // title
      97             : 
      98           0 :   Push(nsGkAtoms::link, nsHtml5ViewSourceUtils::NewLinkAttributes());
      99             : 
     100           0 :   mOpQueue.AppendElement()->Init(eTreeOpUpdateStyleSheet, CurrentNode());
     101             : 
     102           0 :   Pop(); // link
     103             : 
     104           0 :   Pop(); // head
     105             : 
     106           0 :   Push(nsGkAtoms::body, nsHtml5ViewSourceUtils::NewBodyAttributes());
     107             : 
     108           0 :   nsHtml5HtmlAttributes* preAttrs = new nsHtml5HtmlAttributes(0);
     109           0 :   nsHtml5String preId = nsHtml5Portability::newStringFromLiteral("line1");
     110           0 :   preAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, preId, -1);
     111           0 :   Push(nsGkAtoms::pre, preAttrs);
     112             : 
     113           0 :   StartCharacters();
     114             : 
     115           0 :   mOpQueue.AppendElement()->Init(eTreeOpStartLayout);
     116           0 : }
     117             : 
     118             : int32_t
     119           0 : nsHtml5Highlighter::Transition(int32_t aState, bool aReconsume, int32_t aPos)
     120             : {
     121           0 :   mPos = aPos;
     122           0 :   switch (mState) {
     123             :     case nsHtml5Tokenizer::SCRIPT_DATA:
     124             :     case nsHtml5Tokenizer::RAWTEXT:
     125             :     case nsHtml5Tokenizer::RCDATA:
     126             :     case nsHtml5Tokenizer::DATA:
     127             :       // We can transition on < and on &. Either way, we don't yet know the
     128             :       // role of the token, so open a span without class.
     129           0 :       if (aState == nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE) {
     130           0 :         StartSpan();
     131             :         // Start another span for highlighting the ampersand
     132           0 :         StartSpan();
     133           0 :         mAmpersand = CurrentNode();
     134             :       } else {
     135           0 :         EndCharactersAndStartMarkupRun();
     136             :       }
     137           0 :       break;
     138             :     case nsHtml5Tokenizer::TAG_OPEN:
     139           0 :       switch (aState) {
     140             :         case nsHtml5Tokenizer::TAG_NAME:
     141           0 :           StartSpan(sStartTag);
     142           0 :           break;
     143             :         case nsHtml5Tokenizer::DATA:
     144           0 :           FinishTag(); // DATA
     145           0 :           break;
     146             :         case nsHtml5Tokenizer::PROCESSING_INSTRUCTION:
     147           0 :           AddClass(sPi);
     148           0 :           break;
     149             :       }
     150           0 :       break;
     151             :     case nsHtml5Tokenizer::TAG_NAME:
     152           0 :       switch (aState) {
     153             :         case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME:
     154           0 :           EndSpanOrA(); // nsHtml5Tokenizer::TAG_NAME
     155           0 :           break;
     156             :         case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
     157           0 :           EndSpanOrA(); // nsHtml5Tokenizer::TAG_NAME
     158           0 :           StartSpan(); // for highlighting the slash
     159           0 :           mSlash = CurrentNode();
     160           0 :           break;
     161             :         default:
     162           0 :           FinishTag();
     163           0 :           break;
     164             :       }
     165           0 :       break;
     166             :     case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME:
     167           0 :       switch (aState) {
     168             :         case nsHtml5Tokenizer::ATTRIBUTE_NAME:
     169           0 :           StartSpan(sAttributeName);
     170           0 :           break;
     171             :         case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
     172           0 :           StartSpan(); // for highlighting the slash
     173           0 :           mSlash = CurrentNode();
     174           0 :           break;
     175             :         default:
     176           0 :           FinishTag();
     177           0 :           break;
     178             :       }
     179           0 :       break;
     180             :     case nsHtml5Tokenizer::ATTRIBUTE_NAME:
     181           0 :       switch (aState) {
     182             :         case nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME:
     183             :         case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE:
     184           0 :           EndSpanOrA(); // nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME
     185           0 :           break;
     186             :         case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
     187           0 :           EndSpanOrA(); // nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME
     188           0 :           StartSpan(); // for highlighting the slash
     189           0 :           mSlash = CurrentNode();
     190           0 :           break;
     191             :         default:
     192           0 :           FinishTag();
     193           0 :           break;
     194             :       }
     195           0 :       break;
     196             :     case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE:
     197           0 :       switch (aState) {
     198             :         case nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED:
     199             :         case nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED:
     200           0 :           FlushCurrent();
     201           0 :           StartA();
     202           0 :           break;
     203             :         case nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED:
     204           0 :           StartA();
     205           0 :           break;
     206             :         default:
     207           0 :           FinishTag();
     208           0 :           break;
     209             :       }
     210           0 :       break;
     211             :     case nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED:
     212             :     case nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED:
     213           0 :       switch (aState) {
     214             :         case nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED:
     215           0 :           EndSpanOrA();
     216           0 :           break;
     217             :         case nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE:
     218           0 :           StartSpan();
     219           0 :           StartSpan(); // for ampersand itself
     220           0 :           mAmpersand = CurrentNode();
     221           0 :           break;
     222             :         default:
     223           0 :           NS_NOTREACHED("Impossible transition.");
     224           0 :           break;
     225             :       }
     226           0 :       break;
     227             :     case nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED:
     228           0 :       switch (aState) {
     229             :         case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME:
     230           0 :           break;
     231             :         case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
     232           0 :           StartSpan(); // for highlighting the slash
     233           0 :           mSlash = CurrentNode();
     234           0 :           break;
     235             :         default:
     236           0 :           FinishTag();
     237           0 :           break;
     238             :       }
     239           0 :       break;
     240             :     case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
     241           0 :       EndSpanOrA(); // end the slash highlight
     242           0 :       switch (aState) {
     243             :         case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME:
     244           0 :           break;
     245             :         default:
     246           0 :           FinishTag();
     247           0 :           break;
     248             :       }
     249           0 :       break;
     250             :     case nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED:
     251           0 :       switch (aState) {
     252             :         case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME:
     253           0 :           EndSpanOrA();
     254           0 :           break;
     255             :         case nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE:
     256           0 :           StartSpan();
     257           0 :           StartSpan(); // for ampersand itself
     258           0 :           mAmpersand = CurrentNode();
     259           0 :           break;
     260             :         default:
     261           0 :           FinishTag();
     262           0 :           break;
     263             :       }
     264           0 :       break;
     265             :     case nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME:
     266           0 :       switch (aState) {
     267             :         case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
     268           0 :           StartSpan(); // for highlighting the slash
     269           0 :           mSlash = CurrentNode();
     270           0 :           break;
     271             :         case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE:
     272           0 :           break;
     273             :         case nsHtml5Tokenizer::ATTRIBUTE_NAME:
     274           0 :           StartSpan(sAttributeName);
     275           0 :           break;
     276             :         default:
     277           0 :           FinishTag();
     278           0 :           break;
     279             :       }
     280           0 :       break;
     281             :       // most comment states are omitted, because they don't matter to
     282             :       // highlighting
     283             :     case nsHtml5Tokenizer::COMMENT_START:
     284             :     case nsHtml5Tokenizer::COMMENT_END:
     285             :     case nsHtml5Tokenizer::COMMENT_END_BANG:
     286             :     case nsHtml5Tokenizer::COMMENT_START_DASH:
     287             :     case nsHtml5Tokenizer::BOGUS_COMMENT:
     288             :     case nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN:
     289           0 :       if (aState == nsHtml5Tokenizer::DATA) {
     290           0 :         AddClass(sComment);
     291           0 :         FinishTag();
     292             :       }
     293           0 :       break;
     294             :     // most cdata states are omitted, because they don't matter to
     295             :     // highlighting
     296             :     case nsHtml5Tokenizer::CDATA_RSQB_RSQB:
     297           0 :       if (aState == nsHtml5Tokenizer::DATA) {
     298           0 :         AddClass(sCdata);
     299           0 :         FinishTag();
     300             :       }
     301           0 :       break;
     302             :     case nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE:
     303           0 :       EndSpanOrA(); // the span for the ampersand
     304           0 :       switch (aState) {
     305             :         case nsHtml5Tokenizer::CONSUME_NCR:
     306             :         case nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP:
     307           0 :           break;
     308             :         default:
     309             :           // not actually a character reference
     310           0 :           EndSpanOrA();
     311           0 :           break;
     312             :       }
     313           0 :       break;
     314             :     case nsHtml5Tokenizer::CHARACTER_REFERENCE_HILO_LOOKUP:
     315           0 :       if (aState == nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL) {
     316           0 :         break;
     317             :       }
     318             :       // not actually a character reference
     319           0 :       EndSpanOrA();
     320           0 :       break;
     321             :     case nsHtml5Tokenizer::CHARACTER_REFERENCE_TAIL:
     322           0 :       if (!aReconsume) {
     323           0 :         FlushCurrent();
     324             :       }
     325           0 :       EndSpanOrA();
     326           0 :       break;
     327             :     case nsHtml5Tokenizer::DECIMAL_NRC_LOOP:
     328             :     case nsHtml5Tokenizer::HEX_NCR_LOOP:
     329           0 :       switch (aState) {
     330             :         case nsHtml5Tokenizer::HANDLE_NCR_VALUE:
     331           0 :           AddClass(sEntity);
     332           0 :           FlushCurrent();
     333           0 :           break;
     334             :         case nsHtml5Tokenizer::HANDLE_NCR_VALUE_RECONSUME:
     335           0 :           AddClass(sEntity);
     336           0 :           break;
     337             :       }
     338           0 :       EndSpanOrA();
     339           0 :       break;
     340             :     case nsHtml5Tokenizer::CLOSE_TAG_OPEN:
     341           0 :       switch (aState) {
     342             :         case nsHtml5Tokenizer::DATA:
     343           0 :           FinishTag();
     344           0 :           break;
     345             :         case nsHtml5Tokenizer::TAG_NAME:
     346           0 :           StartSpan(sEndTag);
     347           0 :           break;
     348             :       }
     349           0 :       break;
     350             :     case nsHtml5Tokenizer::RAWTEXT_RCDATA_LESS_THAN_SIGN:
     351           0 :       if (aState == nsHtml5Tokenizer::NON_DATA_END_TAG_NAME) {
     352           0 :         FlushCurrent();
     353           0 :         StartSpan(); // don't know if it is "end-tag" yet :-(
     354           0 :         break;
     355             :       }
     356           0 :       EndSpanOrA();
     357           0 :       StartCharacters();
     358           0 :       break;
     359             :     case nsHtml5Tokenizer::NON_DATA_END_TAG_NAME:
     360           0 :       switch (aState) {
     361             :         case nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME:
     362           0 :           AddClass(sEndTag);
     363           0 :           EndSpanOrA();
     364           0 :           break;
     365             :         case nsHtml5Tokenizer::SELF_CLOSING_START_TAG:
     366           0 :           AddClass(sEndTag);
     367           0 :           EndSpanOrA();
     368           0 :           StartSpan(); // for highlighting the slash
     369           0 :           mSlash = CurrentNode();
     370           0 :           break;
     371             :         case nsHtml5Tokenizer::DATA: // yes, as a result of emitting the token
     372           0 :           AddClass(sEndTag);
     373           0 :           FinishTag();
     374           0 :           break;
     375             :         default:
     376           0 :           FinishTag();
     377           0 :           break;
     378             :       }
     379           0 :       break;
     380             :     case nsHtml5Tokenizer::SCRIPT_DATA_LESS_THAN_SIGN:
     381             :     case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
     382           0 :       if (aState == nsHtml5Tokenizer::NON_DATA_END_TAG_NAME) {
     383           0 :         FlushCurrent();
     384           0 :         StartSpan(); // don't know if it is "end-tag" yet :-(
     385           0 :         break;
     386             :       }
     387           0 :       FinishTag();
     388           0 :       break;
     389             :     case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH_DASH:
     390             :     case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED:
     391             :     case nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_DASH:
     392           0 :       if (aState == nsHtml5Tokenizer::SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN) {
     393           0 :         EndCharactersAndStartMarkupRun();
     394             :       }
     395           0 :       break;
     396             :     // Lots of double escape states omitted, because they don't highlight.
     397             :     // Likewise, only doctype states that can emit the doctype are of
     398             :     // interest. Otherwise, the transition out of bogus comment deals.
     399             :     case nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME:
     400             :     case nsHtml5Tokenizer::DOCTYPE_NAME:
     401             :     case nsHtml5Tokenizer::AFTER_DOCTYPE_NAME:
     402             :     case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD:
     403             :     case nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
     404             :     case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
     405             :     case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
     406             :     case nsHtml5Tokenizer::BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
     407             :     case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
     408             :     case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
     409             :     case nsHtml5Tokenizer::BOGUS_DOCTYPE:
     410             :     case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD:
     411             :     case nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
     412             :     case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
     413             :     case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
     414           0 :       if (aState == nsHtml5Tokenizer::DATA) {
     415           0 :         AddClass(sDoctype);
     416           0 :         FinishTag();
     417             :       }
     418           0 :       break;
     419             :     case nsHtml5Tokenizer::PROCESSING_INSTRUCTION_QUESTION_MARK:
     420           0 :       if (aState == nsHtml5Tokenizer::DATA) {
     421           0 :         FinishTag();
     422             :       }
     423           0 :       break;
     424             :     default:
     425           0 :       break;
     426             :   }
     427           0 :   mState = aState;
     428           0 :   return aState;
     429             : }
     430             : 
     431             : void
     432           0 : nsHtml5Highlighter::End()
     433             : {
     434           0 :   switch (mState) {
     435             :     case nsHtml5Tokenizer::COMMENT_END:
     436             :     case nsHtml5Tokenizer::COMMENT_END_BANG:
     437             :     case nsHtml5Tokenizer::COMMENT_START_DASH:
     438             :     case nsHtml5Tokenizer::BOGUS_COMMENT:
     439             :     case nsHtml5Tokenizer::BOGUS_COMMENT_HYPHEN:
     440           0 :       AddClass(sComment);
     441           0 :       break;
     442             :     case nsHtml5Tokenizer::CDATA_RSQB_RSQB:
     443           0 :       AddClass(sCdata);
     444           0 :       break;
     445             :     case nsHtml5Tokenizer::DECIMAL_NRC_LOOP:
     446             :     case nsHtml5Tokenizer::HEX_NCR_LOOP:
     447             :       // XXX need tokenizer help here
     448           0 :       break;
     449             :     case nsHtml5Tokenizer::BEFORE_DOCTYPE_NAME:
     450             :     case nsHtml5Tokenizer::DOCTYPE_NAME:
     451             :     case nsHtml5Tokenizer::AFTER_DOCTYPE_NAME:
     452             :     case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_KEYWORD:
     453             :     case nsHtml5Tokenizer::BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
     454             :     case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
     455             :     case nsHtml5Tokenizer::AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
     456             :     case nsHtml5Tokenizer::BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
     457             :     case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
     458             :     case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
     459             :     case nsHtml5Tokenizer::BOGUS_DOCTYPE:
     460             :     case nsHtml5Tokenizer::AFTER_DOCTYPE_SYSTEM_KEYWORD:
     461             :     case nsHtml5Tokenizer::BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
     462             :     case nsHtml5Tokenizer::DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
     463             :     case nsHtml5Tokenizer::DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
     464           0 :       AddClass(sDoctype);
     465           0 :       break;
     466             :     default:
     467           0 :       break;
     468             :   }
     469           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     470           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     471           0 :   treeOp->Init(eTreeOpStreamEnded);
     472           0 :   FlushOps();
     473           0 : }
     474             : 
     475             : void
     476           0 : nsHtml5Highlighter::SetBuffer(nsHtml5UTF16Buffer* aBuffer)
     477             : {
     478           0 :   NS_PRECONDITION(!mBuffer, "Old buffer still here!");
     479           0 :   mBuffer = aBuffer;
     480           0 :   mCStart = aBuffer->getStart();
     481           0 : }
     482             : 
     483             : void
     484           0 : nsHtml5Highlighter::DropBuffer(int32_t aPos)
     485             : {
     486           0 :   NS_PRECONDITION(mBuffer, "No buffer to drop!");
     487           0 :   mPos = aPos;
     488           0 :   FlushChars();
     489           0 :   mBuffer = nullptr;
     490           0 : }
     491             : 
     492             : void
     493           0 : nsHtml5Highlighter::StartSpan()
     494             : {
     495           0 :   FlushChars();
     496           0 :   Push(nsGkAtoms::span, nullptr);
     497           0 :   ++mInlinesOpen;
     498           0 : }
     499             : 
     500             : void
     501           0 : nsHtml5Highlighter::StartSpan(const char16_t* aClass)
     502             : {
     503           0 :   StartSpan();
     504           0 :   AddClass(aClass);
     505           0 : }
     506             : 
     507             : void
     508           0 : nsHtml5Highlighter::EndSpanOrA()
     509             : {
     510           0 :   FlushChars();
     511           0 :   Pop();
     512           0 :   --mInlinesOpen;
     513           0 : }
     514             : 
     515             : void
     516           0 : nsHtml5Highlighter::StartCharacters()
     517             : {
     518           0 :   NS_PRECONDITION(!mInCharacters, "Already in characters!");
     519           0 :   FlushChars();
     520           0 :   Push(nsGkAtoms::span, nullptr);
     521           0 :   mCurrentRun = CurrentNode();
     522           0 :   mInCharacters = true;
     523           0 : }
     524             : 
     525             : void
     526           0 : nsHtml5Highlighter::EndCharactersAndStartMarkupRun()
     527             : {
     528           0 :   NS_PRECONDITION(mInCharacters, "Not in characters!");
     529           0 :   FlushChars();
     530           0 :   Pop();
     531           0 :   mInCharacters = false;
     532             :   // Now start markup run
     533           0 :   StartSpan();
     534           0 :   mCurrentRun = CurrentNode();
     535           0 : }
     536             : 
     537             : void
     538           0 : nsHtml5Highlighter::StartA()
     539             : {
     540           0 :   FlushChars();
     541           0 :   Push(nsGkAtoms::a, nullptr);
     542           0 :   AddClass(sAttributeValue);
     543           0 :   ++mInlinesOpen;
     544           0 : }
     545             : 
     546             : void
     547           0 : nsHtml5Highlighter::FinishTag()
     548             : {
     549           0 :   while (mInlinesOpen > 1) {
     550           0 :     EndSpanOrA();
     551             :   }
     552           0 :   FlushCurrent(); // >
     553           0 :   EndSpanOrA(); // DATA
     554           0 :   NS_ASSERTION(!mInlinesOpen, "mInlinesOpen got out of sync!");
     555           0 :   StartCharacters();
     556           0 : }
     557             : 
     558             : void
     559           0 : nsHtml5Highlighter::FlushChars()
     560             : {
     561           0 :   if (mCStart < mPos) {
     562           0 :     char16_t* buf = mBuffer->getBuffer();
     563           0 :     int32_t i = mCStart;
     564           0 :     while (i < mPos) {
     565           0 :       char16_t c = buf[i];
     566           0 :       switch (c) {
     567             :         case '\r':
     568             :           // The input this code sees has been normalized so that there are
     569             :           // CR breaks and LF breaks but no CRLF breaks. Overwrite CR with LF
     570             :           // to show consistent LF line breaks to layout. It is OK to mutate
     571             :           // the input data, because there are no reparses in the View Source
     572             :           // case, so we won't need the original data in the buffer anymore.
     573           0 :           buf[i] = '\n';
     574             :           MOZ_FALLTHROUGH;
     575             :         case '\n': {
     576           0 :           ++i;
     577           0 :           if (mCStart < i) {
     578           0 :             int32_t len = i - mCStart;
     579           0 :             AppendCharacters(buf, mCStart, len);
     580           0 :             mCStart = i;
     581             :           }
     582           0 :           ++mLineNumber;
     583           0 :           Push(nsGkAtoms::span, nullptr);
     584           0 :           nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     585           0 :           NS_ASSERTION(treeOp, "Tree op allocation failed.");
     586           0 :           treeOp->InitAddLineNumberId(CurrentNode(), mLineNumber);
     587           0 :           Pop();
     588           0 :           break;
     589             :         }
     590             :         default:
     591           0 :           ++i;
     592           0 :           break;
     593             :       }
     594             :     }
     595           0 :     if (mCStart < mPos) {
     596           0 :       int32_t len = mPos - mCStart;
     597           0 :       AppendCharacters(buf, mCStart, len);
     598           0 :       mCStart = mPos;
     599             :     }
     600             :   }
     601           0 : }
     602             : 
     603             : void
     604           0 : nsHtml5Highlighter::FlushCurrent()
     605             : {
     606           0 :   mPos++;
     607           0 :   FlushChars();
     608           0 : }
     609             : 
     610             : bool
     611           0 : nsHtml5Highlighter::FlushOps()
     612             : {
     613           0 :   bool hasOps = !mOpQueue.IsEmpty();
     614           0 :   if (hasOps) {
     615           0 :     mOpSink->MoveOpsFrom(mOpQueue);
     616             :   }
     617           0 :   return hasOps;
     618             : }
     619             : 
     620             : void
     621           0 : nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
     622             :                                                nsHtml5String aValue)
     623             : {
     624           0 :   if (!(nsHtml5AttributeName::ATTR_HREF == aName ||
     625           0 :         nsHtml5AttributeName::ATTR_SRC == aName ||
     626           0 :         nsHtml5AttributeName::ATTR_ACTION == aName ||
     627           0 :         nsHtml5AttributeName::ATTR_CITE == aName ||
     628           0 :         nsHtml5AttributeName::ATTR_BACKGROUND == aName ||
     629           0 :         nsHtml5AttributeName::ATTR_LONGDESC == aName ||
     630           0 :         nsHtml5AttributeName::ATTR_XLINK_HREF == aName ||
     631           0 :         nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) {
     632           0 :     return;
     633             :   }
     634           0 :   AddViewSourceHref(aValue);
     635             : }
     636             : 
     637             : void
     638           0 : nsHtml5Highlighter::CompletedNamedCharacterReference()
     639             : {
     640           0 :   AddClass(sEntity);
     641           0 : }
     642             : 
     643             : nsIContent**
     644           0 : nsHtml5Highlighter::AllocateContentHandle()
     645             : {
     646           0 :   if (mHandlesUsed == NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH) {
     647           0 :     mOldHandles.AppendElement(Move(mHandles));
     648           0 :     mHandles = MakeUnique<nsIContent*[]>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH);
     649           0 :     mHandlesUsed = 0;
     650             :   }
     651             : #ifdef DEBUG
     652           0 :   mHandles[mHandlesUsed] = reinterpret_cast<nsIContent*>(uintptr_t(0xC0DEDBAD));
     653             : #endif
     654           0 :   return &mHandles[mHandlesUsed++];
     655             : }
     656             : 
     657             : nsIContent**
     658           0 : nsHtml5Highlighter::CreateElement(nsIAtom* aName,
     659             :                                   nsHtml5HtmlAttributes* aAttributes,
     660             :                                   nsIContent** aIntendedParent)
     661             : {
     662           0 :   NS_PRECONDITION(aName, "Got null name.");
     663           0 :   nsIContent** content = AllocateContentHandle();
     664           0 :   mOpQueue.AppendElement()->Init(kNameSpaceID_XHTML,
     665             :                                  aName,
     666             :                                  aAttributes,
     667             :                                  content,
     668             :                                  aIntendedParent,
     669           0 :                                  true);
     670           0 :   return content;
     671             : }
     672             : 
     673             : nsIContent**
     674           0 : nsHtml5Highlighter::CurrentNode()
     675             : {
     676           0 :   NS_PRECONDITION(mStack.Length() >= 1, "Must have something on stack.");
     677           0 :   return mStack[mStack.Length() - 1];
     678             : }
     679             : 
     680             : void
     681           0 : nsHtml5Highlighter::Push(nsIAtom* aName,
     682             :                          nsHtml5HtmlAttributes* aAttributes)
     683             : {
     684           0 :   NS_PRECONDITION(mStack.Length() >= 1, "Pushing without root.");
     685           0 :   nsIContent** elt = CreateElement(aName, aAttributes, CurrentNode()); // Don't inline below!
     686           0 :   mOpQueue.AppendElement()->Init(eTreeOpAppend, elt, CurrentNode());
     687           0 :   mStack.AppendElement(elt);
     688           0 : }
     689             : 
     690             : void
     691           0 : nsHtml5Highlighter::Pop()
     692             : {
     693           0 :   NS_PRECONDITION(mStack.Length() >= 2, "Popping when stack too short.");
     694           0 :   mStack.RemoveElementAt(mStack.Length() - 1);
     695           0 : }
     696             : 
     697             : void
     698           0 : nsHtml5Highlighter::AppendCharacters(const char16_t* aBuffer,
     699             :                                      int32_t aStart,
     700             :                                      int32_t aLength)
     701             : {
     702           0 :   NS_PRECONDITION(aBuffer, "Null buffer");
     703             : 
     704           0 :   char16_t* bufferCopy = new char16_t[aLength];
     705           0 :   memcpy(bufferCopy, aBuffer + aStart, aLength * sizeof(char16_t));
     706             : 
     707           0 :   mOpQueue.AppendElement()->Init(eTreeOpAppendText,
     708             :                                  bufferCopy,
     709             :                                  aLength,
     710           0 :                                  CurrentNode());
     711           0 : }
     712             : 
     713             : 
     714             : void
     715           0 : nsHtml5Highlighter::AddClass(const char16_t* aClass)
     716             : {
     717           0 :   mOpQueue.AppendElement()->InitAddClass(CurrentNode(), aClass);
     718           0 : }
     719             : 
     720             : void
     721           0 : nsHtml5Highlighter::AddViewSourceHref(nsHtml5String aValue)
     722             : {
     723           0 :   char16_t* bufferCopy = new char16_t[aValue.Length() + 1];
     724           0 :   aValue.CopyToBuffer(bufferCopy);
     725           0 :   bufferCopy[aValue.Length()] = 0;
     726             : 
     727           0 :   mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceHref,
     728             :                                  bufferCopy,
     729           0 :                                  aValue.Length(),
     730           0 :                                  CurrentNode());
     731           0 : }
     732             : 
     733             : void
     734           0 : nsHtml5Highlighter::AddBase(nsHtml5String aValue)
     735             : {
     736           0 :   if(mSeenBase) {
     737           0 :     return;
     738             :   }
     739           0 :   mSeenBase = true;
     740           0 :   char16_t* bufferCopy = new char16_t[aValue.Length() + 1];
     741           0 :   aValue.CopyToBuffer(bufferCopy);
     742           0 :   bufferCopy[aValue.Length()] = 0;
     743             : 
     744           0 :   mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceBase,
     745             :                                  bufferCopy,
     746           0 :                                  aValue.Length());
     747             : }
     748             : 
     749             : void
     750           0 : nsHtml5Highlighter::AddErrorToCurrentNode(const char* aMsgId)
     751             : {
     752           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     753           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     754           0 :   treeOp->Init(CurrentNode(), aMsgId);
     755           0 : }
     756             : 
     757             : void
     758           0 : nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId)
     759             : {
     760           0 :   NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
     761           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     762           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     763           0 :   treeOp->Init(mCurrentRun, aMsgId);
     764           0 : }
     765             : 
     766             : void
     767           0 : nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
     768             :                                          nsIAtom* aName)
     769             : {
     770           0 :   NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
     771           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     772           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     773           0 :   treeOp->Init(mCurrentRun, aMsgId, aName);
     774           0 : }
     775             : 
     776             : void
     777           0 : nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
     778             :                                          nsIAtom* aName,
     779             :                                          nsIAtom* aOther)
     780             : {
     781           0 :   NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
     782           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     783           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     784           0 :   treeOp->Init(mCurrentRun, aMsgId, aName, aOther);
     785           0 : }
     786             : 
     787             : void
     788           0 : nsHtml5Highlighter::AddErrorToCurrentAmpersand(const char* aMsgId)
     789             : {
     790           0 :   NS_PRECONDITION(mAmpersand, "Adding error to ampersand without one!");
     791           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     792           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     793           0 :   treeOp->Init(mAmpersand, aMsgId);
     794           0 : }
     795             : 
     796             : void
     797           0 : nsHtml5Highlighter::AddErrorToCurrentSlash(const char* aMsgId)
     798             : {
     799           0 :   NS_PRECONDITION(mSlash, "Adding error to slash without one!");
     800           0 :   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     801           0 :   NS_ASSERTION(treeOp, "Tree op allocation failed.");
     802           0 :   treeOp->Init(mSlash, aMsgId);
     803           0 : }

Generated by: LCOV version 1.13