htmljs-parser 5.6.2 → 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 +123 -47
- package/dist/index.mjs +123 -47
- 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 */:
|
|
@@ -1618,20 +1620,26 @@ var DTD = {
|
|
|
1618
1620
|
// src/states/EXPRESSION.ts
|
|
1619
1621
|
var shouldTerminate = () => false;
|
|
1620
1622
|
var unaryKeywords = [
|
|
1623
|
+
"asserts",
|
|
1621
1624
|
"async",
|
|
1622
1625
|
"await",
|
|
1623
|
-
"keyof",
|
|
1624
1626
|
"class",
|
|
1625
1627
|
"function",
|
|
1628
|
+
"infer",
|
|
1629
|
+
"is",
|
|
1630
|
+
"keyof",
|
|
1626
1631
|
"new",
|
|
1632
|
+
"readonly",
|
|
1627
1633
|
"typeof",
|
|
1634
|
+
"unique",
|
|
1628
1635
|
"void"
|
|
1629
1636
|
];
|
|
1630
1637
|
var binaryKeywords = [
|
|
1631
|
-
"instanceof",
|
|
1632
|
-
"in",
|
|
1633
1638
|
"as",
|
|
1634
1639
|
"extends",
|
|
1640
|
+
"instanceof",
|
|
1641
|
+
// Note: instanceof must be checked before `in`
|
|
1642
|
+
"in",
|
|
1635
1643
|
"satisfies"
|
|
1636
1644
|
];
|
|
1637
1645
|
var EXPRESSION = {
|
|
@@ -1646,6 +1654,9 @@ var EXPRESSION = {
|
|
|
1646
1654
|
shouldTerminate,
|
|
1647
1655
|
operators: false,
|
|
1648
1656
|
wasComment: false,
|
|
1657
|
+
inType: false,
|
|
1658
|
+
forceType: false,
|
|
1659
|
+
ternaryDepth: 0,
|
|
1649
1660
|
terminatedByEOL: false,
|
|
1650
1661
|
terminatedByWhitespace: false,
|
|
1651
1662
|
consumeIndentedContent: false
|
|
@@ -1661,7 +1672,7 @@ var EXPRESSION = {
|
|
|
1661
1672
|
}
|
|
1662
1673
|
return;
|
|
1663
1674
|
}
|
|
1664
|
-
if (expression.shouldTerminate(code, this.data, this.pos)) {
|
|
1675
|
+
if (expression.shouldTerminate(code, this.data, this.pos, expression)) {
|
|
1665
1676
|
let wasExpression = false;
|
|
1666
1677
|
if (expression.operators) {
|
|
1667
1678
|
const prevNonWhitespacePos = lookBehindWhile(
|
|
@@ -1670,7 +1681,11 @@ var EXPRESSION = {
|
|
|
1670
1681
|
this.pos - 1
|
|
1671
1682
|
);
|
|
1672
1683
|
if (prevNonWhitespacePos > expression.start) {
|
|
1673
|
-
wasExpression = lookBehindForOperator(
|
|
1684
|
+
wasExpression = lookBehindForOperator(
|
|
1685
|
+
expression,
|
|
1686
|
+
this.data,
|
|
1687
|
+
prevNonWhitespacePos
|
|
1688
|
+
) !== -1;
|
|
1674
1689
|
}
|
|
1675
1690
|
}
|
|
1676
1691
|
if (!wasExpression) {
|
|
@@ -1689,6 +1704,38 @@ var EXPRESSION = {
|
|
|
1689
1704
|
case 96 /* BACKTICK */:
|
|
1690
1705
|
this.enterState(states_exports.TEMPLATE_STRING);
|
|
1691
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;
|
|
1692
1739
|
case 47 /* FORWARD_SLASH */:
|
|
1693
1740
|
switch (this.lookAtCharCodeAhead(1)) {
|
|
1694
1741
|
case 47 /* FORWARD_SLASH */:
|
|
@@ -1720,9 +1767,19 @@ var EXPRESSION = {
|
|
|
1720
1767
|
case 123 /* OPEN_CURLY_BRACE */:
|
|
1721
1768
|
expression.groupStack.push(125 /* CLOSE_CURLY_BRACE */);
|
|
1722
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;
|
|
1723
1779
|
case 41 /* CLOSE_PAREN */:
|
|
1724
1780
|
case 93 /* CLOSE_SQUARE_BRACKET */:
|
|
1725
|
-
case 125 /* CLOSE_CURLY_BRACE */:
|
|
1781
|
+
case 125 /* CLOSE_CURLY_BRACE */:
|
|
1782
|
+
case (expression.inType && 62 /* CLOSE_ANGLE_BRACKET */): {
|
|
1726
1783
|
if (!expression.groupStack.length) {
|
|
1727
1784
|
return this.emitError(
|
|
1728
1785
|
expression,
|
|
@@ -1799,7 +1856,7 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1799
1856
|
if (!expression.operators)
|
|
1800
1857
|
return false;
|
|
1801
1858
|
const { pos, data } = parser;
|
|
1802
|
-
if (lookBehindForOperator(data, pos) !== -1) {
|
|
1859
|
+
if (lookBehindForOperator(expression, data, pos) !== -1) {
|
|
1803
1860
|
parser.consumeWhitespace();
|
|
1804
1861
|
parser.forward = 0;
|
|
1805
1862
|
return true;
|
|
@@ -1814,9 +1871,10 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1814
1871
|
if (!expression.shouldTerminate(
|
|
1815
1872
|
data.charCodeAt(nextNonSpace),
|
|
1816
1873
|
data,
|
|
1817
|
-
nextNonSpace
|
|
1874
|
+
nextNonSpace,
|
|
1875
|
+
expression
|
|
1818
1876
|
)) {
|
|
1819
|
-
const lookAheadPos = lookAheadForOperator(data, nextNonSpace);
|
|
1877
|
+
const lookAheadPos = lookAheadForOperator(expression, data, nextNonSpace);
|
|
1820
1878
|
if (lookAheadPos !== -1) {
|
|
1821
1879
|
parser.pos = lookAheadPos;
|
|
1822
1880
|
parser.forward = 0;
|
|
@@ -1826,7 +1884,7 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1826
1884
|
}
|
|
1827
1885
|
return false;
|
|
1828
1886
|
}
|
|
1829
|
-
function lookBehindForOperator(data, pos) {
|
|
1887
|
+
function lookBehindForOperator(expression, data, pos) {
|
|
1830
1888
|
const curPos = pos - 1;
|
|
1831
1889
|
const code = data.charCodeAt(curPos);
|
|
1832
1890
|
switch (code) {
|
|
@@ -1837,12 +1895,13 @@ function lookBehindForOperator(data, pos) {
|
|
|
1837
1895
|
case 61 /* EQUAL */:
|
|
1838
1896
|
case 33 /* EXCLAMATION */:
|
|
1839
1897
|
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
1840
|
-
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1841
1898
|
case 37 /* PERCENT */:
|
|
1842
1899
|
case 124 /* PIPE */:
|
|
1843
1900
|
case 63 /* QUESTION */:
|
|
1844
1901
|
case 126 /* TILDE */:
|
|
1845
1902
|
return curPos;
|
|
1903
|
+
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1904
|
+
return data.charCodeAt(curPos - 1) === 61 /* EQUAL */ ? curPos - 1 : expression.inType ? -1 : curPos;
|
|
1846
1905
|
case 46 /* PERIOD */: {
|
|
1847
1906
|
const nextPos = lookAheadWhile(isWhitespaceCode, data, pos);
|
|
1848
1907
|
return isWordCode(data.charCodeAt(nextPos)) ? nextPos : -1;
|
|
@@ -1851,6 +1910,7 @@ function lookBehindForOperator(data, pos) {
|
|
|
1851
1910
|
case 45 /* HYPHEN */: {
|
|
1852
1911
|
if (data.charCodeAt(curPos - 1) === code) {
|
|
1853
1912
|
return lookBehindForOperator(
|
|
1913
|
+
expression,
|
|
1854
1914
|
data,
|
|
1855
1915
|
lookBehindWhile(isWhitespaceCode, data, curPos - 2)
|
|
1856
1916
|
);
|
|
@@ -1861,15 +1921,14 @@ function lookBehindForOperator(data, pos) {
|
|
|
1861
1921
|
for (const keyword of unaryKeywords) {
|
|
1862
1922
|
const keywordPos = lookBehindFor(data, curPos, keyword);
|
|
1863
1923
|
if (keywordPos !== -1) {
|
|
1864
|
-
|
|
1865
|
-
return prevCode === 46 /* PERIOD */ || isWordCode(prevCode) ? -1 : keywordPos;
|
|
1924
|
+
return isWordOrPeriodCode(data.charCodeAt(keywordPos - 1)) ? -1 : keywordPos;
|
|
1866
1925
|
}
|
|
1867
1926
|
}
|
|
1868
1927
|
return -1;
|
|
1869
1928
|
}
|
|
1870
1929
|
}
|
|
1871
1930
|
}
|
|
1872
|
-
function lookAheadForOperator(data, pos) {
|
|
1931
|
+
function lookAheadForOperator(expression, data, pos) {
|
|
1873
1932
|
switch (data.charCodeAt(pos)) {
|
|
1874
1933
|
case 38 /* AMPERSAND */:
|
|
1875
1934
|
case 42 /* ASTERISK */:
|
|
@@ -1878,17 +1937,17 @@ function lookAheadForOperator(data, pos) {
|
|
|
1878
1937
|
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
1879
1938
|
case 37 /* PERCENT */:
|
|
1880
1939
|
case 124 /* PIPE */:
|
|
1881
|
-
case 63 /* QUESTION */:
|
|
1882
1940
|
case 126 /* TILDE */:
|
|
1883
1941
|
case 43 /* PLUS */:
|
|
1884
1942
|
case 45 /* HYPHEN */:
|
|
1885
|
-
case 58 /* COLON */:
|
|
1886
|
-
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1887
|
-
case 61 /* EQUAL */:
|
|
1888
1943
|
return pos + 1;
|
|
1889
1944
|
case 47 /* FORWARD_SLASH */:
|
|
1890
1945
|
case 123 /* OPEN_CURLY_BRACE */:
|
|
1891
1946
|
case 40 /* OPEN_PAREN */:
|
|
1947
|
+
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1948
|
+
case 63 /* QUESTION */:
|
|
1949
|
+
case 58 /* COLON */:
|
|
1950
|
+
case 61 /* EQUAL */:
|
|
1892
1951
|
return pos;
|
|
1893
1952
|
case 46 /* PERIOD */: {
|
|
1894
1953
|
const nextPos = lookAheadWhile(isWhitespaceCode, data, pos + 1);
|
|
@@ -1896,30 +1955,29 @@ function lookAheadForOperator(data, pos) {
|
|
|
1896
1955
|
}
|
|
1897
1956
|
default: {
|
|
1898
1957
|
for (const keyword of binaryKeywords) {
|
|
1899
|
-
|
|
1900
|
-
if (
|
|
1958
|
+
const keywordPos = lookAheadFor(data, pos, keyword);
|
|
1959
|
+
if (keywordPos === -1)
|
|
1901
1960
|
continue;
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
if (nextPos === max)
|
|
1909
|
-
return -1;
|
|
1910
|
-
nextCode = data.charCodeAt(nextPos);
|
|
1911
|
-
} else {
|
|
1912
|
-
return -1;
|
|
1913
|
-
}
|
|
1914
|
-
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)) {
|
|
1915
1967
|
case 58 /* COLON */:
|
|
1916
1968
|
case 44 /* COMMA */:
|
|
1917
1969
|
case 61 /* EQUAL */:
|
|
1918
1970
|
case 47 /* FORWARD_SLASH */:
|
|
1919
1971
|
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1920
1972
|
case 59 /* SEMICOLON */:
|
|
1921
|
-
|
|
1973
|
+
break;
|
|
1922
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
|
+
}
|
|
1923
1981
|
return nextPos;
|
|
1924
1982
|
}
|
|
1925
1983
|
}
|
|
@@ -1945,6 +2003,9 @@ function canFollowDivision(code) {
|
|
|
1945
2003
|
return false;
|
|
1946
2004
|
}
|
|
1947
2005
|
}
|
|
2006
|
+
function isWordOrPeriodCode(code) {
|
|
2007
|
+
return code === 46 /* PERIOD */ || isWordCode(code);
|
|
2008
|
+
}
|
|
1948
2009
|
function isWordCode(code) {
|
|
1949
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 */;
|
|
1950
2011
|
}
|
|
@@ -2453,15 +2514,22 @@ var REGULAR_EXPRESSION = {
|
|
|
2453
2514
|
exit() {
|
|
2454
2515
|
},
|
|
2455
2516
|
char(code, regExp) {
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
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;
|
|
2465
2533
|
}
|
|
2466
2534
|
},
|
|
2467
2535
|
eol(_, regExp) {
|
|
@@ -2599,6 +2667,14 @@ var TAG_NAME = {
|
|
|
2599
2667
|
expr.operators = true;
|
|
2600
2668
|
expr.terminatedByEOL = true;
|
|
2601
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
|
+
}
|
|
2602
2678
|
}
|
|
2603
2679
|
}
|
|
2604
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 */:
|
|
@@ -1593,20 +1595,26 @@ var DTD = {
|
|
|
1593
1595
|
// src/states/EXPRESSION.ts
|
|
1594
1596
|
var shouldTerminate = () => false;
|
|
1595
1597
|
var unaryKeywords = [
|
|
1598
|
+
"asserts",
|
|
1596
1599
|
"async",
|
|
1597
1600
|
"await",
|
|
1598
|
-
"keyof",
|
|
1599
1601
|
"class",
|
|
1600
1602
|
"function",
|
|
1603
|
+
"infer",
|
|
1604
|
+
"is",
|
|
1605
|
+
"keyof",
|
|
1601
1606
|
"new",
|
|
1607
|
+
"readonly",
|
|
1602
1608
|
"typeof",
|
|
1609
|
+
"unique",
|
|
1603
1610
|
"void"
|
|
1604
1611
|
];
|
|
1605
1612
|
var binaryKeywords = [
|
|
1606
|
-
"instanceof",
|
|
1607
|
-
"in",
|
|
1608
1613
|
"as",
|
|
1609
1614
|
"extends",
|
|
1615
|
+
"instanceof",
|
|
1616
|
+
// Note: instanceof must be checked before `in`
|
|
1617
|
+
"in",
|
|
1610
1618
|
"satisfies"
|
|
1611
1619
|
];
|
|
1612
1620
|
var EXPRESSION = {
|
|
@@ -1621,6 +1629,9 @@ var EXPRESSION = {
|
|
|
1621
1629
|
shouldTerminate,
|
|
1622
1630
|
operators: false,
|
|
1623
1631
|
wasComment: false,
|
|
1632
|
+
inType: false,
|
|
1633
|
+
forceType: false,
|
|
1634
|
+
ternaryDepth: 0,
|
|
1624
1635
|
terminatedByEOL: false,
|
|
1625
1636
|
terminatedByWhitespace: false,
|
|
1626
1637
|
consumeIndentedContent: false
|
|
@@ -1636,7 +1647,7 @@ var EXPRESSION = {
|
|
|
1636
1647
|
}
|
|
1637
1648
|
return;
|
|
1638
1649
|
}
|
|
1639
|
-
if (expression.shouldTerminate(code, this.data, this.pos)) {
|
|
1650
|
+
if (expression.shouldTerminate(code, this.data, this.pos, expression)) {
|
|
1640
1651
|
let wasExpression = false;
|
|
1641
1652
|
if (expression.operators) {
|
|
1642
1653
|
const prevNonWhitespacePos = lookBehindWhile(
|
|
@@ -1645,7 +1656,11 @@ var EXPRESSION = {
|
|
|
1645
1656
|
this.pos - 1
|
|
1646
1657
|
);
|
|
1647
1658
|
if (prevNonWhitespacePos > expression.start) {
|
|
1648
|
-
wasExpression = lookBehindForOperator(
|
|
1659
|
+
wasExpression = lookBehindForOperator(
|
|
1660
|
+
expression,
|
|
1661
|
+
this.data,
|
|
1662
|
+
prevNonWhitespacePos
|
|
1663
|
+
) !== -1;
|
|
1649
1664
|
}
|
|
1650
1665
|
}
|
|
1651
1666
|
if (!wasExpression) {
|
|
@@ -1664,6 +1679,38 @@ var EXPRESSION = {
|
|
|
1664
1679
|
case 96 /* BACKTICK */:
|
|
1665
1680
|
this.enterState(states_exports.TEMPLATE_STRING);
|
|
1666
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;
|
|
1667
1714
|
case 47 /* FORWARD_SLASH */:
|
|
1668
1715
|
switch (this.lookAtCharCodeAhead(1)) {
|
|
1669
1716
|
case 47 /* FORWARD_SLASH */:
|
|
@@ -1695,9 +1742,19 @@ var EXPRESSION = {
|
|
|
1695
1742
|
case 123 /* OPEN_CURLY_BRACE */:
|
|
1696
1743
|
expression.groupStack.push(125 /* CLOSE_CURLY_BRACE */);
|
|
1697
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;
|
|
1698
1754
|
case 41 /* CLOSE_PAREN */:
|
|
1699
1755
|
case 93 /* CLOSE_SQUARE_BRACKET */:
|
|
1700
|
-
case 125 /* CLOSE_CURLY_BRACE */:
|
|
1756
|
+
case 125 /* CLOSE_CURLY_BRACE */:
|
|
1757
|
+
case (expression.inType && 62 /* CLOSE_ANGLE_BRACKET */): {
|
|
1701
1758
|
if (!expression.groupStack.length) {
|
|
1702
1759
|
return this.emitError(
|
|
1703
1760
|
expression,
|
|
@@ -1774,7 +1831,7 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1774
1831
|
if (!expression.operators)
|
|
1775
1832
|
return false;
|
|
1776
1833
|
const { pos, data } = parser;
|
|
1777
|
-
if (lookBehindForOperator(data, pos) !== -1) {
|
|
1834
|
+
if (lookBehindForOperator(expression, data, pos) !== -1) {
|
|
1778
1835
|
parser.consumeWhitespace();
|
|
1779
1836
|
parser.forward = 0;
|
|
1780
1837
|
return true;
|
|
@@ -1789,9 +1846,10 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1789
1846
|
if (!expression.shouldTerminate(
|
|
1790
1847
|
data.charCodeAt(nextNonSpace),
|
|
1791
1848
|
data,
|
|
1792
|
-
nextNonSpace
|
|
1849
|
+
nextNonSpace,
|
|
1850
|
+
expression
|
|
1793
1851
|
)) {
|
|
1794
|
-
const lookAheadPos = lookAheadForOperator(data, nextNonSpace);
|
|
1852
|
+
const lookAheadPos = lookAheadForOperator(expression, data, nextNonSpace);
|
|
1795
1853
|
if (lookAheadPos !== -1) {
|
|
1796
1854
|
parser.pos = lookAheadPos;
|
|
1797
1855
|
parser.forward = 0;
|
|
@@ -1801,7 +1859,7 @@ function checkForOperators(parser, expression, eol) {
|
|
|
1801
1859
|
}
|
|
1802
1860
|
return false;
|
|
1803
1861
|
}
|
|
1804
|
-
function lookBehindForOperator(data, pos) {
|
|
1862
|
+
function lookBehindForOperator(expression, data, pos) {
|
|
1805
1863
|
const curPos = pos - 1;
|
|
1806
1864
|
const code = data.charCodeAt(curPos);
|
|
1807
1865
|
switch (code) {
|
|
@@ -1812,12 +1870,13 @@ function lookBehindForOperator(data, pos) {
|
|
|
1812
1870
|
case 61 /* EQUAL */:
|
|
1813
1871
|
case 33 /* EXCLAMATION */:
|
|
1814
1872
|
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
1815
|
-
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1816
1873
|
case 37 /* PERCENT */:
|
|
1817
1874
|
case 124 /* PIPE */:
|
|
1818
1875
|
case 63 /* QUESTION */:
|
|
1819
1876
|
case 126 /* TILDE */:
|
|
1820
1877
|
return curPos;
|
|
1878
|
+
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1879
|
+
return data.charCodeAt(curPos - 1) === 61 /* EQUAL */ ? curPos - 1 : expression.inType ? -1 : curPos;
|
|
1821
1880
|
case 46 /* PERIOD */: {
|
|
1822
1881
|
const nextPos = lookAheadWhile(isWhitespaceCode, data, pos);
|
|
1823
1882
|
return isWordCode(data.charCodeAt(nextPos)) ? nextPos : -1;
|
|
@@ -1826,6 +1885,7 @@ function lookBehindForOperator(data, pos) {
|
|
|
1826
1885
|
case 45 /* HYPHEN */: {
|
|
1827
1886
|
if (data.charCodeAt(curPos - 1) === code) {
|
|
1828
1887
|
return lookBehindForOperator(
|
|
1888
|
+
expression,
|
|
1829
1889
|
data,
|
|
1830
1890
|
lookBehindWhile(isWhitespaceCode, data, curPos - 2)
|
|
1831
1891
|
);
|
|
@@ -1836,15 +1896,14 @@ function lookBehindForOperator(data, pos) {
|
|
|
1836
1896
|
for (const keyword of unaryKeywords) {
|
|
1837
1897
|
const keywordPos = lookBehindFor(data, curPos, keyword);
|
|
1838
1898
|
if (keywordPos !== -1) {
|
|
1839
|
-
|
|
1840
|
-
return prevCode === 46 /* PERIOD */ || isWordCode(prevCode) ? -1 : keywordPos;
|
|
1899
|
+
return isWordOrPeriodCode(data.charCodeAt(keywordPos - 1)) ? -1 : keywordPos;
|
|
1841
1900
|
}
|
|
1842
1901
|
}
|
|
1843
1902
|
return -1;
|
|
1844
1903
|
}
|
|
1845
1904
|
}
|
|
1846
1905
|
}
|
|
1847
|
-
function lookAheadForOperator(data, pos) {
|
|
1906
|
+
function lookAheadForOperator(expression, data, pos) {
|
|
1848
1907
|
switch (data.charCodeAt(pos)) {
|
|
1849
1908
|
case 38 /* AMPERSAND */:
|
|
1850
1909
|
case 42 /* ASTERISK */:
|
|
@@ -1853,17 +1912,17 @@ function lookAheadForOperator(data, pos) {
|
|
|
1853
1912
|
case 60 /* OPEN_ANGLE_BRACKET */:
|
|
1854
1913
|
case 37 /* PERCENT */:
|
|
1855
1914
|
case 124 /* PIPE */:
|
|
1856
|
-
case 63 /* QUESTION */:
|
|
1857
1915
|
case 126 /* TILDE */:
|
|
1858
1916
|
case 43 /* PLUS */:
|
|
1859
1917
|
case 45 /* HYPHEN */:
|
|
1860
|
-
case 58 /* COLON */:
|
|
1861
|
-
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1862
|
-
case 61 /* EQUAL */:
|
|
1863
1918
|
return pos + 1;
|
|
1864
1919
|
case 47 /* FORWARD_SLASH */:
|
|
1865
1920
|
case 123 /* OPEN_CURLY_BRACE */:
|
|
1866
1921
|
case 40 /* OPEN_PAREN */:
|
|
1922
|
+
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1923
|
+
case 63 /* QUESTION */:
|
|
1924
|
+
case 58 /* COLON */:
|
|
1925
|
+
case 61 /* EQUAL */:
|
|
1867
1926
|
return pos;
|
|
1868
1927
|
case 46 /* PERIOD */: {
|
|
1869
1928
|
const nextPos = lookAheadWhile(isWhitespaceCode, data, pos + 1);
|
|
@@ -1871,30 +1930,29 @@ function lookAheadForOperator(data, pos) {
|
|
|
1871
1930
|
}
|
|
1872
1931
|
default: {
|
|
1873
1932
|
for (const keyword of binaryKeywords) {
|
|
1874
|
-
|
|
1875
|
-
if (
|
|
1933
|
+
const keywordPos = lookAheadFor(data, pos, keyword);
|
|
1934
|
+
if (keywordPos === -1)
|
|
1876
1935
|
continue;
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
if (nextPos === max)
|
|
1884
|
-
return -1;
|
|
1885
|
-
nextCode = data.charCodeAt(nextPos);
|
|
1886
|
-
} else {
|
|
1887
|
-
return -1;
|
|
1888
|
-
}
|
|
1889
|
-
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)) {
|
|
1890
1942
|
case 58 /* COLON */:
|
|
1891
1943
|
case 44 /* COMMA */:
|
|
1892
1944
|
case 61 /* EQUAL */:
|
|
1893
1945
|
case 47 /* FORWARD_SLASH */:
|
|
1894
1946
|
case 62 /* CLOSE_ANGLE_BRACKET */:
|
|
1895
1947
|
case 59 /* SEMICOLON */:
|
|
1896
|
-
|
|
1948
|
+
break;
|
|
1897
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
|
+
}
|
|
1898
1956
|
return nextPos;
|
|
1899
1957
|
}
|
|
1900
1958
|
}
|
|
@@ -1920,6 +1978,9 @@ function canFollowDivision(code) {
|
|
|
1920
1978
|
return false;
|
|
1921
1979
|
}
|
|
1922
1980
|
}
|
|
1981
|
+
function isWordOrPeriodCode(code) {
|
|
1982
|
+
return code === 46 /* PERIOD */ || isWordCode(code);
|
|
1983
|
+
}
|
|
1923
1984
|
function isWordCode(code) {
|
|
1924
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 */;
|
|
1925
1986
|
}
|
|
@@ -2428,15 +2489,22 @@ var REGULAR_EXPRESSION = {
|
|
|
2428
2489
|
exit() {
|
|
2429
2490
|
},
|
|
2430
2491
|
char(code, regExp) {
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
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;
|
|
2440
2508
|
}
|
|
2441
2509
|
},
|
|
2442
2510
|
eol(_, regExp) {
|
|
@@ -2574,6 +2642,14 @@ var TAG_NAME = {
|
|
|
2574
2642
|
expr.operators = true;
|
|
2575
2643
|
expr.terminatedByEOL = true;
|
|
2576
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
|
+
}
|
|
2577
2653
|
}
|
|
2578
2654
|
}
|
|
2579
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"
|