Bug 482921 part 14 - Address review comments. r=Olli.Pettay.
authorHenri Sivonen <hsivonen@iki.fi>
Tue, 01 Nov 2011 13:33:11 +0200
changeset 79518 d9cc2539a85dfbdd9b27b94731e77b0cba6e23ae
parent 79517 c890f75cf0f31876d285a60775a6d936b72e9814
child 79519 cd9add22f090445f1d73e999aaa4c0050b8e4e16
push id21408
push userkhuey@mozilla.com
push dateTue, 01 Nov 2011 14:32:20 +0000
treeherdermozilla-central@cd9add22f090 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersOlli.Pettay
bugs482921
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 482921 part 14 - Address review comments. r=Olli.Pettay.
parser/html/javasrc/TreeBuilder.java
parser/html/nsHtml5Highlighter.cpp
parser/html/nsHtml5Highlighter.h
parser/html/nsHtml5StreamParser.cpp
parser/html/nsHtml5Tokenizer.cpp
parser/html/nsHtml5TokenizerCppSupplement.h
parser/html/nsHtml5TokenizerLoopPolicies.h
parser/html/nsHtml5TreeBuilderHSupplement.h
parser/html/nsHtml5TreeOpExecutor.cpp
parser/html/nsHtml5TreeOperation.cpp
--- a/parser/html/javasrc/TreeBuilder.java
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -863,16 +863,18 @@ public abstract class TreeBuilder<T> imp
     }
 
     /**
      * @see nu.validator.htmlparser.common.TokenHandler#characters(char[], int,
      *      int)
      */
     public final void characters(@Const @NoLength char[] buf, int start, int length)
             throws SAXException {
+        // Note: Can't attach error messages to EOF in C++ yet
+
         // CPPONLY: if (tokenizer.isViewingXmlSource()) {
         // CPPONLY: return;
         // CPPONLY: }
         if (needToDropLF) {
             needToDropLF = false;
             if (buf[start] == '\n') {
                 start++;
                 length--;
@@ -1266,16 +1268,17 @@ public abstract class TreeBuilder<T> imp
                 return;
             }
             accumulateCharacters(REPLACEMENT_CHARACTER, 0, 1);
         }
     }
 
     public final void eof() throws SAXException {
         flushCharacters();
+        // Note: Can't attach error messages to EOF in C++ yet
         eofloop: for (;;) {
             if (isInForeign()) {
                 // [NOCPP[
                 err("End of file in a foreign namespace context.");
                 // ]NOCPP]
                 break eofloop;
             }
             switch (mode) {
--- a/parser/html/nsHtml5Highlighter.cpp
+++ b/parser/html/nsHtml5Highlighter.cpp
@@ -200,20 +200,20 @@ nsHtml5Highlighter::Transition(PRInt32 a
         case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION:
           AddClass(sPi);
           break;
       }
       break;
     case NS_HTML5TOKENIZER_TAG_NAME:
       switch (aState) {
         case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
-          EndInline(); // NS_HTML5TOKENIZER_TAG_NAME
+          EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
           break;
         case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
-          EndInline(); // NS_HTML5TOKENIZER_TAG_NAME
+          EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
           StartSpan(); // for highlighting the slash
           mSlash = CurrentNode();
           break;
         default:
           FinishTag();
           break;
       }
       break;
@@ -230,20 +230,20 @@ nsHtml5Highlighter::Transition(PRInt32 a
           FinishTag();
           break;
       }
       break;
     case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
       switch (aState) {
         case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
         case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
-          EndInline(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
+          EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
           break;
         case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
-          EndInline(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
+          EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
           StartSpan(); // for highlighting the slash
           mSlash = CurrentNode();
           break;
         default:
           FinishTag();
           break;
       }
       break;
@@ -261,17 +261,17 @@ nsHtml5Highlighter::Transition(PRInt32 a
           FinishTag();
           break;
       }
       break;
     case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
     case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
       switch (aState) {
         case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
-          EndInline();
+          EndSpanOrA();
           break;
         case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
           StartSpan();
           StartSpan(); // for ampersand itself
           mAmpersand = CurrentNode();
           break;
         default:
           NS_NOTREACHED("Impossible transition.");
@@ -287,29 +287,29 @@ nsHtml5Highlighter::Transition(PRInt32 a
           mSlash = CurrentNode();
           break;
         default:
           FinishTag();
           break;
       }
       break;
     case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
-      EndInline(); // end the slash highlight
+      EndSpanOrA(); // end the slash highlight
       switch (aState) {
         case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
           break;
         default:
           FinishTag();
           break;
       }
       break;
     case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED:
       switch (aState) {
         case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
-          EndInline();
+          EndSpanOrA();
           break;
         case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
           StartSpan();
           StartSpan(); // for ampersand itself
           mAmpersand = CurrentNode();
           break;
         default:
           FinishTag();
@@ -348,52 +348,52 @@ nsHtml5Highlighter::Transition(PRInt32 a
       // highlighting
     case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB:
       if (aState == NS_HTML5TOKENIZER_DATA) {
         AddClass(sCdata);
         FinishTag();
       }
       break;
     case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
-      EndInline(); // the span for the ampersand
+      EndSpanOrA(); // the span for the ampersand
       switch (aState) {
         case NS_HTML5TOKENIZER_CONSUME_NCR:
         case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
           break;
         default:
           // not actually a character reference
-          EndInline();
+          EndSpanOrA();
           break;
       }
       break;
     case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
       if (aState == NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL) {
         break;
       }
       // not actually a character reference
-      EndInline();
+      EndSpanOrA();
       break;
     case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL:
       if (!aReconsume) {
         FlushCurrent();
       }
-      EndInline();
+      EndSpanOrA();
       break;
     case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
     case NS_HTML5TOKENIZER_HEX_NCR_LOOP:
       switch (aState) {
         case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE:
           AddClass(sEntity);
           FlushCurrent();
           break;
         case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE_RECONSUME:
           AddClass(sEntity);
           break;
       }
-      EndInline();
+      EndSpanOrA();
       break;
     case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN:
       switch (aState) {
         case NS_HTML5TOKENIZER_DATA:
           FinishTag();
           break;
         case NS_HTML5TOKENIZER_TAG_NAME:
           StartSpan(sEndTag);
@@ -401,28 +401,28 @@ nsHtml5Highlighter::Transition(PRInt32 a
       }
       break;
     case NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN:
       if (aState == NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME) {
         FlushCurrent();
         StartSpan(); // don't know if it is "end-tag" yet :-(
         break;
       }
-      EndInline();
+      EndSpanOrA();
       StartCharacters();
       break;
     case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME:
       switch (aState) {
         case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
           AddClass(sEndTag);
-          EndInline();
+          EndSpanOrA();
           break;
         case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
           AddClass(sEndTag);
-          EndInline();
+          EndSpanOrA();
           StartSpan(); // for highlighting the slash
           mSlash = CurrentNode();
           break;
         case NS_HTML5TOKENIZER_DATA: // yes, as a result of emitting the token
           AddClass(sEndTag);
           FinishTag();
           break;
         default:
@@ -552,17 +552,17 @@ nsHtml5Highlighter::StartSpan()
 void
 nsHtml5Highlighter::StartSpan(const PRUnichar* aClass)
 {
   StartSpan();
   AddClass(aClass);
 }
 
 void
-nsHtml5Highlighter::EndInline()
+nsHtml5Highlighter::EndSpanOrA()
 {
   FlushChars();
   Pop();
   --mInlinesOpen;
 }
 
 void
 nsHtml5Highlighter::StartCharacters()
@@ -591,20 +591,20 @@ nsHtml5Highlighter::StartA()
   AddClass(sAttributeValue);
   ++mInlinesOpen;
 }
 
 void
 nsHtml5Highlighter::FinishTag()
 {
   while (mInlinesOpen > 1) {
-    EndInline();
+    EndSpanOrA();
   }
   FlushCurrent(); // >
-  EndInline(); // DATA
+  EndSpanOrA(); // DATA
   NS_ASSERTION(!mInlinesOpen, "mInlinesOpen got out of sync!");
   StartCharacters();
 }
 
 void
 nsHtml5Highlighter::FlushChars()
 {
   if (mCStart < mPos) {
@@ -680,24 +680,24 @@ nsHtml5Highlighter::FlushOps()
   }
   return hasOps;
 }
 
 void
 nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
                                                nsString* aValue)
 {
-  if (!(nsHtml5AttributeName::ATTR_HREF == aName
-      || nsHtml5AttributeName::ATTR_SRC == aName
-      || nsHtml5AttributeName::ATTR_ACTION == aName
-      || nsHtml5AttributeName::ATTR_CITE == aName
-      || nsHtml5AttributeName::ATTR_BACKGROUND == aName
-      || nsHtml5AttributeName::ATTR_LONGDESC == aName
-      || nsHtml5AttributeName::ATTR_XLINK_HREF == aName
-      || nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) {
+  if (!(nsHtml5AttributeName::ATTR_HREF == aName ||
+        nsHtml5AttributeName::ATTR_SRC == aName ||
+        nsHtml5AttributeName::ATTR_ACTION == aName ||
+        nsHtml5AttributeName::ATTR_CITE == aName ||
+        nsHtml5AttributeName::ATTR_BACKGROUND == aName ||
+        nsHtml5AttributeName::ATTR_LONGDESC == aName ||
+        nsHtml5AttributeName::ATTR_XLINK_HREF == aName ||
+        nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) {
     return;
   }
   AddViewSourceHref(*aValue);
 }
 
 void
 nsHtml5Highlighter::CompletedNamedCharacterReference()
 {
--- a/parser/html/nsHtml5Highlighter.h
+++ b/parser/html/nsHtml5Highlighter.h
@@ -187,19 +187,19 @@ class nsHtml5Highlighter
      * Starts a <span> and sets the class attribute on it.
      *
      * @param aClass the class to set (MUST be a static string that does not
      *        need to be released!)
      */
     void StartSpan(const PRUnichar* aClass);
 
     /**
-     * End the current <span> or <a>.
+     * End the current <span> or <a> in the highlighter output.
      */
-    void EndInline();
+    void EndSpanOrA();
 
     /**
      * Starts a wrapper around a run of characters.
      */
     void StartCharacters();
 
     /**
      * Ends a wrapper around a run of characters.
@@ -217,32 +217,37 @@ class nsHtml5Highlighter
     void FlushChars();
 
     /**
      * Flushes characters up to and including the current one.
      */
     void FlushCurrent();
 
     /**
-     * Finishes a source tag being highlighted by closing the open <span> and
-     * <a> elements.
+     * Finishes highlighting a tag in the input data by closing the open
+     * <span> and <a> elements in the highlighter output and then starts
+     * another <span> for potentially highlighting characters potentially
+     * appearing next.
      */
     void FinishTag();
 
     /**
      * Adds a class attribute to the current node.
      *
      * @param aClass the class to set (MUST be a static string that does not
      *        need to be released!)
      */
     void AddClass(const PRUnichar* aClass);
 
     /**
      * Allocates a handle for an element.
      *
+     * See the documentation for nsHtml5TreeBuilder::AllocateContentHandle()
+     * in nsHtml5TreeBuilderHSupplement.h.
+     *
      * @return the handle
      */
     nsIContent** AllocateContentHandle();
 
     /**
      * Enqueues an element creation tree operation.
      *
      * @param aName the name of the element
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -511,16 +511,24 @@ nsHtml5StreamParser::FinalizeSniffing(co
     ud.mExpat = XML_ParserCreate_MM(kISO88591, &memsuite, kExpatSeparator);
     XML_SetXmlDeclHandler(ud.mExpat, HandleXMLDeclaration);
     XML_SetElementHandler(ud.mExpat, HandleStartElement, HandleEndElement);
     XML_SetCommentHandler(ud.mExpat, HandleComment);
     XML_SetProcessingInstructionHandler(ud.mExpat, HandleProcessingInstruction);
     XML_SetUserData(ud.mExpat, static_cast<void*>(&ud));
 
     XML_Status status = XML_STATUS_OK;
+
+    // aFromSegment points to the data obtained from the current network
+    // event. mSniffingBuffer (if it exists) contains the data obtained before
+    // the current event. Thus, mSniffingLenth bytes of mSniffingBuffer
+    // followed by aCountToSniffingLimit bytes from aFromSegment are the
+    // first 1024 bytes of the file (or the file as a whole if the file is
+    // 1024 bytes long or shorter). Thus, we parse both buffers, but if the
+    // first call succeeds already, we skip parsing the second buffer.
     if (mSniffingBuffer) {
       status = XML_Parse(ud.mExpat,
                          reinterpret_cast<const char*>(mSniffingBuffer.get()),
                          mSniffingLength,
                          false);
     }
     if (status == XML_STATUS_OK &&
         mCharsetSource < kCharsetFromMetaTag &&
@@ -677,18 +685,18 @@ nsHtml5StreamParser::SniffStreamBytes(co
     mMetaScanner = new nsHtml5MetaScanner();
   }
   
   if (mSniffingLength + aCount >= NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE) {
     // this is the last buffer
     PRUint32 countToSniffingLimit =
         NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE - mSniffingLength;
     if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML) {
-      nsHtml5ByteReadable readable(aFromSegment, aFromSegment
-          + countToSniffingLimit);
+      nsHtml5ByteReadable readable(aFromSegment, aFromSegment +
+          countToSniffingLimit);
       mMetaScanner->sniff(&readable, getter_AddRefs(mUnicodeDecoder), mCharset);
       if (mUnicodeDecoder) {
         mUnicodeDecoder->SetInputErrorBehavior(
             nsIUnicodeDecoder::kOnError_Recover);
         // meta scan successful
         mCharsetSource = kCharsetFromMetaPrescan;
         mFeedChardet = false;
         mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
--- a/parser/html/nsHtml5Tokenizer.cpp
+++ b/parser/html/nsHtml5Tokenizer.cpp
@@ -491,34 +491,34 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_CLOSE_TAG_OPEN, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\?': {
               if (viewingXmlSource) {
                 state = P::transition(mViewSource, NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION, reconsume, pos);
                 NS_HTML5_CONTINUE(stateloop);
               }
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errProcessingInstruction();
               }
               clearLongStrBufAndAppend(c);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errLtGt();
               }
               tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2);
               cstart = pos + 1;
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             default: {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errBadCharAfterLt(c);
               }
               tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
               cstart = pos;
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               reconsume = true;
               NS_HTML5_CONTINUE(stateloop);
             }
@@ -612,17 +612,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             }
             case '\0': {
               c = 0xfffd;
             }
             case '\"':
             case '\'':
             case '<':
             case '=': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errBadCharBeforeAttributeNameOrNull(c);
               }
             }
             default: {
               if (c >= 'A' && c <= 'Z') {
                 c += 0x20;
               }
               clearStrBufAndAppend(c);
@@ -677,17 +677,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             case '\"':
             case '\'':
             case '<': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errQuoteOrLtInAttributeNameOrNull(c);
               }
             }
             default: {
               if (c >= 'A' && c <= 'Z') {
                 c += 0x20;
               }
               appendStrBuf(c);
@@ -729,33 +729,33 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\'': {
               clearLongStrBuf();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errAttributeValueMissing();
               }
               addAttributeWithoutValue();
               state = P::transition(mViewSource, emitCurrentTagToken(false, pos), reconsume, pos);
               if (shouldSuspend) {
                 NS_HTML5_BREAK(stateloop);
               }
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             case '<':
             case '=':
             case '`': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
               }
             }
             default: {
               clearLongStrBufAndAppend(c);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED, reconsume, pos);
 
               NS_HTML5_CONTINUE(stateloop);
@@ -834,17 +834,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             case '>': {
               state = P::transition(mViewSource, emitCurrentTagToken(false, pos), reconsume, pos);
               if (shouldSuspend) {
                 NS_HTML5_BREAK(stateloop);
               }
               NS_HTML5_CONTINUE(stateloop);
             }
             default: {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoSpaceBetweenAttributes();
               }
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
               reconsume = true;
               NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
@@ -859,17 +859,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           case '>': {
             state = P::transition(mViewSource, emitCurrentTagToken(true, pos), reconsume, pos);
             if (shouldSuspend) {
               NS_HTML5_BREAK(stateloop);
             }
             NS_HTML5_CONTINUE(stateloop);
           }
           default: {
-            if (P::viewingSource) {
+            if (P::reportErrors) {
               errSlashNotFollowedByGt();
             }
             state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME, reconsume, pos);
             reconsume = true;
             NS_HTML5_CONTINUE(stateloop);
           }
         }
       }
@@ -918,17 +918,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             case '\0': {
               c = 0xfffd;
             }
             case '<':
             case '\"':
             case '\'':
             case '=':
             case '`': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errUnquotedAttributeValOrNull(c);
               }
             }
             default: {
 
               appendLongStrBuf(c);
               continue;
             }
@@ -972,17 +972,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
             }
             case '\"':
             case '\'':
             case '<': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errQuoteOrLtInAttributeNameOrNull(c);
               }
             }
             default: {
               addAttributeWithoutValue();
               if (c >= 'A' && c <= 'Z') {
                 c += 0x20;
               }
@@ -1016,17 +1016,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               if (tokenHandler->cdataSectionAllowed()) {
                 clearLongStrBufAndAppend(c);
                 index = 0;
                 state = P::transition(mViewSource, NS_HTML5TOKENIZER_CDATA_START, reconsume, pos);
                 NS_HTML5_CONTINUE(stateloop);
               }
             }
             default: {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errBogusComment();
               }
               clearLongStrBuf();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
               reconsume = true;
               NS_HTML5_CONTINUE(stateloop);
             }
           }
@@ -1044,17 +1044,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               NS_HTML5_BREAK(stateloop);
             }
             case '-': {
               clearLongStrBuf();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT_START, reconsume, pos);
               NS_HTML5_BREAK(markupdeclarationhyphenloop);
             }
             default: {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errBogusComment();
               }
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
               reconsume = true;
               NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
@@ -1068,17 +1068,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           c = checkChar(buf, pos);
           switch(c) {
             case '-': {
               appendLongStrBuf(c);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT_START_DASH, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errPrematureEndOfComment();
               }
               emitComment(0, pos);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\r': {
               appendLongStrBufCarriageReturn();
@@ -1189,17 +1189,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               NS_HTML5_BREAK(stateloop);
             }
             case '\n': {
               adjustDoubleHyphenAndAppendToLongStrBufLineFeed();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '!': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errHyphenHyphenBang();
               }
               appendLongStrBuf(c);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT_END_BANG, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
               c = 0xfffd;
@@ -1256,17 +1256,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
         c = checkChar(buf, pos);
         switch(c) {
           case '-': {
             appendLongStrBuf(c);
             state = P::transition(mViewSource, NS_HTML5TOKENIZER_COMMENT_END, reconsume, pos);
             NS_HTML5_CONTINUE(stateloop);
           }
           case '>': {
-            if (P::viewingSource) {
+            if (P::reportErrors) {
               errPrematureEndOfComment();
             }
             emitComment(1, pos);
             state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
             NS_HTML5_CONTINUE(stateloop);
           }
           case '\r': {
             appendLongStrBufCarriageReturn();
@@ -1293,17 +1293,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           if (++pos == endPos) {
             NS_HTML5_BREAK(stateloop);
           }
           c = checkChar(buf, pos);
           if (index < 6) {
             if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) {
               appendLongStrBuf(c);
             } else {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errBogusComment();
               }
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
               reconsume = true;
               NS_HTML5_CONTINUE(stateloop);
             }
             index++;
             continue;
@@ -1469,17 +1469,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               reconsume = true;
               NS_HTML5_CONTINUE(stateloop);
             }
             if (c >= 'a' && c <= 'z') {
               firstCharKey = c - 'a' + 26;
             } else if (c >= 'A' && c <= 'Z') {
               firstCharKey = c - 'A';
             } else {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoNamedCharacterMatch();
               }
               emitOrAppendStrBuf(returnState);
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos;
               }
               state = P::transition(mViewSource, returnState, reconsume, pos);
               reconsume = true;
@@ -1502,17 +1502,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           PRInt32 hilo = 0;
           if (c <= 'z') {
             const PRInt32* row = nsHtml5NamedCharactersAccel::HILO_ACCEL[c];
             if (row) {
               hilo = row[firstCharKey];
             }
           }
           if (!hilo) {
-            if (P::viewingSource) {
+            if (P::reportErrors) {
               errNoNamedCharacterMatch();
             }
             emitOrAppendStrBuf(returnState);
             if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
               cstart = pos;
             }
             state = P::transition(mViewSource, returnState, reconsume, pos);
             reconsume = true;
@@ -1573,17 +1573,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           if (hi < lo) {
             NS_HTML5_BREAK(outer);
           }
           appendStrBuf(c);
           continue;
         }
         outer_end: ;
         if (candidate == -1) {
-          if (P::viewingSource) {
+          if (P::reportErrors) {
             errNoNamedCharacterMatch();
           }
           emitOrAppendStrBuf(returnState);
           if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
             cstart = pos;
           }
           state = P::transition(mViewSource, returnState, reconsume, pos);
           reconsume = true;
@@ -1594,31 +1594,31 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
               PRUnichar ch;
               if (strBufMark == strBufLen) {
                 ch = c;
               } else {
                 ch = strBuf[strBufMark];
               }
               if (ch == '=' || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
-                if (P::viewingSource) {
+                if (P::reportErrors) {
                   errNoNamedCharacterMatch();
                 }
                 appendStrBufToLongStrBuf();
                 state = P::transition(mViewSource, returnState, reconsume, pos);
                 reconsume = true;
                 NS_HTML5_CONTINUE(stateloop);
               }
             }
             if ((returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errUnescapedAmpersandInterpretedAsCharacterReference();
               }
             } else {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNotSemicolonTerminated();
               }
             }
           }
           P::completedNamedCharacterReference(mViewSource);
           const PRUnichar* val = nsHtml5NamedCharacters::VALUES[candidate];
           if (!val[1]) {
             emitOrAppendOne(val, returnState);
@@ -1685,41 +1685,41 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           } else if (c == ';') {
             if (seenDigits) {
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos + 1;
               }
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_HANDLE_NCR_VALUE, reconsume, pos);
               NS_HTML5_BREAK(decimalloop);
             } else {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoDigitsInNCR();
               }
               appendStrBuf(';');
               emitOrAppendStrBuf(returnState);
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos + 1;
               }
               state = P::transition(mViewSource, returnState, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
           } else {
             if (!seenDigits) {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoDigitsInNCR();
               }
               emitOrAppendStrBuf(returnState);
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos;
               }
               state = P::transition(mViewSource, returnState, reconsume, pos);
               reconsume = true;
               NS_HTML5_CONTINUE(stateloop);
             } else {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errCharRefLacksSemicolon();
               }
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos;
               }
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_HANDLE_NCR_VALUE, reconsume, pos);
               reconsume = true;
               NS_HTML5_BREAK(decimalloop);
@@ -1761,41 +1761,41 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           } else if (c == ';') {
             if (seenDigits) {
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos + 1;
               }
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_HANDLE_NCR_VALUE, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             } else {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoDigitsInNCR();
               }
               appendStrBuf(';');
               emitOrAppendStrBuf(returnState);
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos + 1;
               }
               state = P::transition(mViewSource, returnState, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
           } else {
             if (!seenDigits) {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoDigitsInNCR();
               }
               emitOrAppendStrBuf(returnState);
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos;
               }
               state = P::transition(mViewSource, returnState, reconsume, pos);
               reconsume = true;
               NS_HTML5_CONTINUE(stateloop);
             } else {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errCharRefLacksSemicolon();
               }
               if (!(returnState & NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK)) {
                 cstart = pos;
               }
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_HANDLE_NCR_VALUE, reconsume, pos);
               reconsume = true;
               NS_HTML5_CONTINUE(stateloop);
@@ -1834,35 +1834,35 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
       }
       case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN: {
         if (++pos == endPos) {
           NS_HTML5_BREAK(stateloop);
         }
         c = checkChar(buf, pos);
         switch(c) {
           case '>': {
-            if (P::viewingSource) {
+            if (P::reportErrors) {
               errLtSlashGt();
             }
             cstart = pos + 1;
             state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
             NS_HTML5_CONTINUE(stateloop);
           }
           case '\r': {
             silentCarriageReturn();
-            if (P::viewingSource) {
+            if (P::reportErrors) {
               errGarbageAfterLtSlash();
             }
             clearLongStrBufAndAppend('\n');
             state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
             NS_HTML5_BREAK(stateloop);
           }
           case '\n': {
             silentLineFeed();
-            if (P::viewingSource) {
+            if (P::reportErrors) {
               errGarbageAfterLtSlash();
             }
             clearLongStrBufAndAppend('\n');
             state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
             NS_HTML5_CONTINUE(stateloop);
           }
           case '\0': {
             c = 0xfffd;
@@ -1872,17 +1872,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               c += 0x20;
             }
             if (c >= 'a' && c <= 'z') {
               endTag = true;
               clearStrBufAndAppend(c);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_TAG_NAME, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             } else {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errGarbageAfterLtSlash();
               }
               clearLongStrBufAndAppend(c);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
           }
         }
@@ -2620,17 +2620,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           if (index < 6) {
             PRUnichar folded = c;
             if (c >= 'A' && c <= 'Z') {
               folded += 0x20;
             }
             if (folded == nsHtml5Tokenizer::OCTYPE[index]) {
               appendLongStrBuf(c);
             } else {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errBogusComment();
               }
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_BOGUS_COMMENT, reconsume, pos);
               reconsume = true;
               NS_HTML5_CONTINUE(stateloop);
             }
             index++;
             continue;
@@ -2664,17 +2664,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             }
             case ' ':
             case '\t':
             case '\f': {
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME, reconsume, pos);
               NS_HTML5_BREAK(doctypeloop);
             }
             default: {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errMissingSpaceBeforeDoctypeName();
               }
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME, reconsume, pos);
               reconsume = true;
               NS_HTML5_BREAK(doctypeloop);
             }
           }
         }
@@ -2699,17 +2699,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               silentLineFeed();
             }
             case ' ':
             case '\t':
             case '\f': {
               continue;
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNamelessDoctype();
               }
               forceQuirks = true;
               emitDoctypeToken(pos);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\0': {
@@ -2863,33 +2863,33 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             }
             case ' ':
             case '\t':
             case '\f': {
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
               NS_HTML5_BREAK(afterdoctypepublickeywordloop);
             }
             case '\"': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoSpaceBetweenDoctypePublicKeywordAndQuote();
               }
               clearLongStrBuf();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\'': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoSpaceBetweenDoctypePublicKeywordAndQuote();
               }
               clearLongStrBuf();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errExpectedPublicId();
               }
               forceQuirks = true;
               emitDoctypeToken(pos);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             default: {
@@ -2926,17 +2926,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               NS_HTML5_BREAK(beforedoctypepublicidentifierloop);
             }
             case '\'': {
               clearLongStrBuf();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errExpectedPublicId();
               }
               forceQuirks = true;
               emitDoctypeToken(pos);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             default: {
@@ -2956,17 +2956,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           c = checkChar(buf, pos);
           switch(c) {
             case '\"': {
               publicIdentifier = longStrBufToString();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
               NS_HTML5_BREAK(doctypepublicidentifierdoublequotedloop);
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errGtInPublicId();
               }
               forceQuirks = true;
               publicIdentifier = longStrBufToString();
               emitDoctypeToken(pos);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
@@ -3011,25 +3011,25 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               NS_HTML5_BREAK(afterdoctypepublicidentifierloop);
             }
             case '>': {
               emitDoctypeToken(pos);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\"': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoSpaceBetweenPublicAndSystemIds();
               }
               clearLongStrBuf();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\'': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoSpaceBetweenPublicAndSystemIds();
               }
               clearLongStrBuf();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             default: {
               bogusDoctype();
@@ -3091,17 +3091,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           c = checkChar(buf, pos);
           switch(c) {
             case '\"': {
               systemIdentifier = longStrBufToString();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errGtInSystemId();
               }
               forceQuirks = true;
               systemIdentifier = longStrBufToString();
               emitDoctypeToken(pos);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
@@ -3234,33 +3234,33 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
             }
             case ' ':
             case '\t':
             case '\f': {
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
               NS_HTML5_BREAK(afterdoctypesystemkeywordloop);
             }
             case '\"': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
               }
               clearLongStrBuf();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\'': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
               }
               clearLongStrBuf();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errExpectedPublicId();
               }
               forceQuirks = true;
               emitDoctypeToken(pos);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             default: {
@@ -3297,17 +3297,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
               NS_HTML5_CONTINUE(stateloop);
             }
             case '\'': {
               clearLongStrBuf();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED, reconsume, pos);
               NS_HTML5_BREAK(beforedoctypesystemidentifierloop);
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errExpectedSystemId();
               }
               forceQuirks = true;
               emitDoctypeToken(pos);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             default: {
@@ -3327,17 +3327,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           c = checkChar(buf, pos);
           switch(c) {
             case '\'': {
               systemIdentifier = longStrBufToString();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errGtInSystemId();
               }
               forceQuirks = true;
               systemIdentifier = longStrBufToString();
               emitDoctypeToken(pos);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
@@ -3367,17 +3367,17 @@ nsHtml5Tokenizer::stateLoop(PRInt32 stat
           c = checkChar(buf, pos);
           switch(c) {
             case '\'': {
               publicIdentifier = longStrBufToString();
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
             case '>': {
-              if (P::viewingSource) {
+              if (P::reportErrors) {
                 errGtInPublicId();
               }
               forceQuirks = true;
               publicIdentifier = longStrBufToString();
               emitDoctypeToken(pos);
               state = P::transition(mViewSource, NS_HTML5TOKENIZER_DATA, reconsume, pos);
               NS_HTML5_CONTINUE(stateloop);
             }
--- a/parser/html/nsHtml5TokenizerCppSupplement.h
+++ b/parser/html/nsHtml5TokenizerCppSupplement.h
@@ -59,77 +59,89 @@ nsHtml5Tokenizer::EndViewSource()
   mViewSource->End();
 }
 
 void
 nsHtml5Tokenizer::errWarnLtSlashInRcdata()
 {
 }
 
+// The null checks below annotated NS_LIKELY are not actually necessary.
+
 void
 nsHtml5Tokenizer::errUnquotedAttributeValOrNull(PRUnichar c)
 {
-  switch (c) {
-    case '<':
-      mViewSource->AddErrorToCurrentNode("errUnquotedAttributeLt");
-      return;
-    case '`':
-      mViewSource->AddErrorToCurrentNode("errUnquotedAttributeGrave");
-      return;
-    case '\'':
-    case '"':
-      mViewSource->AddErrorToCurrentNode("errUnquotedAttributeQuote");
-      return;
-    case '=':
-      mViewSource->AddErrorToCurrentNode("errUnquotedAttributeEquals");
-      return;
+  if (NS_LIKELY(mViewSource)) {
+    switch (c) {
+      case '<':
+        mViewSource->AddErrorToCurrentNode("errUnquotedAttributeLt");
+        return;
+      case '`':
+        mViewSource->AddErrorToCurrentNode("errUnquotedAttributeGrave");
+        return;
+      case '\'':
+      case '"':
+        mViewSource->AddErrorToCurrentNode("errUnquotedAttributeQuote");
+        return;
+      case '=':
+        mViewSource->AddErrorToCurrentNode("errUnquotedAttributeEquals");
+        return;
+    }
   }
 }
 
 void
 nsHtml5Tokenizer::errLtOrEqualsOrGraveInUnquotedAttributeOrNull(PRUnichar c)
 {
-  switch (c) {
-    case '=':
-      mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartEquals");
-      return;
-    case '<':
-      mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartLt");
-      return;
-    case '`':
-      mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartGrave");
-      return;
+  if (NS_LIKELY(mViewSource)) {
+    switch (c) {
+      case '=':
+        mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartEquals");
+        return;
+      case '<':
+        mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartLt");
+        return;
+      case '`':
+        mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartGrave");
+        return;
+    }
   }
 }
 
 void
 nsHtml5Tokenizer::errBadCharBeforeAttributeNameOrNull(PRUnichar c)
 {
-  if (c == '<') {
-    mViewSource->AddErrorToCurrentNode("errBadCharBeforeAttributeNameLt");
-  } else if (c == '=') {
-    errEqualsSignBeforeAttributeName();
-  } else if (c != 0xFFFD) {
-    errQuoteBeforeAttributeName(c);
+  if (NS_LIKELY(mViewSource)) {
+    if (c == '<') {
+      mViewSource->AddErrorToCurrentNode("errBadCharBeforeAttributeNameLt");
+    } else if (c == '=') {
+      errEqualsSignBeforeAttributeName();
+    } else if (c != 0xFFFD) {
+      errQuoteBeforeAttributeName(c);
+    }
   }
 }
 
 void
 nsHtml5Tokenizer::errBadCharAfterLt(PRUnichar c)
 {
-  mViewSource->AddErrorToCurrentNode("errBadCharAfterLt");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errBadCharAfterLt");
+  }
 }
 
 void
 nsHtml5Tokenizer::errQuoteOrLtInAttributeNameOrNull(PRUnichar c)
 {
-  if (c == '<') {
-    mViewSource->AddErrorToCurrentNode("errLtInAttributeName");
-  } else if (c != 0xFFFD) {
-    mViewSource->AddErrorToCurrentNode("errQuoteInAttributeName");
+  if (NS_LIKELY(mViewSource)) {
+    if (c == '<') {
+      mViewSource->AddErrorToCurrentNode("errLtInAttributeName");
+    } else if (c != 0xFFFD) {
+      mViewSource->AddErrorToCurrentNode("errQuoteInAttributeName");
+    }
   }
 }
 
 void
 nsHtml5Tokenizer::maybeErrAttributesOnEndTag(nsHtml5HtmlAttributes* attrs)
 {
   if (mViewSource && attrs->getLength() != 0) {
     /*
@@ -172,23 +184,27 @@ nsHtml5Tokenizer::errNcrControlChar(PRUn
     mViewSource->AddErrorToCurrentNode("errNcrControlChar");
   }
   return ch;
 }
 
 void
 nsHtml5Tokenizer::errGarbageAfterLtSlash()
 {
-  mViewSource->AddErrorToCurrentNode("errGarbageAfterLtSlash");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errGarbageAfterLtSlash");
+  }
 }
 
 void
 nsHtml5Tokenizer::errLtSlashGt()
 {
-  mViewSource->AddErrorToCurrentNode("errLtSlashGt");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errLtSlashGt");
+  }
 }
 
 void
 nsHtml5Tokenizer::errCharRefLacksSemicolon()
 {
   if (NS_UNLIKELY(mViewSource)) {
     mViewSource->AddErrorToCurrentNode("errCharRefLacksSemicolon");
   }
@@ -200,87 +216,107 @@ nsHtml5Tokenizer::errNoDigitsInNCR()
   if (NS_UNLIKELY(mViewSource)) {
     mViewSource->AddErrorToCurrentNode("errNoDigitsInNCR");
   }
 }
 
 void
 nsHtml5Tokenizer::errGtInSystemId()
 {
-  mViewSource->AddErrorToCurrentNode("errGtInSystemId");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errGtInSystemId");
+  }
 }
 
 void
 nsHtml5Tokenizer::errGtInPublicId()
 {
-  mViewSource->AddErrorToCurrentNode("errGtInPublicId");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errGtInPublicId");
+  }
 }
 
 void
 nsHtml5Tokenizer::errNamelessDoctype()
 {
-  mViewSource->AddErrorToCurrentNode("errNamelessDoctype");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errNamelessDoctype");
+  }
 }
 
 void
 nsHtml5Tokenizer::errConsecutiveHyphens()
 {
   if (NS_UNLIKELY(mViewSource)) {
     mViewSource->AddErrorToCurrentNode("errConsecutiveHyphens");
   }
 }
 
 void
 nsHtml5Tokenizer::errPrematureEndOfComment()
 {
-  mViewSource->AddErrorToCurrentNode("errPrematureEndOfComment");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errPrematureEndOfComment");
+  }
 }
 
 void
 nsHtml5Tokenizer::errBogusComment()
 {
   if (NS_UNLIKELY(mViewSource)) {
     mViewSource->AddErrorToCurrentNode("errBogusComment");
   }
 }
 
 void
 nsHtml5Tokenizer::errSlashNotFollowedByGt()
 {
-  mViewSource->AddErrorToCurrentSlash("errSlashNotFollowedByGt");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentSlash("errSlashNotFollowedByGt");
+  }
 }
 
 void
 nsHtml5Tokenizer::errNoSpaceBetweenAttributes()
 {
-  mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenAttributes");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenAttributes");
+  }
 }
 
 void
 nsHtml5Tokenizer::errAttributeValueMissing()
 {
-  mViewSource->AddErrorToCurrentNode("errAttributeValueMissing");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errAttributeValueMissing");
+  }
 }
 
 void
 nsHtml5Tokenizer::errEqualsSignBeforeAttributeName()
 {
-  mViewSource->AddErrorToCurrentNode("errEqualsSignBeforeAttributeName");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errEqualsSignBeforeAttributeName");
+  }
 }
 
 void
 nsHtml5Tokenizer::errLtGt()
 {
-  mViewSource->AddErrorToCurrentNode("errLtGt");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errLtGt");
+  }
 }
 
 void
 nsHtml5Tokenizer::errProcessingInstruction()
 {
-  mViewSource->AddErrorToCurrentNode("errProcessingInstruction");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errProcessingInstruction");
+  }
 }
 
 void
 nsHtml5Tokenizer::errUnescapedAmpersandInterpretedAsCharacterReference()
 {
   if (NS_UNLIKELY(mViewSource)) {
     mViewSource->AddErrorToCurrentAmpersand("errUnescapedAmpersandInterpretedAsCharacterReference");
   }
@@ -300,23 +336,27 @@ nsHtml5Tokenizer::errNoNamedCharacterMat
   if (NS_UNLIKELY(mViewSource)) {
     mViewSource->AddErrorToCurrentAmpersand("errNoNamedCharacterMatch");
   }
 }
 
 void
 nsHtml5Tokenizer::errQuoteBeforeAttributeName(PRUnichar c)
 {
-  mViewSource->AddErrorToCurrentNode("errQuoteBeforeAttributeName");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errQuoteBeforeAttributeName");
+  }
 }
 
 void
 nsHtml5Tokenizer::errExpectedPublicId()
 {
-  mViewSource->AddErrorToCurrentNode("errExpectedPublicId");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errExpectedPublicId");
+  }
 }
 
 void
 nsHtml5Tokenizer::errBogusDoctype()
 {
   if (NS_UNLIKELY(mViewSource)) {
     mViewSource->AddErrorToCurrentNode("errBogusDoctype");
   }
@@ -448,29 +488,35 @@ nsHtml5Tokenizer::errEofInSystemId()
   if (NS_UNLIKELY(mViewSource)) {
     mViewSource->AddErrorToCurrentRun("errEofInSystemId");
   }
 }
 
 void
 nsHtml5Tokenizer::errExpectedSystemId()
 {
-  mViewSource->AddErrorToCurrentNode("errExpectedSystemId");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errExpectedSystemId");
+  }
 }
 
 void
 nsHtml5Tokenizer::errMissingSpaceBeforeDoctypeName()
 {
-  mViewSource->AddErrorToCurrentNode("errMissingSpaceBeforeDoctypeName");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errMissingSpaceBeforeDoctypeName");
+  }
 }
 
 void
 nsHtml5Tokenizer::errHyphenHyphenBang()
 {
-  mViewSource->AddErrorToCurrentNode("errHyphenHyphenBang");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errHyphenHyphenBang");
+  }
 }
 
 void
 nsHtml5Tokenizer::errNcrControlChar()
 {
   if (NS_UNLIKELY(mViewSource)) {
     mViewSource->AddErrorToCurrentNode("errNcrControlChar");
   }
@@ -482,22 +528,28 @@ nsHtml5Tokenizer::errNcrZero()
   if (NS_UNLIKELY(mViewSource)) {
     mViewSource->AddErrorToCurrentNode("errNcrZero");
   }
 }
 
 void
 nsHtml5Tokenizer::errNoSpaceBetweenDoctypeSystemKeywordAndQuote()
 {
-  mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypeSystemKeywordAndQuote");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypeSystemKeywordAndQuote");
+  }
 }
 
 void
 nsHtml5Tokenizer::errNoSpaceBetweenPublicAndSystemIds()
 {
-  mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenPublicAndSystemIds");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenPublicAndSystemIds");
+  }
 }
 
 void
 nsHtml5Tokenizer::errNoSpaceBetweenDoctypePublicKeywordAndQuote()
 {
-  mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypePublicKeywordAndQuote");
+  if (NS_LIKELY(mViewSource)) {
+    mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypePublicKeywordAndQuote");
+  }
 }
--- a/parser/html/nsHtml5TokenizerLoopPolicies.h
+++ b/parser/html/nsHtml5TokenizerLoopPolicies.h
@@ -33,32 +33,40 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsHtml5TokenizerLoopPolicies_h_
 #define nsHtml5TokenizerLoopPolicies_h_
 
+/**
+ * This policy does not report tokenizer transitions anywhere. To be used
+ * when _not_ viewing source.
+ */
 struct nsHtml5SilentPolicy
 {
-  static const bool viewingSource = false;
+  static const bool reportErrors = false;
   static PRInt32 transition(nsHtml5Highlighter* aHighlighter,
                             PRInt32 aState,
                             bool aReconsume,
                             PRInt32 aPos) {
     return aState;
   }
   static void completedNamedCharacterReference(nsHtml5Highlighter* aHighlighter) {
   }
 };
 
+/**
+ * This policy reports the tokenizer transitions to a highlighter. To be used
+ * when viewing source.
+ */
 struct nsHtml5ViewSourcePolicy
 {
-  static const bool viewingSource = true;
+  static const bool reportErrors = true;
   static PRInt32 transition(nsHtml5Highlighter* aHighlighter,
                             PRInt32 aState,
                             bool aReconsume,
                             PRInt32 aPos) {
     return aHighlighter->Transition(aState, aReconsume, aPos);
   }
   static void completedNamedCharacterReference(nsHtml5Highlighter* aHighlighter) {
     aHighlighter->CompletedNamedCharacterReference();
--- a/parser/html/nsHtml5TreeBuilderHSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderHSupplement.h
@@ -53,16 +53,39 @@
 #endif
 
     // DocumentModeHandler
     /**
      * Tree builder uses this to report quirkiness of the document
      */
     void documentMode(nsHtml5DocumentMode m);
 
+    /**
+     * Using nsIContent** instead of nsIContent* is the parser deals with DOM
+     * nodes in a way that works off the main thread. Non-main-thread code
+     * can't refcount or otherwise touch nsIContent objects in any way.
+     * Yet, the off-the-main-thread code needs to have a way to hold onto a
+     * particular node and repeatedly operate on the same node.
+     *
+     * The way this works is that the off-the-main-thread code has an
+     * nsIContent** for each DOM node and a given nsIContent** is only ever
+     * actually dereferenced into an actual nsIContent* on the main thread.
+     * When the off-the-main-thread code requests a new node, it gets an
+     * nsIContent** immediately and a tree op is enqueued for later allocating
+     * an actual nsIContent object and writing a pointer to it into the memory
+     * location pointed to by the nsIContent**.
+     *
+     * Since tree ops are in a queue, the node creating tree op will always
+     * run before tree ops that try to further operate on the node that the
+     * nsIContent** is a handle to.
+     *
+     * On-the-main-thread parts of the parser use the same mechanism in order
+     * to avoid having to have duplicate code paths for on-the-main-thread and
+     * off-the-main-thread tree builder instances.)
+     */
     nsIContent** AllocateContentHandle();
     
     void accumulateCharactersForced(const PRUnichar* aBuf, PRInt32 aStart, PRInt32 aLength)
     {
       accumulateCharacters(aBuf, aStart, aLength);
     }
 
   public:
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -900,16 +900,18 @@ nsHtml5TreeOpExecutor::GetViewSourceBase
     nsCOMPtr<nsIURI> orig = mDocument->GetOriginalURI();
     bool isViewSource;
     orig->SchemeIs("view-source", &isViewSource);
     if (isViewSource) {
       nsCOMPtr<nsINestedURI> nested = do_QueryInterface(orig);
       NS_ASSERTION(nested, "URI with scheme view-source didn't QI to nested!");
       nested->GetInnerURI(getter_AddRefs(mViewSourceBaseURI));
     } else {
+      // Fail gracefully if the base URL isn't a view-source: URL.
+      // Not sure if this can ever happen.
       mViewSourceBaseURI = orig;
     }
   }
   return mViewSourceBaseURI;
 }
 
 // Speculative loading
 
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -710,16 +710,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
         NS_WARNING("failed to dispatch svg load dispatcher");
       }
       return rv;
     }
     case eTreeOpAddClass: {
       nsIContent* node = *(mOne.node);
       PRUnichar* str = mTwo.unicharPtr;
       nsDependentString depStr(str);
+      // See viewsource.css for the possible classes
       nsAutoString klass;
       node->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
       if (!klass.IsEmpty()) {
         klass.Append(' ');
         klass.Append(depStr);
         node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
       } else {
         node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, depStr, true);
@@ -755,18 +756,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       // URLs that execute script (e.g. "javascript:" URLs) should just be
       // ignored.  There's nothing reasonable we can do with them, and allowing
       // them to execute in the context of the view-source window presents a
       // security risk.  Just return the empty string in this case.
       bool openingExecutesScript = false;
       rv = NS_URIChainHasFlags(uri,
                                nsIProtocolHandler::URI_OPENING_EXECUTES_SCRIPT,
                                &openingExecutesScript);
-      NS_ENSURE_SUCCESS(rv, NS_OK);
-      if (openingExecutesScript) {
+      if (NS_FAILED(rv) || openingExecutesScript) {
         return NS_OK;
       }
 
       nsCAutoString viewSourceUrl;
 
       // URLs that return data (e.g. "http:" URLs) should be prefixed with
       // "view-source:".  URLs that don't return data should just be returned
       // undecorated.
@@ -790,16 +790,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       node->SetAttr(kNameSpaceID_None, nsGkAtoms::href, utf16, true);
       return rv;
     }
     case eTreeOpAddError: {
       nsIContent* node = *(mOne.node);
       char* msgId = mTwo.charPtr;
       nsCOMPtr<nsIAtom> atom = Reget(mThree.atom);
       nsCOMPtr<nsIAtom> otherAtom = Reget(mFour.atom);
+      // See viewsource.css for the possible classes in addition to "error".
       nsAutoString klass;
       node->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
       if (!klass.IsEmpty()) {
         klass.Append(NS_LITERAL_STRING(" error"));
         node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
       } else {
         node->SetAttr(kNameSpaceID_None,
                       nsGkAtoms::_class,