htmljs-parser 3.3.2 → 3.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -363,6 +363,7 @@ __export(states_exports, {
363
363
  REGULAR_EXPRESSION: () => REGULAR_EXPRESSION,
364
364
  STRING: () => STRING,
365
365
  TAG_NAME: () => TAG_NAME,
366
+ TAG_STAGE: () => TAG_STAGE,
366
367
  TEMPLATE_STRING: () => TEMPLATE_STRING,
367
368
  checkForCDATA: () => checkForCDATA,
368
369
  checkForClosingTag: () => checkForClosingTag,
@@ -421,6 +422,7 @@ var ATTRIBUTE = {
421
422
  return;
422
423
  } else if (code === 61 /* EQUAL */ || code === 58 /* COLON */ && this.lookAtCharCodeAhead(1) === 61 /* EQUAL */ || code === 46 /* PERIOD */ && this.lookAheadFor("..")) {
423
424
  attr.valueStart = this.pos;
425
+ this.forward = 0;
424
426
  if (code === 58 /* COLON */) {
425
427
  ensureAttrName(this, attr);
426
428
  attr.bound = true;
@@ -438,28 +440,27 @@ var ATTRIBUTE = {
438
440
  const expr = this.enterState(states_exports.EXPRESSION);
439
441
  expr.terminatedByWhitespace = true;
440
442
  expr.terminator = this.isConcise ? CONCISE_VALUE_TERMINATORS : HTML_VALUE_TERMINATORS;
441
- this.pos--;
442
443
  } else if (code === 40 /* OPEN_PAREN */) {
443
444
  ensureAttrName(this, attr);
444
445
  attr.stage = 3 /* ARGUMENT */;
445
446
  this.pos++;
447
+ this.forward = 0;
446
448
  this.enterState(states_exports.EXPRESSION).terminator = 41 /* CLOSE_PAREN */;
447
- this.pos--;
448
449
  } else if (code === 123 /* OPEN_CURLY_BRACE */ && attr.args) {
449
450
  ensureAttrName(this, attr);
450
451
  attr.stage = 4 /* BLOCK */;
451
452
  this.pos++;
453
+ this.forward = 0;
452
454
  const expr = this.enterState(states_exports.EXPRESSION);
453
455
  expr.terminatedByWhitespace = false;
454
456
  expr.terminator = 125 /* CLOSE_CURLY_BRACE */;
455
- this.pos--;
456
457
  } else if (attr.stage === 0 /* UNKNOWN */) {
457
458
  attr.stage = 1 /* NAME */;
459
+ this.forward = 0;
458
460
  const expr = this.enterState(states_exports.EXPRESSION);
459
461
  expr.terminatedByWhitespace = true;
460
462
  expr.skipOperators = true;
461
463
  expr.terminator = this.isConcise ? CONCISE_NAME_TERMINATORS : HTML_NAME_TERMINATORS;
462
- this.pos--;
463
464
  } else {
464
465
  this.exitState();
465
466
  }
@@ -596,8 +597,8 @@ var BEGIN_DELIMITED_HTML_BLOCK = {
596
597
  const startPos = this.pos;
597
598
  if (!this.consumeWhitespaceOnLine()) {
598
599
  this.pos = startPos + 1;
600
+ this.forward = 0;
599
601
  this.beginHtmlBlock(void 0, true);
600
- this.pos--;
601
602
  }
602
603
  }
603
604
  },
@@ -860,7 +861,7 @@ var CONCISE_HTML_CONTENT = {
860
861
  }
861
862
  }
862
863
  this.enterState(states_exports.OPEN_TAG);
863
- this.pos--;
864
+ this.forward = 0;
864
865
  }
865
866
  },
866
867
  eol() {
@@ -984,8 +985,9 @@ var DTD = {
984
985
  };
985
986
 
986
987
  // src/states/EXPRESSION.ts
987
- var conciseOperatorPattern = buildOperatorPattern(true);
988
- var htmlOperatorPattern = buildOperatorPattern(false);
988
+ var htmlAttrsPattern = buildPattern(0 /* HTML_ATTRS */);
989
+ var conciseAttrsPattern = buildPattern(1 /* CONCISE_ATTRS */);
990
+ var conciseAttrsGroupPattern = buildPattern(2 /* CONCISE_ATTRS_GROUP */);
989
991
  var EXPRESSION = {
990
992
  name: "EXPRESSION",
991
993
  enter(parent, start) {
@@ -1068,7 +1070,7 @@ var EXPRESSION = {
1068
1070
  }
1069
1071
  },
1070
1072
  eol(_, expression) {
1071
- if (!expression.groupStack.length && (expression.terminatedByWhitespace || expression.terminatedByEOL)) {
1073
+ if (!expression.groupStack.length && (expression.terminatedByEOL || expression.terminatedByWhitespace) && !checkForOperators(this, expression)) {
1072
1074
  this.exitState();
1073
1075
  }
1074
1076
  },
@@ -1096,28 +1098,30 @@ var EXPRESSION = {
1096
1098
  return() {
1097
1099
  }
1098
1100
  };
1099
- function buildOperatorPattern(isConcise) {
1100
- const binary = `(?:[!~*%&^|?:<]+=*)+|[>/+-=]+=|=>|(?<!\\+)[ \\t]*\\+(?:[ \\t]*\\+[ \\t]*\\+)*[ \\t]*(?!\\+)|(?<!-)-${isConcise ? "" : "(?:[ \\t]*-[ \\t]*-)*[ \\t]*"}(?!-)|(?<![/*])/(?![/*${isConcise ? "" : ">"}])|(?<!\\.)\\.(?!\\.)|>${isConcise ? "+" : "{2,}"}|\\b(?:in(?:stanceof)?|as|extends)(?=[ \\t]+[^=/,;:>])`;
1101
- const unary = "\\b(?:a(?:sync|wait)|keyof|class|function|new|typeof|void)\\b";
1102
- const lookAheadPattern = "[ \\t]*(?:" + binary + `)[ \\t]*|[ \\t]+(?=[{(])`;
1101
+ function buildPattern(type) {
1102
+ const space = type === 1 /* CONCISE_ATTRS */ ? "[ \\t]" : "\\s";
1103
+ const binary = `(?:[!~*%&^|?<]+=*)+|:+(?!=)|[>/+=-]+=|=>|(?<!\\+)[ \\t]*\\+(?:\\s*\\+\\s*\\+)*\\s*(?!\\+)|(?<!-)-${type === 1 /* CONCISE_ATTRS */ ? "" : "(?:\\s*-\\s*-)*\\s*"}(?!-)|(?<![/*])/(?![/*${type === 0 /* HTML_ATTRS */ ? ">" : ""}])|(?<!\\.)\\.(?!\\.)|>${type === 0 /* HTML_ATTRS */ ? "{2,}" : "+"}|[ \\t]+(?:in(?:stanceof)?|as|extends)(?=[ \\t]+[^=/,;:>])`;
1104
+ const unary = "\\b(?<![.]\\s*)(?:a(?:sync|wait)|keyof|class|function|new|typeof|void)\\b";
1105
+ const lookAheadPattern = `${space}*(?:${binary})\\s*|${space}+(?=[{(])`;
1103
1106
  const lookBehindPattern = `(?<=${unary}|${binary})`;
1104
1107
  return new RegExp(`${lookAheadPattern}|${lookBehindPattern}`, "ym");
1105
1108
  }
1106
1109
  function checkForOperators(parser, expression) {
1110
+ var _a;
1107
1111
  if (expression.skipOperators) {
1108
1112
  return false;
1109
1113
  }
1110
- const pattern = parser.isConcise || expression.terminatedByEOL ? conciseOperatorPattern : htmlOperatorPattern;
1114
+ const pattern = parser.isConcise ? ((_a = parser.activeTag) == null ? void 0 : _a.stage) === states_exports.TAG_STAGE.ATTR_GROUP ? conciseAttrsGroupPattern : conciseAttrsPattern : expression.terminatedByEOL ? conciseAttrsPattern : htmlAttrsPattern;
1111
1115
  pattern.lastIndex = parser.pos;
1112
1116
  const matches = pattern.exec(parser.data);
1113
1117
  if (matches) {
1114
1118
  const [match] = matches;
1115
1119
  if (match.length === 0) {
1116
1120
  parser.consumeWhitespace();
1117
- parser.pos--;
1118
1121
  } else {
1119
- parser.pos += match.length - 1;
1122
+ parser.pos += match.length;
1120
1123
  }
1124
+ parser.forward = 0;
1121
1125
  } else {
1122
1126
  return false;
1123
1127
  }
@@ -1303,17 +1307,16 @@ var INLINE_SCRIPT = {
1303
1307
  eof() {
1304
1308
  },
1305
1309
  char(code, inlineScript) {
1310
+ this.forward = 0;
1306
1311
  if (code === 123 /* OPEN_CURLY_BRACE */) {
1307
1312
  inlineScript.block = true;
1308
1313
  this.pos++;
1309
1314
  const expr = this.enterState(states_exports.EXPRESSION);
1310
1315
  expr.terminator = 125 /* CLOSE_CURLY_BRACE */;
1311
1316
  expr.skipOperators = true;
1312
- this.pos--;
1313
1317
  } else {
1314
1318
  const expr = this.enterState(states_exports.EXPRESSION);
1315
1319
  expr.terminatedByEOL = true;
1316
- this.pos--;
1317
1320
  }
1318
1321
  },
1319
1322
  return(child, inlineScript) {
@@ -1509,8 +1512,8 @@ function checkForPlaceholder(parser, code) {
1509
1512
  parser.endText();
1510
1513
  parser.enterState(PLACEHOLDER).escape = escape;
1511
1514
  parser.pos += escape ? 2 : 3;
1515
+ parser.forward = 0;
1512
1516
  parser.enterState(states_exports.EXPRESSION).terminator = 125 /* CLOSE_CURLY_BRACE */;
1513
- parser.pos--;
1514
1517
  return true;
1515
1518
  }
1516
1519
  }
@@ -1656,8 +1659,8 @@ var TAG_NAME = {
1656
1659
  char(code) {
1657
1660
  if (code === 36 /* DOLLAR */ && this.lookAtCharCodeAhead(1) === 123 /* OPEN_CURLY_BRACE */) {
1658
1661
  this.pos += 2;
1662
+ this.forward = 0;
1659
1663
  this.enterState(states_exports.EXPRESSION).terminator = 125 /* CLOSE_CURLY_BRACE */;
1660
- this.pos--;
1661
1664
  } else if (isWhitespaceCode(code) || code === 61 /* EQUAL */ || code === 58 /* COLON */ && this.lookAtCharCodeAhead(1) === 61 /* EQUAL */ || code === 40 /* OPEN_PAREN */ || code === 47 /* FORWARD_SLASH */ || code === 124 /* PIPE */ || (this.isConcise ? code === 59 /* SEMICOLON */ : code === 62 /* CLOSE_ANGLE_BRACKET */)) {
1662
1665
  this.activeTag.shorthandEnd = this.pos;
1663
1666
  this.exitState();
@@ -1740,6 +1743,14 @@ var TEMPLATE_STRING = {
1740
1743
  };
1741
1744
 
1742
1745
  // src/states/OPEN_TAG.ts
1746
+ var TAG_STAGE = /* @__PURE__ */ ((TAG_STAGE2) => {
1747
+ TAG_STAGE2[TAG_STAGE2["UNKNOWN"] = 0] = "UNKNOWN";
1748
+ TAG_STAGE2[TAG_STAGE2["VAR"] = 1] = "VAR";
1749
+ TAG_STAGE2[TAG_STAGE2["ARGUMENT"] = 2] = "ARGUMENT";
1750
+ TAG_STAGE2[TAG_STAGE2["PARAMS"] = 3] = "PARAMS";
1751
+ TAG_STAGE2[TAG_STAGE2["ATTR_GROUP"] = 4] = "ATTR_GROUP";
1752
+ return TAG_STAGE2;
1753
+ })(TAG_STAGE || {});
1743
1754
  var CONCISE_TAG_VAR_TERMINATORS = [
1744
1755
  59 /* SEMICOLON */,
1745
1756
  40 /* OPEN_PAREN */,
@@ -1919,16 +1930,18 @@ var OPEN_TAG = {
1919
1930
  if (isWhitespaceCode(code)) {
1920
1931
  } else if (code === 44 /* COMMA */) {
1921
1932
  this.pos++;
1933
+ this.forward = 0;
1922
1934
  this.consumeWhitespace();
1923
- this.pos--;
1924
1935
  } else if (code === 47 /* FORWARD_SLASH */ && !tag.hasAttrs) {
1925
1936
  tag.stage = 1 /* VAR */;
1926
1937
  this.pos++;
1938
+ this.forward = 0;
1939
+ if (isWhitespaceCode(this.lookAtCharCodeAhead(0))) {
1940
+ return this.emitError(this.pos, 23 /* MISSING_TAG_VARIABLE */, "A slash was found that was not followed by a variable name or lhs expression");
1941
+ }
1927
1942
  const expr = this.enterState(states_exports.EXPRESSION);
1928
- expr.skipOperators = true;
1929
1943
  expr.terminatedByWhitespace = true;
1930
1944
  expr.terminator = this.isConcise ? CONCISE_TAG_VAR_TERMINATORS : HTML_TAG_VAR_TERMINATORS;
1931
- this.pos--;
1932
1945
  } else if (code === 40 /* OPEN_PAREN */ && !tag.hasAttrs) {
1933
1946
  if (tag.hasArgs) {
1934
1947
  this.emitError(this.pos, 11 /* INVALID_TAG_ARGUMENT */, "A tag can only have one argument");
@@ -1936,25 +1949,25 @@ var OPEN_TAG = {
1936
1949
  }
1937
1950
  tag.stage = 2 /* ARGUMENT */;
1938
1951
  this.pos++;
1952
+ this.forward = 0;
1939
1953
  const expr = this.enterState(states_exports.EXPRESSION);
1940
1954
  expr.skipOperators = true;
1941
1955
  expr.terminator = 41 /* CLOSE_PAREN */;
1942
- this.pos--;
1943
1956
  } else if (code === 124 /* PIPE */ && !tag.hasAttrs) {
1944
1957
  tag.stage = 3 /* PARAMS */;
1945
1958
  this.pos++;
1959
+ this.forward = 0;
1946
1960
  const expr = this.enterState(states_exports.EXPRESSION);
1947
1961
  expr.skipOperators = true;
1948
1962
  expr.terminator = 124 /* PIPE */;
1949
- this.pos--;
1950
1963
  } else {
1964
+ this.forward = 0;
1951
1965
  if (tag.tagName) {
1952
1966
  this.enterState(states_exports.ATTRIBUTE);
1953
1967
  tag.hasAttrs = true;
1954
1968
  } else {
1955
1969
  this.enterState(states_exports.TAG_NAME);
1956
1970
  }
1957
- this.pos--;
1958
1971
  }
1959
1972
  },
1960
1973
  return(child, tag) {
@@ -1991,7 +2004,7 @@ var OPEN_TAG = {
1991
2004
  attr.start = start;
1992
2005
  attr.args = { start, end, value };
1993
2006
  tag.hasAttrs = true;
1994
- this.pos--;
2007
+ this.forward = 0;
1995
2008
  } else {
1996
2009
  tag.hasArgs = true;
1997
2010
  (_d = (_c = this.options).onTagArgs) == null ? void 0 : _d.call(_c, {
package/dist/index.mjs CHANGED
@@ -342,6 +342,7 @@ __export(states_exports, {
342
342
  REGULAR_EXPRESSION: () => REGULAR_EXPRESSION,
343
343
  STRING: () => STRING,
344
344
  TAG_NAME: () => TAG_NAME,
345
+ TAG_STAGE: () => TAG_STAGE,
345
346
  TEMPLATE_STRING: () => TEMPLATE_STRING,
346
347
  checkForCDATA: () => checkForCDATA,
347
348
  checkForClosingTag: () => checkForClosingTag,
@@ -400,6 +401,7 @@ var ATTRIBUTE = {
400
401
  return;
401
402
  } else if (code === 61 /* EQUAL */ || code === 58 /* COLON */ && this.lookAtCharCodeAhead(1) === 61 /* EQUAL */ || code === 46 /* PERIOD */ && this.lookAheadFor("..")) {
402
403
  attr.valueStart = this.pos;
404
+ this.forward = 0;
403
405
  if (code === 58 /* COLON */) {
404
406
  ensureAttrName(this, attr);
405
407
  attr.bound = true;
@@ -417,28 +419,27 @@ var ATTRIBUTE = {
417
419
  const expr = this.enterState(states_exports.EXPRESSION);
418
420
  expr.terminatedByWhitespace = true;
419
421
  expr.terminator = this.isConcise ? CONCISE_VALUE_TERMINATORS : HTML_VALUE_TERMINATORS;
420
- this.pos--;
421
422
  } else if (code === 40 /* OPEN_PAREN */) {
422
423
  ensureAttrName(this, attr);
423
424
  attr.stage = 3 /* ARGUMENT */;
424
425
  this.pos++;
426
+ this.forward = 0;
425
427
  this.enterState(states_exports.EXPRESSION).terminator = 41 /* CLOSE_PAREN */;
426
- this.pos--;
427
428
  } else if (code === 123 /* OPEN_CURLY_BRACE */ && attr.args) {
428
429
  ensureAttrName(this, attr);
429
430
  attr.stage = 4 /* BLOCK */;
430
431
  this.pos++;
432
+ this.forward = 0;
431
433
  const expr = this.enterState(states_exports.EXPRESSION);
432
434
  expr.terminatedByWhitespace = false;
433
435
  expr.terminator = 125 /* CLOSE_CURLY_BRACE */;
434
- this.pos--;
435
436
  } else if (attr.stage === 0 /* UNKNOWN */) {
436
437
  attr.stage = 1 /* NAME */;
438
+ this.forward = 0;
437
439
  const expr = this.enterState(states_exports.EXPRESSION);
438
440
  expr.terminatedByWhitespace = true;
439
441
  expr.skipOperators = true;
440
442
  expr.terminator = this.isConcise ? CONCISE_NAME_TERMINATORS : HTML_NAME_TERMINATORS;
441
- this.pos--;
442
443
  } else {
443
444
  this.exitState();
444
445
  }
@@ -575,8 +576,8 @@ var BEGIN_DELIMITED_HTML_BLOCK = {
575
576
  const startPos = this.pos;
576
577
  if (!this.consumeWhitespaceOnLine()) {
577
578
  this.pos = startPos + 1;
579
+ this.forward = 0;
578
580
  this.beginHtmlBlock(void 0, true);
579
- this.pos--;
580
581
  }
581
582
  }
582
583
  },
@@ -839,7 +840,7 @@ var CONCISE_HTML_CONTENT = {
839
840
  }
840
841
  }
841
842
  this.enterState(states_exports.OPEN_TAG);
842
- this.pos--;
843
+ this.forward = 0;
843
844
  }
844
845
  },
845
846
  eol() {
@@ -963,8 +964,9 @@ var DTD = {
963
964
  };
964
965
 
965
966
  // src/states/EXPRESSION.ts
966
- var conciseOperatorPattern = buildOperatorPattern(true);
967
- var htmlOperatorPattern = buildOperatorPattern(false);
967
+ var htmlAttrsPattern = buildPattern(0 /* HTML_ATTRS */);
968
+ var conciseAttrsPattern = buildPattern(1 /* CONCISE_ATTRS */);
969
+ var conciseAttrsGroupPattern = buildPattern(2 /* CONCISE_ATTRS_GROUP */);
968
970
  var EXPRESSION = {
969
971
  name: "EXPRESSION",
970
972
  enter(parent, start) {
@@ -1047,7 +1049,7 @@ var EXPRESSION = {
1047
1049
  }
1048
1050
  },
1049
1051
  eol(_, expression) {
1050
- if (!expression.groupStack.length && (expression.terminatedByWhitespace || expression.terminatedByEOL)) {
1052
+ if (!expression.groupStack.length && (expression.terminatedByEOL || expression.terminatedByWhitespace) && !checkForOperators(this, expression)) {
1051
1053
  this.exitState();
1052
1054
  }
1053
1055
  },
@@ -1075,28 +1077,30 @@ var EXPRESSION = {
1075
1077
  return() {
1076
1078
  }
1077
1079
  };
1078
- function buildOperatorPattern(isConcise) {
1079
- const binary = `(?:[!~*%&^|?:<]+=*)+|[>/+-=]+=|=>|(?<!\\+)[ \\t]*\\+(?:[ \\t]*\\+[ \\t]*\\+)*[ \\t]*(?!\\+)|(?<!-)-${isConcise ? "" : "(?:[ \\t]*-[ \\t]*-)*[ \\t]*"}(?!-)|(?<![/*])/(?![/*${isConcise ? "" : ">"}])|(?<!\\.)\\.(?!\\.)|>${isConcise ? "+" : "{2,}"}|\\b(?:in(?:stanceof)?|as|extends)(?=[ \\t]+[^=/,;:>])`;
1080
- const unary = "\\b(?:a(?:sync|wait)|keyof|class|function|new|typeof|void)\\b";
1081
- const lookAheadPattern = "[ \\t]*(?:" + binary + `)[ \\t]*|[ \\t]+(?=[{(])`;
1080
+ function buildPattern(type) {
1081
+ const space = type === 1 /* CONCISE_ATTRS */ ? "[ \\t]" : "\\s";
1082
+ const binary = `(?:[!~*%&^|?<]+=*)+|:+(?!=)|[>/+=-]+=|=>|(?<!\\+)[ \\t]*\\+(?:\\s*\\+\\s*\\+)*\\s*(?!\\+)|(?<!-)-${type === 1 /* CONCISE_ATTRS */ ? "" : "(?:\\s*-\\s*-)*\\s*"}(?!-)|(?<![/*])/(?![/*${type === 0 /* HTML_ATTRS */ ? ">" : ""}])|(?<!\\.)\\.(?!\\.)|>${type === 0 /* HTML_ATTRS */ ? "{2,}" : "+"}|[ \\t]+(?:in(?:stanceof)?|as|extends)(?=[ \\t]+[^=/,;:>])`;
1083
+ const unary = "\\b(?<![.]\\s*)(?:a(?:sync|wait)|keyof|class|function|new|typeof|void)\\b";
1084
+ const lookAheadPattern = `${space}*(?:${binary})\\s*|${space}+(?=[{(])`;
1082
1085
  const lookBehindPattern = `(?<=${unary}|${binary})`;
1083
1086
  return new RegExp(`${lookAheadPattern}|${lookBehindPattern}`, "ym");
1084
1087
  }
1085
1088
  function checkForOperators(parser, expression) {
1089
+ var _a;
1086
1090
  if (expression.skipOperators) {
1087
1091
  return false;
1088
1092
  }
1089
- const pattern = parser.isConcise || expression.terminatedByEOL ? conciseOperatorPattern : htmlOperatorPattern;
1093
+ const pattern = parser.isConcise ? ((_a = parser.activeTag) == null ? void 0 : _a.stage) === states_exports.TAG_STAGE.ATTR_GROUP ? conciseAttrsGroupPattern : conciseAttrsPattern : expression.terminatedByEOL ? conciseAttrsPattern : htmlAttrsPattern;
1090
1094
  pattern.lastIndex = parser.pos;
1091
1095
  const matches = pattern.exec(parser.data);
1092
1096
  if (matches) {
1093
1097
  const [match] = matches;
1094
1098
  if (match.length === 0) {
1095
1099
  parser.consumeWhitespace();
1096
- parser.pos--;
1097
1100
  } else {
1098
- parser.pos += match.length - 1;
1101
+ parser.pos += match.length;
1099
1102
  }
1103
+ parser.forward = 0;
1100
1104
  } else {
1101
1105
  return false;
1102
1106
  }
@@ -1282,17 +1286,16 @@ var INLINE_SCRIPT = {
1282
1286
  eof() {
1283
1287
  },
1284
1288
  char(code, inlineScript) {
1289
+ this.forward = 0;
1285
1290
  if (code === 123 /* OPEN_CURLY_BRACE */) {
1286
1291
  inlineScript.block = true;
1287
1292
  this.pos++;
1288
1293
  const expr = this.enterState(states_exports.EXPRESSION);
1289
1294
  expr.terminator = 125 /* CLOSE_CURLY_BRACE */;
1290
1295
  expr.skipOperators = true;
1291
- this.pos--;
1292
1296
  } else {
1293
1297
  const expr = this.enterState(states_exports.EXPRESSION);
1294
1298
  expr.terminatedByEOL = true;
1295
- this.pos--;
1296
1299
  }
1297
1300
  },
1298
1301
  return(child, inlineScript) {
@@ -1488,8 +1491,8 @@ function checkForPlaceholder(parser, code) {
1488
1491
  parser.endText();
1489
1492
  parser.enterState(PLACEHOLDER).escape = escape;
1490
1493
  parser.pos += escape ? 2 : 3;
1494
+ parser.forward = 0;
1491
1495
  parser.enterState(states_exports.EXPRESSION).terminator = 125 /* CLOSE_CURLY_BRACE */;
1492
- parser.pos--;
1493
1496
  return true;
1494
1497
  }
1495
1498
  }
@@ -1635,8 +1638,8 @@ var TAG_NAME = {
1635
1638
  char(code) {
1636
1639
  if (code === 36 /* DOLLAR */ && this.lookAtCharCodeAhead(1) === 123 /* OPEN_CURLY_BRACE */) {
1637
1640
  this.pos += 2;
1641
+ this.forward = 0;
1638
1642
  this.enterState(states_exports.EXPRESSION).terminator = 125 /* CLOSE_CURLY_BRACE */;
1639
- this.pos--;
1640
1643
  } else if (isWhitespaceCode(code) || code === 61 /* EQUAL */ || code === 58 /* COLON */ && this.lookAtCharCodeAhead(1) === 61 /* EQUAL */ || code === 40 /* OPEN_PAREN */ || code === 47 /* FORWARD_SLASH */ || code === 124 /* PIPE */ || (this.isConcise ? code === 59 /* SEMICOLON */ : code === 62 /* CLOSE_ANGLE_BRACKET */)) {
1641
1644
  this.activeTag.shorthandEnd = this.pos;
1642
1645
  this.exitState();
@@ -1719,6 +1722,14 @@ var TEMPLATE_STRING = {
1719
1722
  };
1720
1723
 
1721
1724
  // src/states/OPEN_TAG.ts
1725
+ var TAG_STAGE = /* @__PURE__ */ ((TAG_STAGE2) => {
1726
+ TAG_STAGE2[TAG_STAGE2["UNKNOWN"] = 0] = "UNKNOWN";
1727
+ TAG_STAGE2[TAG_STAGE2["VAR"] = 1] = "VAR";
1728
+ TAG_STAGE2[TAG_STAGE2["ARGUMENT"] = 2] = "ARGUMENT";
1729
+ TAG_STAGE2[TAG_STAGE2["PARAMS"] = 3] = "PARAMS";
1730
+ TAG_STAGE2[TAG_STAGE2["ATTR_GROUP"] = 4] = "ATTR_GROUP";
1731
+ return TAG_STAGE2;
1732
+ })(TAG_STAGE || {});
1722
1733
  var CONCISE_TAG_VAR_TERMINATORS = [
1723
1734
  59 /* SEMICOLON */,
1724
1735
  40 /* OPEN_PAREN */,
@@ -1898,16 +1909,18 @@ var OPEN_TAG = {
1898
1909
  if (isWhitespaceCode(code)) {
1899
1910
  } else if (code === 44 /* COMMA */) {
1900
1911
  this.pos++;
1912
+ this.forward = 0;
1901
1913
  this.consumeWhitespace();
1902
- this.pos--;
1903
1914
  } else if (code === 47 /* FORWARD_SLASH */ && !tag.hasAttrs) {
1904
1915
  tag.stage = 1 /* VAR */;
1905
1916
  this.pos++;
1917
+ this.forward = 0;
1918
+ if (isWhitespaceCode(this.lookAtCharCodeAhead(0))) {
1919
+ return this.emitError(this.pos, 23 /* MISSING_TAG_VARIABLE */, "A slash was found that was not followed by a variable name or lhs expression");
1920
+ }
1906
1921
  const expr = this.enterState(states_exports.EXPRESSION);
1907
- expr.skipOperators = true;
1908
1922
  expr.terminatedByWhitespace = true;
1909
1923
  expr.terminator = this.isConcise ? CONCISE_TAG_VAR_TERMINATORS : HTML_TAG_VAR_TERMINATORS;
1910
- this.pos--;
1911
1924
  } else if (code === 40 /* OPEN_PAREN */ && !tag.hasAttrs) {
1912
1925
  if (tag.hasArgs) {
1913
1926
  this.emitError(this.pos, 11 /* INVALID_TAG_ARGUMENT */, "A tag can only have one argument");
@@ -1915,25 +1928,25 @@ var OPEN_TAG = {
1915
1928
  }
1916
1929
  tag.stage = 2 /* ARGUMENT */;
1917
1930
  this.pos++;
1931
+ this.forward = 0;
1918
1932
  const expr = this.enterState(states_exports.EXPRESSION);
1919
1933
  expr.skipOperators = true;
1920
1934
  expr.terminator = 41 /* CLOSE_PAREN */;
1921
- this.pos--;
1922
1935
  } else if (code === 124 /* PIPE */ && !tag.hasAttrs) {
1923
1936
  tag.stage = 3 /* PARAMS */;
1924
1937
  this.pos++;
1938
+ this.forward = 0;
1925
1939
  const expr = this.enterState(states_exports.EXPRESSION);
1926
1940
  expr.skipOperators = true;
1927
1941
  expr.terminator = 124 /* PIPE */;
1928
- this.pos--;
1929
1942
  } else {
1943
+ this.forward = 0;
1930
1944
  if (tag.tagName) {
1931
1945
  this.enterState(states_exports.ATTRIBUTE);
1932
1946
  tag.hasAttrs = true;
1933
1947
  } else {
1934
1948
  this.enterState(states_exports.TAG_NAME);
1935
1949
  }
1936
- this.pos--;
1937
1950
  }
1938
1951
  },
1939
1952
  return(child, tag) {
@@ -1970,7 +1983,7 @@ var OPEN_TAG = {
1970
1983
  attr.start = start;
1971
1984
  attr.args = { start, end, value };
1972
1985
  tag.hasAttrs = true;
1973
- this.pos--;
1986
+ this.forward = 0;
1974
1987
  } else {
1975
1988
  tag.hasArgs = true;
1976
1989
  (_d = (_c = this.options).onTagArgs) == null ? void 0 : _d.call(_c, {
@@ -1,5 +1,5 @@
1
1
  import { StateDefinition, Ranges, Meta, TagType } from "../internal";
2
- declare const enum TAG_STAGE {
2
+ export declare const enum TAG_STAGE {
3
3
  UNKNOWN = 0,
4
4
  VAR = 1,
5
5
  ARGUMENT = 2,
@@ -22,4 +22,3 @@ export interface OpenTagMeta extends Meta {
22
22
  parentTag: OpenTagMeta | undefined;
23
23
  }
24
24
  export declare const OPEN_TAG: StateDefinition<OpenTagMeta>;
25
- export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "htmljs-parser",
3
3
  "description": "An HTML parser recognizes content and string placeholders and allows JavaScript expressions as attribute values",
4
- "version": "3.3.2",
4
+ "version": "3.3.5",
5
5
  "devDependencies": {
6
6
  "@changesets/changelog-github": "^0.4.4",
7
7
  "@changesets/cli": "^2.22.0",
@@ -68,13 +68,12 @@
68
68
  "lint:prettier": "prettier \"./**/*{.ts,.js,.json,.md,.yml,rc}\"",
69
69
  "mocha": "cross-env NODE_ENV=test mocha \"./src/**/__tests__/*.test.ts\"",
70
70
  "prepare": "husky install",
71
- "prepublishOnly": "npm run build",
72
71
  "publish": "npm run build && changeset publish",
73
72
  "report": "open ./coverage/lcov-report/index.html",
74
73
  "test": "npm run mocha -- --watch",
75
74
  "test:inspect": "npm test -- --inspect",
76
75
  "test:update": "npm run mocha -- --update",
77
- "version": "changeset version"
76
+ "version": "changeset version && npm i --package-lock-only"
78
77
  },
79
78
  "types": "dist/index.d.ts"
80
79
  }