htmljs-parser 5.6.1 → 5.7.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.
- package/README.md +4 -1
- package/dist/index.js +124 -49
- package/dist/index.mjs +124 -49
- package/dist/states/EXPRESSION.d.ts +4 -1
- package/package.json +4 -6
package/README.md
CHANGED
|
@@ -201,15 +201,18 @@ const parser = createParser({
|
|
|
201
201
|
// TagType.void makes this a void element (cannot have children).
|
|
202
202
|
return TagType.void;
|
|
203
203
|
case "html-comment":
|
|
204
|
+
case "html-script":
|
|
205
|
+
case "html-style":
|
|
204
206
|
case "script":
|
|
205
207
|
case "style":
|
|
206
208
|
case "textarea":
|
|
207
209
|
// TagType.text makes the child content text only (with placeholders).
|
|
208
210
|
return TagType.text;
|
|
209
|
-
case "class":
|
|
210
211
|
case "export":
|
|
211
212
|
case "import":
|
|
212
213
|
case "static":
|
|
214
|
+
case "client":
|
|
215
|
+
case "server":
|
|
213
216
|
// TagType.statement makes this a statement tag where the content following the tag name will be parsed as script code until we reach a new line, eg for `import x from "y"`).
|
|
214
217
|
return TagType.statement;
|
|
215
218
|
}
|
package/dist/index.js
CHANGED
|
@@ -793,15 +793,16 @@ var OPEN_TAG = {
|
|
|
793
793
|
}
|
|
794
794
|
}
|
|
795
795
|
};
|
|
796
|
-
function shouldTerminateConciseTagVar(code, data, pos) {
|
|
796
|
+
function shouldTerminateConciseTagVar(code, data, pos, expression) {
|
|
797
797
|
switch (code) {
|
|
798
798
|
case 44 /* COMMA */:
|
|
799
799
|
case 61 /* EQUAL */:
|
|
800
800
|
case 124 /* PIPE */:
|
|
801
801
|
case 40 /* OPEN_PAREN */:
|
|
802
802
|
case 59 /* SEMICOLON */:
|
|
803
|
-
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
804
803
|
return true;
|
|
804
|
+
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
805
|
+
return !expression.inType;
|
|
805
806
|
case 45 /* HYPHEN */:
|
|
806
807
|
return data.charCodeAt(pos + 1) === 45 /* HYPHEN */;
|
|
807
808
|
case 58 /* COLON */:
|
|
@@ -810,15 +811,16 @@ function shouldTerminateConciseTagVar(code, data, pos) {
|
|
|
810
811
|
return false;
|
|
811
812
|
}
|
|
812
813
|
}
|
|
813
|
-
function shouldTerminateHtmlTagVar(code, data, pos) {
|
|
814
|
+
function shouldTerminateHtmlTagVar(code, data, pos, expression) {
|
|
814
815
|
switch (code) {
|
|
815
816
|
case 124 /* PIPE */:
|
|
816
817
|
case 44 /* COMMA */:
|
|
817
818
|
case 61 /* EQUAL */:
|
|
818
819
|
case 40 /* OPEN_PAREN */:
|
|
819
820
|
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
820
|
-
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
821
821
|
return true;
|
|
822
|
+
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
823
|
+
return !expression.inType;
|
|
822
824
|
case 58 /* COLON */:
|
|
823
825
|
return data.charCodeAt(pos + 1) === 61 /* EQUAL */;
|
|
824
826
|
case 47 /* FORWARD_SLASH */:
|
|
@@ -1195,7 +1197,6 @@ function handleDelimitedBlockEOL(parser, newLineLength, {
|
|
|
1195
1197
|
parser.endText();
|
|
1196
1198
|
parser.pos += endHtmlBlockLookahead.length;
|
|
1197
1199
|
if (parser.consumeWhitespaceOnLine(0)) {
|
|
1198
|
-
parser.endText();
|
|
1199
1200
|
parser.exitState();
|
|
1200
1201
|
parser.exitState();
|
|
1201
1202
|
} else {
|
|
@@ -1212,7 +1213,7 @@ function handleDelimitedBlockEOL(parser, newLineLength, {
|
|
|
1212
1213
|
parser.endText();
|
|
1213
1214
|
parser.exitState();
|
|
1214
1215
|
parser.exitState();
|
|
1215
|
-
} else {
|
|
1216
|
+
} else if (parser.pos + newLineLength !== parser.maxPos) {
|
|
1216
1217
|
parser.startText();
|
|
1217
1218
|
}
|
|
1218
1219
|
}
|
|
@@ -1619,20 +1620,26 @@ var DTD = {
|
|
|
1619
1620
|
// src/states/EXPRESSION.ts
|
|
1620
1621
|
var shouldTerminate = () => false;
|
|
1621
1622
|
var unaryKeywords = [
|
|
1623
|
+
"asserts",
|
|
1622
1624
|
"async",
|
|
1623
1625
|
"await",
|
|
1624
|
-
"keyof",
|
|
1625
1626
|
"class",
|
|
1626
1627
|
"function",
|
|
1628
|
+
"infer",
|
|
1629
|
+
"is",
|
|
1630
|
+
"keyof",
|
|
1627
1631
|
"new",
|
|
1632
|
+
"readonly",
|
|
1628
1633
|
"typeof",
|
|
1634
|
+
"unique",
|
|
1629
1635
|
"void"
|
|
1630
1636
|
];
|
|
1631
1637
|
var binaryKeywords = [
|
|
1632
|
-
"instanceof",
|
|
1633
|
-
"in",
|
|
1634
1638
|
"as",
|
|
1635
1639
|
"extends",
|
|
1640
|
+
"instanceof",
|
|
1641
|
+
// Note: instanceof must be checked before `in`
|
|
1642
|
+
"in",
|
|
1636
1643
|
"satisfies"
|
|
1637
1644
|
];
|
|
1638
1645
|
var EXPRESSION = {
|
|
@@ -1647,6 +1654,9 @@ var EXPRESSION = {
|
|
|
1647
1654
|
shouldTerminate,
|
|
1648
1655
|
operators: false,
|
|
1649
1656
|
wasComment: false,
|
|
1657
|
+
inType: false,
|
|
1658
|
+
forceType: false,
|
|
1659
|
+
ternaryDepth: 0,
|
|
1650
1660
|
terminatedByEOL: false,
|
|
1651
1661
|
terminatedByWhitespace: false,
|
|
1652
1662
|
consumeIndentedContent: false
|
|
@@ -1662,7 +1672,7 @@ var EXPRESSION = {
|
|
|
1662
1672
|
}
|
|
1663
1673
|
return;
|
|
1664
1674
|
}
|
|
1665
|
-
if (expression.shouldTerminate(code, this.data, this.pos)) {
|
|
1675
|
+
if (expression.shouldTerminate(code, this.data, this.pos, expression)) {
|
|
1666
1676
|
let wasExpression = false;
|
|
1667
1677
|
if (expression.operators) {
|
|
1668
1678
|
const prevNonWhitespacePos = lookBehindWhile(
|
|
@@ -1671,7 +1681,11 @@ var EXPRESSION = {
|
|
|
1671
1681
|
this.pos - 1
|
|
1672
1682
|
);
|
|
1673
1683
|
if (prevNonWhitespacePos > expression.start) {
|
|
1674
|
-
wasExpression = lookBehindForOperator(
|
|
1684
|
+
wasExpression = lookBehindForOperator(
|
|
1685
|
+
expression,
|
|
1686
|
+
this.data,
|
|
1687
|
+
prevNonWhitespacePos
|
|
1688
|
+
) !== -1;
|
|
1675
1689
|
}
|
|
1676
1690
|
}
|
|
1677
1691
|
if (!wasExpression) {
|
|
@@ -1690,6 +1704,38 @@ var EXPRESSION = {
|
|
|
1690
1704
|
case 96 /* BACKTICK */:
|
|
1691
1705
|
this.enterState(states_exports.TEMPLATE_STRING);
|
|
1692
1706
|
break;
|
|
1707
|
+
case 63 /* QUESTION */:
|
|
1708
|
+
if (expression.operators && !expression.groupStack.length) {
|
|
1709
|
+
expression.ternaryDepth++;
|
|
1710
|
+
this.pos++;
|
|
1711
|
+
this.forward = 0;
|
|
1712
|
+
this.consumeWhitespace();
|
|
1713
|
+
}
|
|
1714
|
+
break;
|
|
1715
|
+
case 58 /* COLON */:
|
|
1716
|
+
if (expression.operators && !expression.groupStack.length) {
|
|
1717
|
+
if (expression.ternaryDepth) {
|
|
1718
|
+
expression.ternaryDepth--;
|
|
1719
|
+
} else {
|
|
1720
|
+
expression.inType = true;
|
|
1721
|
+
}
|
|
1722
|
+
this.pos++;
|
|
1723
|
+
this.forward = 0;
|
|
1724
|
+
this.consumeWhitespace();
|
|
1725
|
+
}
|
|
1726
|
+
break;
|
|
1727
|
+
case 61 /* EQUAL */:
|
|
1728
|
+
if (expression.operators && !expression.groupStack.length) {
|
|
1729
|
+
if (this.lookAtCharCodeAhead(1) === 62 /* CLOSE_ANGLE_BRACKET */) {
|
|
1730
|
+
this.pos++;
|
|
1731
|
+
} else if (!expression.forceType) {
|
|
1732
|
+
expression.inType = false;
|
|
1733
|
+
}
|
|
1734
|
+
this.pos++;
|
|
1735
|
+
this.forward = 0;
|
|
1736
|
+
this.consumeWhitespace();
|
|
1737
|
+
}
|
|
1738
|
+
break;
|
|
1693
1739
|
case 47 /* FORWARD_SLASH */:
|
|
1694
1740
|
switch (this.lookAtCharCodeAhead(1)) {
|
|
1695
1741
|
case 47 /* FORWARD_SLASH */:
|
|
@@ -1721,9 +1767,19 @@ var EXPRESSION = {
|
|
|
1721
1767
|
case 123 /* OPEN_CURLY_BRACE */:
|
|
1722
1768
|
expression.groupStack.push(125 /* CLOSE_CURLY_BRACE */);
|
|
1723
1769
|
break;
|
|
1770
|
+
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
1771
|
+
if (expression.inType) {
|
|
1772
|
+
expression.groupStack.push(62 /* CLOSE_ANGLE_BRACKET */);
|
|
1773
|
+
} else if (expression.operators && !expression.groupStack.length) {
|
|
1774
|
+
this.pos++;
|
|
1775
|
+
this.forward = 0;
|
|
1776
|
+
this.consumeWhitespace();
|
|
1777
|
+
}
|
|
1778
|
+
break;
|
|
1724
1779
|
case 41 /* CLOSE_PAREN */:
|
|
1725
1780
|
case 93 /* CLOSE_SQUARE_BRACKET */:
|
|
1726
|
-
case 125 /* CLOSE_CURLY_BRACE */:
|
|
1781
|
+
case 125 /* CLOSE_CURLY_BRACE */:
|
|
1782
|
+
case (expression.inType && 62 /* CLOSE_ANGLE_BRACKET */): {
|
|
1727
1783
|
if (!expression.groupStack.length) {
|
|
1728
1784
|
return this.emitError(
|
|
1729
1785
|
expression,
|
|
@@ -1800,7 +1856,7 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1800
1856
|
if (!expression.operators)
|
|
1801
1857
|
return false;
|
|
1802
1858
|
const { pos, data } = parser;
|
|
1803
|
-
if (lookBehindForOperator(data, pos) !== -1) {
|
|
1859
|
+
if (lookBehindForOperator(expression, data, pos) !== -1) {
|
|
1804
1860
|
parser.consumeWhitespace();
|
|
1805
1861
|
parser.forward = 0;
|
|
1806
1862
|
return true;
|
|
@@ -1815,9 +1871,10 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1815
1871
|
if (!expression.shouldTerminate(
|
|
1816
1872
|
data.charCodeAt(nextNonSpace),
|
|
1817
1873
|
data,
|
|
1818
|
-
nextNonSpace
|
|
1874
|
+
nextNonSpace,
|
|
1875
|
+
expression
|
|
1819
1876
|
)) {
|
|
1820
|
-
const lookAheadPos = lookAheadForOperator(data, nextNonSpace);
|
|
1877
|
+
const lookAheadPos = lookAheadForOperator(expression, data, nextNonSpace);
|
|
1821
1878
|
if (lookAheadPos !== -1) {
|
|
1822
1879
|
parser.pos = lookAheadPos;
|
|
1823
1880
|
parser.forward = 0;
|
|
@@ -1827,7 +1884,7 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1827
1884
|
}
|
|
1828
1885
|
return false;
|
|
1829
1886
|
}
|
|
1830
|
-
function lookBehindForOperator(data, pos) {
|
|
1887
|
+
function lookBehindForOperator(expression, data, pos) {
|
|
1831
1888
|
const curPos = pos - 1;
|
|
1832
1889
|
const code = data.charCodeAt(curPos);
|
|
1833
1890
|
switch (code) {
|
|
@@ -1838,12 +1895,13 @@ function lookBehindForOperator(data, pos) {
|
|
|
1838
1895
|
case 61 /* EQUAL */:
|
|
1839
1896
|
case 33 /* EXCLAMATION */:
|
|
1840
1897
|
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
1841
|
-
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1842
1898
|
case 37 /* PERCENT */:
|
|
1843
1899
|
case 124 /* PIPE */:
|
|
1844
1900
|
case 63 /* QUESTION */:
|
|
1845
1901
|
case 126 /* TILDE */:
|
|
1846
1902
|
return curPos;
|
|
1903
|
+
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1904
|
+
return data.charCodeAt(curPos - 1) === 61 /* EQUAL */ ? curPos - 1 : expression.inType ? -1 : curPos;
|
|
1847
1905
|
case 46 /* PERIOD */: {
|
|
1848
1906
|
const nextPos = lookAheadWhile(isWhitespaceCode, data, pos);
|
|
1849
1907
|
return isWordCode(data.charCodeAt(nextPos)) ? nextPos : -1;
|
|
@@ -1852,6 +1910,7 @@ function lookBehindForOperator(data, pos) {
|
|
|
1852
1910
|
case 45 /* HYPHEN */: {
|
|
1853
1911
|
if (data.charCodeAt(curPos - 1) === code) {
|
|
1854
1912
|
return lookBehindForOperator(
|
|
1913
|
+
expression,
|
|
1855
1914
|
data,
|
|
1856
1915
|
lookBehindWhile(isWhitespaceCode, data, curPos - 2)
|
|
1857
1916
|
);
|
|
@@ -1862,15 +1921,14 @@ function lookBehindForOperator(data, pos) {
|
|
|
1862
1921
|
for (const keyword of unaryKeywords) {
|
|
1863
1922
|
const keywordPos = lookBehindFor(data, curPos, keyword);
|
|
1864
1923
|
if (keywordPos !== -1) {
|
|
1865
|
-
|
|
1866
|
-
return prevCode === 46 /* PERIOD */ || isWordCode(prevCode) ? -1 : keywordPos;
|
|
1924
|
+
return isWordOrPeriodCode(data.charCodeAt(keywordPos - 1)) ? -1 : keywordPos;
|
|
1867
1925
|
}
|
|
1868
1926
|
}
|
|
1869
1927
|
return -1;
|
|
1870
1928
|
}
|
|
1871
1929
|
}
|
|
1872
1930
|
}
|
|
1873
|
-
function lookAheadForOperator(data, pos) {
|
|
1931
|
+
function lookAheadForOperator(expression, data, pos) {
|
|
1874
1932
|
switch (data.charCodeAt(pos)) {
|
|
1875
1933
|
case 38 /* AMPERSAND */:
|
|
1876
1934
|
case 42 /* ASTERISK */:
|
|
@@ -1879,17 +1937,17 @@ function lookAheadForOperator(data, pos) {
|
|
|
1879
1937
|
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
1880
1938
|
case 37 /* PERCENT */:
|
|
1881
1939
|
case 124 /* PIPE */:
|
|
1882
|
-
case 63 /* QUESTION */:
|
|
1883
1940
|
case 126 /* TILDE */:
|
|
1884
1941
|
case 43 /* PLUS */:
|
|
1885
1942
|
case 45 /* HYPHEN */:
|
|
1886
|
-
case 58 /* COLON */:
|
|
1887
|
-
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1888
|
-
case 61 /* EQUAL */:
|
|
1889
1943
|
return pos + 1;
|
|
1890
1944
|
case 47 /* FORWARD_SLASH */:
|
|
1891
1945
|
case 123 /* OPEN_CURLY_BRACE */:
|
|
1892
1946
|
case 40 /* OPEN_PAREN */:
|
|
1947
|
+
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1948
|
+
case 63 /* QUESTION */:
|
|
1949
|
+
case 58 /* COLON */:
|
|
1950
|
+
case 61 /* EQUAL */:
|
|
1893
1951
|
return pos;
|
|
1894
1952
|
case 46 /* PERIOD */: {
|
|
1895
1953
|
const nextPos = lookAheadWhile(isWhitespaceCode, data, pos + 1);
|
|
@@ -1897,30 +1955,29 @@ function lookAheadForOperator(data, pos) {
|
|
|
1897
1955
|
}
|
|
1898
1956
|
default: {
|
|
1899
1957
|
for (const keyword of binaryKeywords) {
|
|
1900
|
-
|
|
1901
|
-
if (
|
|
1958
|
+
const keywordPos = lookAheadFor(data, pos, keyword);
|
|
1959
|
+
if (keywordPos === -1)
|
|
1902
1960
|
continue;
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
if (nextPos === max)
|
|
1910
|
-
return -1;
|
|
1911
|
-
nextCode = data.charCodeAt(nextPos);
|
|
1912
|
-
} else {
|
|
1913
|
-
return -1;
|
|
1914
|
-
}
|
|
1915
|
-
switch (nextCode) {
|
|
1961
|
+
if (!isWhitespaceCode(data.charCodeAt(keywordPos + 1)))
|
|
1962
|
+
break;
|
|
1963
|
+
const nextPos = lookAheadWhile(isWhitespaceCode, data, keywordPos + 2);
|
|
1964
|
+
if (nextPos === data.length - 1)
|
|
1965
|
+
break;
|
|
1966
|
+
switch (data.charCodeAt(nextPos)) {
|
|
1916
1967
|
case 58 /* COLON */:
|
|
1917
1968
|
case 44 /* COMMA */:
|
|
1918
1969
|
case 61 /* EQUAL */:
|
|
1919
1970
|
case 47 /* FORWARD_SLASH */:
|
|
1920
1971
|
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1921
1972
|
case 59 /* SEMICOLON */:
|
|
1922
|
-
|
|
1973
|
+
break;
|
|
1923
1974
|
default:
|
|
1975
|
+
if (!expression.inType && (keyword === "as" || keyword === "satisfies")) {
|
|
1976
|
+
expression.inType = true;
|
|
1977
|
+
if (!(expression.ternaryDepth || expression.groupStack.length)) {
|
|
1978
|
+
expression.forceType = true;
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1924
1981
|
return nextPos;
|
|
1925
1982
|
}
|
|
1926
1983
|
}
|
|
@@ -1946,6 +2003,9 @@ function canFollowDivision(code) {
|
|
|
1946
2003
|
return false;
|
|
1947
2004
|
}
|
|
1948
2005
|
}
|
|
2006
|
+
function isWordOrPeriodCode(code) {
|
|
2007
|
+
return code === 46 /* PERIOD */ || isWordCode(code);
|
|
2008
|
+
}
|
|
1949
2009
|
function isWordCode(code) {
|
|
1950
2010
|
return code >= 65 /* UPPER_A */ && code <= 90 /* UPPER_Z */ || code >= 97 /* LOWER_A */ && code <= 122 /* LOWER_Z */ || code >= 48 /* NUMBER_0 */ && code <= 57 /* NUMBER_9 */ || code == 36 /* DOLLAR */ || code === 95 /* UNDERSCORE */;
|
|
1951
2011
|
}
|
|
@@ -2454,15 +2514,22 @@ var REGULAR_EXPRESSION = {
|
|
|
2454
2514
|
exit() {
|
|
2455
2515
|
},
|
|
2456
2516
|
char(code, regExp) {
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2517
|
+
switch (code) {
|
|
2518
|
+
case 92 /* BACK_SLASH */:
|
|
2519
|
+
this.pos++;
|
|
2520
|
+
break;
|
|
2521
|
+
case 91 /* OPEN_SQUARE_BRACKET */:
|
|
2522
|
+
regExp.isInCharSet = true;
|
|
2523
|
+
break;
|
|
2524
|
+
case 93 /* CLOSE_SQUARE_BRACKET */:
|
|
2525
|
+
regExp.isInCharSet = false;
|
|
2526
|
+
break;
|
|
2527
|
+
case 47 /* FORWARD_SLASH */:
|
|
2528
|
+
if (!regExp.isInCharSet) {
|
|
2529
|
+
this.pos++;
|
|
2530
|
+
this.exitState();
|
|
2531
|
+
}
|
|
2532
|
+
break;
|
|
2466
2533
|
}
|
|
2467
2534
|
},
|
|
2468
2535
|
eol(_, regExp) {
|
|
@@ -2600,6 +2667,14 @@ var TAG_NAME = {
|
|
|
2600
2667
|
expr.operators = true;
|
|
2601
2668
|
expr.terminatedByEOL = true;
|
|
2602
2669
|
expr.consumeIndentedContent = true;
|
|
2670
|
+
const typeStatementMatch = this.lookAheadFor("declare ") || this.lookAheadFor("interface ") || this.lookAheadFor("type ");
|
|
2671
|
+
if (typeStatementMatch) {
|
|
2672
|
+
expr.inType = true;
|
|
2673
|
+
expr.forceType = true;
|
|
2674
|
+
this.pos += typeStatementMatch.length;
|
|
2675
|
+
this.forward = 0;
|
|
2676
|
+
this.consumeWhitespace();
|
|
2677
|
+
}
|
|
2603
2678
|
}
|
|
2604
2679
|
}
|
|
2605
2680
|
break;
|
package/dist/index.mjs
CHANGED
|
@@ -768,15 +768,16 @@ var OPEN_TAG = {
|
|
|
768
768
|
}
|
|
769
769
|
}
|
|
770
770
|
};
|
|
771
|
-
function shouldTerminateConciseTagVar(code, data, pos) {
|
|
771
|
+
function shouldTerminateConciseTagVar(code, data, pos, expression) {
|
|
772
772
|
switch (code) {
|
|
773
773
|
case 44 /* COMMA */:
|
|
774
774
|
case 61 /* EQUAL */:
|
|
775
775
|
case 124 /* PIPE */:
|
|
776
776
|
case 40 /* OPEN_PAREN */:
|
|
777
777
|
case 59 /* SEMICOLON */:
|
|
778
|
-
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
779
778
|
return true;
|
|
779
|
+
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
780
|
+
return !expression.inType;
|
|
780
781
|
case 45 /* HYPHEN */:
|
|
781
782
|
return data.charCodeAt(pos + 1) === 45 /* HYPHEN */;
|
|
782
783
|
case 58 /* COLON */:
|
|
@@ -785,15 +786,16 @@ function shouldTerminateConciseTagVar(code, data, pos) {
|
|
|
785
786
|
return false;
|
|
786
787
|
}
|
|
787
788
|
}
|
|
788
|
-
function shouldTerminateHtmlTagVar(code, data, pos) {
|
|
789
|
+
function shouldTerminateHtmlTagVar(code, data, pos, expression) {
|
|
789
790
|
switch (code) {
|
|
790
791
|
case 124 /* PIPE */:
|
|
791
792
|
case 44 /* COMMA */:
|
|
792
793
|
case 61 /* EQUAL */:
|
|
793
794
|
case 40 /* OPEN_PAREN */:
|
|
794
795
|
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
795
|
-
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
796
796
|
return true;
|
|
797
|
+
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
798
|
+
return !expression.inType;
|
|
797
799
|
case 58 /* COLON */:
|
|
798
800
|
return data.charCodeAt(pos + 1) === 61 /* EQUAL */;
|
|
799
801
|
case 47 /* FORWARD_SLASH */:
|
|
@@ -1170,7 +1172,6 @@ function handleDelimitedBlockEOL(parser, newLineLength, {
|
|
|
1170
1172
|
parser.endText();
|
|
1171
1173
|
parser.pos += endHtmlBlockLookahead.length;
|
|
1172
1174
|
if (parser.consumeWhitespaceOnLine(0)) {
|
|
1173
|
-
parser.endText();
|
|
1174
1175
|
parser.exitState();
|
|
1175
1176
|
parser.exitState();
|
|
1176
1177
|
} else {
|
|
@@ -1187,7 +1188,7 @@ function handleDelimitedBlockEOL(parser, newLineLength, {
|
|
|
1187
1188
|
parser.endText();
|
|
1188
1189
|
parser.exitState();
|
|
1189
1190
|
parser.exitState();
|
|
1190
|
-
} else {
|
|
1191
|
+
} else if (parser.pos + newLineLength !== parser.maxPos) {
|
|
1191
1192
|
parser.startText();
|
|
1192
1193
|
}
|
|
1193
1194
|
}
|
|
@@ -1594,20 +1595,26 @@ var DTD = {
|
|
|
1594
1595
|
// src/states/EXPRESSION.ts
|
|
1595
1596
|
var shouldTerminate = () => false;
|
|
1596
1597
|
var unaryKeywords = [
|
|
1598
|
+
"asserts",
|
|
1597
1599
|
"async",
|
|
1598
1600
|
"await",
|
|
1599
|
-
"keyof",
|
|
1600
1601
|
"class",
|
|
1601
1602
|
"function",
|
|
1603
|
+
"infer",
|
|
1604
|
+
"is",
|
|
1605
|
+
"keyof",
|
|
1602
1606
|
"new",
|
|
1607
|
+
"readonly",
|
|
1603
1608
|
"typeof",
|
|
1609
|
+
"unique",
|
|
1604
1610
|
"void"
|
|
1605
1611
|
];
|
|
1606
1612
|
var binaryKeywords = [
|
|
1607
|
-
"instanceof",
|
|
1608
|
-
"in",
|
|
1609
1613
|
"as",
|
|
1610
1614
|
"extends",
|
|
1615
|
+
"instanceof",
|
|
1616
|
+
// Note: instanceof must be checked before `in`
|
|
1617
|
+
"in",
|
|
1611
1618
|
"satisfies"
|
|
1612
1619
|
];
|
|
1613
1620
|
var EXPRESSION = {
|
|
@@ -1622,6 +1629,9 @@ var EXPRESSION = {
|
|
|
1622
1629
|
shouldTerminate,
|
|
1623
1630
|
operators: false,
|
|
1624
1631
|
wasComment: false,
|
|
1632
|
+
inType: false,
|
|
1633
|
+
forceType: false,
|
|
1634
|
+
ternaryDepth: 0,
|
|
1625
1635
|
terminatedByEOL: false,
|
|
1626
1636
|
terminatedByWhitespace: false,
|
|
1627
1637
|
consumeIndentedContent: false
|
|
@@ -1637,7 +1647,7 @@ var EXPRESSION = {
|
|
|
1637
1647
|
}
|
|
1638
1648
|
return;
|
|
1639
1649
|
}
|
|
1640
|
-
if (expression.shouldTerminate(code, this.data, this.pos)) {
|
|
1650
|
+
if (expression.shouldTerminate(code, this.data, this.pos, expression)) {
|
|
1641
1651
|
let wasExpression = false;
|
|
1642
1652
|
if (expression.operators) {
|
|
1643
1653
|
const prevNonWhitespacePos = lookBehindWhile(
|
|
@@ -1646,7 +1656,11 @@ var EXPRESSION = {
|
|
|
1646
1656
|
this.pos - 1
|
|
1647
1657
|
);
|
|
1648
1658
|
if (prevNonWhitespacePos > expression.start) {
|
|
1649
|
-
wasExpression = lookBehindForOperator(
|
|
1659
|
+
wasExpression = lookBehindForOperator(
|
|
1660
|
+
expression,
|
|
1661
|
+
this.data,
|
|
1662
|
+
prevNonWhitespacePos
|
|
1663
|
+
) !== -1;
|
|
1650
1664
|
}
|
|
1651
1665
|
}
|
|
1652
1666
|
if (!wasExpression) {
|
|
@@ -1665,6 +1679,38 @@ var EXPRESSION = {
|
|
|
1665
1679
|
case 96 /* BACKTICK */:
|
|
1666
1680
|
this.enterState(states_exports.TEMPLATE_STRING);
|
|
1667
1681
|
break;
|
|
1682
|
+
case 63 /* QUESTION */:
|
|
1683
|
+
if (expression.operators && !expression.groupStack.length) {
|
|
1684
|
+
expression.ternaryDepth++;
|
|
1685
|
+
this.pos++;
|
|
1686
|
+
this.forward = 0;
|
|
1687
|
+
this.consumeWhitespace();
|
|
1688
|
+
}
|
|
1689
|
+
break;
|
|
1690
|
+
case 58 /* COLON */:
|
|
1691
|
+
if (expression.operators && !expression.groupStack.length) {
|
|
1692
|
+
if (expression.ternaryDepth) {
|
|
1693
|
+
expression.ternaryDepth--;
|
|
1694
|
+
} else {
|
|
1695
|
+
expression.inType = true;
|
|
1696
|
+
}
|
|
1697
|
+
this.pos++;
|
|
1698
|
+
this.forward = 0;
|
|
1699
|
+
this.consumeWhitespace();
|
|
1700
|
+
}
|
|
1701
|
+
break;
|
|
1702
|
+
case 61 /* EQUAL */:
|
|
1703
|
+
if (expression.operators && !expression.groupStack.length) {
|
|
1704
|
+
if (this.lookAtCharCodeAhead(1) === 62 /* CLOSE_ANGLE_BRACKET */) {
|
|
1705
|
+
this.pos++;
|
|
1706
|
+
} else if (!expression.forceType) {
|
|
1707
|
+
expression.inType = false;
|
|
1708
|
+
}
|
|
1709
|
+
this.pos++;
|
|
1710
|
+
this.forward = 0;
|
|
1711
|
+
this.consumeWhitespace();
|
|
1712
|
+
}
|
|
1713
|
+
break;
|
|
1668
1714
|
case 47 /* FORWARD_SLASH */:
|
|
1669
1715
|
switch (this.lookAtCharCodeAhead(1)) {
|
|
1670
1716
|
case 47 /* FORWARD_SLASH */:
|
|
@@ -1696,9 +1742,19 @@ var EXPRESSION = {
|
|
|
1696
1742
|
case 123 /* OPEN_CURLY_BRACE */:
|
|
1697
1743
|
expression.groupStack.push(125 /* CLOSE_CURLY_BRACE */);
|
|
1698
1744
|
break;
|
|
1745
|
+
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
1746
|
+
if (expression.inType) {
|
|
1747
|
+
expression.groupStack.push(62 /* CLOSE_ANGLE_BRACKET */);
|
|
1748
|
+
} else if (expression.operators && !expression.groupStack.length) {
|
|
1749
|
+
this.pos++;
|
|
1750
|
+
this.forward = 0;
|
|
1751
|
+
this.consumeWhitespace();
|
|
1752
|
+
}
|
|
1753
|
+
break;
|
|
1699
1754
|
case 41 /* CLOSE_PAREN */:
|
|
1700
1755
|
case 93 /* CLOSE_SQUARE_BRACKET */:
|
|
1701
|
-
case 125 /* CLOSE_CURLY_BRACE */:
|
|
1756
|
+
case 125 /* CLOSE_CURLY_BRACE */:
|
|
1757
|
+
case (expression.inType && 62 /* CLOSE_ANGLE_BRACKET */): {
|
|
1702
1758
|
if (!expression.groupStack.length) {
|
|
1703
1759
|
return this.emitError(
|
|
1704
1760
|
expression,
|
|
@@ -1775,7 +1831,7 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1775
1831
|
if (!expression.operators)
|
|
1776
1832
|
return false;
|
|
1777
1833
|
const { pos, data } = parser;
|
|
1778
|
-
if (lookBehindForOperator(data, pos) !== -1) {
|
|
1834
|
+
if (lookBehindForOperator(expression, data, pos) !== -1) {
|
|
1779
1835
|
parser.consumeWhitespace();
|
|
1780
1836
|
parser.forward = 0;
|
|
1781
1837
|
return true;
|
|
@@ -1790,9 +1846,10 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1790
1846
|
if (!expression.shouldTerminate(
|
|
1791
1847
|
data.charCodeAt(nextNonSpace),
|
|
1792
1848
|
data,
|
|
1793
|
-
nextNonSpace
|
|
1849
|
+
nextNonSpace,
|
|
1850
|
+
expression
|
|
1794
1851
|
)) {
|
|
1795
|
-
const lookAheadPos = lookAheadForOperator(data, nextNonSpace);
|
|
1852
|
+
const lookAheadPos = lookAheadForOperator(expression, data, nextNonSpace);
|
|
1796
1853
|
if (lookAheadPos !== -1) {
|
|
1797
1854
|
parser.pos = lookAheadPos;
|
|
1798
1855
|
parser.forward = 0;
|
|
@@ -1802,7 +1859,7 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1802
1859
|
}
|
|
1803
1860
|
return false;
|
|
1804
1861
|
}
|
|
1805
|
-
function lookBehindForOperator(data, pos) {
|
|
1862
|
+
function lookBehindForOperator(expression, data, pos) {
|
|
1806
1863
|
const curPos = pos - 1;
|
|
1807
1864
|
const code = data.charCodeAt(curPos);
|
|
1808
1865
|
switch (code) {
|
|
@@ -1813,12 +1870,13 @@ function lookBehindForOperator(data, pos) {
|
|
|
1813
1870
|
case 61 /* EQUAL */:
|
|
1814
1871
|
case 33 /* EXCLAMATION */:
|
|
1815
1872
|
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
1816
|
-
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1817
1873
|
case 37 /* PERCENT */:
|
|
1818
1874
|
case 124 /* PIPE */:
|
|
1819
1875
|
case 63 /* QUESTION */:
|
|
1820
1876
|
case 126 /* TILDE */:
|
|
1821
1877
|
return curPos;
|
|
1878
|
+
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1879
|
+
return data.charCodeAt(curPos - 1) === 61 /* EQUAL */ ? curPos - 1 : expression.inType ? -1 : curPos;
|
|
1822
1880
|
case 46 /* PERIOD */: {
|
|
1823
1881
|
const nextPos = lookAheadWhile(isWhitespaceCode, data, pos);
|
|
1824
1882
|
return isWordCode(data.charCodeAt(nextPos)) ? nextPos : -1;
|
|
@@ -1827,6 +1885,7 @@ function lookBehindForOperator(data, pos) {
|
|
|
1827
1885
|
case 45 /* HYPHEN */: {
|
|
1828
1886
|
if (data.charCodeAt(curPos - 1) === code) {
|
|
1829
1887
|
return lookBehindForOperator(
|
|
1888
|
+
expression,
|
|
1830
1889
|
data,
|
|
1831
1890
|
lookBehindWhile(isWhitespaceCode, data, curPos - 2)
|
|
1832
1891
|
);
|
|
@@ -1837,15 +1896,14 @@ function lookBehindForOperator(data, pos) {
|
|
|
1837
1896
|
for (const keyword of unaryKeywords) {
|
|
1838
1897
|
const keywordPos = lookBehindFor(data, curPos, keyword);
|
|
1839
1898
|
if (keywordPos !== -1) {
|
|
1840
|
-
|
|
1841
|
-
return prevCode === 46 /* PERIOD */ || isWordCode(prevCode) ? -1 : keywordPos;
|
|
1899
|
+
return isWordOrPeriodCode(data.charCodeAt(keywordPos - 1)) ? -1 : keywordPos;
|
|
1842
1900
|
}
|
|
1843
1901
|
}
|
|
1844
1902
|
return -1;
|
|
1845
1903
|
}
|
|
1846
1904
|
}
|
|
1847
1905
|
}
|
|
1848
|
-
function lookAheadForOperator(data, pos) {
|
|
1906
|
+
function lookAheadForOperator(expression, data, pos) {
|
|
1849
1907
|
switch (data.charCodeAt(pos)) {
|
|
1850
1908
|
case 38 /* AMPERSAND */:
|
|
1851
1909
|
case 42 /* ASTERISK */:
|
|
@@ -1854,17 +1912,17 @@ function lookAheadForOperator(data, pos) {
|
|
|
1854
1912
|
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
1855
1913
|
case 37 /* PERCENT */:
|
|
1856
1914
|
case 124 /* PIPE */:
|
|
1857
|
-
case 63 /* QUESTION */:
|
|
1858
1915
|
case 126 /* TILDE */:
|
|
1859
1916
|
case 43 /* PLUS */:
|
|
1860
1917
|
case 45 /* HYPHEN */:
|
|
1861
|
-
case 58 /* COLON */:
|
|
1862
|
-
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1863
|
-
case 61 /* EQUAL */:
|
|
1864
1918
|
return pos + 1;
|
|
1865
1919
|
case 47 /* FORWARD_SLASH */:
|
|
1866
1920
|
case 123 /* OPEN_CURLY_BRACE */:
|
|
1867
1921
|
case 40 /* OPEN_PAREN */:
|
|
1922
|
+
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1923
|
+
case 63 /* QUESTION */:
|
|
1924
|
+
case 58 /* COLON */:
|
|
1925
|
+
case 61 /* EQUAL */:
|
|
1868
1926
|
return pos;
|
|
1869
1927
|
case 46 /* PERIOD */: {
|
|
1870
1928
|
const nextPos = lookAheadWhile(isWhitespaceCode, data, pos + 1);
|
|
@@ -1872,30 +1930,29 @@ function lookAheadForOperator(data, pos) {
|
|
|
1872
1930
|
}
|
|
1873
1931
|
default: {
|
|
1874
1932
|
for (const keyword of binaryKeywords) {
|
|
1875
|
-
|
|
1876
|
-
if (
|
|
1933
|
+
const keywordPos = lookAheadFor(data, pos, keyword);
|
|
1934
|
+
if (keywordPos === -1)
|
|
1877
1935
|
continue;
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
if (nextPos === max)
|
|
1885
|
-
return -1;
|
|
1886
|
-
nextCode = data.charCodeAt(nextPos);
|
|
1887
|
-
} else {
|
|
1888
|
-
return -1;
|
|
1889
|
-
}
|
|
1890
|
-
switch (nextCode) {
|
|
1936
|
+
if (!isWhitespaceCode(data.charCodeAt(keywordPos + 1)))
|
|
1937
|
+
break;
|
|
1938
|
+
const nextPos = lookAheadWhile(isWhitespaceCode, data, keywordPos + 2);
|
|
1939
|
+
if (nextPos === data.length - 1)
|
|
1940
|
+
break;
|
|
1941
|
+
switch (data.charCodeAt(nextPos)) {
|
|
1891
1942
|
case 58 /* COLON */:
|
|
1892
1943
|
case 44 /* COMMA */:
|
|
1893
1944
|
case 61 /* EQUAL */:
|
|
1894
1945
|
case 47 /* FORWARD_SLASH */:
|
|
1895
1946
|
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1896
1947
|
case 59 /* SEMICOLON */:
|
|
1897
|
-
|
|
1948
|
+
break;
|
|
1898
1949
|
default:
|
|
1950
|
+
if (!expression.inType && (keyword === "as" || keyword === "satisfies")) {
|
|
1951
|
+
expression.inType = true;
|
|
1952
|
+
if (!(expression.ternaryDepth || expression.groupStack.length)) {
|
|
1953
|
+
expression.forceType = true;
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1899
1956
|
return nextPos;
|
|
1900
1957
|
}
|
|
1901
1958
|
}
|
|
@@ -1921,6 +1978,9 @@ function canFollowDivision(code) {
|
|
|
1921
1978
|
return false;
|
|
1922
1979
|
}
|
|
1923
1980
|
}
|
|
1981
|
+
function isWordOrPeriodCode(code) {
|
|
1982
|
+
return code === 46 /* PERIOD */ || isWordCode(code);
|
|
1983
|
+
}
|
|
1924
1984
|
function isWordCode(code) {
|
|
1925
1985
|
return code >= 65 /* UPPER_A */ && code <= 90 /* UPPER_Z */ || code >= 97 /* LOWER_A */ && code <= 122 /* LOWER_Z */ || code >= 48 /* NUMBER_0 */ && code <= 57 /* NUMBER_9 */ || code == 36 /* DOLLAR */ || code === 95 /* UNDERSCORE */;
|
|
1926
1986
|
}
|
|
@@ -2429,15 +2489,22 @@ var REGULAR_EXPRESSION = {
|
|
|
2429
2489
|
exit() {
|
|
2430
2490
|
},
|
|
2431
2491
|
char(code, regExp) {
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2492
|
+
switch (code) {
|
|
2493
|
+
case 92 /* BACK_SLASH */:
|
|
2494
|
+
this.pos++;
|
|
2495
|
+
break;
|
|
2496
|
+
case 91 /* OPEN_SQUARE_BRACKET */:
|
|
2497
|
+
regExp.isInCharSet = true;
|
|
2498
|
+
break;
|
|
2499
|
+
case 93 /* CLOSE_SQUARE_BRACKET */:
|
|
2500
|
+
regExp.isInCharSet = false;
|
|
2501
|
+
break;
|
|
2502
|
+
case 47 /* FORWARD_SLASH */:
|
|
2503
|
+
if (!regExp.isInCharSet) {
|
|
2504
|
+
this.pos++;
|
|
2505
|
+
this.exitState();
|
|
2506
|
+
}
|
|
2507
|
+
break;
|
|
2441
2508
|
}
|
|
2442
2509
|
},
|
|
2443
2510
|
eol(_, regExp) {
|
|
@@ -2575,6 +2642,14 @@ var TAG_NAME = {
|
|
|
2575
2642
|
expr.operators = true;
|
|
2576
2643
|
expr.terminatedByEOL = true;
|
|
2577
2644
|
expr.consumeIndentedContent = true;
|
|
2645
|
+
const typeStatementMatch = this.lookAheadFor("declare ") || this.lookAheadFor("interface ") || this.lookAheadFor("type ");
|
|
2646
|
+
if (typeStatementMatch) {
|
|
2647
|
+
expr.inType = true;
|
|
2648
|
+
expr.forceType = true;
|
|
2649
|
+
this.pos += typeStatementMatch.length;
|
|
2650
|
+
this.forward = 0;
|
|
2651
|
+
this.consumeWhitespace();
|
|
2652
|
+
}
|
|
2578
2653
|
}
|
|
2579
2654
|
}
|
|
2580
2655
|
break;
|
|
@@ -3,9 +3,12 @@ export interface ExpressionMeta extends Meta {
|
|
|
3
3
|
groupStack: number[];
|
|
4
4
|
operators: boolean;
|
|
5
5
|
wasComment: boolean;
|
|
6
|
+
inType: boolean;
|
|
7
|
+
forceType: boolean;
|
|
8
|
+
ternaryDepth: number;
|
|
6
9
|
terminatedByEOL: boolean;
|
|
7
10
|
terminatedByWhitespace: boolean;
|
|
8
11
|
consumeIndentedContent: boolean;
|
|
9
|
-
shouldTerminate(code: number, data: string, pos: number): boolean;
|
|
12
|
+
shouldTerminate(code: number, data: string, pos: number, expression: ExpressionMeta): boolean;
|
|
10
13
|
}
|
|
11
14
|
export declare const EXPRESSION: StateDefinition<ExpressionMeta>;
|
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": "5.
|
|
4
|
+
"version": "5.7.0",
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@changesets/changelog-github": "^0.5.0",
|
|
7
7
|
"@changesets/cli": "^2.27.1",
|
|
@@ -63,18 +63,16 @@
|
|
|
63
63
|
"bench": "tsx bench.mts",
|
|
64
64
|
"build": "tsc -b && tsx build.mts",
|
|
65
65
|
"change": "changeset add",
|
|
66
|
-
"ci:test": "nyc npm
|
|
66
|
+
"ci:test": "nyc npm test -- --forbid-only",
|
|
67
67
|
"format": "npm run lint:eslint -- --fix && npm run lint:prettier -- --write && (fixpack || true)",
|
|
68
68
|
"lint": "tsc -b && npm run lint:eslint && npm run lint:prettier -- -l && fixpack",
|
|
69
69
|
"lint:eslint": "eslint -f visualstudio .",
|
|
70
70
|
"lint:prettier": "prettier \"./**/*{.ts,.js,.json,.md,.yml,rc}\"",
|
|
71
|
-
"mocha": "cross-env NODE_ENV=test mocha \"./src/**/__tests__/*.test.ts\"",
|
|
72
71
|
"prepare": "husky",
|
|
73
72
|
"release": "npm run build && changeset publish",
|
|
74
73
|
"report": "open ./coverage/lcov-report/index.html",
|
|
75
|
-
"test": "
|
|
76
|
-
"test:
|
|
77
|
-
"test:update": "npm run mocha -- --update",
|
|
74
|
+
"test": "cross-env NODE_ENV=test mocha \"./src/**/__tests__/*.test.ts\"",
|
|
75
|
+
"test:update": "npm test -- --update",
|
|
78
76
|
"version": "changeset version && npm i --package-lock-only"
|
|
79
77
|
},
|
|
80
78
|
"types": "dist/index.d.ts"
|