Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/parser/html/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 168 kB image not shown  

Quelle  nsHtml5Tokenizer.cpp   Sprache: C

 
/*
 * Copyright (c) 2005-2007 Henri Sivonen
 * Copyright (c) 2007-2017 Mozilla Foundation
 * Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
 * Foundation, and Opera Software ASA.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */


/*
 * THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
 * Please edit Tokenizer.java instead and regenerate.
 */


#define nsHtml5Tokenizer_cpp__

#include "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5StackNode.h"
#include "nsHtml5UTF16Buffer.h"
#include "nsHtml5StateSnapshot.h"
#include "nsHtml5Portability.h"

#include "nsHtml5Tokenizer.h"

#include "nsHtml5TokenizerLoopPolicies.h"

char16_t nsHtml5Tokenizer::LT_GT[] = {'<''>'};
char16_t nsHtml5Tokenizer::LT_SOLIDUS[] = {'<''/'};
char16_t nsHtml5Tokenizer::RSQB_RSQB[] = {']'']'};
char16_t nsHtml5Tokenizer::REPLACEMENT_CHARACTER[] = {0xfffd};
char16_t nsHtml5Tokenizer::LF[] = {'\n'};
char16_t nsHtml5Tokenizer::CDATA_LSQB[] = {'C''D''A''T''A''['};
char16_t nsHtml5Tokenizer::OCTYPE[] = {'o''c''t''y''p''e'};
char16_t nsHtml5Tokenizer::UBLIC[] = {'u''b''l''i''c'};
char16_t nsHtml5Tokenizer::YSTEM[] = {'y''s''t''e''m'};
static char16_t const TITLE_ARR_DATA[] = {'t''i''t''l''e'};
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::TITLE_ARR = {
    TITLE_ARR_DATA, std::size(TITLE_ARR_DATA)};
static char16_t const SCRIPT_ARR_DATA[] = {'s''c''r''i''p''t'};
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::SCRIPT_ARR = {
    SCRIPT_ARR_DATA, std::size(SCRIPT_ARR_DATA)};
static char16_t const STYLE_ARR_DATA[] = {'s''t''y''l''e'};
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::STYLE_ARR = {
    STYLE_ARR_DATA, std::size(STYLE_ARR_DATA)};
static char16_t const PLAINTEXT_ARR_DATA[] = {'p''l''a''i''n',
                                              't''e''x''t'};
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::PLAINTEXT_ARR = {
    PLAINTEXT_ARR_DATA, std::size(PLAINTEXT_ARR_DATA)};
static char16_t const XMP_ARR_DATA[] = {'x''m''p'};
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::XMP_ARR = {
    XMP_ARR_DATA, std::size(XMP_ARR_DATA)};
static char16_t const TEXTAREA_ARR_DATA[] = {'t''e''x''t',
                                             'a''r''e''a'};
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::TEXTAREA_ARR = {
    TEXTAREA_ARR_DATA, std::size(TEXTAREA_ARR_DATA)};
static char16_t const IFRAME_ARR_DATA[] = {'i''f''r''a''m''e'};
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::IFRAME_ARR = {
    IFRAME_ARR_DATA, std::size(IFRAME_ARR_DATA)};
static char16_t const NOEMBED_ARR_DATA[] = {'n''o''e''m''b''e''d'};
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOEMBED_ARR = {
    NOEMBED_ARR_DATA, std::size(NOEMBED_ARR_DATA)};
static char16_t const NOSCRIPT_ARR_DATA[] = {'n''o''s''c',
                                             'r''i''p''t'};
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOSCRIPT_ARR = {
    NOSCRIPT_ARR_DATA, std::size(NOSCRIPT_ARR_DATA)};
static char16_t const NOFRAMES_ARR_DATA[] = {'n''o''f''r',
                                             'a''m''e''s'};
staticJArray<char16_t, int32_t> nsHtml5Tokenizer::NOFRAMES_ARR = {
    NOFRAMES_ARR_DATA, std::size(NOFRAMES_ARR_DATA)};

nsHtml5Tokenizer::nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler,
                                   bool viewingXmlSource)
    : tokenHandler(tokenHandler),
      encodingDeclarationHandler(nullptr),
      lastCR(false),
      stateSave(0),
      returnStateSave(0),
      index(0),
      forceQuirks(false),
      additional('\0'),
      entCol(0),
      firstCharKey(0),
      lo(0),
      hi(0),
      candidate(0),
      charRefBufMark(0),
      value(0),
      seenDigits(false),
      suspendAfterCurrentNonTextToken(false),
      cstart(0),
      strBufLen(0),
      charRefBuf(jArray<char16_t, int32_t>::newJArray(32)),
      charRefBufLen(0),
      bmpChar(jArray<char16_t, int32_t>::newJArray(1)),
      astralChar(jArray<char16_t, int32_t>::newJArray(2)),
      endTagExpectation(nullptr),
      endTagExpectationAsArray(nullptr),
      endTag(false),
      containsHyphen(false),
      tagName(nullptr),
      nonInternedTagName(new nsHtml5ElementName()),
      attributeName(nullptr),
      nonInternedAttributeName(new nsHtml5AttributeName()),
      doctypeName(nullptr),
      publicIdentifier(nullptr),
      systemIdentifier(nullptr),
      attributes(tokenHandler->HasBuilder() ? new nsHtml5HtmlAttributes(0)
                                            : nullptr),
      newAttributesEachTime(!tokenHandler->HasBuilder()),
      shouldSuspend(false),
      keepBuffer(false),
      confident(false),
      line(0),
      attributeLine(0),
      interner(nullptr),
      viewingXmlSource(viewingXmlSource) {
  MOZ_COUNT_CTOR(nsHtml5Tokenizer);
}

void nsHtml5Tokenizer::setInterner(nsHtml5AtomTable* interner) {
  this->interner = interner;
}

void nsHtml5Tokenizer::initLocation(nsHtml5String newPublicId,
                                    nsHtml5String newSystemId) {
  this->systemId = newSystemId;
  this->publicId = newPublicId;
}

bool nsHtml5Tokenizer::isViewingXmlSource() { return viewingXmlSource; }

void nsHtml5Tokenizer::setKeepBuffer(bool keepBuffer) {
  this->keepBuffer = keepBuffer;
}

bool nsHtml5Tokenizer::dropBufferIfLongerThan(int32_t length) {
  if (strBuf.length > length) {
    strBuf = nullptr;
    return true;
  }
  return false;
}

void nsHtml5Tokenizer::setState(int32_t specialTokenizerState) {
  this->stateSave = specialTokenizerState;
  this->endTagExpectation = nullptr;
  this->endTagExpectationAsArray = nullptr;
}

void nsHtml5Tokenizer::setStateAndEndTagExpectation(
    int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation) {
  this->stateSave = specialTokenizerState;
  this->endTagExpectation = endTagExpectation;
  endTagExpectationToArray();
}

void nsHtml5Tokenizer::endTagExpectationToArray() {
  switch (endTagExpectation->getGroup()) {
    case nsHtml5TreeBuilder::TITLE: {
      endTagExpectationAsArray = TITLE_ARR;
      return;
    }
    case nsHtml5TreeBuilder::SCRIPT: {
      endTagExpectationAsArray = SCRIPT_ARR;
      return;
    }
    case nsHtml5TreeBuilder::STYLE: {
      endTagExpectationAsArray = STYLE_ARR;
      return;
    }
    case nsHtml5TreeBuilder::PLAINTEXT: {
      endTagExpectationAsArray = PLAINTEXT_ARR;
      return;
    }
    case nsHtml5TreeBuilder::XMP: {
      endTagExpectationAsArray = XMP_ARR;
      return;
    }
    case nsHtml5TreeBuilder::TEXTAREA: {
      endTagExpectationAsArray = TEXTAREA_ARR;
      return;
    }
    case nsHtml5TreeBuilder::IFRAME: {
      endTagExpectationAsArray = IFRAME_ARR;
      return;
    }
    case nsHtml5TreeBuilder::NOEMBED: {
      endTagExpectationAsArray = NOEMBED_ARR;
      return;
    }
    case nsHtml5TreeBuilder::NOSCRIPT: {
      endTagExpectationAsArray = NOSCRIPT_ARR;
      return;
    }
    case nsHtml5TreeBuilder::NOFRAMES: {
      endTagExpectationAsArray = NOFRAMES_ARR;
      return;
    }
    default: {
      MOZ_ASSERT(false"Bad end tag expectation.");
      return;
    }
  }
}

void nsHtml5Tokenizer::setLineNumber(int32_t line) {
  this->attributeLine = line;
  this->line = line;
}

nsHtml5HtmlAttributes* nsHtml5Tokenizer::emptyAttributes() {
  return nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES;
}

void nsHtml5Tokenizer::emitOrAppendCharRefBuf(int32_t returnState) {
  if ((returnState & DATA_AND_RCDATA_MASK)) {
    appendCharRefBufToStrBuf();
  } else {
    if (charRefBufLen > 0) {
      tokenHandler->characters(charRefBuf, 0, charRefBufLen);
      charRefBufLen = 0;
    }
  }
}

nsHtml5String nsHtml5Tokenizer::strBufToString() {
  nsHtml5String str = nsHtml5Portability::newStringFromBuffer(
      strBuf, 0, strBufLen, tokenHandler,
      !newAttributesEachTime &&
          attributeName == nsHtml5AttributeName::ATTR_CLASS);
  clearStrBufAfterUse();
  return str;
}

void nsHtml5Tokenizer::strBufToDoctypeName() {
  doctypeName =
      nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen, interner);
  clearStrBufAfterUse();
}

void nsHtml5Tokenizer::emitStrBuf() {
  if (strBufLen > 0) {
    tokenHandler->characters(strBuf, 0, strBufLen);
    clearStrBufAfterUse();
  }
}

void nsHtml5Tokenizer::appendStrBuf(char16_t* buffer, int32_t offset,
                                    int32_t length) {
  int32_t newLen = nsHtml5Portability::checkedAdd(strBufLen, length);
  MOZ_ASSERT(newLen <= strBuf.length, "Previous buffer length insufficient.");
  if (MOZ_UNLIKELY(strBuf.length < newLen)) {
    if (MOZ_UNLIKELY(!EnsureBufferSpace(length))) {
      MOZ_CRASH("Unable to recover from buffer reallocation failure");
    }
  }
  nsHtml5ArrayCopy::arraycopy(buffer, offset, strBuf, strBufLen, length);
  strBufLen = newLen;
}

void nsHtml5Tokenizer::emitComment(int32_t provisionalHyphens, int32_t pos) {
  RememberGt(pos);
  tokenHandler->comment(strBuf, 0, strBufLen - provisionalHyphens);
  clearStrBufAfterUse();
  cstart = pos + 1;
  suspendIfRequestedAfterCurrentNonTextToken();
}

void nsHtml5Tokenizer::flushChars(char16_t* buf, int32_t pos) {
  if (pos > cstart) {
    tokenHandler->characters(buf, cstart, pos - cstart);
  }
  cstart = INT32_MAX;
}

void nsHtml5Tokenizer::strBufToElementNameString() {
  if (containsHyphen) {
    nsAtom* annotationName = nsHtml5ElementName::ELT_ANNOTATION_XML->getName();
    if (nsHtml5Portability::localEqualsBuffer(annotationName, strBuf,
                                              strBufLen)) {
      tagName = nsHtml5ElementName::ELT_ANNOTATION_XML;
    } else {
      nonInternedTagName->setNameForNonInterned(
          nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
                                                     interner),
          true);
      tagName = nonInternedTagName;
    }
  } else {
    tagName = nsHtml5ElementName::elementNameByBuffer(strBuf, strBufLen);
    if (!tagName) {
      nonInternedTagName->setNameForNonInterned(
          nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
                                                     interner),
          false);
      tagName = nonInternedTagName;
    }
  }
  containsHyphen = false;
  clearStrBufAfterUse();
}

int32_t nsHtml5Tokenizer::emitCurrentTagToken(bool selfClosing, int32_t pos) {
  RememberGt(pos);
  cstart = pos + 1;
  maybeErrSlashInEndTag(selfClosing);
  stateSave = nsHtml5Tokenizer::DATA;
  nsHtml5HtmlAttributes* attrs =
      (!attributes ? nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES : attributes);
  if (endTag) {
    maybeErrAttributesOnEndTag(attrs);
    if (!viewingXmlSource) {
      tokenHandler->endTag(tagName);
    }
    if (newAttributesEachTime) {
      delete attributes;
      attributes = nullptr;
    }
  } else {
    if (viewingXmlSource) {
      MOZ_ASSERT(newAttributesEachTime);
      delete attributes;
      attributes = nullptr;
    } else {
      tokenHandler->startTag(tagName, attrs, selfClosing);
    }
  }
  tagName = nullptr;
  if (newAttributesEachTime) {
    attributes = nullptr;
  } else {
    attributes->clear(0);
  }
  suspendIfRequestedAfterCurrentNonTextToken();
  return stateSave;
}

void nsHtml5Tokenizer::attributeNameComplete() {
  attributeName =
      nsHtml5AttributeName::nameByBuffer(strBuf, strBufLen, interner);
  if (!attributeName) {
    nonInternedAttributeName->setNameForNonInterned(
        nsHtml5Portability::newLocalNameFromBuffer(strBuf, strBufLen,
                                                   interner));
    attributeName = nonInternedAttributeName;
  }
  clearStrBufAfterUse();
  if (!attributes) {
    attributes = new nsHtml5HtmlAttributes(0);
  }
  if (attributes->contains(attributeName)) {
    errDuplicateAttribute();
    attributeName = nullptr;
  }
}

void nsHtml5Tokenizer::addAttributeWithoutValue() {
  if (attributeName) {
    attributes->addAttribute(
        attributeName, nsHtml5Portability::newEmptyString(), attributeLine);
    attributeName = nullptr;
  } else {
    clearStrBufAfterUse();
  }
}

void nsHtml5Tokenizer::addAttributeWithValue() {
  if (attributeName) {
    nsHtml5String val = strBufToString();
    if (mViewSource) {
      mViewSource->MaybeLinkifyAttributeValue(attributeName, val);
    }
    attributes->addAttribute(attributeName, val, attributeLine);
    attributeName = nullptr;
  } else {
    clearStrBufAfterUse();
  }
}

void nsHtml5Tokenizer::start() {
  initializeWithoutStarting();
  tokenHandler->startTokenization(this);
  if (mViewSource) {
    line = 1;
    col = -1;
    nextCharOnNewLine = false;
  } else if (tokenHandler->WantsLineAndColumn()) {
    line = 0;
    col = 1;
    nextCharOnNewLine = true;
  } else {
    line = -1;
    col = -1;
    nextCharOnNewLine = false;
  }
}

bool nsHtml5Tokenizer::tokenizeBuffer(nsHtml5UTF16Buffer* buffer) {
  int32_t state = stateSave;
  int32_t returnState = returnStateSave;
  char16_t c = '\0';
  shouldSuspend = false;
  lastCR = false;
  int32_t start = buffer->getStart();
  int32_t end = buffer->getEnd();
  int32_t pos = start - 1;
  switch (state) {
    case DATA:
    case RCDATA:
    case SCRIPT_DATA:
    case PLAINTEXT:
    case RAWTEXT:
    case CDATA_SECTION:
    case SCRIPT_DATA_ESCAPED:
    case SCRIPT_DATA_ESCAPE_START:
    case SCRIPT_DATA_ESCAPE_START_DASH:
    case SCRIPT_DATA_ESCAPED_DASH:
    case SCRIPT_DATA_ESCAPED_DASH_DASH:
    case SCRIPT_DATA_DOUBLE_ESCAPE_START:
    case SCRIPT_DATA_DOUBLE_ESCAPED:
    case SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:
    case SCRIPT_DATA_DOUBLE_ESCAPED_DASH:
    case SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:
    case SCRIPT_DATA_DOUBLE_ESCAPE_END: {
      cstart = start;
      break;
    }
    default: {
      cstart = INT32_MAX;
      break;
    }
  }
  if (mViewSource) {
    mViewSource->SetBuffer(buffer);
    pos = stateLoop<nsHtml5ViewSourcePolicy>(state, c, pos, buffer->getBuffer(),
                                             false, returnState,
                                             buffer->getEnd());
    mViewSource->DropBuffer((pos == buffer->getEnd()) ? pos : pos + 1);
  } else if (tokenHandler->WantsLineAndColumn()) {
    pos = stateLoop<nsHtml5LineColPolicy>(state, c, pos, buffer->getBuffer(),
                                          false, returnState, buffer->getEnd());
  } else {
    pos = stateLoop<nsHtml5FastestPolicy>(state, c, pos, buffer->getBuffer(),
                                          false, returnState, buffer->getEnd());
  }
  if (pos == end) {
    buffer->setStart(pos);
  } else {
    buffer->setStart(pos + 1);
  }
  return lastCR;
}

template <class P>
int32_t nsHtml5Tokenizer::stateLoop(int32_t state, char16_t c, int32_t pos,
                                    char16_t* buf, bool reconsume,
                                    int32_t returnState, int32_t endPos) {
  bool reportedConsecutiveHyphens = false;
stateloop:
  for (;;) {
    switch (state) {
      case DATA: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '&': {
              flushChars(buf, pos);
              MOZ_ASSERT(!charRefBufLen,
                         "charRefBufLen not reset after previous use!");
              appendCharRefBuf(c);
              setAdditionalAndRememberAmpersandLocation('\0');
              returnState = state;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '<': {
              flushChars(buf, pos);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::TAG_OPEN, reconsume, pos);
              NS_HTML5_BREAK(dataloop);
            }
            case '\0': {
              maybeEmitReplacementCharacter(buf, pos);
              continue;
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              continue;
            }
          }
        }
      dataloop_end:;
        [[fallthrough]];
      }
      case TAG_OPEN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          if (c >= 'A' && c <= 'Z') {
            endTag = false;
            clearStrBufBeforeUse();
            appendStrBuf((char16_t)(c + 0x20));
            containsHyphen = false;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
                                  reconsume, pos);
            NS_HTML5_BREAK(tagopenloop);
          } else if (c >= 'a' && c <= 'z') {
            endTag = false;
            clearStrBufBeforeUse();
            appendStrBuf(c);
            containsHyphen = false;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::TAG_NAME,
                                  reconsume, pos);
            NS_HTML5_BREAK(tagopenloop);
          }
          switch (c) {
            case '!': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::MARKUP_DECLARATION_OPEN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '/': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::CLOSE_TAG_OPEN, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\?': {
              if (viewingXmlSource) {
                state = P::transition(mViewSource.get(),
                                      nsHtml5Tokenizer::PROCESSING_INSTRUCTION,
                                      reconsume, pos);
                NS_HTML5_CONTINUE(stateloop);
              }
              if (P::reportErrors) {
                errProcessingInstruction();
              }
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              if (P::reportErrors) {
                errLtGt();
              }
              tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 2);
              cstart = pos + 1;
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              if (P::reportErrors) {
                errBadCharAfterLt(c);
              }
              tokenHandler->characters(nsHtml5Tokenizer::LT_GT, 0, 1);
              cstart = pos;
              reconsume = true;
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      tagopenloop_end:;
        [[fallthrough]];
      }
      case TAG_NAME: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              strBufToElementNameString();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              strBufToElementNameString();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(tagnameloop);
            }
            case '/': {
              strBufToElementNameString();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              strBufToElementNameString();
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              if (c >= 'A' && c <= 'Z') {
                c += 0x20;
              } else if (c == '-') {
                containsHyphen = true;
              }
              appendStrBuf(c);
              continue;
            }
          }
        }
      tagnameloop_end:;
        [[fallthrough]];
      }
      case BEFORE_ATTRIBUTE_NAME: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '/': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            case '\"':
            case '\'':
            case '<':
            case '=': {
              if (P::reportErrors) {
                errBadCharBeforeAttributeNameOrNull(c);
              }
              [[fallthrough]];
            }
            default: {
              if (c >= 'A' && c <= 'Z') {
                c += 0x20;
              }
              attributeLine = line;
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
                                    pos);
              NS_HTML5_BREAK(beforeattributenameloop);
            }
          }
        }
      beforeattributenameloop_end:;
        [[fallthrough]];
      }
      case ATTRIBUTE_NAME: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              attributeNameComplete();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              attributeNameComplete();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::AFTER_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '/': {
              attributeNameComplete();
              addAttributeWithoutValue();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '=': {
              attributeNameComplete();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
                                    reconsume, pos);
              NS_HTML5_BREAK(attributenameloop);
            }
            case '>': {
              attributeNameComplete();
              addAttributeWithoutValue();
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            case '\"':
            case '\'':
            case '<': {
              if (P::reportErrors) {
                errQuoteOrLtInAttributeNameOrNull(c);
              }
              [[fallthrough]];
            }
            default: {
              if (c >= 'A' && c <= 'Z') {
                c += 0x20;
              }
              appendStrBuf(c);
              continue;
            }
          }
        }
      attributenameloop_end:;
        [[fallthrough]];
      }
      case BEFORE_ATTRIBUTE_VALUE: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '\"': {
              attributeLine = line;
              clearStrBufBeforeUse();
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::ATTRIBUTE_VALUE_DOUBLE_QUOTED,
                                reconsume, pos);
              NS_HTML5_BREAK(beforeattributevalueloop);
            }
            case '&': {
              attributeLine = line;
              clearStrBufBeforeUse();
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
                                    reconsume, pos);

              NS_HTML5_CONTINUE(stateloop);
            }
            case '\'': {
              attributeLine = line;
              clearStrBufBeforeUse();
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::ATTRIBUTE_VALUE_SINGLE_QUOTED,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              if (P::reportErrors) {
                errAttributeValueMissing();
              }
              addAttributeWithoutValue();
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            case '<':
            case '=':
            case '`': {
              if (P::reportErrors) {
                errLtOrEqualsOrGraveInUnquotedAttributeOrNull(c);
              }
              [[fallthrough]];
            }
            default: {
              attributeLine = line;
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::ATTRIBUTE_VALUE_UNQUOTED,
                                    reconsume, pos);

              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      beforeattributevalueloop_end:;
        [[fallthrough]];
      }
      case ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '\"': {
              addAttributeWithValue();
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::AFTER_ATTRIBUTE_VALUE_QUOTED,
                                reconsume, pos);
              NS_HTML5_BREAK(attributevaluedoublequotedloop);
            }
            case '&': {
              MOZ_ASSERT(!charRefBufLen,
                         "charRefBufLen not reset after previous use!");
              appendCharRefBuf(c);
              setAdditionalAndRememberAmpersandLocation('\"');
              returnState = state;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              continue;
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      attributevaluedoublequotedloop_end:;
        [[fallthrough]];
      }
      case AFTER_ATTRIBUTE_VALUE_QUOTED: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '/': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
                                    reconsume, pos);
              NS_HTML5_BREAK(afterattributevaluequotedloop);
            }
            case '>': {
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            default: {
              if (P::reportErrors) {
                errNoSpaceBetweenAttributes();
              }
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      afterattributevaluequotedloop_end:;
        [[fallthrough]];
      }
      case SELF_CLOSING_START_TAG: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case '>': {
            state =
                P::transition(mViewSource.get(), emitCurrentTagToken(true, pos),
                              reconsume, pos);
            if (shouldSuspend) {
              NS_HTML5_BREAK(stateloop);
            }
            NS_HTML5_CONTINUE(stateloop);
          }
          default: {
            if (P::reportErrors) {
              errSlashNotFollowedByGt();
            }
            reconsume = true;
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
        }
      }
      case ATTRIBUTE_VALUE_UNQUOTED: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              addAttributeWithValue();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              addAttributeWithValue();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_NAME,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '&': {
              MOZ_ASSERT(!charRefBufLen,
                         "charRefBufLen not reset after previous use!");
              appendCharRefBuf(c);
              setAdditionalAndRememberAmpersandLocation('>');
              returnState = state;
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::CONSUME_CHARACTER_REFERENCE,
                                reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              addAttributeWithValue();
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            case '<':
            case '\"':
            case '\'':
            case '=':
            case '`': {
              if (P::reportErrors) {
                errUnquotedAttributeValOrNull(c);
              }
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      }
      case AFTER_ATTRIBUTE_NAME: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '\r': {
              P::silentCarriageReturn(this);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            case ' ':
            case '\t':
            case '\f': {
              continue;
            }
            case '/': {
              addAttributeWithoutValue();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::SELF_CLOSING_START_TAG,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '=': {
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BEFORE_ATTRIBUTE_VALUE,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              addAttributeWithoutValue();
              state = P::transition(mViewSource.get(),
                                    emitCurrentTagToken(false, pos), reconsume,
                                    pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            case '\"':
            case '\'':
            case '<': {
              if (P::reportErrors) {
                errQuoteOrLtInAttributeNameOrNull(c);
              }
              [[fallthrough]];
            }
            default: {
              addAttributeWithoutValue();
              if (c >= 'A' && c <= 'Z') {
                c += 0x20;
              }
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::ATTRIBUTE_NAME, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      }
      case MARKUP_DECLARATION_OPEN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              clearStrBufBeforeUse();
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::MARKUP_DECLARATION_HYPHEN,
                                    reconsume, pos);
              NS_HTML5_BREAK(markupdeclarationopenloop);
            }
            case 'd':
            case 'D': {
              clearStrBufBeforeUse();
              appendStrBuf(c);
              index = 0;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::MARKUP_DECLARATION_OCTYPE,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '[': {
              if (tokenHandler->cdataSectionAllowed()) {
                clearStrBufBeforeUse();
                appendStrBuf(c);
                index = 0;
                state = P::transition(mViewSource.get(),
                                      nsHtml5Tokenizer::CDATA_START, reconsume,
                                      pos);
                NS_HTML5_CONTINUE(stateloop);
              }
              [[fallthrough]];
            }
            default: {
              if (P::reportErrors) {
                errBogusComment();
              }
              clearStrBufBeforeUse();
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      markupdeclarationopenloop_end:;
        [[fallthrough]];
      }
      case MARKUP_DECLARATION_HYPHEN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              clearStrBufAfterOneHyphen();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_START, reconsume,
                                    pos);
              NS_HTML5_BREAK(markupdeclarationhyphenloop);
            }
            default: {
              if (P::reportErrors) {
                errBogusComment();
              }
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      markupdeclarationhyphenloop_end:;
        [[fallthrough]];
      }
      case COMMENT_START: {
        reportedConsecutiveHyphens = false;
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_START_DASH,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '>': {
              if (P::reportErrors) {
                errPrematureEndOfComment();
              }
              emitComment(0, pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '<': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(commentstartloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(commentstartloop);
            }
          }
        }
      commentstartloop_end:;
        [[fallthrough]];
      }
      case COMMENT: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_END_DASH,
                                    reconsume, pos);
              NS_HTML5_BREAK(commentloop);
            }
            case '<': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              continue;
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              continue;
            }
          }
        }
      commentloop_end:;
        [[fallthrough]];
      }
      case COMMENT_END_DASH: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              appendStrBuf(c);
              state =
                  P::transition(mViewSource.get(),
                                nsHtml5Tokenizer::COMMENT_END, reconsume, pos);
              NS_HTML5_BREAK(commentenddashloop);
            }
            case '<': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      commentenddashloop_end:;
        [[fallthrough]];
      }
      case COMMENT_END: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '>': {
              emitComment(2, pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '-': {
              adjustDoubleHyphenAndAppendToStrBufAndErr(
                  c, reportedConsecutiveHyphens);
              reportedConsecutiveHyphens = true;
              continue;
            }
            case '<': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              adjustDoubleHyphenAndAppendToStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              adjustDoubleHyphenAndAppendToStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '!': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_END_BANG,
                                    reconsume, pos);
              NS_HTML5_BREAK(commentendloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              adjustDoubleHyphenAndAppendToStrBufAndErr(
                  c, reportedConsecutiveHyphens);
              reportedConsecutiveHyphens = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      commentendloop_end:;
        [[fallthrough]];
      }
      case COMMENT_END_BANG: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '>': {
              emitComment(3, pos);
              state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                    reconsume, pos);
              if (shouldSuspend) {
                NS_HTML5_BREAK(stateloop);
              }
              NS_HTML5_CONTINUE(stateloop);
            }
            case '-': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_END_DASH,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      }
      case COMMENT_LESSTHAN: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '!': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG,
                                    reconsume, pos);
              NS_HTML5_BREAK(commentlessthanloop);
            }
            case '<': {
              appendStrBuf(c);
              continue;
            }
            case '-': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_END_DASH,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      commentlessthanloop_end:;
        [[fallthrough]];
      }
      case COMMENT_LESSTHAN_BANG: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          switch (c) {
            case '-': {
              appendStrBuf(c);
              state = P::transition(
                  mViewSource.get(),
                  nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH, reconsume, pos);
              NS_HTML5_BREAK(commentlessthanbangloop);
            }
            case '<': {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT_LESSTHAN,
                                    reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\r': {
              appendStrBufCarriageReturn<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              appendStrBufLineFeed<P>();
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            case '\0': {
              c = 0xfffd;
              [[fallthrough]];
            }
            default: {
              appendStrBuf(c);
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::COMMENT, reconsume, pos);
              NS_HTML5_CONTINUE(stateloop);
            }
          }
        }
      commentlessthanbangloop_end:;
        [[fallthrough]];
      }
      case COMMENT_LESSTHAN_BANG_DASH: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case '-': {
            appendStrBuf(c);
            state =
                P::transition(mViewSource.get(),
                              nsHtml5Tokenizer::COMMENT_LESSTHAN_BANG_DASH_DASH,
                              reconsume, pos);
            break;
          }
          case '<': {
            appendStrBuf(c);
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
                                  pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\r': {
            appendStrBufCarriageReturn<P>();
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_BREAK(stateloop);
          }
          case '\n': {
            appendStrBufLineFeed<P>();
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\0': {
            c = 0xfffd;
            [[fallthrough]];
          }
          default: {
            appendStrBuf(c);
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
        }
        [[fallthrough]];
      }
      case COMMENT_LESSTHAN_BANG_DASH_DASH: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case '>': {
            appendStrBuf(c);
            emitComment(3, pos);
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                  reconsume, pos);
            if (shouldSuspend) {
              NS_HTML5_BREAK(stateloop);
            }
            NS_HTML5_CONTINUE(stateloop);
          }
          case '-': {
            if (P::reportErrors) {
              errNestedComment();
            }
            adjustDoubleHyphenAndAppendToStrBufAndErr(
                c, reportedConsecutiveHyphens);
            reportedConsecutiveHyphens = true;
            state =
                P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
                              reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\r': {
            c = '\n';
            P::silentCarriageReturn(this);
            if (P::reportErrors) {
              errNestedComment();
            }
            adjustDoubleHyphenAndAppendToStrBufAndErr(
                c, reportedConsecutiveHyphens);
            reportedConsecutiveHyphens = true;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_BREAK(stateloop);
          }
          case '\n': {
            P::silentLineFeed(this);
            if (P::reportErrors) {
              errNestedComment();
            }
            adjustDoubleHyphenAndAppendToStrBufAndErr(
                c, reportedConsecutiveHyphens);
            reportedConsecutiveHyphens = true;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '!': {
            if (P::reportErrors) {
              errNestedComment();
            }
            adjustDoubleHyphenAndAppendToStrBufAndErr(
                c, reportedConsecutiveHyphens);
            reportedConsecutiveHyphens = true;
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::COMMENT_END_BANG, reconsume,
                                  pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\0': {
            c = 0xfffd;
            [[fallthrough]];
          }
          default: {
            if (P::reportErrors) {
              errNestedComment();
            }
            adjustDoubleHyphenAndAppendToStrBufAndErr(
                c, reportedConsecutiveHyphens);
            reportedConsecutiveHyphens = true;
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
        }
      }
      case COMMENT_START_DASH: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case '-': {
            appendStrBuf(c);
            state =
                P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT_END,
                              reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '>': {
            if (P::reportErrors) {
              errPrematureEndOfComment();
            }
            emitComment(1, pos);
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::DATA,
                                  reconsume, pos);
            if (shouldSuspend) {
              NS_HTML5_BREAK(stateloop);
            }
            NS_HTML5_CONTINUE(stateloop);
          }
          case '<': {
            appendStrBuf(c);
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::COMMENT_LESSTHAN, reconsume,
                                  pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\r': {
            appendStrBufCarriageReturn<P>();
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_BREAK(stateloop);
          }
          case '\n': {
            appendStrBufLineFeed<P>();
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
          case '\0': {
            c = 0xfffd;
            [[fallthrough]];
          }
          default: {
            appendStrBuf(c);
            state = P::transition(mViewSource.get(), nsHtml5Tokenizer::COMMENT,
                                  reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
        }
      }
      case CDATA_START: {
        for (;;) {
          if (++pos == endPos) {
            NS_HTML5_BREAK(stateloop);
          }
          c = P::checkChar(this, buf, pos);
          if (index < 6) {
            if (c == nsHtml5Tokenizer::CDATA_LSQB[index]) {
              appendStrBuf(c);
            } else {
              if (P::reportErrors) {
                errBogusComment();
              }
              reconsume = true;
              state = P::transition(mViewSource.get(),
                                    nsHtml5Tokenizer::BOGUS_COMMENT, reconsume,
                                    pos);
              NS_HTML5_CONTINUE(stateloop);
            }
            index++;
            continue;
          } else {
            clearStrBufAfterUse();
            cstart = pos;
            reconsume = true;
            state =
                P::transition(mViewSource.get(),
                              nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
            break;
          }
        }
        [[fallthrough]];
      }
      case CDATA_SECTION: {
        for (;;) {
          if (reconsume) {
            reconsume = false;
          } else {
            if (++pos == endPos) {
              NS_HTML5_BREAK(stateloop);
            }
            c = P::checkChar(this, buf, pos);
          }
          switch (c) {
            case ']': {
              flushChars(buf, pos);
              state =
                  P::transition(mViewSource.get(), nsHtml5Tokenizer::CDATA_RSQB,
                                reconsume, pos);
              NS_HTML5_BREAK(cdatasectionloop);
            }
            case '\0': {
              maybeEmitReplacementCharacter(buf, pos);
              continue;
            }
            case '\r': {
              emitCarriageReturn<P>(buf, pos);
              NS_HTML5_BREAK(stateloop);
            }
            case '\n': {
              P::silentLineFeed(this);
              [[fallthrough]];
            }
            default: {
              continue;
            }
          }
        }
      cdatasectionloop_end:;
        [[fallthrough]];
      }
      case CDATA_RSQB: {
        if (++pos == endPos) {
          NS_HTML5_BREAK(stateloop);
        }
        c = P::checkChar(this, buf, pos);
        switch (c) {
          case ']': {
            state = P::transition(mViewSource.get(),
                                  nsHtml5Tokenizer::CDATA_RSQB_RSQB, reconsume,
                                  pos);
            break;
          }
          default: {
            tokenHandler->characters(nsHtml5Tokenizer::RSQB_RSQB, 0, 1);
            cstart = pos;
            reconsume = true;
            state =
                P::transition(mViewSource.get(),
                              nsHtml5Tokenizer::CDATA_SECTION, reconsume, pos);
            NS_HTML5_CONTINUE(stateloop);
          }
        }
        [[fallthrough]];
      }
      case CDATA_RSQB_RSQB: {
        for (;;) {
--> --------------------

--> maximum size reached

--> --------------------

93%


¤ Dauer der Verarbeitung: 0.26 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.