htmljs-parser 3.1.0 → 3.2.0

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.
@@ -1,4 +1,4 @@
1
- import { STATE, Range, Handlers } from "../internal";
1
+ import { STATE, Range, ParserOptions as Options } from "../internal";
2
2
  export interface Meta extends Range {
3
3
  parent: Meta;
4
4
  state: StateDefinition;
@@ -15,7 +15,7 @@ export interface StateDefinition<P extends Meta = Meta> {
15
15
  return: (this: Parser, child: Meta, activeRange: P) => void;
16
16
  }
17
17
  export declare class Parser {
18
- handlers: Handlers;
18
+ options: Options;
19
19
  pos: number;
20
20
  maxPos: number;
21
21
  data: string;
@@ -30,7 +30,7 @@ export declare class Parser {
30
30
  endingMixedModeAtEOL?: boolean;
31
31
  textPos: number;
32
32
  lines: undefined | number[];
33
- constructor(handlers: Handlers);
33
+ constructor(options: Options);
34
34
  read(range: Range): string;
35
35
  positionAt(index: number): import("../internal").Position;
36
36
  locationAt(range: Range): import("../internal").Location;
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { type Handlers, type Range } from "./internal";
2
- export { OpenTagEnding, type Handlers, type Position, type Location, type Ranges, type Range, } from "./internal";
1
+ import { type ParserOptions, type Range } from "./internal";
2
+ export { TagType, type ParserOptions as Handlers, type Position, type Location, type Ranges, type Range, } from "./internal";
3
3
  /**
4
4
  * Creates a new Marko parser.
5
5
  */
6
- export declare function createParser(handlers: Handlers): {
6
+ export declare function createParser(handlers: ParserOptions): {
7
7
  /**
8
8
  * Parses code and calls the provided handlers.
9
9
  */
package/dist/index.js CHANGED
@@ -19,19 +19,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  // src/index.ts
20
20
  var src_exports = {};
21
21
  __export(src_exports, {
22
- OpenTagEnding: () => OpenTagEnding,
22
+ TagType: () => TagType,
23
23
  createParser: () => createParser
24
24
  });
25
25
  module.exports = __toCommonJS(src_exports);
26
26
 
27
27
  // src/util/constants.ts
28
- var OpenTagEnding = /* @__PURE__ */ ((OpenTagEnding2) => {
29
- OpenTagEnding2[OpenTagEnding2["tag"] = 0] = "tag";
30
- OpenTagEnding2[OpenTagEnding2["self"] = 1] = "self";
31
- OpenTagEnding2[OpenTagEnding2["void"] = 2] = "void";
32
- OpenTagEnding2[OpenTagEnding2["code"] = 4] = "code";
33
- return OpenTagEnding2;
34
- })(OpenTagEnding || {});
28
+ var TagType = /* @__PURE__ */ ((TagType2) => {
29
+ TagType2[TagType2["html"] = 0] = "html";
30
+ TagType2[TagType2["text"] = 1] = "text";
31
+ TagType2[TagType2["void"] = 2] = "void";
32
+ TagType2[TagType2["statement"] = 3] = "statement";
33
+ return TagType2;
34
+ })(TagType || {});
35
35
 
36
36
  // src/util/util.ts
37
37
  function isWhitespaceCode(code) {
@@ -80,9 +80,9 @@ function htmlEOF() {
80
80
 
81
81
  // src/core/Parser.ts
82
82
  var Parser = class {
83
- constructor(handlers) {
84
- this.handlers = handlers;
85
- this.handlers = handlers;
83
+ constructor(options) {
84
+ this.options = options;
85
+ this.options = options;
86
86
  }
87
87
  pos;
88
88
  maxPos;
@@ -173,13 +173,13 @@ var Parser = class {
173
173
  var _a, _b;
174
174
  const start = this.textPos;
175
175
  if (start !== -1) {
176
- (_b = (_a = this.handlers).onText) == null ? void 0 : _b.call(_a, { start, end: this.pos });
176
+ (_b = (_a = this.options).onText) == null ? void 0 : _b.call(_a, { start, end: this.pos });
177
177
  this.textPos = -1;
178
178
  }
179
179
  }
180
180
  beginHtmlBlock(delimiter, singleLine) {
181
181
  var _a;
182
- const content = this.enterState(((_a = this.activeTag) == null ? void 0 : _a.bodyMode) === 1 /* PARSED_TEXT */ ? states_exports.PARSED_TEXT_CONTENT : states_exports.HTML_CONTENT);
182
+ const content = this.enterState(((_a = this.activeTag) == null ? void 0 : _a.type) === 1 /* text */ ? states_exports.PARSED_TEXT_CONTENT : states_exports.HTML_CONTENT);
183
183
  content.singleLine = singleLine;
184
184
  content.delimiter = delimiter;
185
185
  content.indent = this.indent;
@@ -193,7 +193,7 @@ var Parser = class {
193
193
  start = range.start;
194
194
  end = range.end;
195
195
  }
196
- (_b = (_a = this.handlers).onError) == null ? void 0 : _b.call(_a, {
196
+ (_b = (_a = this.options).onError) == null ? void 0 : _b.call(_a, {
197
197
  start,
198
198
  end,
199
199
  code,
@@ -207,7 +207,7 @@ var Parser = class {
207
207
  if (beginMixedMode)
208
208
  this.endingMixedModeAtEOL = true;
209
209
  this.activeTag = parentTag;
210
- (_b = (_a = this.handlers).onCloseTag) == null ? void 0 : _b.call(_a, {
210
+ (_b = (_a = this.options).onCloseTag) == null ? void 0 : _b.call(_a, {
211
211
  start,
212
212
  end,
213
213
  value
@@ -454,7 +454,7 @@ var ATTRIBUTE = {
454
454
  start: child.start,
455
455
  end: child.end
456
456
  };
457
- (_b = (_a = this.handlers).onAttrName) == null ? void 0 : _b.call(_a, attr.name);
457
+ (_b = (_a = this.options).onAttrName) == null ? void 0 : _b.call(_a, attr.name);
458
458
  break;
459
459
  }
460
460
  case 3 /* ARGUMENT */: {
@@ -476,7 +476,7 @@ var ATTRIBUTE = {
476
476
  };
477
477
  } else {
478
478
  attr.args = true;
479
- (_d = (_c = this.handlers).onAttrArgs) == null ? void 0 : _d.call(_c, {
479
+ (_d = (_c = this.options).onAttrArgs) == null ? void 0 : _d.call(_c, {
480
480
  start,
481
481
  end,
482
482
  value
@@ -488,7 +488,7 @@ var ATTRIBUTE = {
488
488
  const params = attr.args;
489
489
  const start = params.start;
490
490
  const end = ++this.pos;
491
- (_f = (_e = this.handlers).onAttrMethod) == null ? void 0 : _f.call(_e, {
491
+ (_f = (_e = this.options).onAttrMethod) == null ? void 0 : _f.call(_e, {
492
492
  start,
493
493
  end,
494
494
  params,
@@ -509,7 +509,7 @@ var ATTRIBUTE = {
509
509
  return this.emitError(child, "ILLEGAL_ATTRIBUTE_VALUE", "Missing value for attribute");
510
510
  }
511
511
  if (attr.spread) {
512
- (_h = (_g = this.handlers).onAttrSpread) == null ? void 0 : _h.call(_g, {
512
+ (_h = (_g = this.options).onAttrSpread) == null ? void 0 : _h.call(_g, {
513
513
  start: attr.valueStart,
514
514
  end: child.end,
515
515
  value: {
@@ -518,7 +518,7 @@ var ATTRIBUTE = {
518
518
  }
519
519
  });
520
520
  } else {
521
- (_j = (_i = this.handlers).onAttrValue) == null ? void 0 : _j.call(_i, {
521
+ (_j = (_i = this.options).onAttrValue) == null ? void 0 : _j.call(_i, {
522
522
  start: attr.valueStart,
523
523
  end: child.end,
524
524
  bound: attr.bound,
@@ -537,7 +537,7 @@ var ATTRIBUTE = {
537
537
  function ensureAttrName(parser, attr) {
538
538
  var _a, _b;
539
539
  if (!attr.name) {
540
- (_b = (_a = parser.handlers).onAttrName) == null ? void 0 : _b.call(_a, {
540
+ (_b = (_a = parser.options).onAttrName) == null ? void 0 : _b.call(_a, {
541
541
  start: attr.start,
542
542
  end: attr.start
543
543
  });
@@ -634,7 +634,7 @@ var CDATA = {
634
634
  },
635
635
  exit(cdata) {
636
636
  var _a, _b;
637
- (_b = (_a = this.handlers).onCDATA) == null ? void 0 : _b.call(_a, {
637
+ (_b = (_a = this.options).onCDATA) == null ? void 0 : _b.call(_a, {
638
638
  start: cdata.start,
639
639
  end: cdata.end,
640
640
  value: {
@@ -782,11 +782,7 @@ var CONCISE_HTML_CONTENT = {
782
782
  return;
783
783
  }
784
784
  if (parentTag) {
785
- if (parentTag.ending !== 0 /* tag */) {
786
- this.emitError(this.pos, "INVALID_BODY", `The "${this.read(parentTag.tagName)}" tag does not allow nested body content`);
787
- return;
788
- }
789
- if (parentTag.bodyMode === 1 /* PARSED_TEXT */ && code !== 45 /* HTML_BLOCK_DELIMITER */) {
785
+ if (parentTag.type === 1 /* text */ && code !== 45 /* HTML_BLOCK_DELIMITER */) {
790
786
  this.emitError(this.pos, "ILLEGAL_LINE_START", 'A line within a tag that only allows text content must begin with a "-" character');
791
787
  return;
792
788
  }
@@ -847,7 +843,7 @@ var CONCISE_HTML_CONTENT = {
847
843
  this.isConcise = true;
848
844
  switch (child.state) {
849
845
  case states_exports.JS_COMMENT_LINE:
850
- (_b = (_a = this.handlers).onComment) == null ? void 0 : _b.call(_a, {
846
+ (_b = (_a = this.options).onComment) == null ? void 0 : _b.call(_a, {
851
847
  start: child.start,
852
848
  end: child.end,
853
849
  value: {
@@ -857,7 +853,7 @@ var CONCISE_HTML_CONTENT = {
857
853
  });
858
854
  break;
859
855
  case states_exports.JS_COMMENT_BLOCK: {
860
- (_d = (_c = this.handlers).onComment) == null ? void 0 : _d.call(_c, {
856
+ (_d = (_c = this.options).onComment) == null ? void 0 : _d.call(_c, {
861
857
  start: child.start,
862
858
  end: child.end,
863
859
  value: {
@@ -909,7 +905,7 @@ function exitDeclaration(parser, declaration, closeOffset) {
909
905
  var _a, _b;
910
906
  parser.pos += closeOffset;
911
907
  parser.exitState();
912
- (_b = (_a = parser.handlers).onDeclaration) == null ? void 0 : _b.call(_a, {
908
+ (_b = (_a = parser.options).onDeclaration) == null ? void 0 : _b.call(_a, {
913
909
  start: declaration.start,
914
910
  end: declaration.end,
915
911
  value: {
@@ -933,7 +929,7 @@ var DTD = {
933
929
  },
934
930
  exit(documentType) {
935
931
  var _a, _b;
936
- (_b = (_a = this.handlers).onDoctype) == null ? void 0 : _b.call(_a, {
932
+ (_b = (_a = this.options).onDoctype) == null ? void 0 : _b.call(_a, {
937
933
  start: documentType.start,
938
934
  end: documentType.end,
939
935
  value: {
@@ -1136,7 +1132,7 @@ var HTML_COMMENT = {
1136
1132
  },
1137
1133
  exit(comment) {
1138
1134
  var _a, _b;
1139
- (_b = (_a = this.handlers).onComment) == null ? void 0 : _b.call(_a, {
1135
+ (_b = (_a = this.options).onComment) == null ? void 0 : _b.call(_a, {
1140
1136
  start: comment.start,
1141
1137
  end: comment.end,
1142
1138
  value: {
@@ -1266,7 +1262,7 @@ var INLINE_SCRIPT = {
1266
1262
  },
1267
1263
  exit(inlineScript) {
1268
1264
  var _a, _b;
1269
- (_b = (_a = this.handlers).onScriptlet) == null ? void 0 : _b.call(_a, {
1265
+ (_b = (_a = this.options).onScriptlet) == null ? void 0 : _b.call(_a, {
1270
1266
  start: inlineScript.start,
1271
1267
  end: inlineScript.end,
1272
1268
  block: inlineScript.block,
@@ -1346,7 +1342,7 @@ var JS_COMMENT_LINE = {
1346
1342
  },
1347
1343
  char(code) {
1348
1344
  var _a;
1349
- if (!this.isConcise && code === 60 /* OPEN_ANGLE_BRACKET */ && ((_a = this.activeTag) == null ? void 0 : _a.bodyMode) === 1 /* PARSED_TEXT */) {
1345
+ if (!this.isConcise && code === 60 /* OPEN_ANGLE_BRACKET */ && ((_a = this.activeTag) == null ? void 0 : _a.type) === 1 /* text */) {
1350
1346
  states_exports.checkForClosingTag(this);
1351
1347
  }
1352
1348
  },
@@ -1430,7 +1426,7 @@ var PLACEHOLDER = {
1430
1426
  },
1431
1427
  exit(placeholder) {
1432
1428
  var _a, _b;
1433
- (_b = (_a = this.handlers).onPlaceholder) == null ? void 0 : _b.call(_a, {
1429
+ (_b = (_a = this.options).onPlaceholder) == null ? void 0 : _b.call(_a, {
1434
1430
  start: placeholder.start,
1435
1431
  end: placeholder.end,
1436
1432
  escape: placeholder.escape,
@@ -1566,23 +1562,6 @@ var STRING = {
1566
1562
  };
1567
1563
 
1568
1564
  // src/states/TAG_NAME.ts
1569
- var VOID_TAGS = [
1570
- "area",
1571
- "base",
1572
- "br",
1573
- "col",
1574
- "hr",
1575
- "embed",
1576
- "img",
1577
- "input",
1578
- "link",
1579
- "meta",
1580
- "param",
1581
- "source",
1582
- "track",
1583
- "wbr"
1584
- ];
1585
- var CODE_TAGS = ["import", "export", "static", "class"];
1586
1565
  var TAG_NAME = {
1587
1566
  name: "TAG_NAME",
1588
1567
  enter(parent, start) {
@@ -1607,7 +1586,7 @@ var TAG_NAME = {
1607
1586
  return this.emitError(tagName, "INVALID_TAG_SHORTHAND", "Multiple shorthand ID parts are not allowed on the same tag");
1608
1587
  }
1609
1588
  this.activeTag.hasShorthandId = true;
1610
- (_b = (_a = this.handlers).onTagShorthandId) == null ? void 0 : _b.call(_a, {
1589
+ (_b = (_a = this.options).onTagShorthandId) == null ? void 0 : _b.call(_a, {
1611
1590
  start,
1612
1591
  end,
1613
1592
  quasis,
@@ -1615,7 +1594,7 @@ var TAG_NAME = {
1615
1594
  });
1616
1595
  break;
1617
1596
  case 46 /* PERIOD */:
1618
- (_d = (_c = this.handlers).onTagShorthandClass) == null ? void 0 : _d.call(_c, {
1597
+ (_d = (_c = this.options).onTagShorthandClass) == null ? void 0 : _d.call(_c, {
1619
1598
  start,
1620
1599
  end,
1621
1600
  quasis,
@@ -1624,28 +1603,26 @@ var TAG_NAME = {
1624
1603
  break;
1625
1604
  default: {
1626
1605
  const tag = this.activeTag;
1606
+ const tagType = (_f = (_e = this.options).onTagName) == null ? void 0 : _f.call(_e, {
1607
+ start,
1608
+ end,
1609
+ quasis,
1610
+ expressions,
1611
+ concise: this.isConcise
1612
+ });
1627
1613
  tag.tagName = tagName;
1628
- if (tagName.expressions.length === 0) {
1629
- if (this.matchAnyAtPos(tagName, VOID_TAGS)) {
1630
- tag.ending |= 2 /* void */;
1631
- } else if (this.matchAnyAtPos(tagName, CODE_TAGS)) {
1614
+ if (tagType) {
1615
+ tag.type = tagType;
1616
+ if (tagType === 3 /* statement */) {
1632
1617
  if (!tag.concise) {
1633
1618
  return this.emitError(tagName, "RESERVED_TAG_NAME", `The "${this.read(tagName)}" tag is reserved and cannot be used as an HTML tag.`);
1634
1619
  }
1635
1620
  if (tag.parentTag) {
1636
1621
  return this.emitError(tagName, "ROOT_TAG_ONLY", `"${this.read(tagName)}" can only be used at the root of the template.`);
1637
1622
  }
1638
- tag.ending |= 4 /* code */;
1639
1623
  this.enterState(states_exports.EXPRESSION).terminatedByEOL = true;
1640
1624
  }
1641
1625
  }
1642
- (_f = (_e = this.handlers).onTagName) == null ? void 0 : _f.call(_e, {
1643
- start,
1644
- end,
1645
- quasis,
1646
- expressions,
1647
- concise: this.isConcise
1648
- });
1649
1626
  break;
1650
1627
  }
1651
1628
  }
@@ -1737,7 +1714,6 @@ var TEMPLATE_STRING = {
1737
1714
  };
1738
1715
 
1739
1716
  // src/states/OPEN_TAG.ts
1740
- var PARSED_TEXT_TAGS = ["script", "style", "textarea", "html-comment"];
1741
1717
  var CONCISE_TAG_VAR_TERMINATORS = [
1742
1718
  59 /* SEMICOLON */,
1743
1719
  40 /* OPEN_PAREN */,
@@ -1758,6 +1734,7 @@ var OPEN_TAG = {
1758
1734
  enter(parent, start) {
1759
1735
  const tag = this.activeTag = {
1760
1736
  state: OPEN_TAG,
1737
+ type: 0 /* html */,
1761
1738
  parent,
1762
1739
  start,
1763
1740
  end: start,
@@ -1768,11 +1745,10 @@ var OPEN_TAG = {
1768
1745
  hasShorthandId: false,
1769
1746
  hasArgs: false,
1770
1747
  hasAttrs: false,
1748
+ selfClosed: false,
1771
1749
  shorthandEnd: -1,
1772
1750
  tagName: void 0,
1773
- ending: 0 /* tag */,
1774
1751
  concise: this.isConcise,
1775
- bodyMode: 0 /* HTML */,
1776
1752
  beginMixedMode: this.beginMixedMode || this.endingMixedModeAtEOL
1777
1753
  };
1778
1754
  this.beginMixedMode = false;
@@ -1782,21 +1758,27 @@ var OPEN_TAG = {
1782
1758
  },
1783
1759
  exit(tag) {
1784
1760
  var _a, _b;
1785
- const { tagName, ending } = tag;
1786
- (_b = (_a = this.handlers).onOpenTagEnd) == null ? void 0 : _b.call(_a, {
1787
- start: this.pos - (this.isConcise ? 0 : ending & 1 /* self */ ? 2 : 1),
1761
+ const { selfClosed } = tag;
1762
+ (_b = (_a = this.options).onOpenTagEnd) == null ? void 0 : _b.call(_a, {
1763
+ start: this.pos - (this.isConcise ? 0 : selfClosed ? 2 : 1),
1788
1764
  end: this.pos,
1789
- ending
1765
+ selfClosed
1790
1766
  });
1791
- if (!this.isConcise && ending !== 0 /* tag */) {
1792
- this.closeTag(this.pos, this.pos, void 0);
1793
- } else if (tagName.expressions.length === 0 && this.matchAnyAtPos(tagName, PARSED_TEXT_TAGS)) {
1794
- tag.bodyMode = 1 /* PARSED_TEXT */;
1795
- if (this.isConcise) {
1796
- this.enterState(states_exports.CONCISE_HTML_CONTENT);
1797
- } else {
1798
- this.enterState(states_exports.PARSED_TEXT_CONTENT);
1767
+ switch (selfClosed ? 2 /* void */ : tag.type) {
1768
+ case 2 /* void */:
1769
+ case 3 /* statement */: {
1770
+ if (tag.beginMixedMode)
1771
+ this.endingMixedModeAtEOL = true;
1772
+ this.activeTag = tag.parentTag;
1773
+ break;
1799
1774
  }
1775
+ case 1 /* text */:
1776
+ if (this.isConcise) {
1777
+ this.enterState(states_exports.CONCISE_HTML_CONTENT);
1778
+ } else {
1779
+ this.enterState(states_exports.PARSED_TEXT_CONTENT);
1780
+ }
1781
+ break;
1800
1782
  }
1801
1783
  },
1802
1784
  eol(_, tag) {
@@ -1895,7 +1877,7 @@ var OPEN_TAG = {
1895
1877
  this.exitState();
1896
1878
  return;
1897
1879
  } else if (code === 47 /* FORWARD_SLASH */ && this.lookAtCharCodeAhead(1) === 62 /* CLOSE_ANGLE_BRACKET */) {
1898
- tag.ending |= 1 /* self */;
1880
+ tag.selfClosed = true;
1899
1881
  this.pos += 2;
1900
1882
  this.exitState();
1901
1883
  return;
@@ -1961,7 +1943,7 @@ var OPEN_TAG = {
1961
1943
  if (child.start === child.end) {
1962
1944
  return this.emitError(child, "MISSING_TAG_VARIABLE", "A slash was found that was not followed by a variable name or lhs expression");
1963
1945
  }
1964
- (_b = (_a = this.handlers).onTagVar) == null ? void 0 : _b.call(_a, {
1946
+ (_b = (_a = this.options).onTagVar) == null ? void 0 : _b.call(_a, {
1965
1947
  start: child.start - 1,
1966
1948
  end: child.end,
1967
1949
  value: {
@@ -1986,7 +1968,7 @@ var OPEN_TAG = {
1986
1968
  this.pos--;
1987
1969
  } else {
1988
1970
  tag.hasArgs = true;
1989
- (_d = (_c = this.handlers).onTagArgs) == null ? void 0 : _d.call(_c, {
1971
+ (_d = (_c = this.options).onTagArgs) == null ? void 0 : _d.call(_c, {
1990
1972
  start,
1991
1973
  end,
1992
1974
  value
@@ -1996,7 +1978,7 @@ var OPEN_TAG = {
1996
1978
  }
1997
1979
  case 3 /* PARAMS */: {
1998
1980
  const end = ++this.pos;
1999
- (_f = (_e = this.handlers).onTagParams) == null ? void 0 : _f.call(_e, {
1981
+ (_f = (_e = this.options).onTagParams) == null ? void 0 : _f.call(_e, {
2000
1982
  start: child.start - 1,
2001
1983
  end,
2002
1984
  value: {
@@ -2033,6 +2015,6 @@ function createParser(handlers) {
2033
2015
  }
2034
2016
  // Annotate the CommonJS export names for ESM import in node:
2035
2017
  0 && (module.exports = {
2036
- OpenTagEnding,
2018
+ TagType,
2037
2019
  createParser
2038
2020
  });
package/dist/index.mjs CHANGED
@@ -5,13 +5,13 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/util/constants.ts
8
- var OpenTagEnding = /* @__PURE__ */ ((OpenTagEnding2) => {
9
- OpenTagEnding2[OpenTagEnding2["tag"] = 0] = "tag";
10
- OpenTagEnding2[OpenTagEnding2["self"] = 1] = "self";
11
- OpenTagEnding2[OpenTagEnding2["void"] = 2] = "void";
12
- OpenTagEnding2[OpenTagEnding2["code"] = 4] = "code";
13
- return OpenTagEnding2;
14
- })(OpenTagEnding || {});
8
+ var TagType = /* @__PURE__ */ ((TagType2) => {
9
+ TagType2[TagType2["html"] = 0] = "html";
10
+ TagType2[TagType2["text"] = 1] = "text";
11
+ TagType2[TagType2["void"] = 2] = "void";
12
+ TagType2[TagType2["statement"] = 3] = "statement";
13
+ return TagType2;
14
+ })(TagType || {});
15
15
 
16
16
  // src/util/util.ts
17
17
  function isWhitespaceCode(code) {
@@ -60,9 +60,9 @@ function htmlEOF() {
60
60
 
61
61
  // src/core/Parser.ts
62
62
  var Parser = class {
63
- constructor(handlers) {
64
- this.handlers = handlers;
65
- this.handlers = handlers;
63
+ constructor(options) {
64
+ this.options = options;
65
+ this.options = options;
66
66
  }
67
67
  pos;
68
68
  maxPos;
@@ -153,13 +153,13 @@ var Parser = class {
153
153
  var _a, _b;
154
154
  const start = this.textPos;
155
155
  if (start !== -1) {
156
- (_b = (_a = this.handlers).onText) == null ? void 0 : _b.call(_a, { start, end: this.pos });
156
+ (_b = (_a = this.options).onText) == null ? void 0 : _b.call(_a, { start, end: this.pos });
157
157
  this.textPos = -1;
158
158
  }
159
159
  }
160
160
  beginHtmlBlock(delimiter, singleLine) {
161
161
  var _a;
162
- const content = this.enterState(((_a = this.activeTag) == null ? void 0 : _a.bodyMode) === 1 /* PARSED_TEXT */ ? states_exports.PARSED_TEXT_CONTENT : states_exports.HTML_CONTENT);
162
+ const content = this.enterState(((_a = this.activeTag) == null ? void 0 : _a.type) === 1 /* text */ ? states_exports.PARSED_TEXT_CONTENT : states_exports.HTML_CONTENT);
163
163
  content.singleLine = singleLine;
164
164
  content.delimiter = delimiter;
165
165
  content.indent = this.indent;
@@ -173,7 +173,7 @@ var Parser = class {
173
173
  start = range.start;
174
174
  end = range.end;
175
175
  }
176
- (_b = (_a = this.handlers).onError) == null ? void 0 : _b.call(_a, {
176
+ (_b = (_a = this.options).onError) == null ? void 0 : _b.call(_a, {
177
177
  start,
178
178
  end,
179
179
  code,
@@ -187,7 +187,7 @@ var Parser = class {
187
187
  if (beginMixedMode)
188
188
  this.endingMixedModeAtEOL = true;
189
189
  this.activeTag = parentTag;
190
- (_b = (_a = this.handlers).onCloseTag) == null ? void 0 : _b.call(_a, {
190
+ (_b = (_a = this.options).onCloseTag) == null ? void 0 : _b.call(_a, {
191
191
  start,
192
192
  end,
193
193
  value
@@ -434,7 +434,7 @@ var ATTRIBUTE = {
434
434
  start: child.start,
435
435
  end: child.end
436
436
  };
437
- (_b = (_a = this.handlers).onAttrName) == null ? void 0 : _b.call(_a, attr.name);
437
+ (_b = (_a = this.options).onAttrName) == null ? void 0 : _b.call(_a, attr.name);
438
438
  break;
439
439
  }
440
440
  case 3 /* ARGUMENT */: {
@@ -456,7 +456,7 @@ var ATTRIBUTE = {
456
456
  };
457
457
  } else {
458
458
  attr.args = true;
459
- (_d = (_c = this.handlers).onAttrArgs) == null ? void 0 : _d.call(_c, {
459
+ (_d = (_c = this.options).onAttrArgs) == null ? void 0 : _d.call(_c, {
460
460
  start,
461
461
  end,
462
462
  value
@@ -468,7 +468,7 @@ var ATTRIBUTE = {
468
468
  const params = attr.args;
469
469
  const start = params.start;
470
470
  const end = ++this.pos;
471
- (_f = (_e = this.handlers).onAttrMethod) == null ? void 0 : _f.call(_e, {
471
+ (_f = (_e = this.options).onAttrMethod) == null ? void 0 : _f.call(_e, {
472
472
  start,
473
473
  end,
474
474
  params,
@@ -489,7 +489,7 @@ var ATTRIBUTE = {
489
489
  return this.emitError(child, "ILLEGAL_ATTRIBUTE_VALUE", "Missing value for attribute");
490
490
  }
491
491
  if (attr.spread) {
492
- (_h = (_g = this.handlers).onAttrSpread) == null ? void 0 : _h.call(_g, {
492
+ (_h = (_g = this.options).onAttrSpread) == null ? void 0 : _h.call(_g, {
493
493
  start: attr.valueStart,
494
494
  end: child.end,
495
495
  value: {
@@ -498,7 +498,7 @@ var ATTRIBUTE = {
498
498
  }
499
499
  });
500
500
  } else {
501
- (_j = (_i = this.handlers).onAttrValue) == null ? void 0 : _j.call(_i, {
501
+ (_j = (_i = this.options).onAttrValue) == null ? void 0 : _j.call(_i, {
502
502
  start: attr.valueStart,
503
503
  end: child.end,
504
504
  bound: attr.bound,
@@ -517,7 +517,7 @@ var ATTRIBUTE = {
517
517
  function ensureAttrName(parser, attr) {
518
518
  var _a, _b;
519
519
  if (!attr.name) {
520
- (_b = (_a = parser.handlers).onAttrName) == null ? void 0 : _b.call(_a, {
520
+ (_b = (_a = parser.options).onAttrName) == null ? void 0 : _b.call(_a, {
521
521
  start: attr.start,
522
522
  end: attr.start
523
523
  });
@@ -614,7 +614,7 @@ var CDATA = {
614
614
  },
615
615
  exit(cdata) {
616
616
  var _a, _b;
617
- (_b = (_a = this.handlers).onCDATA) == null ? void 0 : _b.call(_a, {
617
+ (_b = (_a = this.options).onCDATA) == null ? void 0 : _b.call(_a, {
618
618
  start: cdata.start,
619
619
  end: cdata.end,
620
620
  value: {
@@ -762,11 +762,7 @@ var CONCISE_HTML_CONTENT = {
762
762
  return;
763
763
  }
764
764
  if (parentTag) {
765
- if (parentTag.ending !== 0 /* tag */) {
766
- this.emitError(this.pos, "INVALID_BODY", `The "${this.read(parentTag.tagName)}" tag does not allow nested body content`);
767
- return;
768
- }
769
- if (parentTag.bodyMode === 1 /* PARSED_TEXT */ && code !== 45 /* HTML_BLOCK_DELIMITER */) {
765
+ if (parentTag.type === 1 /* text */ && code !== 45 /* HTML_BLOCK_DELIMITER */) {
770
766
  this.emitError(this.pos, "ILLEGAL_LINE_START", 'A line within a tag that only allows text content must begin with a "-" character');
771
767
  return;
772
768
  }
@@ -827,7 +823,7 @@ var CONCISE_HTML_CONTENT = {
827
823
  this.isConcise = true;
828
824
  switch (child.state) {
829
825
  case states_exports.JS_COMMENT_LINE:
830
- (_b = (_a = this.handlers).onComment) == null ? void 0 : _b.call(_a, {
826
+ (_b = (_a = this.options).onComment) == null ? void 0 : _b.call(_a, {
831
827
  start: child.start,
832
828
  end: child.end,
833
829
  value: {
@@ -837,7 +833,7 @@ var CONCISE_HTML_CONTENT = {
837
833
  });
838
834
  break;
839
835
  case states_exports.JS_COMMENT_BLOCK: {
840
- (_d = (_c = this.handlers).onComment) == null ? void 0 : _d.call(_c, {
836
+ (_d = (_c = this.options).onComment) == null ? void 0 : _d.call(_c, {
841
837
  start: child.start,
842
838
  end: child.end,
843
839
  value: {
@@ -889,7 +885,7 @@ function exitDeclaration(parser, declaration, closeOffset) {
889
885
  var _a, _b;
890
886
  parser.pos += closeOffset;
891
887
  parser.exitState();
892
- (_b = (_a = parser.handlers).onDeclaration) == null ? void 0 : _b.call(_a, {
888
+ (_b = (_a = parser.options).onDeclaration) == null ? void 0 : _b.call(_a, {
893
889
  start: declaration.start,
894
890
  end: declaration.end,
895
891
  value: {
@@ -913,7 +909,7 @@ var DTD = {
913
909
  },
914
910
  exit(documentType) {
915
911
  var _a, _b;
916
- (_b = (_a = this.handlers).onDoctype) == null ? void 0 : _b.call(_a, {
912
+ (_b = (_a = this.options).onDoctype) == null ? void 0 : _b.call(_a, {
917
913
  start: documentType.start,
918
914
  end: documentType.end,
919
915
  value: {
@@ -1116,7 +1112,7 @@ var HTML_COMMENT = {
1116
1112
  },
1117
1113
  exit(comment) {
1118
1114
  var _a, _b;
1119
- (_b = (_a = this.handlers).onComment) == null ? void 0 : _b.call(_a, {
1115
+ (_b = (_a = this.options).onComment) == null ? void 0 : _b.call(_a, {
1120
1116
  start: comment.start,
1121
1117
  end: comment.end,
1122
1118
  value: {
@@ -1246,7 +1242,7 @@ var INLINE_SCRIPT = {
1246
1242
  },
1247
1243
  exit(inlineScript) {
1248
1244
  var _a, _b;
1249
- (_b = (_a = this.handlers).onScriptlet) == null ? void 0 : _b.call(_a, {
1245
+ (_b = (_a = this.options).onScriptlet) == null ? void 0 : _b.call(_a, {
1250
1246
  start: inlineScript.start,
1251
1247
  end: inlineScript.end,
1252
1248
  block: inlineScript.block,
@@ -1326,7 +1322,7 @@ var JS_COMMENT_LINE = {
1326
1322
  },
1327
1323
  char(code) {
1328
1324
  var _a;
1329
- if (!this.isConcise && code === 60 /* OPEN_ANGLE_BRACKET */ && ((_a = this.activeTag) == null ? void 0 : _a.bodyMode) === 1 /* PARSED_TEXT */) {
1325
+ if (!this.isConcise && code === 60 /* OPEN_ANGLE_BRACKET */ && ((_a = this.activeTag) == null ? void 0 : _a.type) === 1 /* text */) {
1330
1326
  states_exports.checkForClosingTag(this);
1331
1327
  }
1332
1328
  },
@@ -1410,7 +1406,7 @@ var PLACEHOLDER = {
1410
1406
  },
1411
1407
  exit(placeholder) {
1412
1408
  var _a, _b;
1413
- (_b = (_a = this.handlers).onPlaceholder) == null ? void 0 : _b.call(_a, {
1409
+ (_b = (_a = this.options).onPlaceholder) == null ? void 0 : _b.call(_a, {
1414
1410
  start: placeholder.start,
1415
1411
  end: placeholder.end,
1416
1412
  escape: placeholder.escape,
@@ -1546,23 +1542,6 @@ var STRING = {
1546
1542
  };
1547
1543
 
1548
1544
  // src/states/TAG_NAME.ts
1549
- var VOID_TAGS = [
1550
- "area",
1551
- "base",
1552
- "br",
1553
- "col",
1554
- "hr",
1555
- "embed",
1556
- "img",
1557
- "input",
1558
- "link",
1559
- "meta",
1560
- "param",
1561
- "source",
1562
- "track",
1563
- "wbr"
1564
- ];
1565
- var CODE_TAGS = ["import", "export", "static", "class"];
1566
1545
  var TAG_NAME = {
1567
1546
  name: "TAG_NAME",
1568
1547
  enter(parent, start) {
@@ -1587,7 +1566,7 @@ var TAG_NAME = {
1587
1566
  return this.emitError(tagName, "INVALID_TAG_SHORTHAND", "Multiple shorthand ID parts are not allowed on the same tag");
1588
1567
  }
1589
1568
  this.activeTag.hasShorthandId = true;
1590
- (_b = (_a = this.handlers).onTagShorthandId) == null ? void 0 : _b.call(_a, {
1569
+ (_b = (_a = this.options).onTagShorthandId) == null ? void 0 : _b.call(_a, {
1591
1570
  start,
1592
1571
  end,
1593
1572
  quasis,
@@ -1595,7 +1574,7 @@ var TAG_NAME = {
1595
1574
  });
1596
1575
  break;
1597
1576
  case 46 /* PERIOD */:
1598
- (_d = (_c = this.handlers).onTagShorthandClass) == null ? void 0 : _d.call(_c, {
1577
+ (_d = (_c = this.options).onTagShorthandClass) == null ? void 0 : _d.call(_c, {
1599
1578
  start,
1600
1579
  end,
1601
1580
  quasis,
@@ -1604,28 +1583,26 @@ var TAG_NAME = {
1604
1583
  break;
1605
1584
  default: {
1606
1585
  const tag = this.activeTag;
1586
+ const tagType = (_f = (_e = this.options).onTagName) == null ? void 0 : _f.call(_e, {
1587
+ start,
1588
+ end,
1589
+ quasis,
1590
+ expressions,
1591
+ concise: this.isConcise
1592
+ });
1607
1593
  tag.tagName = tagName;
1608
- if (tagName.expressions.length === 0) {
1609
- if (this.matchAnyAtPos(tagName, VOID_TAGS)) {
1610
- tag.ending |= 2 /* void */;
1611
- } else if (this.matchAnyAtPos(tagName, CODE_TAGS)) {
1594
+ if (tagType) {
1595
+ tag.type = tagType;
1596
+ if (tagType === 3 /* statement */) {
1612
1597
  if (!tag.concise) {
1613
1598
  return this.emitError(tagName, "RESERVED_TAG_NAME", `The "${this.read(tagName)}" tag is reserved and cannot be used as an HTML tag.`);
1614
1599
  }
1615
1600
  if (tag.parentTag) {
1616
1601
  return this.emitError(tagName, "ROOT_TAG_ONLY", `"${this.read(tagName)}" can only be used at the root of the template.`);
1617
1602
  }
1618
- tag.ending |= 4 /* code */;
1619
1603
  this.enterState(states_exports.EXPRESSION).terminatedByEOL = true;
1620
1604
  }
1621
1605
  }
1622
- (_f = (_e = this.handlers).onTagName) == null ? void 0 : _f.call(_e, {
1623
- start,
1624
- end,
1625
- quasis,
1626
- expressions,
1627
- concise: this.isConcise
1628
- });
1629
1606
  break;
1630
1607
  }
1631
1608
  }
@@ -1717,7 +1694,6 @@ var TEMPLATE_STRING = {
1717
1694
  };
1718
1695
 
1719
1696
  // src/states/OPEN_TAG.ts
1720
- var PARSED_TEXT_TAGS = ["script", "style", "textarea", "html-comment"];
1721
1697
  var CONCISE_TAG_VAR_TERMINATORS = [
1722
1698
  59 /* SEMICOLON */,
1723
1699
  40 /* OPEN_PAREN */,
@@ -1738,6 +1714,7 @@ var OPEN_TAG = {
1738
1714
  enter(parent, start) {
1739
1715
  const tag = this.activeTag = {
1740
1716
  state: OPEN_TAG,
1717
+ type: 0 /* html */,
1741
1718
  parent,
1742
1719
  start,
1743
1720
  end: start,
@@ -1748,11 +1725,10 @@ var OPEN_TAG = {
1748
1725
  hasShorthandId: false,
1749
1726
  hasArgs: false,
1750
1727
  hasAttrs: false,
1728
+ selfClosed: false,
1751
1729
  shorthandEnd: -1,
1752
1730
  tagName: void 0,
1753
- ending: 0 /* tag */,
1754
1731
  concise: this.isConcise,
1755
- bodyMode: 0 /* HTML */,
1756
1732
  beginMixedMode: this.beginMixedMode || this.endingMixedModeAtEOL
1757
1733
  };
1758
1734
  this.beginMixedMode = false;
@@ -1762,21 +1738,27 @@ var OPEN_TAG = {
1762
1738
  },
1763
1739
  exit(tag) {
1764
1740
  var _a, _b;
1765
- const { tagName, ending } = tag;
1766
- (_b = (_a = this.handlers).onOpenTagEnd) == null ? void 0 : _b.call(_a, {
1767
- start: this.pos - (this.isConcise ? 0 : ending & 1 /* self */ ? 2 : 1),
1741
+ const { selfClosed } = tag;
1742
+ (_b = (_a = this.options).onOpenTagEnd) == null ? void 0 : _b.call(_a, {
1743
+ start: this.pos - (this.isConcise ? 0 : selfClosed ? 2 : 1),
1768
1744
  end: this.pos,
1769
- ending
1745
+ selfClosed
1770
1746
  });
1771
- if (!this.isConcise && ending !== 0 /* tag */) {
1772
- this.closeTag(this.pos, this.pos, void 0);
1773
- } else if (tagName.expressions.length === 0 && this.matchAnyAtPos(tagName, PARSED_TEXT_TAGS)) {
1774
- tag.bodyMode = 1 /* PARSED_TEXT */;
1775
- if (this.isConcise) {
1776
- this.enterState(states_exports.CONCISE_HTML_CONTENT);
1777
- } else {
1778
- this.enterState(states_exports.PARSED_TEXT_CONTENT);
1747
+ switch (selfClosed ? 2 /* void */ : tag.type) {
1748
+ case 2 /* void */:
1749
+ case 3 /* statement */: {
1750
+ if (tag.beginMixedMode)
1751
+ this.endingMixedModeAtEOL = true;
1752
+ this.activeTag = tag.parentTag;
1753
+ break;
1779
1754
  }
1755
+ case 1 /* text */:
1756
+ if (this.isConcise) {
1757
+ this.enterState(states_exports.CONCISE_HTML_CONTENT);
1758
+ } else {
1759
+ this.enterState(states_exports.PARSED_TEXT_CONTENT);
1760
+ }
1761
+ break;
1780
1762
  }
1781
1763
  },
1782
1764
  eol(_, tag) {
@@ -1875,7 +1857,7 @@ var OPEN_TAG = {
1875
1857
  this.exitState();
1876
1858
  return;
1877
1859
  } else if (code === 47 /* FORWARD_SLASH */ && this.lookAtCharCodeAhead(1) === 62 /* CLOSE_ANGLE_BRACKET */) {
1878
- tag.ending |= 1 /* self */;
1860
+ tag.selfClosed = true;
1879
1861
  this.pos += 2;
1880
1862
  this.exitState();
1881
1863
  return;
@@ -1941,7 +1923,7 @@ var OPEN_TAG = {
1941
1923
  if (child.start === child.end) {
1942
1924
  return this.emitError(child, "MISSING_TAG_VARIABLE", "A slash was found that was not followed by a variable name or lhs expression");
1943
1925
  }
1944
- (_b = (_a = this.handlers).onTagVar) == null ? void 0 : _b.call(_a, {
1926
+ (_b = (_a = this.options).onTagVar) == null ? void 0 : _b.call(_a, {
1945
1927
  start: child.start - 1,
1946
1928
  end: child.end,
1947
1929
  value: {
@@ -1966,7 +1948,7 @@ var OPEN_TAG = {
1966
1948
  this.pos--;
1967
1949
  } else {
1968
1950
  tag.hasArgs = true;
1969
- (_d = (_c = this.handlers).onTagArgs) == null ? void 0 : _d.call(_c, {
1951
+ (_d = (_c = this.options).onTagArgs) == null ? void 0 : _d.call(_c, {
1970
1952
  start,
1971
1953
  end,
1972
1954
  value
@@ -1976,7 +1958,7 @@ var OPEN_TAG = {
1976
1958
  }
1977
1959
  case 3 /* PARAMS */: {
1978
1960
  const end = ++this.pos;
1979
- (_f = (_e = this.handlers).onTagParams) == null ? void 0 : _f.call(_e, {
1961
+ (_f = (_e = this.options).onTagParams) == null ? void 0 : _f.call(_e, {
1980
1962
  start: child.start - 1,
1981
1963
  end,
1982
1964
  value: {
@@ -2012,6 +1994,6 @@ function createParser(handlers) {
2012
1994
  };
2013
1995
  }
2014
1996
  export {
2015
- OpenTagEnding,
1997
+ TagType,
2016
1998
  createParser
2017
1999
  };
@@ -1,4 +1,4 @@
1
- import { StateDefinition, BODY_MODE, OpenTagEnding, Ranges, Meta } from "../internal";
1
+ import { StateDefinition, Ranges, Meta, TagType } from "../internal";
2
2
  declare const enum TAG_STAGE {
3
3
  UNKNOWN = 0,
4
4
  VAR = 1,
@@ -7,7 +7,7 @@ declare const enum TAG_STAGE {
7
7
  ATTR_GROUP = 4
8
8
  }
9
9
  export interface OpenTagMeta extends Meta {
10
- bodyMode: BODY_MODE;
10
+ type: TagType;
11
11
  stage: TAG_STAGE;
12
12
  concise: boolean;
13
13
  beginMixedMode?: boolean;
@@ -16,7 +16,7 @@ export interface OpenTagMeta extends Meta {
16
16
  hasArgs: boolean;
17
17
  hasAttrs: boolean;
18
18
  hasShorthandId: boolean;
19
- ending: OpenTagEnding;
19
+ selfClosed: boolean;
20
20
  indent: string;
21
21
  nestedIndent: string | undefined;
22
22
  parentTag: OpenTagMeta | undefined;
@@ -37,10 +37,6 @@ export declare const enum CODE {
37
37
  SPACE = 32,
38
38
  TAB = 9
39
39
  }
40
- export declare const enum BODY_MODE {
41
- HTML = 0,
42
- PARSED_TEXT = 1
43
- }
44
40
  export interface Position {
45
41
  /**
46
42
  * Line position in a document (zero-based).
@@ -94,19 +90,19 @@ export declare namespace Ranges {
94
90
  params: Value;
95
91
  }
96
92
  interface OpenTagEnd extends Range {
97
- ending: OpenTagEnding;
93
+ selfClosed: boolean;
98
94
  }
99
95
  interface CloseTag extends Range {
100
96
  value: Range | undefined;
101
97
  }
102
98
  }
103
- export declare const enum OpenTagEnding {
104
- tag = 0,
105
- self = 1,
99
+ export declare const enum TagType {
100
+ html = 0,
101
+ text = 1,
106
102
  void = 2,
107
- code = 4
103
+ statement = 3
108
104
  }
109
- export interface Handlers {
105
+ export interface ParserOptions {
110
106
  onError?(data: Ranges.Error): void;
111
107
  onText?(data: Range): void;
112
108
  onComment?(data: Ranges.Value): void;
@@ -115,7 +111,7 @@ export interface Handlers {
115
111
  onDoctype?(data: Ranges.Value): void;
116
112
  onScriptlet?(data: Ranges.Scriptlet): void;
117
113
  onPlaceholder?(data: Ranges.Placeholder): void;
118
- onTagName?(data: Ranges.TagName): void;
114
+ onTagName?(data: Ranges.TagName): TagType | void;
119
115
  onTagShorthandId?(data: Ranges.Template): void;
120
116
  onTagShorthandClass?(data: Ranges.Template): void;
121
117
  onTagVar?(data: Ranges.Value): void;
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.1.0",
4
+ "version": "3.2.0",
5
5
  "author": "Phillip Gates-Idem <phillip.idem@gmail.com>",
6
6
  "devDependencies": {
7
7
  "@commitlint/cli": "^16.2.3",