function consume_opening_or_closing_tag (proc_stack) {
  proc_stack.tSkip();
  let is_closing = proc_stack.tSkipIf("/");
  let tag_name = proc_stack.tAcceptUntilSet(TAG_NAME_DELIMITER).toLocaleLowerCase();
  if (!/^[a-z0-9]+(-[a-z0-9]+)*(:[a-z0-9]+(-[a-z0-9]+)*)?$/.test(tag_name)) {
    throw new SyntaxError(`Invalid HTML tag name "${tag_name}"`);
  }

  if (!is_closing && /^zc-/.test(tag_name)) {
    return consume_directive_tag(proc_stack, tag_name);
  }

  let parts = []; // Parts are needed for attribute value directives

  let html = "<" + (is_closing ? "/" : "") + tag_name;
  let done = false;
  while (!done) {
    html += proc_stack.tAcceptUntilSet(ATTR_VAL_START_OR_TAG_END_DELIMITER);
    let c = proc_stack.tAccept();
    html += c;

    switch (c) {
    case "\"":
      parts.push(html);
      Array.prototype.push.apply(parts, consume_char_data_with_entity_directives(proc_stack, false, "\""));
      html = proc_stack.tAccept();
      break;

    case ">":
      done = true;
      break;

    default:
      throw new Error(`INTERR Invalid char after ATTR_VAL_START_OR_TAG_END_DELIMITER`);
    }
  }

  parts.push(html);

  return parts;
}
function consume_opening_or_closing_tag (proc_stack) {
  proc_stack.tSkip();
  let is_closing = proc_stack.tSkipIf("/");
  let tag_name = proc_stack.tAcceptUntilSet(TAG_NAME_DELIMITER).toLocaleLowerCase();
  if (!/^[a-z0-9]+(-[a-z0-9]+)*(:[a-z0-9]+(-[a-z0-9]+)*)?$/.test(tag_name)) {
    throw new SyntaxError(`Invalid HTML tag name "${tag_name}"`);
  }

  if (!is_closing && /^zc-/.test(tag_name)) {
    return consume_directive_tag(proc_stack, tag_name);
  }

  let parts = []; 

  let html = "<" + (is_closing ? "/" : "") + tag_name;
  let done = false;
  while (!done) {
    html += proc_stack.tAcceptUntilSet(ATTR_VAL_START_OR_TAG_END_DELIMITER);
    let c = proc_stack.tAccept();
    html += c;

    switch (c) {
    case "\"":
      parts.push(html);
      Array.prototype.push.apply(parts, consume_char_data_with_entity_directives(proc_stack, false, "\""));
      html = proc_stack.tAccept();
      break;

    case ">":
      done = true;
      break;

    default:
      throw new Error(`INTERR Invalid char after ATTR_VAL_START_OR_TAG_END_DELIMITER`);
    }
  }

  parts.push(html);

  return parts;
}
function consume_opening_or_closing_tag ( proc_stack ) { proc_stack . tSkip ( ) ; let is_closing = proc_stack . tSkipIf ( "/" ) ; let tag_name = proc_stack . tAcceptUntilSet ( TAG_NAME_DELIMITER ) . toLocaleLowerCase ( ) ; if ( ! / ^[a-z0-9]+(-[a-z0-9]+)*(:[a-z0-9]+(-[a-z0-9]+)*)?$ / . test ( tag_name ) ) { throw new SyntaxError ( ` ${ tag_name } ` ) ; } if ( ! is_closing && / ^zc- / . test ( tag_name ) ) { return consume_directive_tag ( proc_stack , tag_name ) ; } let parts = [ ] ; // Parts are needed for attribute value directives let html = "<" + ( is_closing ? "/" : "" ) + tag_name ; let done = false ; while ( ! done ) { html += proc_stack . tAcceptUntilSet ( ATTR_VAL_START_OR_TAG_END_DELIMITER ) ; let c = proc_stack . tAccept ( ) ; html += c ; switch ( c ) { case "\"" : parts . push ( html ) ; Array . prototype . push . apply ( parts , consume_char_data_with_entity_directives ( proc_stack , false , "\"" ) ) ; html = proc_stack . tAccept ( ) ; break ; case ">" : done = true ; break ; default : throw new Error ( ` ` ) ; } } parts . push ( html ) ; return parts ; }
Called on match `<`
Called on match <