svelte2tsx 0.4.13 → 0.5.2
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/index.d.ts +14 -1
- package/index.js +1815 -253
- package/index.mjs +1815 -253
- package/package.json +2 -2
- package/svelte-jsx.d.ts +302 -1
- package/svelte-native-jsx.d.ts +10 -0
- package/svelte-shims.d.ts +43 -0
package/index.js
CHANGED
|
@@ -1137,7 +1137,7 @@ function parseAttributes(str, start) {
|
|
|
1137
1137
|
});
|
|
1138
1138
|
return attrs;
|
|
1139
1139
|
}
|
|
1140
|
-
function extractTag(htmlx, tag) {
|
|
1140
|
+
function extractTag(htmlx, tag, useNewTransformation) {
|
|
1141
1141
|
const exp = new RegExp(`(<!--[^]*?-->)|(<${tag}([\\S\\s]*?)>)([\\S\\s]*?)<\\/${tag}>`, 'g');
|
|
1142
1142
|
const matches = [];
|
|
1143
1143
|
let match = null;
|
|
@@ -1146,10 +1146,16 @@ function extractTag(htmlx, tag) {
|
|
|
1146
1146
|
// Tag is inside comment
|
|
1147
1147
|
continue;
|
|
1148
1148
|
}
|
|
1149
|
-
|
|
1149
|
+
let content = match[4];
|
|
1150
1150
|
if (!content) {
|
|
1151
|
-
|
|
1152
|
-
|
|
1151
|
+
if (useNewTransformation) {
|
|
1152
|
+
// Keep tag and transform it properly by removing it
|
|
1153
|
+
content = '';
|
|
1154
|
+
}
|
|
1155
|
+
else {
|
|
1156
|
+
// Self-closing/empty tags don't need replacement
|
|
1157
|
+
continue;
|
|
1158
|
+
}
|
|
1153
1159
|
}
|
|
1154
1160
|
const start = match.index + match[2].length;
|
|
1155
1161
|
const end = start + content.length;
|
|
@@ -1172,8 +1178,11 @@ function extractTag(htmlx, tag) {
|
|
|
1172
1178
|
}
|
|
1173
1179
|
return matches;
|
|
1174
1180
|
}
|
|
1175
|
-
function findVerbatimElements(htmlx) {
|
|
1176
|
-
return [
|
|
1181
|
+
function findVerbatimElements(htmlx, useNewTransformation) {
|
|
1182
|
+
return [
|
|
1183
|
+
...extractTag(htmlx, 'script', useNewTransformation),
|
|
1184
|
+
...extractTag(htmlx, 'style', useNewTransformation)
|
|
1185
|
+
];
|
|
1177
1186
|
}
|
|
1178
1187
|
function blankVerbatimContent(htmlx, verbatimElements) {
|
|
1179
1188
|
let output = htmlx;
|
|
@@ -1196,7 +1205,7 @@ function blankVerbatimContent(htmlx, verbatimElements) {
|
|
|
1196
1205
|
function parseHtmlx(htmlx, options) {
|
|
1197
1206
|
//Svelte tries to parse style and script tags which doesn't play well with typescript, so we blank them out.
|
|
1198
1207
|
//HTMLx spec says they should just be retained after processing as is, so this is fine
|
|
1199
|
-
const verbatimElements = findVerbatimElements(htmlx);
|
|
1208
|
+
const verbatimElements = findVerbatimElements(htmlx, options === null || options === void 0 ? void 0 : options.useNewTransformation);
|
|
1200
1209
|
const deconstructed = blankVerbatimContent(htmlx, verbatimElements);
|
|
1201
1210
|
//extract the html content parsed as htmlx this excludes our script and style tags
|
|
1202
1211
|
const parsingCode = (options === null || options === void 0 ? void 0 : options.emitOnTemplateError)
|
|
@@ -1574,7 +1583,7 @@ function getInstanceTypeForDefaultSlot(node, originalStr, replacedPropsPrefix) {
|
|
|
1574
1583
|
const propsStr = getNameValuePairsFromAttributes(node, originalStr)
|
|
1575
1584
|
.map(({ name, value, identifier, complexExpression }) => {
|
|
1576
1585
|
if (complexExpression || lets.has(identifier)) {
|
|
1577
|
-
const replacement = replacedPropsPrefix + sanitizePropName(name);
|
|
1586
|
+
const replacement = replacedPropsPrefix + sanitizePropName$1(name);
|
|
1578
1587
|
shadowedProps.push({ name, value, replacement });
|
|
1579
1588
|
return `'${name}':${replacement}`;
|
|
1580
1589
|
}
|
|
@@ -1632,7 +1641,7 @@ function getNameValuePairsFromAttributes(node, originalStr) {
|
|
|
1632
1641
|
return { name, value: `\`${value}\`` };
|
|
1633
1642
|
});
|
|
1634
1643
|
}
|
|
1635
|
-
function sanitizePropName(name) {
|
|
1644
|
+
function sanitizePropName$1(name) {
|
|
1636
1645
|
return name
|
|
1637
1646
|
.split('')
|
|
1638
1647
|
.map((char) => (/[0-9A-Za-z$_]/.test(char) ? char : '_'))
|
|
@@ -1677,11 +1686,26 @@ function usesLet(node) {
|
|
|
1677
1686
|
var _a;
|
|
1678
1687
|
return (_a = node.attributes) === null || _a === void 0 ? void 0 : _a.some((attr) => attr.type === 'Let');
|
|
1679
1688
|
}
|
|
1689
|
+
function buildTemplateString(attr, str, htmlx, leadingOverride, trailingOverride, overrideStart) {
|
|
1690
|
+
overrideStart = overrideStart !== null && overrideStart !== void 0 ? overrideStart : htmlx.lastIndexOf('=', attr.value[0].start);
|
|
1691
|
+
str.overwrite(overrideStart, attr.value[0].start, leadingOverride);
|
|
1692
|
+
for (const n of attr.value) {
|
|
1693
|
+
if (n.type == 'MustacheTag') {
|
|
1694
|
+
str.appendRight(n.start, '$');
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
if (isQuote(htmlx[attr.end - 1])) {
|
|
1698
|
+
str.overwrite(attr.end - 1, attr.end, trailingOverride);
|
|
1699
|
+
}
|
|
1700
|
+
else {
|
|
1701
|
+
str.appendLeft(attr.end, trailingOverride);
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1680
1704
|
|
|
1681
1705
|
/**
|
|
1682
1706
|
* use:xxx={params} ---> {...__sveltets_1_ensureAction(xxx(__sveltets_1_mapElementTag('ParentNodeName'),(params)))}
|
|
1683
1707
|
*/
|
|
1684
|
-
function handleActionDirective(htmlx, str, attr, parent) {
|
|
1708
|
+
function handleActionDirective$1(htmlx, str, attr, parent) {
|
|
1685
1709
|
str.overwrite(attr.start, attr.start + 'use:'.length, '{...__sveltets_1_ensureAction(');
|
|
1686
1710
|
const name = parent.name === 'svelte:body' ? 'body' : parent.name;
|
|
1687
1711
|
if (!attr.expression) {
|
|
@@ -1699,7 +1723,7 @@ function handleActionDirective(htmlx, str, attr, parent) {
|
|
|
1699
1723
|
/**
|
|
1700
1724
|
* animate:xxx(yyy) ---> {...__sveltets_1_ensureAnimation(xxx(__sveltets_1_mapElementTag('..'),__sveltets_1_AnimationMove,(yyy)))}
|
|
1701
1725
|
*/
|
|
1702
|
-
function handleAnimateDirective(htmlx, str, attr, parent) {
|
|
1726
|
+
function handleAnimateDirective$1(htmlx, str, attr, parent) {
|
|
1703
1727
|
str.overwrite(attr.start, htmlx.indexOf(':', attr.start) + 1, '{...__sveltets_1_ensureAnimation(');
|
|
1704
1728
|
const nodeType = `__sveltets_1_mapElementTag('${parent.name}')`;
|
|
1705
1729
|
if (!attr.expression) {
|
|
@@ -1713,12 +1737,12 @@ function handleAnimateDirective(htmlx, str, attr, parent) {
|
|
|
1713
1737
|
}
|
|
1714
1738
|
}
|
|
1715
1739
|
|
|
1716
|
-
var svgAttributes = 'accent-height accumulate additive alignment-baseline allowReorder alphabetic amplitude arabic-form ascent attributeName attributeType autoReverse azimuth baseFrequency baseline-shift baseProfile bbox begin bias by calcMode cap-height class clip clipPathUnits clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominant-baseline dur dx dy edgeMode elevation enable-background end exponent externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format from fr fx fy g1 g2 glyph-name glyph-orientation-horizontal glyph-orientation-vertical glyphRef gradientTransform gradientUnits hanging height href horiz-adv-x horiz-origin-x id ideographic image-rendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lang lengthAdjust letter-spacing lighting-color limitingConeAngle local marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical max media method min mode name numOctaves offset onabort onactivate onbegin onclick onend onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onrepeat onresize onscroll onunload opacity operator order orient orientation origin overflow overline-position overline-thickness panose-1 paint-order pathLength patternContentUnits patternTransform patternUnits pointer-events points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY rendering-intent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shape-rendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stop-color stop-opacity strikethrough-position strikethrough-thickness string stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale systemLanguage tabindex tableValues target targetX targetY text-anchor text-decoration text-rendering textLength to transform type u1 u2 underline-position underline-thickness unicode unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical values version vert-adv-y vert-origin-x vert-origin-y viewBox viewTarget visibility width widths word-spacing writing-mode x x-height x1 x2 xChannelSelector xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y y1 y2 yChannelSelector z zoomAndPan'.split(' ');
|
|
1740
|
+
var svgAttributes$1 = 'accent-height accumulate additive alignment-baseline allowReorder alphabetic amplitude arabic-form ascent attributeName attributeType autoReverse azimuth baseFrequency baseline-shift baseProfile bbox begin bias by calcMode cap-height class clip clipPathUnits clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominant-baseline dur dx dy edgeMode elevation enable-background end exponent externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format from fr fx fy g1 g2 glyph-name glyph-orientation-horizontal glyph-orientation-vertical glyphRef gradientTransform gradientUnits hanging height href horiz-adv-x horiz-origin-x id ideographic image-rendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lang lengthAdjust letter-spacing lighting-color limitingConeAngle local marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical max media method min mode name numOctaves offset onabort onactivate onbegin onclick onend onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onrepeat onresize onscroll onunload opacity operator order orient orientation origin overflow overline-position overline-thickness panose-1 paint-order pathLength patternContentUnits patternTransform patternUnits pointer-events points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY rendering-intent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shape-rendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stop-color stop-opacity strikethrough-position strikethrough-thickness string stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale systemLanguage tabindex tableValues target targetX targetY text-anchor text-decoration text-rendering textLength to transform type u1 u2 underline-position underline-thickness unicode unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical values version vert-adv-y vert-origin-x vert-origin-y viewBox viewTarget visibility width widths word-spacing writing-mode x x-height x1 x2 xChannelSelector xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y y1 y2 yChannelSelector z zoomAndPan'.split(' ');
|
|
1717
1741
|
|
|
1718
1742
|
/**
|
|
1719
1743
|
* List taken from `svelte-jsx.d.ts` by searching for all attributes of type number
|
|
1720
1744
|
*/
|
|
1721
|
-
const numberOnlyAttributes = new Set([
|
|
1745
|
+
const numberOnlyAttributes$1 = new Set([
|
|
1722
1746
|
'cols',
|
|
1723
1747
|
'colspan',
|
|
1724
1748
|
'currenttime',
|
|
@@ -1746,7 +1770,7 @@ const numberOnlyAttributes = new Set([
|
|
|
1746
1770
|
* - lowercase DOM attributes
|
|
1747
1771
|
* - multi-value handling
|
|
1748
1772
|
*/
|
|
1749
|
-
function handleAttribute(htmlx, str, attr, parent, preserveCase) {
|
|
1773
|
+
function handleAttribute$1(htmlx, str, attr, parent, preserveCase) {
|
|
1750
1774
|
var _a, _b, _c;
|
|
1751
1775
|
const shouldApplySlotCheck = parent.type === 'Slot' && attr.name !== 'name';
|
|
1752
1776
|
const slotName = shouldApplySlotCheck
|
|
@@ -1755,7 +1779,7 @@ function handleAttribute(htmlx, str, attr, parent, preserveCase) {
|
|
|
1755
1779
|
const ensureSlotStr = `__sveltets_ensureSlot("${slotName}","${attr.name}",`;
|
|
1756
1780
|
let transformedFromDirectiveOrNamespace = false;
|
|
1757
1781
|
const transformAttributeCase = (name) => {
|
|
1758
|
-
if (!preserveCase && !svgAttributes.find((x) => x == name)) {
|
|
1782
|
+
if (!preserveCase && !svgAttributes$1.find((x) => x == name)) {
|
|
1759
1783
|
return name.toLowerCase();
|
|
1760
1784
|
}
|
|
1761
1785
|
else {
|
|
@@ -1835,7 +1859,7 @@ function handleAttribute(htmlx, str, attr, parent, preserveCase) {
|
|
|
1835
1859
|
htmlx.lastIndexOf("}'", attrVal.end) === attrVal.end - 1;
|
|
1836
1860
|
const needsNumberConversion = !hasBrackets &&
|
|
1837
1861
|
parent.type === 'Element' &&
|
|
1838
|
-
numberOnlyAttributes.has(attr.name.toLowerCase()) &&
|
|
1862
|
+
numberOnlyAttributes$1.has(attr.name.toLowerCase()) &&
|
|
1839
1863
|
!isNaN(attrVal.data);
|
|
1840
1864
|
if (needsNumberConversion) {
|
|
1841
1865
|
const begin = '{' + (shouldApplySlotCheck ? ensureSlotStr : '');
|
|
@@ -1879,21 +1903,6 @@ function handleAttribute(htmlx, str, attr, parent, preserveCase) {
|
|
|
1879
1903
|
// We have multiple attribute values, so we build a template string out of them.
|
|
1880
1904
|
buildTemplateString(attr, str, htmlx, shouldApplySlotCheck ? `={${ensureSlotStr}\`` : '={`', shouldApplySlotCheck ? '`)}' : '`}');
|
|
1881
1905
|
}
|
|
1882
|
-
function buildTemplateString(attr, str, htmlx, leadingOverride, trailingOverride) {
|
|
1883
|
-
const equals = htmlx.lastIndexOf('=', attr.value[0].start);
|
|
1884
|
-
str.overwrite(equals, attr.value[0].start, leadingOverride);
|
|
1885
|
-
for (const n of attr.value) {
|
|
1886
|
-
if (n.type == 'MustacheTag') {
|
|
1887
|
-
str.appendRight(n.start, '$');
|
|
1888
|
-
}
|
|
1889
|
-
}
|
|
1890
|
-
if (isQuote(htmlx[attr.end - 1])) {
|
|
1891
|
-
str.overwrite(attr.end - 1, attr.end, trailingOverride);
|
|
1892
|
-
}
|
|
1893
|
-
else {
|
|
1894
|
-
str.appendLeft(attr.end, trailingOverride);
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
1906
|
function sanitizeLeadingChars(attrName) {
|
|
1898
1907
|
let sanitizedName = '';
|
|
1899
1908
|
for (let i = 0; i < attrName.length; i++) {
|
|
@@ -1908,10 +1917,28 @@ function sanitizeLeadingChars(attrName) {
|
|
|
1908
1917
|
return sanitizedName;
|
|
1909
1918
|
}
|
|
1910
1919
|
|
|
1920
|
+
function extractConstTags(children) {
|
|
1921
|
+
const tags = [];
|
|
1922
|
+
for (const child of children) {
|
|
1923
|
+
if (child.type === 'ConstTag') {
|
|
1924
|
+
const constTag = child;
|
|
1925
|
+
tags.push((insertionPoint, str) => {
|
|
1926
|
+
str.appendRight(constTag.expression.left.start, 'const ');
|
|
1927
|
+
str.move(constTag.expression.left.start, constTag.expression.right.end, insertionPoint);
|
|
1928
|
+
str.appendLeft(constTag.expression.right.end, ';');
|
|
1929
|
+
str.overwrite(constTag.start + 1, constTag.expression.left.start - 1, '', {
|
|
1930
|
+
contentOnly: true
|
|
1931
|
+
});
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
return tags;
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1911
1938
|
/**
|
|
1912
1939
|
* Transform {#await ...} into something JSX understands
|
|
1913
1940
|
*/
|
|
1914
|
-
function handleAwait(htmlx, str, awaitBlock, ifScope, templateScopeManager) {
|
|
1941
|
+
function handleAwait$1(htmlx, str, awaitBlock, ifScope, templateScopeManager) {
|
|
1915
1942
|
// {#await somePromise then value} ->
|
|
1916
1943
|
// {() => {let _$$p = (somePromise);
|
|
1917
1944
|
let ifCondition = ifScope.getFullCondition();
|
|
@@ -1973,16 +2000,24 @@ function handleAwaitThen(awaitBlock, htmlx, str, ifScope) {
|
|
|
1973
2000
|
}
|
|
1974
2001
|
if (awaitBlock.value) {
|
|
1975
2002
|
str.overwrite(thenStart, awaitBlock.value.start, '__sveltets_1_awaitThen(_$$p, (');
|
|
1976
|
-
str.overwrite(awaitBlock.value.end, thenEnd,
|
|
2003
|
+
str.overwrite(awaitBlock.value.end, thenEnd, ') => {');
|
|
2004
|
+
extractConstTags(awaitBlock.then.children).forEach((insertion) => {
|
|
2005
|
+
insertion(thenEnd, str);
|
|
2006
|
+
});
|
|
2007
|
+
str.appendRight(thenEnd, `${ifScope.addPossibleIfCondition()}<>`);
|
|
1977
2008
|
}
|
|
1978
2009
|
else {
|
|
1979
|
-
const awaitThenFn =
|
|
2010
|
+
const awaitThenFn = '__sveltets_1_awaitThen(_$$p, () => {';
|
|
1980
2011
|
if (thenStart === thenEnd) {
|
|
1981
2012
|
str.appendLeft(thenStart, awaitThenFn);
|
|
1982
2013
|
}
|
|
1983
2014
|
else {
|
|
1984
2015
|
str.overwrite(thenStart, thenEnd, awaitThenFn);
|
|
1985
2016
|
}
|
|
2017
|
+
extractConstTags(awaitBlock.then.children).forEach((insertion) => {
|
|
2018
|
+
insertion(thenEnd, str);
|
|
2019
|
+
});
|
|
2020
|
+
str.appendRight(thenEnd, `${ifScope.addPossibleIfCondition()}<>`); // eslint-disable-line
|
|
1986
2021
|
}
|
|
1987
2022
|
}
|
|
1988
2023
|
function handleAwaitCatch(awaitBlock, htmlx, str, ifScope) {
|
|
@@ -1994,12 +2029,20 @@ function handleAwaitCatch(awaitBlock, htmlx, str, ifScope) {
|
|
|
1994
2029
|
// {#await ... catch ...}
|
|
1995
2030
|
const catchBegin = htmlx.indexOf('}', awaitBlock.error.end) + 1;
|
|
1996
2031
|
str.overwrite(awaitBlock.expression.end, awaitBlock.error.start, '); __sveltets_1_awaitThen(_$$p, () => {}, (');
|
|
1997
|
-
str.overwrite(awaitBlock.error.end, catchBegin, ') => {
|
|
2032
|
+
str.overwrite(awaitBlock.error.end, catchBegin, ') => {');
|
|
2033
|
+
extractConstTags(awaitBlock.catch.children).forEach((insertion) => {
|
|
2034
|
+
insertion(catchBegin, str);
|
|
2035
|
+
});
|
|
2036
|
+
str.appendRight(catchBegin, '<>');
|
|
1998
2037
|
}
|
|
1999
2038
|
else {
|
|
2000
2039
|
// {#await ... catch}
|
|
2001
2040
|
const catchBegin = htmlx.indexOf('}', awaitBlock.expression.end) + 1;
|
|
2002
|
-
str.overwrite(awaitBlock.expression.end, catchBegin, '); __sveltets_1_awaitThen(_$$p, () => {}, () => {
|
|
2041
|
+
str.overwrite(awaitBlock.expression.end, catchBegin, '); __sveltets_1_awaitThen(_$$p, () => {}, () => {');
|
|
2042
|
+
extractConstTags(awaitBlock.catch.children).forEach((insertion) => {
|
|
2043
|
+
insertion(catchBegin, str);
|
|
2044
|
+
});
|
|
2045
|
+
str.appendRight(catchBegin, '<>');
|
|
2003
2046
|
}
|
|
2004
2047
|
}
|
|
2005
2048
|
else {
|
|
@@ -2012,11 +2055,15 @@ function handleAwaitCatch(awaitBlock, htmlx, str, ifScope) {
|
|
|
2012
2055
|
const errorEnd = awaitBlock.error ? awaitBlock.error.end : errorStart;
|
|
2013
2056
|
const catchEnd = htmlx.indexOf('}', errorEnd) + 1;
|
|
2014
2057
|
str.overwrite(catchStart, errorStart, '</>}, (');
|
|
2015
|
-
str.overwrite(errorEnd, catchEnd,
|
|
2058
|
+
str.overwrite(errorEnd, catchEnd, ') => {');
|
|
2059
|
+
extractConstTags(awaitBlock.catch.children).forEach((insertion) => {
|
|
2060
|
+
insertion(catchEnd, str);
|
|
2061
|
+
});
|
|
2062
|
+
str.appendRight(catchEnd, `${ifScope.addPossibleIfCondition()}<>`);
|
|
2016
2063
|
}
|
|
2017
2064
|
}
|
|
2018
2065
|
|
|
2019
|
-
const oneWayBindingAttributes = new Map(['clientWidth', 'clientHeight', 'offsetWidth', 'offsetHeight']
|
|
2066
|
+
const oneWayBindingAttributes$1 = new Map(['clientWidth', 'clientHeight', 'offsetWidth', 'offsetHeight']
|
|
2020
2067
|
.map((e) => [e, 'HTMLDivElement'])
|
|
2021
2068
|
.concat(['duration', 'buffered', 'seekable', 'seeking', 'played', 'ended'].map((e) => [
|
|
2022
2069
|
e,
|
|
@@ -2026,11 +2073,11 @@ const oneWayBindingAttributes = new Map(['clientWidth', 'clientHeight', 'offsetW
|
|
|
2026
2073
|
* List of all binding names that are transformed to sth like `binding = variable`.
|
|
2027
2074
|
* This applies to readonly bindings and the this binding.
|
|
2028
2075
|
*/
|
|
2029
|
-
const assignmentBindings = new Set([...oneWayBindingAttributes.keys(), 'this']);
|
|
2076
|
+
const assignmentBindings = new Set([...oneWayBindingAttributes$1.keys(), 'this']);
|
|
2030
2077
|
/**
|
|
2031
2078
|
* Transform bind:xxx into something that conforms to JSX
|
|
2032
2079
|
*/
|
|
2033
|
-
function handleBinding(htmlx, str, attr, el) {
|
|
2080
|
+
function handleBinding$1(htmlx, str, attr, el) {
|
|
2034
2081
|
//bind group on input
|
|
2035
2082
|
if (attr.name == 'group' && el.name == 'input') {
|
|
2036
2083
|
str.remove(attr.start, attr.expression.start);
|
|
@@ -2069,16 +2116,16 @@ function handleBinding(htmlx, str, attr, el) {
|
|
|
2069
2116
|
}
|
|
2070
2117
|
}
|
|
2071
2118
|
//one way binding
|
|
2072
|
-
if (oneWayBindingAttributes.has(attr.name) && el.type === 'Element') {
|
|
2119
|
+
if (oneWayBindingAttributes$1.has(attr.name) && el.type === 'Element') {
|
|
2073
2120
|
str.remove(attr.start, attr.expression.start);
|
|
2074
2121
|
str.appendLeft(attr.expression.start, '{...__sveltets_1_empty(');
|
|
2075
2122
|
if (isShortHandAttribute(attr)) {
|
|
2076
2123
|
// eslint-disable-next-line max-len
|
|
2077
|
-
str.appendLeft(attr.end, `=__sveltets_1_instanceOf(${oneWayBindingAttributes.get(attr.name)}).${attr.name})}`);
|
|
2124
|
+
str.appendLeft(attr.end, `=__sveltets_1_instanceOf(${oneWayBindingAttributes$1.get(attr.name)}).${attr.name})}`);
|
|
2078
2125
|
}
|
|
2079
2126
|
else {
|
|
2080
2127
|
// eslint-disable-next-line max-len
|
|
2081
|
-
str.overwrite(attr.expression.end, attr.end, `=__sveltets_1_instanceOf(${oneWayBindingAttributes.get(attr.name)}).${attr.name})}`);
|
|
2128
|
+
str.overwrite(attr.expression.end, attr.end, `=__sveltets_1_instanceOf(${oneWayBindingAttributes$1.get(attr.name)}).${attr.name})}`);
|
|
2082
2129
|
}
|
|
2083
2130
|
return;
|
|
2084
2131
|
}
|
|
@@ -2100,7 +2147,7 @@ function handleBinding(htmlx, str, attr, el) {
|
|
|
2100
2147
|
/**
|
|
2101
2148
|
* class:xx={yyy} ---> {...__sveltets_1_ensureType(Boolean, !!(yyy))}
|
|
2102
2149
|
*/
|
|
2103
|
-
function handleClassDirective(str, attr) {
|
|
2150
|
+
function handleClassDirective$1(str, attr) {
|
|
2104
2151
|
str.overwrite(attr.start, attr.expression.start, '{...__sveltets_1_ensureType(Boolean, !!(');
|
|
2105
2152
|
const endBrackets = '))}';
|
|
2106
2153
|
if (attr.end !== attr.expression.end) {
|
|
@@ -2114,20 +2161,29 @@ function handleClassDirective(str, attr) {
|
|
|
2114
2161
|
/**
|
|
2115
2162
|
* Removes comment
|
|
2116
2163
|
*/
|
|
2117
|
-
function handleComment(str, node) {
|
|
2164
|
+
function handleComment$1(str, node) {
|
|
2118
2165
|
str.overwrite(node.start, node.end, '', { contentOnly: true });
|
|
2119
2166
|
}
|
|
2120
2167
|
|
|
2121
2168
|
const shadowedPropsSymbol = Symbol('shadowedProps');
|
|
2122
2169
|
/**
|
|
2123
|
-
* Transforms the usage of a slot (
|
|
2170
|
+
* Transforms the usage of a slot (slot="xxx")
|
|
2171
|
+
* - transforms let:xx, {@const xx}
|
|
2124
2172
|
*/
|
|
2125
2173
|
function handleSlot(htmlx, str, slotEl, component, slotName, ifScope, templateScope) {
|
|
2126
2174
|
var _a;
|
|
2127
2175
|
//collect "let" definitions
|
|
2128
2176
|
const slotElIsComponent = slotEl === component;
|
|
2129
|
-
let
|
|
2177
|
+
let hasMovedLet = false;
|
|
2130
2178
|
let slotDefInsertionPoint;
|
|
2179
|
+
// lazily calculate insertion point only when needed
|
|
2180
|
+
const calculateSlotDefInsertionPoint = () => {
|
|
2181
|
+
slotDefInsertionPoint =
|
|
2182
|
+
slotDefInsertionPoint ||
|
|
2183
|
+
(slotElIsComponent
|
|
2184
|
+
? htmlx.lastIndexOf('>', slotEl.children[0].start) + 1
|
|
2185
|
+
: slotEl.start);
|
|
2186
|
+
};
|
|
2131
2187
|
for (const attr of slotEl.attributes) {
|
|
2132
2188
|
if (attr.type != 'Let') {
|
|
2133
2189
|
continue;
|
|
@@ -2137,19 +2193,15 @@ function handleSlot(htmlx, str, slotEl, component, slotName, ifScope, templateSc
|
|
|
2137
2193
|
str.remove(attr.start, attr.end);
|
|
2138
2194
|
continue;
|
|
2139
2195
|
}
|
|
2140
|
-
|
|
2141
|
-
slotDefInsertionPoint ||
|
|
2142
|
-
(slotElIsComponent
|
|
2143
|
-
? htmlx.lastIndexOf('>', slotEl.children[0].start) + 1
|
|
2144
|
-
: slotEl.start);
|
|
2196
|
+
calculateSlotDefInsertionPoint();
|
|
2145
2197
|
str.move(attr.start, attr.end, slotDefInsertionPoint);
|
|
2146
2198
|
//remove let:
|
|
2147
2199
|
str.remove(attr.start, attr.start + 'let:'.length);
|
|
2148
|
-
if (
|
|
2200
|
+
if (hasMovedLet) {
|
|
2149
2201
|
str.appendRight(attr.start + 'let:'.length, ', ');
|
|
2150
2202
|
}
|
|
2151
2203
|
templateScope.inits.add(((_a = attr.expression) === null || _a === void 0 ? void 0 : _a.name) || attr.name);
|
|
2152
|
-
|
|
2204
|
+
hasMovedLet = true;
|
|
2153
2205
|
if (attr.expression) {
|
|
2154
2206
|
//overwrite the = as a :
|
|
2155
2207
|
const equalSign = htmlx.lastIndexOf('=', attr.expression.start);
|
|
@@ -2158,13 +2210,34 @@ function handleSlot(htmlx, str, slotEl, component, slotName, ifScope, templateSc
|
|
|
2158
2210
|
str.remove(attr.expression.end, attr.end);
|
|
2159
2211
|
}
|
|
2160
2212
|
}
|
|
2161
|
-
|
|
2213
|
+
const hasConstTag = slotEl.children.some((child) => child.type === 'ConstTag');
|
|
2214
|
+
if (!hasMovedLet && !hasConstTag) {
|
|
2162
2215
|
return;
|
|
2163
2216
|
}
|
|
2217
|
+
calculateSlotDefInsertionPoint();
|
|
2164
2218
|
const { singleSlotDef, constRedeclares } = getSingleSlotDefAndConstsRedeclaration(component, slotName, str.original, ifScope, slotElIsComponent);
|
|
2165
2219
|
const prefix = constRedeclares ? `() => {${constRedeclares}` : '';
|
|
2166
|
-
str.appendLeft(slotDefInsertionPoint, `{${prefix}() => {
|
|
2167
|
-
|
|
2220
|
+
str.appendLeft(slotDefInsertionPoint, `{${prefix}() => { `);
|
|
2221
|
+
if (hasMovedLet) {
|
|
2222
|
+
str.appendLeft(slotDefInsertionPoint, 'let {');
|
|
2223
|
+
str.appendRight(slotDefInsertionPoint, `} = ${singleSlotDef};`);
|
|
2224
|
+
}
|
|
2225
|
+
if (hasConstTag) {
|
|
2226
|
+
// unable to move multiple codes to the same place while insert code in between
|
|
2227
|
+
// NOTE: cheat by move to `slotDefInsertionPoint + 1` position
|
|
2228
|
+
// then copy the character in str[slotDefInsertionPoint...slotDefInsertionPoint + 1] to the back
|
|
2229
|
+
// and comment out the original str[slotDefInsertionPoint...slotDefInsertionPoint + 1]
|
|
2230
|
+
str.appendRight(slotDefInsertionPoint, '/*');
|
|
2231
|
+
extractConstTags(slotEl.children).forEach((insertion) => {
|
|
2232
|
+
insertion(slotDefInsertionPoint + 1, str);
|
|
2233
|
+
});
|
|
2234
|
+
str.appendRight(slotDefInsertionPoint + 1, `${ifScope.addPossibleIfCondition()}<>`);
|
|
2235
|
+
str.appendRight(slotDefInsertionPoint + 1, str.original.slice(slotDefInsertionPoint, slotDefInsertionPoint + 1));
|
|
2236
|
+
str.appendLeft(slotDefInsertionPoint + 1, '*/');
|
|
2237
|
+
}
|
|
2238
|
+
else {
|
|
2239
|
+
str.appendRight(slotDefInsertionPoint, `${ifScope.addPossibleIfCondition()}<>`);
|
|
2240
|
+
}
|
|
2168
2241
|
const closeSlotDefInsertionPoint = slotElIsComponent
|
|
2169
2242
|
? htmlx.lastIndexOf('<', slotEl.end - 1)
|
|
2170
2243
|
: slotEl.end;
|
|
@@ -2219,7 +2292,7 @@ function handleComponent(htmlx, str, el, parent, ifScope, templateScope) {
|
|
|
2219
2292
|
* {@debug a, b} ---> {a}{b}
|
|
2220
2293
|
* tsx won't accept commas, must split
|
|
2221
2294
|
*/
|
|
2222
|
-
function handleDebug(_htmlx, str, debugBlock) {
|
|
2295
|
+
function handleDebug$1(_htmlx, str, debugBlock) {
|
|
2223
2296
|
let cursor = debugBlock.start;
|
|
2224
2297
|
for (const identifier of debugBlock.identifiers) {
|
|
2225
2298
|
str.remove(cursor, identifier.start);
|
|
@@ -2233,7 +2306,7 @@ function handleDebug(_htmlx, str, debugBlock) {
|
|
|
2233
2306
|
/**
|
|
2234
2307
|
* Transform each block into something JSX can understand.
|
|
2235
2308
|
*/
|
|
2236
|
-
function handleEach(htmlx, str, eachBlock, ifScope) {
|
|
2309
|
+
function handleEach$1(htmlx, str, eachBlock, ifScope) {
|
|
2237
2310
|
// {#each items as item,i (key)} ->
|
|
2238
2311
|
// {__sveltets_1_each(items, (item,i) => (key) && (possible if expression &&) <>
|
|
2239
2312
|
const constRedeclares = ifScope.getConstDeclaration();
|
|
@@ -2250,7 +2323,11 @@ function handleEach(htmlx, str, eachBlock, ifScope) {
|
|
|
2250
2323
|
const idxLoc = htmlx.indexOf(eachBlock.index, contextEnd);
|
|
2251
2324
|
contextEnd = idxLoc + eachBlock.index.length;
|
|
2252
2325
|
}
|
|
2253
|
-
|
|
2326
|
+
const constTags = extractConstTags(eachBlock.children);
|
|
2327
|
+
str.prependLeft(contextEnd, ') =>' + (constTags.length ? ' {' : ''));
|
|
2328
|
+
constTags.forEach((insertion) => {
|
|
2329
|
+
insertion(contextEnd, str);
|
|
2330
|
+
});
|
|
2254
2331
|
if (eachBlock.key) {
|
|
2255
2332
|
const endEachStart = htmlx.indexOf('}', eachBlock.key.end);
|
|
2256
2333
|
str.overwrite(endEachStart, endEachStart + 1, ` && ${ifScope.addPossibleIfCondition()}<>`);
|
|
@@ -2260,8 +2337,8 @@ function handleEach(htmlx, str, eachBlock, ifScope) {
|
|
|
2260
2337
|
str.overwrite(endEachStart, endEachStart + 1, ` ${ifScope.addPossibleIfCondition()}<>`);
|
|
2261
2338
|
}
|
|
2262
2339
|
const endEach = htmlx.lastIndexOf('{', eachBlock.end - 1);
|
|
2263
|
-
const suffix = constRedeclares ? '
|
|
2264
|
-
// {/each} -> </>)} or {:else} -> </>)}
|
|
2340
|
+
const suffix = '</>' + (constTags.length ? '}' : '') + (constRedeclares ? ')}}}' : ')}');
|
|
2341
|
+
// {/each} -> </>})} or {:else} -> </>})}
|
|
2265
2342
|
if (eachBlock.else) {
|
|
2266
2343
|
const elseEnd = htmlx.lastIndexOf('}', eachBlock.else.start);
|
|
2267
2344
|
const elseStart = htmlx.lastIndexOf('{', elseEnd);
|
|
@@ -2299,7 +2376,7 @@ function handleElement(htmlx, str, node, parent, ifScope, templateScope) {
|
|
|
2299
2376
|
* - For DOM elements: ---> onxxx={yyy}
|
|
2300
2377
|
* - For Svelte components/special elements: ---> {__sveltets_1_instanceOf(..ComponentType..).$on("xxx", yyy)}
|
|
2301
2378
|
*/
|
|
2302
|
-
function handleEventHandler(htmlx, str, attr, parent) {
|
|
2379
|
+
function handleEventHandler$1(htmlx, str, attr, parent) {
|
|
2303
2380
|
const jsxEventName = attr.name;
|
|
2304
2381
|
if (['Element', 'Window', 'Body'].includes(parent.type) /*&& KnownEvents.indexOf('on'+jsxEventName) >= 0*/) {
|
|
2305
2382
|
if (attr.expression) {
|
|
@@ -2338,7 +2415,7 @@ function handleEventHandler(htmlx, str, attr, parent) {
|
|
|
2338
2415
|
/**
|
|
2339
2416
|
* {# if ...}...{/if} ---> {() => {if(...){<>...</>}}}
|
|
2340
2417
|
*/
|
|
2341
|
-
function handleIf(htmlx, str, ifBlock, ifScope) {
|
|
2418
|
+
function handleIf$1(htmlx, str, ifBlock, ifScope) {
|
|
2342
2419
|
const endIf = htmlx.lastIndexOf('{', ifBlock.end - 1);
|
|
2343
2420
|
if (ifBlock.elseif) {
|
|
2344
2421
|
// {:else if expr} -> : (expr) ? <>
|
|
@@ -2369,7 +2446,7 @@ function handleIf(htmlx, str, ifBlock, ifScope) {
|
|
|
2369
2446
|
/**
|
|
2370
2447
|
* {:else} ---> </> : <>
|
|
2371
2448
|
*/
|
|
2372
|
-
function handleElse(htmlx, str, elseBlock, parent, ifScope) {
|
|
2449
|
+
function handleElse$1(htmlx, str, elseBlock, parent, ifScope) {
|
|
2373
2450
|
var _a, _b;
|
|
2374
2451
|
if (parent.type !== 'IfBlock' ||
|
|
2375
2452
|
(((_a = elseBlock.children[0]) === null || _a === void 0 ? void 0 : _a.type) === 'IfBlock' && ((_b = elseBlock.children[0]) === null || _b === void 0 ? void 0 : _b.elseif))) {
|
|
@@ -2661,7 +2738,7 @@ class IfScope {
|
|
|
2661
2738
|
/**
|
|
2662
2739
|
* {#key expr}content{/key} ---> {expr} content
|
|
2663
2740
|
*/
|
|
2664
|
-
function handleKey(htmlx, str, keyBlock) {
|
|
2741
|
+
function handleKey$1(htmlx, str, keyBlock) {
|
|
2665
2742
|
// {#key expr} -> {expr}
|
|
2666
2743
|
str.overwrite(keyBlock.start, keyBlock.expression.start, '{');
|
|
2667
2744
|
const end = htmlx.indexOf('}', keyBlock.expression.end);
|
|
@@ -2674,11 +2751,45 @@ function handleKey(htmlx, str, keyBlock) {
|
|
|
2674
2751
|
/**
|
|
2675
2752
|
* {@html ...} ---> {...}
|
|
2676
2753
|
*/
|
|
2677
|
-
function handleRawHtml(htmlx, str, rawBlock) {
|
|
2754
|
+
function handleRawHtml$1(htmlx, str, rawBlock) {
|
|
2678
2755
|
const tokenStart = htmlx.indexOf('@html', rawBlock.start);
|
|
2679
2756
|
str.remove(tokenStart, tokenStart + '@html'.length);
|
|
2680
2757
|
}
|
|
2681
2758
|
|
|
2759
|
+
/**
|
|
2760
|
+
* style:xx ---> __sveltets_1_ensureType(String, Number, xx);
|
|
2761
|
+
* style:xx={yy} ---> __sveltets_1_ensureType(String, Number, yy);
|
|
2762
|
+
* style:xx="yy" ---> __sveltets_1_ensureType(String, Number, "yy");
|
|
2763
|
+
* style:xx="a{b}" ---> __sveltets_1_ensureType(String, Number, `a${b}`);
|
|
2764
|
+
*/
|
|
2765
|
+
function handleStyleDirective$1(str, style) {
|
|
2766
|
+
const htmlx = str.original;
|
|
2767
|
+
if (style.value === true || style.value.length === 0) {
|
|
2768
|
+
str.overwrite(style.start, htmlx.indexOf(':', style.start) + 1, '{...__sveltets_1_ensureType(String, Number, ');
|
|
2769
|
+
str.appendLeft(style.end, ')}');
|
|
2770
|
+
return;
|
|
2771
|
+
}
|
|
2772
|
+
if (style.value.length > 1) {
|
|
2773
|
+
buildTemplateString(style, str, htmlx, '{...__sveltets_1_ensureType(String, Number, `', '`)}', style.start);
|
|
2774
|
+
return;
|
|
2775
|
+
}
|
|
2776
|
+
const styleVal = style.value[0];
|
|
2777
|
+
if (styleVal.type === 'Text') {
|
|
2778
|
+
str.overwrite(style.start, styleVal.start, '{...__sveltets_1_ensureType(String, Number, "');
|
|
2779
|
+
if (styleVal.end === style.end) {
|
|
2780
|
+
str.appendLeft(style.end, '")}');
|
|
2781
|
+
}
|
|
2782
|
+
else {
|
|
2783
|
+
str.overwrite(styleVal.end, style.end, '")}');
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
else {
|
|
2787
|
+
// MustacheTag
|
|
2788
|
+
str.overwrite(style.start, styleVal.start + 1, '{...__sveltets_1_ensureType(String, Number, ');
|
|
2789
|
+
str.overwrite(styleVal.end - 1, style.end, ')}');
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2682
2793
|
/**
|
|
2683
2794
|
* `<svelte:window>...</svelte:window>` ----> `<sveltewindow>...</sveltewindow>`
|
|
2684
2795
|
* (same for :head, :body, :options, :fragment)
|
|
@@ -2753,135 +2864,1558 @@ function extract_identifiers(param, nodes = []) {
|
|
|
2753
2864
|
return nodes;
|
|
2754
2865
|
}
|
|
2755
2866
|
|
|
2756
|
-
class TemplateScope$1 {
|
|
2757
|
-
constructor(parent) {
|
|
2758
|
-
this.inits = new Set();
|
|
2759
|
-
this.parent = parent;
|
|
2867
|
+
class TemplateScope$1 {
|
|
2868
|
+
constructor(parent) {
|
|
2869
|
+
this.inits = new Set();
|
|
2870
|
+
this.parent = parent;
|
|
2871
|
+
}
|
|
2872
|
+
child() {
|
|
2873
|
+
const child = new TemplateScope$1(this);
|
|
2874
|
+
return child;
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
class TemplateScopeManager {
|
|
2878
|
+
constructor() {
|
|
2879
|
+
this.value = new TemplateScope$1();
|
|
2880
|
+
}
|
|
2881
|
+
eachEnter(node) {
|
|
2882
|
+
this.value = this.value.child();
|
|
2883
|
+
if (node.context) {
|
|
2884
|
+
this.handleScope(node.context, node.children);
|
|
2885
|
+
}
|
|
2886
|
+
if (node.index) {
|
|
2887
|
+
this.value.inits.add(node.index);
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
eachLeave(node) {
|
|
2891
|
+
if (!node.else) {
|
|
2892
|
+
this.value = this.value.parent;
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
awaitEnter(node) {
|
|
2896
|
+
var _a;
|
|
2897
|
+
this.value = this.value.child();
|
|
2898
|
+
if (node.value) {
|
|
2899
|
+
this.handleScope(node.value, (_a = node.then) === null || _a === void 0 ? void 0 : _a.children);
|
|
2900
|
+
}
|
|
2901
|
+
if (node.error) {
|
|
2902
|
+
this.handleScope(node.error, []);
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
awaitPendingEnter(node, parent) {
|
|
2906
|
+
if (node.skip || parent.type !== 'AwaitBlock') {
|
|
2907
|
+
return;
|
|
2908
|
+
}
|
|
2909
|
+
// Reset inits, as pending can have no inits
|
|
2910
|
+
this.value.inits.clear();
|
|
2911
|
+
}
|
|
2912
|
+
awaitThenEnter(node, parent) {
|
|
2913
|
+
if (node.skip || parent.type !== 'AwaitBlock') {
|
|
2914
|
+
return;
|
|
2915
|
+
}
|
|
2916
|
+
// Reset inits, this time only taking the then
|
|
2917
|
+
// scope into account.
|
|
2918
|
+
this.value.inits.clear();
|
|
2919
|
+
if (parent.value) {
|
|
2920
|
+
this.handleScope(parent.value, node.children);
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
awaitCatchEnter(node, parent) {
|
|
2924
|
+
if (node.skip || parent.type !== 'AwaitBlock') {
|
|
2925
|
+
return;
|
|
2926
|
+
}
|
|
2927
|
+
// Reset inits, this time only taking the error
|
|
2928
|
+
// scope into account.
|
|
2929
|
+
this.value.inits.clear();
|
|
2930
|
+
if (parent.error) {
|
|
2931
|
+
this.handleScope(parent.error, node.children);
|
|
2932
|
+
}
|
|
2933
|
+
}
|
|
2934
|
+
awaitLeave() {
|
|
2935
|
+
this.value = this.value.parent;
|
|
2936
|
+
}
|
|
2937
|
+
elseEnter(parent) {
|
|
2938
|
+
if (parent.type === 'EachBlock') {
|
|
2939
|
+
this.value = this.value.parent;
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2942
|
+
componentOrSlotTemplateOrElementEnter(node) {
|
|
2943
|
+
var _a;
|
|
2944
|
+
const hasConstTags = (_a = node.children) === null || _a === void 0 ? void 0 : _a.some((child) => child.type === 'ConstTag');
|
|
2945
|
+
if (usesLet(node) || hasConstTags) {
|
|
2946
|
+
this.value = this.value.child();
|
|
2947
|
+
this.handleScope({}, node.children);
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
componentOrSlotTemplateOrElementLeave(node) {
|
|
2951
|
+
if (usesLet(node)) {
|
|
2952
|
+
this.value = this.value.parent;
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
handleScope(identifierDef, children) {
|
|
2956
|
+
if (isIdentifier(identifierDef)) {
|
|
2957
|
+
this.value.inits.add(identifierDef.name);
|
|
2958
|
+
}
|
|
2959
|
+
if (isDestructuringPatterns(identifierDef)) {
|
|
2960
|
+
// the node object is returned as-it with no mutation
|
|
2961
|
+
const identifiers = extract_identifiers(identifierDef);
|
|
2962
|
+
identifiers.forEach((id) => this.value.inits.add(id.name));
|
|
2963
|
+
}
|
|
2964
|
+
if (children === null || children === void 0 ? void 0 : children.length) {
|
|
2965
|
+
children.forEach((child) => {
|
|
2966
|
+
if (child.type === 'ConstTag') {
|
|
2967
|
+
const identifiers = extract_identifiers(child.expression.left);
|
|
2968
|
+
identifiers.forEach((id) => this.value.inits.add(id.name));
|
|
2969
|
+
}
|
|
2970
|
+
});
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
|
|
2975
|
+
function handleText$1(str, node) {
|
|
2976
|
+
if (!node.data) {
|
|
2977
|
+
return;
|
|
2978
|
+
}
|
|
2979
|
+
const needsRemoves = ['}', '>'];
|
|
2980
|
+
for (const token of needsRemoves) {
|
|
2981
|
+
let index = node.data.indexOf(token);
|
|
2982
|
+
while (index >= 0) {
|
|
2983
|
+
str.remove(index + node.start, index + node.start + 1);
|
|
2984
|
+
index = node.data.indexOf(token, index + 1);
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
|
|
2989
|
+
/**
|
|
2990
|
+
* transition:xxx(yyy) ---> {...__sveltets_1_ensureTransition(xxx(__sveltets_1_mapElementTag('..'),(yyy)))}
|
|
2991
|
+
*/
|
|
2992
|
+
function handleTransitionDirective$1(htmlx, str, attr, parent) {
|
|
2993
|
+
str.overwrite(attr.start, htmlx.indexOf(':', attr.start) + 1, '{...__sveltets_1_ensureTransition(');
|
|
2994
|
+
if (attr.modifiers.length) {
|
|
2995
|
+
const local = htmlx.indexOf('|', attr.start);
|
|
2996
|
+
str.remove(local, attr.expression ? attr.expression.start : attr.end);
|
|
2997
|
+
}
|
|
2998
|
+
const nodeType = `__sveltets_1_mapElementTag('${parent.name}')`;
|
|
2999
|
+
if (!attr.expression) {
|
|
3000
|
+
str.appendLeft(attr.end, `(${nodeType},{}))}`);
|
|
3001
|
+
return;
|
|
3002
|
+
}
|
|
3003
|
+
str.overwrite(htmlx.indexOf(':', attr.start) + 1 + `${attr.name}`.length, attr.expression.start, `(${nodeType},(`);
|
|
3004
|
+
str.appendLeft(attr.expression.end, ')))');
|
|
3005
|
+
if (isQuote(htmlx[attr.end - 1])) {
|
|
3006
|
+
str.remove(attr.end - 1, attr.end);
|
|
3007
|
+
}
|
|
3008
|
+
}
|
|
3009
|
+
|
|
3010
|
+
function stripDoctype$1(str) {
|
|
3011
|
+
const regex = /<!doctype(.+?)>(\n)?/i;
|
|
3012
|
+
const result = regex.exec(str.original);
|
|
3013
|
+
if (result) {
|
|
3014
|
+
str.remove(result.index, result.index + result[0].length);
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
3017
|
+
/**
|
|
3018
|
+
* Walks the HTMLx part of the Svelte component
|
|
3019
|
+
* and converts it to JSX
|
|
3020
|
+
*/
|
|
3021
|
+
function convertHtmlxToJsx$1(str, ast, onWalk = null, onLeave = null, options = {}) {
|
|
3022
|
+
const htmlx = str.original;
|
|
3023
|
+
stripDoctype$1(str);
|
|
3024
|
+
str.prepend('<>');
|
|
3025
|
+
str.append('</>');
|
|
3026
|
+
const templateScopeManager = new TemplateScopeManager();
|
|
3027
|
+
let ifScope = new IfScope(templateScopeManager);
|
|
3028
|
+
compiler.walk(ast, {
|
|
3029
|
+
enter: (node, parent, prop, index) => {
|
|
3030
|
+
try {
|
|
3031
|
+
switch (node.type) {
|
|
3032
|
+
case 'IfBlock':
|
|
3033
|
+
handleIf$1(htmlx, str, node, ifScope);
|
|
3034
|
+
if (!node.elseif) {
|
|
3035
|
+
ifScope = ifScope.getChild();
|
|
3036
|
+
}
|
|
3037
|
+
break;
|
|
3038
|
+
case 'EachBlock':
|
|
3039
|
+
templateScopeManager.eachEnter(node);
|
|
3040
|
+
handleEach$1(htmlx, str, node, ifScope);
|
|
3041
|
+
break;
|
|
3042
|
+
case 'ElseBlock':
|
|
3043
|
+
templateScopeManager.elseEnter(parent);
|
|
3044
|
+
handleElse$1(htmlx, str, node, parent, ifScope);
|
|
3045
|
+
break;
|
|
3046
|
+
case 'AwaitBlock':
|
|
3047
|
+
handleAwait$1(htmlx, str, node, ifScope, templateScopeManager);
|
|
3048
|
+
break;
|
|
3049
|
+
case 'PendingBlock':
|
|
3050
|
+
templateScopeManager.awaitPendingEnter(node, parent);
|
|
3051
|
+
handleAwaitPending(parent, htmlx, str, ifScope);
|
|
3052
|
+
break;
|
|
3053
|
+
case 'ThenBlock':
|
|
3054
|
+
templateScopeManager.awaitThenEnter(node, parent);
|
|
3055
|
+
handleAwaitThen(parent, htmlx, str, ifScope);
|
|
3056
|
+
break;
|
|
3057
|
+
case 'CatchBlock':
|
|
3058
|
+
templateScopeManager.awaitCatchEnter(node, parent);
|
|
3059
|
+
handleAwaitCatch(parent, htmlx, str, ifScope);
|
|
3060
|
+
break;
|
|
3061
|
+
case 'KeyBlock':
|
|
3062
|
+
handleKey$1(htmlx, str, node);
|
|
3063
|
+
break;
|
|
3064
|
+
case 'RawMustacheTag':
|
|
3065
|
+
handleRawHtml$1(htmlx, str, node);
|
|
3066
|
+
break;
|
|
3067
|
+
case 'DebugTag':
|
|
3068
|
+
handleDebug$1(htmlx, str, node);
|
|
3069
|
+
break;
|
|
3070
|
+
case 'InlineComponent':
|
|
3071
|
+
templateScopeManager.componentOrSlotTemplateOrElementEnter(node);
|
|
3072
|
+
handleComponent(htmlx, str, node, parent, ifScope, templateScopeManager.value);
|
|
3073
|
+
break;
|
|
3074
|
+
case 'Element':
|
|
3075
|
+
templateScopeManager.componentOrSlotTemplateOrElementEnter(node);
|
|
3076
|
+
handleElement(htmlx, str, node, parent, ifScope, templateScopeManager.value);
|
|
3077
|
+
break;
|
|
3078
|
+
case 'Comment':
|
|
3079
|
+
handleComment$1(str, node);
|
|
3080
|
+
break;
|
|
3081
|
+
case 'Binding':
|
|
3082
|
+
handleBinding$1(htmlx, str, node, parent);
|
|
3083
|
+
break;
|
|
3084
|
+
case 'Class':
|
|
3085
|
+
handleClassDirective$1(str, node);
|
|
3086
|
+
break;
|
|
3087
|
+
case 'StyleDirective':
|
|
3088
|
+
handleStyleDirective$1(str, node);
|
|
3089
|
+
break;
|
|
3090
|
+
case 'Action':
|
|
3091
|
+
handleActionDirective$1(htmlx, str, node, parent);
|
|
3092
|
+
break;
|
|
3093
|
+
case 'Transition':
|
|
3094
|
+
handleTransitionDirective$1(htmlx, str, node, parent);
|
|
3095
|
+
break;
|
|
3096
|
+
case 'Animation':
|
|
3097
|
+
handleAnimateDirective$1(htmlx, str, node, parent);
|
|
3098
|
+
break;
|
|
3099
|
+
case 'Attribute':
|
|
3100
|
+
handleAttribute$1(htmlx, str, node, parent, options.preserveAttributeCase);
|
|
3101
|
+
break;
|
|
3102
|
+
case 'EventHandler':
|
|
3103
|
+
handleEventHandler$1(htmlx, str, node, parent);
|
|
3104
|
+
break;
|
|
3105
|
+
case 'Options':
|
|
3106
|
+
handleSvelteTag(htmlx, str, node);
|
|
3107
|
+
break;
|
|
3108
|
+
case 'Window':
|
|
3109
|
+
handleSvelteTag(htmlx, str, node);
|
|
3110
|
+
break;
|
|
3111
|
+
case 'Head':
|
|
3112
|
+
handleSvelteTag(htmlx, str, node);
|
|
3113
|
+
break;
|
|
3114
|
+
case 'Body':
|
|
3115
|
+
handleSvelteTag(htmlx, str, node);
|
|
3116
|
+
break;
|
|
3117
|
+
case 'SlotTemplate':
|
|
3118
|
+
handleSvelteTag(htmlx, str, node);
|
|
3119
|
+
templateScopeManager.componentOrSlotTemplateOrElementEnter(node);
|
|
3120
|
+
handleSlot(htmlx, str, node, parent, getSlotName(node) || 'default', ifScope, templateScopeManager.value);
|
|
3121
|
+
break;
|
|
3122
|
+
case 'Text':
|
|
3123
|
+
handleText$1(str, node);
|
|
3124
|
+
break;
|
|
3125
|
+
}
|
|
3126
|
+
if (onWalk) {
|
|
3127
|
+
onWalk(node, parent, prop, index);
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3130
|
+
catch (e) {
|
|
3131
|
+
console.error('Error walking node ', node, e);
|
|
3132
|
+
throw e;
|
|
3133
|
+
}
|
|
3134
|
+
},
|
|
3135
|
+
leave: (node, parent, prop, index) => {
|
|
3136
|
+
try {
|
|
3137
|
+
switch (node.type) {
|
|
3138
|
+
case 'IfBlock':
|
|
3139
|
+
if (!node.elseif) {
|
|
3140
|
+
ifScope = ifScope.getParent();
|
|
3141
|
+
}
|
|
3142
|
+
break;
|
|
3143
|
+
case 'EachBlock':
|
|
3144
|
+
templateScopeManager.eachLeave(node);
|
|
3145
|
+
break;
|
|
3146
|
+
case 'AwaitBlock':
|
|
3147
|
+
templateScopeManager.awaitLeave();
|
|
3148
|
+
break;
|
|
3149
|
+
case 'InlineComponent':
|
|
3150
|
+
case 'Element':
|
|
3151
|
+
case 'SlotTemplate':
|
|
3152
|
+
templateScopeManager.componentOrSlotTemplateOrElementLeave(node);
|
|
3153
|
+
break;
|
|
3154
|
+
}
|
|
3155
|
+
if (onLeave) {
|
|
3156
|
+
onLeave(node, parent, prop, index);
|
|
3157
|
+
}
|
|
3158
|
+
}
|
|
3159
|
+
catch (e) {
|
|
3160
|
+
console.error('Error leaving node ', node);
|
|
3161
|
+
throw e;
|
|
3162
|
+
}
|
|
3163
|
+
}
|
|
3164
|
+
});
|
|
3165
|
+
}
|
|
3166
|
+
|
|
3167
|
+
/**
|
|
3168
|
+
* Moves or inserts text to the specified end in order.
|
|
3169
|
+
* "In order" means that the transformation of the text before
|
|
3170
|
+
* the given position reads exactly what was moved/inserted
|
|
3171
|
+
* from left to right.
|
|
3172
|
+
* After the transformation is done, everything inside the start-end-range that was
|
|
3173
|
+
* not moved will be removed. If there's a delete position given, things will be moved
|
|
3174
|
+
* to the end first before getting deleted. This may ensure better mappings for auto completion
|
|
3175
|
+
* for example.
|
|
3176
|
+
*/
|
|
3177
|
+
function transform(str, start, end, _xxx, // TODO
|
|
3178
|
+
transformations) {
|
|
3179
|
+
const moves = [];
|
|
3180
|
+
let appendPosition = end;
|
|
3181
|
+
let ignoreNextString = false;
|
|
3182
|
+
let deletePos;
|
|
3183
|
+
let deleteDest;
|
|
3184
|
+
for (let i = 0; i < transformations.length; i++) {
|
|
3185
|
+
const transformation = transformations[i];
|
|
3186
|
+
if (typeof transformation === 'number') {
|
|
3187
|
+
deletePos = moves.length;
|
|
3188
|
+
deleteDest = transformation;
|
|
3189
|
+
}
|
|
3190
|
+
else if (typeof transformation === 'string') {
|
|
3191
|
+
if (!ignoreNextString) {
|
|
3192
|
+
str.appendLeft(appendPosition, transformation);
|
|
3193
|
+
}
|
|
3194
|
+
ignoreNextString = false;
|
|
3195
|
+
}
|
|
3196
|
+
else {
|
|
3197
|
+
const tStart = transformation[0];
|
|
3198
|
+
let tEnd = transformation[1];
|
|
3199
|
+
if (tStart === tEnd) {
|
|
3200
|
+
// zero-range selection, don't move, it would
|
|
3201
|
+
// cause bugs and isn't necessary anyway
|
|
3202
|
+
continue;
|
|
3203
|
+
}
|
|
3204
|
+
if (tEnd < end - 1 &&
|
|
3205
|
+
// TODO can we somehow make this more performant?
|
|
3206
|
+
!transformations.some((t) => typeof t !== 'string' && (t[0] === tEnd + 1 || t[0] === tEnd))) {
|
|
3207
|
+
tEnd += 1;
|
|
3208
|
+
const next = transformations[i + 1];
|
|
3209
|
+
ignoreNextString = typeof next === 'string';
|
|
3210
|
+
// Do not append the next string, rather overwrite the next character. This ensures
|
|
3211
|
+
// that mappings of the string afterwards are not mapped to a previous character, making
|
|
3212
|
+
// mappings of ranges one character too short. If there's no string in the next transformation,
|
|
3213
|
+
// completely delete the first character afterwards. This also makes the mapping more correct,
|
|
3214
|
+
// so that autocompletion triggered on the last character works correctly.
|
|
3215
|
+
const overwrite = typeof next === 'string' ? next : '';
|
|
3216
|
+
str.overwrite(tEnd - 1, tEnd, overwrite, { contentOnly: true });
|
|
3217
|
+
}
|
|
3218
|
+
appendPosition = ignoreNextString ? tEnd : transformation[1];
|
|
3219
|
+
moves.push([tStart, tEnd]);
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
deletePos = deletePos !== null && deletePos !== void 0 ? deletePos : moves.length;
|
|
3223
|
+
for (let i = 0; i < deletePos; i++) {
|
|
3224
|
+
str.move(moves[i][0], moves[i][1], end);
|
|
3225
|
+
}
|
|
3226
|
+
let removeStart = start;
|
|
3227
|
+
for (const transformation of [...moves].sort((t1, t2) => t1[0] - t2[0])) {
|
|
3228
|
+
if (removeStart < transformation[0]) {
|
|
3229
|
+
if (deletePos !== moves.length && removeStart > deleteDest) {
|
|
3230
|
+
str.move(removeStart, transformation[0], end);
|
|
3231
|
+
}
|
|
3232
|
+
// Use one space because of hover etc: This will make map deleted characters to the whitespace
|
|
3233
|
+
str.overwrite(removeStart, transformation[0], ' ', { contentOnly: true });
|
|
3234
|
+
}
|
|
3235
|
+
removeStart = transformation[1];
|
|
3236
|
+
}
|
|
3237
|
+
if (removeStart < end) {
|
|
3238
|
+
// Completely delete the first character afterwards. This makes the mapping more correct,
|
|
3239
|
+
// so that autocompletion triggered on the last character works correctly.
|
|
3240
|
+
str.overwrite(removeStart, removeStart + 1, '', { contentOnly: true });
|
|
3241
|
+
removeStart++;
|
|
3242
|
+
}
|
|
3243
|
+
if (removeStart < end) {
|
|
3244
|
+
// Use one space because of hover etc: This will map deleted characters to the whitespace
|
|
3245
|
+
if (deletePos !== moves.length && removeStart > deleteDest && removeStart + 1 < end) {
|
|
3246
|
+
// Can only move stuff up to the end, not including, else we get a "cannot move inside itself" error
|
|
3247
|
+
str.move(removeStart, end - 1, end);
|
|
3248
|
+
str.overwrite(removeStart, end - 1, ' ', { contentOnly: true });
|
|
3249
|
+
str.overwrite(end - 1, end, '', { contentOnly: true });
|
|
3250
|
+
}
|
|
3251
|
+
else {
|
|
3252
|
+
str.overwrite(removeStart, end, ' ', { contentOnly: true });
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
for (let i = deletePos; i < moves.length; i++) {
|
|
3256
|
+
str.move(moves[i][0], moves[i][1], end);
|
|
3257
|
+
}
|
|
3258
|
+
}
|
|
3259
|
+
/**
|
|
3260
|
+
* Surrounds given range with a prefix and suffix. This is benefitial
|
|
3261
|
+
* for better mappings in some cases. Example: If we transform `foo` to `"foo"`
|
|
3262
|
+
* and if TS underlines the whole `"foo"`, we need to make sure that the quotes
|
|
3263
|
+
* are also mapped to the correct positions.
|
|
3264
|
+
* Returns the input start/end transformation for convenience.
|
|
3265
|
+
*/
|
|
3266
|
+
function surroundWith(str, [start, end], prefix, suffix) {
|
|
3267
|
+
if (start + 1 === end) {
|
|
3268
|
+
str.overwrite(start, end, `${prefix}${str.original.charAt(start)}${suffix}`, {
|
|
3269
|
+
contentOnly: true
|
|
3270
|
+
});
|
|
3271
|
+
}
|
|
3272
|
+
else {
|
|
3273
|
+
str.overwrite(start, start + 1, `${prefix}${str.original.charAt(start)}`, {
|
|
3274
|
+
contentOnly: true
|
|
3275
|
+
});
|
|
3276
|
+
str.overwrite(end - 1, end, `${str.original.charAt(end - 1)}${suffix}`, {
|
|
3277
|
+
contentOnly: true
|
|
3278
|
+
});
|
|
3279
|
+
}
|
|
3280
|
+
return [start, end];
|
|
3281
|
+
}
|
|
3282
|
+
/**
|
|
3283
|
+
* Returns the [start, end] indexes of a directive (action,animation,etc) name.
|
|
3284
|
+
* Example: use:foo --> [startOfFoo, endOfFoo]
|
|
3285
|
+
*/
|
|
3286
|
+
function getDirectiveNameStartEndIdx(str, node) {
|
|
3287
|
+
const colonIdx = str.original.indexOf(':', node.start);
|
|
3288
|
+
return [colonIdx + 1, colonIdx + 1 + `${node.name}`.length];
|
|
3289
|
+
}
|
|
3290
|
+
/**
|
|
3291
|
+
* Removes characters from the string that are invalid for TS variable names.
|
|
3292
|
+
* Careful: This does not check if the leading character
|
|
3293
|
+
* is valid (numerical values aren't for example).
|
|
3294
|
+
*/
|
|
3295
|
+
function sanitizePropName(name) {
|
|
3296
|
+
return name
|
|
3297
|
+
.split('')
|
|
3298
|
+
.map((char) => (/[0-9A-Za-z$_]/.test(char) ? char : '_'))
|
|
3299
|
+
.join('');
|
|
3300
|
+
}
|
|
3301
|
+
|
|
3302
|
+
/**
|
|
3303
|
+
* use:xxx={params} ---> __sveltets_2_ensureAction(xxx(svelte.mapElementTag('ParentNodeName'),(params)));
|
|
3304
|
+
*/
|
|
3305
|
+
function handleActionDirective(str, attr, element) {
|
|
3306
|
+
const transformations = [
|
|
3307
|
+
'__sveltets_2_ensureAction(',
|
|
3308
|
+
getDirectiveNameStartEndIdx(str, attr),
|
|
3309
|
+
`(${element.typingsNamespace}.mapElementTag('${element.tagName}')`
|
|
3310
|
+
];
|
|
3311
|
+
if (attr.expression) {
|
|
3312
|
+
transformations.push(',(', [attr.expression.start, attr.expression.end], ')');
|
|
3313
|
+
}
|
|
3314
|
+
transformations.push('));');
|
|
3315
|
+
element.appendToStartEnd(transformations);
|
|
3316
|
+
}
|
|
3317
|
+
|
|
3318
|
+
/**
|
|
3319
|
+
* animate:xxx(yyy) ---> __sveltets_2_ensureAnimation(xxx(svelte.mapElementTag('..'),__sveltets_2_AnimationMove,(yyy)));
|
|
3320
|
+
*/
|
|
3321
|
+
function handleAnimateDirective(str, attr, element) {
|
|
3322
|
+
const transformations = [
|
|
3323
|
+
'__sveltets_2_ensureAnimation(',
|
|
3324
|
+
getDirectiveNameStartEndIdx(str, attr),
|
|
3325
|
+
`(${element.typingsNamespace}.mapElementTag('${element.tagName}'),__sveltets_2_AnimationMove`
|
|
3326
|
+
];
|
|
3327
|
+
if (attr.expression) {
|
|
3328
|
+
transformations.push(',(', [attr.expression.start, attr.expression.end], ')');
|
|
3329
|
+
}
|
|
3330
|
+
transformations.push('));');
|
|
3331
|
+
element.appendToStartEnd(transformations);
|
|
3332
|
+
}
|
|
3333
|
+
|
|
3334
|
+
var svgAttributes = 'accent-height accumulate additive alignment-baseline allowReorder alphabetic amplitude arabic-form ascent attributeName attributeType autoReverse azimuth baseFrequency baseline-shift baseProfile bbox begin bias by calcMode cap-height class clip clipPathUnits clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominant-baseline dur dx dy edgeMode elevation enable-background end exponent externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format from fr fx fy g1 g2 glyph-name glyph-orientation-horizontal glyph-orientation-vertical glyphRef gradientTransform gradientUnits hanging height href horiz-adv-x horiz-origin-x id ideographic image-rendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lang lengthAdjust letter-spacing lighting-color limitingConeAngle local marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical max media method min mode name numOctaves offset onabort onactivate onbegin onclick onend onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onrepeat onresize onscroll onunload opacity operator order orient orientation origin overflow overline-position overline-thickness panose-1 paint-order pathLength patternContentUnits patternTransform patternUnits pointer-events points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY rendering-intent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shape-rendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stop-color stop-opacity strikethrough-position strikethrough-thickness string stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale systemLanguage tabindex tableValues target targetX targetY text-anchor text-decoration text-rendering textLength to transform type u1 u2 underline-position underline-thickness unicode unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical values version vert-adv-y vert-origin-x vert-origin-y viewBox viewTarget visibility width widths word-spacing writing-mode x x-height x1 x2 xChannelSelector xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y y1 y2 yChannelSelector z zoomAndPan'.split(' ');
|
|
3335
|
+
|
|
3336
|
+
const voidTags = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr'.split(',');
|
|
3337
|
+
/**
|
|
3338
|
+
* Handles HTML elements as well as svelte:options, svelte:head, svelte:window, svelte:body
|
|
3339
|
+
*
|
|
3340
|
+
* Children of this element should call the methods on this class to add themselves to the correct
|
|
3341
|
+
* position within the transformation.
|
|
3342
|
+
*
|
|
3343
|
+
* The transformation result does not have anything to do with HTMLx, it instead uses plan JS,
|
|
3344
|
+
* leveraging scoped blocks (`{ ... }`). Each element is transformed to something that is
|
|
3345
|
+
* contained in such a block. This ensures we can declare variables inside that do not leak
|
|
3346
|
+
* to the outside while preserving TypeScript's control flow.
|
|
3347
|
+
*
|
|
3348
|
+
* A transformation reads for example like this:
|
|
3349
|
+
* ```
|
|
3350
|
+
* // before
|
|
3351
|
+
* <div class={foo} />
|
|
3352
|
+
* // after
|
|
3353
|
+
* { const $$_div = __sveltets_2_createElement("div", {"class": foo,}); }
|
|
3354
|
+
* ```
|
|
3355
|
+
*/
|
|
3356
|
+
class Element {
|
|
3357
|
+
/**
|
|
3358
|
+
* @param str The MagicString instance used to manipulate the text
|
|
3359
|
+
* @param node The Svelte AST node that represents this element
|
|
3360
|
+
* @param typingsNamespace Determines which namespace to use for the createElement function
|
|
3361
|
+
* @param parent The Svelte AST parent node
|
|
3362
|
+
*/
|
|
3363
|
+
constructor(str, node, typingsNamespace, parent) {
|
|
3364
|
+
var _a, _b;
|
|
3365
|
+
this.str = str;
|
|
3366
|
+
this.node = node;
|
|
3367
|
+
this.typingsNamespace = typingsNamespace;
|
|
3368
|
+
this.parent = parent;
|
|
3369
|
+
this.startTransformation = [];
|
|
3370
|
+
this.startEndTransformation = ['});'];
|
|
3371
|
+
this.attrsTransformation = [];
|
|
3372
|
+
this.endTransformation = [];
|
|
3373
|
+
if (parent) {
|
|
3374
|
+
parent.child = this;
|
|
3375
|
+
}
|
|
3376
|
+
this.tagName = this.node.name === 'svelte:body' ? 'body' : this.node.name;
|
|
3377
|
+
this.isSelfclosing = this.computeIsSelfclosing();
|
|
3378
|
+
this.startTagStart = this.node.start;
|
|
3379
|
+
this.startTagEnd = this.computeStartTagEnd();
|
|
3380
|
+
const createElement = `${this.typingsNamespace}.createElement`;
|
|
3381
|
+
const tagEnd = this.startTagStart + this.node.name.length + 1;
|
|
3382
|
+
// Ensure deleted characters are mapped to the attributes object so we
|
|
3383
|
+
// get autocompletion when triggering it on a whitespace.
|
|
3384
|
+
if (/\s/.test(str.original.charAt(tagEnd))) {
|
|
3385
|
+
this.attrsTransformation.push(tagEnd);
|
|
3386
|
+
this.attrsTransformation.push([tagEnd, tagEnd + 1]);
|
|
3387
|
+
// Overwrite necessary or else we get really weird mappings
|
|
3388
|
+
this.str.overwrite(tagEnd, tagEnd + 1, '', { contentOnly: true });
|
|
3389
|
+
}
|
|
3390
|
+
switch (this.node.name) {
|
|
3391
|
+
// Although not everything that is possible to add to Element
|
|
3392
|
+
// is valid on the special svelte elements,
|
|
3393
|
+
// we still also handle them here and let the Svelte parser handle invalid
|
|
3394
|
+
// cases. For us it doesn't make a difference to a normal HTML element.
|
|
3395
|
+
case 'svelte:options':
|
|
3396
|
+
case 'svelte:head':
|
|
3397
|
+
case 'svelte:window':
|
|
3398
|
+
case 'svelte:body':
|
|
3399
|
+
case 'svelte:fragment': {
|
|
3400
|
+
// remove the colon: svelte:xxx -> sveltexxx
|
|
3401
|
+
const nodeName = `svelte${this.node.name.substring(7)}`;
|
|
3402
|
+
this._name = '$$_' + nodeName + this.computeDepth();
|
|
3403
|
+
this.startTransformation.push(`{ ${createElement}("${nodeName}", {`);
|
|
3404
|
+
this.addNameConstDeclaration = () => (this.startTransformation[0] = `{ const ${this._name} = ${createElement}("${nodeName}", {`);
|
|
3405
|
+
break;
|
|
3406
|
+
}
|
|
3407
|
+
case 'slot': {
|
|
3408
|
+
// If the element is a <slot> tag, create the element with the createSlot-function
|
|
3409
|
+
// which is created inside createRenderFunction.ts to check that the name and attributes
|
|
3410
|
+
// of the slot tag are correct. The check will error if the user defined $$Slots
|
|
3411
|
+
// and the slot definition or its attributes contradict that type definition.
|
|
3412
|
+
this._name = '$$_slot' + this.computeDepth();
|
|
3413
|
+
const slotName = ((_b = (_a = this.node.attributes) === null || _a === void 0 ? void 0 : _a.find((a) => a.name === 'name')) === null || _b === void 0 ? void 0 : _b.value[0]) ||
|
|
3414
|
+
'default';
|
|
3415
|
+
this.startTransformation.push('{ __sveltets_createSlot(', typeof slotName === 'string'
|
|
3416
|
+
? `"${slotName}"`
|
|
3417
|
+
: surroundWith(this.str, [slotName.start, slotName.end], '"', '"'), ', {');
|
|
3418
|
+
this.addNameConstDeclaration = () => (this.startTransformation[0] = `{ const ${this._name} = __sveltets_createSlot(`);
|
|
3419
|
+
break;
|
|
3420
|
+
}
|
|
3421
|
+
default: {
|
|
3422
|
+
this._name = '$$_' + sanitizePropName(this.node.name) + this.computeDepth();
|
|
3423
|
+
this.startTransformation.push(`{ ${createElement}("`, [this.node.start + 1, this.node.start + 1 + this.node.name.length], '", {');
|
|
3424
|
+
this.addNameConstDeclaration = () => (this.startTransformation[0] = `{ const ${this._name} = ${createElement}("`);
|
|
3425
|
+
break;
|
|
3426
|
+
}
|
|
3427
|
+
}
|
|
3428
|
+
}
|
|
3429
|
+
get name() {
|
|
3430
|
+
if (this.addNameConstDeclaration) {
|
|
3431
|
+
this.addNameConstDeclaration();
|
|
3432
|
+
this.addNameConstDeclaration = undefined;
|
|
3433
|
+
}
|
|
3434
|
+
return this._name;
|
|
3435
|
+
}
|
|
3436
|
+
/**
|
|
3437
|
+
* attribute={foo} --> "attribute": foo,
|
|
3438
|
+
* @param name Attribute name
|
|
3439
|
+
* @param value Attribute value, if present. If not present, this is treated as a shorthand attribute
|
|
3440
|
+
*/
|
|
3441
|
+
addAttribute(name, value) {
|
|
3442
|
+
if (value) {
|
|
3443
|
+
this.attrsTransformation.push(...name, ':', ...value, ',');
|
|
3444
|
+
}
|
|
3445
|
+
else {
|
|
3446
|
+
this.attrsTransformation.push(...name, ',');
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
/**
|
|
3450
|
+
* Handle the slot of `<... slot=".." />`
|
|
3451
|
+
* @param transformation Slot name transformation
|
|
3452
|
+
*/
|
|
3453
|
+
addSlotName(transformation) {
|
|
3454
|
+
this.slotLetsTransformation = this.slotLetsTransformation || [[], []];
|
|
3455
|
+
this.slotLetsTransformation[0] = transformation;
|
|
3456
|
+
}
|
|
3457
|
+
/**
|
|
3458
|
+
* Handle the let: of `<... let:xx={yy} />`
|
|
3459
|
+
* @param transformation Let transformation
|
|
3460
|
+
*/
|
|
3461
|
+
addSlotLet(transformation) {
|
|
3462
|
+
this.slotLetsTransformation = this.slotLetsTransformation || [['default'], []];
|
|
3463
|
+
this.slotLetsTransformation[1].push(...transformation, ',');
|
|
3464
|
+
}
|
|
3465
|
+
/**
|
|
3466
|
+
* Add something right after the start tag end.
|
|
3467
|
+
*/
|
|
3468
|
+
appendToStartEnd(value) {
|
|
3469
|
+
this.startEndTransformation.push(...value);
|
|
3470
|
+
}
|
|
3471
|
+
performTransformation() {
|
|
3472
|
+
this.endTransformation.push('}');
|
|
3473
|
+
const slotLetTransformation = [];
|
|
3474
|
+
if (this.slotLetsTransformation) {
|
|
3475
|
+
if (this.slotLetsTransformation[0][0] === 'default') {
|
|
3476
|
+
slotLetTransformation.push(
|
|
3477
|
+
// add dummy destructuring parameter because if all parameters are unused,
|
|
3478
|
+
// the mapping will be confusing, because TS will highlight the whole destructuring
|
|
3479
|
+
`{const {${surroundWithIgnoreComments('$$_$$')},`, ...this.slotLetsTransformation[1], `} = ${this.parent.name}.$$slot_def.default;$$_$$;`);
|
|
3480
|
+
}
|
|
3481
|
+
else {
|
|
3482
|
+
slotLetTransformation.push(
|
|
3483
|
+
// See comment above
|
|
3484
|
+
`{const {${surroundWithIgnoreComments('$$_$$')},`, ...this.slotLetsTransformation[1], `} = ${this.parent.name}.$$slot_def["`, ...this.slotLetsTransformation[0], '"];$$_$$;');
|
|
3485
|
+
}
|
|
3486
|
+
this.endTransformation.push('}');
|
|
3487
|
+
}
|
|
3488
|
+
if (this.isSelfclosing) {
|
|
3489
|
+
transform(this.str, this.startTagStart, this.startTagEnd, this.startTagEnd, [
|
|
3490
|
+
// Named slot transformations go first inside a outer block scope because
|
|
3491
|
+
// <div let:xx {x} /> means "use the x of let:x", and without a separate
|
|
3492
|
+
// block scope this would give a "used before defined" error
|
|
3493
|
+
...slotLetTransformation,
|
|
3494
|
+
...this.startTransformation,
|
|
3495
|
+
...this.attrsTransformation,
|
|
3496
|
+
...this.startEndTransformation,
|
|
3497
|
+
...this.endTransformation
|
|
3498
|
+
]);
|
|
3499
|
+
}
|
|
3500
|
+
else {
|
|
3501
|
+
transform(this.str, this.startTagStart, this.startTagEnd, this.startTagEnd, [
|
|
3502
|
+
...slotLetTransformation,
|
|
3503
|
+
...this.startTransformation,
|
|
3504
|
+
...this.attrsTransformation,
|
|
3505
|
+
...this.startEndTransformation
|
|
3506
|
+
]);
|
|
3507
|
+
const tagEndIdx = this.str.original
|
|
3508
|
+
.substring(this.node.start, this.node.end)
|
|
3509
|
+
.lastIndexOf(`</${this.node.name}`);
|
|
3510
|
+
// tagEndIdx === -1 happens in situations of unclosed tags like `<p>fooo <p>anothertag</p>`
|
|
3511
|
+
const endStart = tagEndIdx === -1 ? this.node.end : tagEndIdx + this.node.start;
|
|
3512
|
+
transform(this.str, endStart, this.node.end, this.node.end, this.endTransformation);
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
computeStartTagEnd() {
|
|
3516
|
+
var _a;
|
|
3517
|
+
if ((_a = this.node.children) === null || _a === void 0 ? void 0 : _a.length) {
|
|
3518
|
+
return this.node.children[0].start;
|
|
3519
|
+
}
|
|
3520
|
+
return this.isSelfclosing
|
|
3521
|
+
? this.node.end
|
|
3522
|
+
: this.str.original.lastIndexOf('>', this.node.end - 2) + 1;
|
|
3523
|
+
}
|
|
3524
|
+
computeIsSelfclosing() {
|
|
3525
|
+
var _a;
|
|
3526
|
+
if (this.str.original[this.node.end - 2] === '/' || voidTags.includes(this.node.name)) {
|
|
3527
|
+
return true;
|
|
3528
|
+
}
|
|
3529
|
+
return (!((_a = this.node.children) === null || _a === void 0 ? void 0 : _a.length) &&
|
|
3530
|
+
// Paranoid check because theoretically there could be other void
|
|
3531
|
+
// tags in different namespaces other than HTML
|
|
3532
|
+
!this.str.original
|
|
3533
|
+
.substring(this.node.start, this.node.end)
|
|
3534
|
+
.match(new RegExp(`</${this.node.name}\\s*>$`)));
|
|
3535
|
+
}
|
|
3536
|
+
computeDepth() {
|
|
3537
|
+
let idx = 0;
|
|
3538
|
+
let parent = this.parent;
|
|
3539
|
+
while (parent) {
|
|
3540
|
+
parent = parent.parent;
|
|
3541
|
+
idx++;
|
|
3542
|
+
}
|
|
3543
|
+
return idx;
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
|
|
3547
|
+
/**
|
|
3548
|
+
* Handles Svelte components as well as svelte:self and svelte:component
|
|
3549
|
+
*
|
|
3550
|
+
* Children of this element should call the methods on this class to add themselves to the correct
|
|
3551
|
+
* position within the transformation.
|
|
3552
|
+
*
|
|
3553
|
+
* The transformation result does not have anything to do with HTMLx, it instead uses plan JS,
|
|
3554
|
+
* leveraging scoped blocks (`{ ... }`). Each element is transformed to something that is
|
|
3555
|
+
* contained in such a block. This ensures we can declare variables inside that do not leak
|
|
3556
|
+
* to the outside while preserving TypeScript's control flow.
|
|
3557
|
+
*
|
|
3558
|
+
* A transformation reads for example like this:
|
|
3559
|
+
* ```
|
|
3560
|
+
* // before
|
|
3561
|
+
* <Comp prop={foo} />
|
|
3562
|
+
* // after
|
|
3563
|
+
* { const $$_Comp = new Comp({ target: __sveltets_2_any(), props: {"prop": foo,}}); }
|
|
3564
|
+
* ```
|
|
3565
|
+
*/
|
|
3566
|
+
class InlineComponent {
|
|
3567
|
+
constructor(str, node, parent) {
|
|
3568
|
+
this.str = str;
|
|
3569
|
+
this.node = node;
|
|
3570
|
+
this.parent = parent;
|
|
3571
|
+
this.startTransformation = [];
|
|
3572
|
+
this.startEndTransformation = [];
|
|
3573
|
+
this.propsTransformation = [];
|
|
3574
|
+
this.eventsTransformation = [];
|
|
3575
|
+
this.endTransformation = [];
|
|
3576
|
+
if (parent) {
|
|
3577
|
+
parent.child = this;
|
|
3578
|
+
}
|
|
3579
|
+
this.isSelfclosing = this.computeIsSelfclosing();
|
|
3580
|
+
this.startTagStart = this.node.start;
|
|
3581
|
+
this.startTagEnd = this.computeStartTagEnd();
|
|
3582
|
+
const tagEnd = this.startTagStart + this.node.name.length + 1;
|
|
3583
|
+
// Ensure deleted characters are mapped to the attributes object so we
|
|
3584
|
+
// get autocompletion when triggering it on a whitespace.
|
|
3585
|
+
if (/\s/.test(str.original.charAt(tagEnd))) {
|
|
3586
|
+
this.propsTransformation.push(tagEnd);
|
|
3587
|
+
this.propsTransformation.push([tagEnd, tagEnd + 1]);
|
|
3588
|
+
// Overwrite necessary or else we get really weird mappings
|
|
3589
|
+
this.str.overwrite(tagEnd, tagEnd + 1, '', { contentOnly: true });
|
|
3590
|
+
}
|
|
3591
|
+
if (this.node.name === 'svelte:self') {
|
|
3592
|
+
// TODO try to get better typing here, maybe TS allows us to use the created class
|
|
3593
|
+
// even if it's used in the function that is used to create it
|
|
3594
|
+
this._name = '$$_svelteself' + this.computeDepth();
|
|
3595
|
+
this.startTransformation.push('{ __sveltets_2_createComponentAny({');
|
|
3596
|
+
this.addNameConstDeclaration = () => (this.startTransformation[0] = `{ const ${this._name} = __sveltets_2_createComponentAny({`);
|
|
3597
|
+
this.startEndTransformation.push('});');
|
|
3598
|
+
}
|
|
3599
|
+
else {
|
|
3600
|
+
const isSvelteComponentTag = this.node.name === 'svelte:component';
|
|
3601
|
+
// We don't know if the thing we use to create the Svelte component with
|
|
3602
|
+
// is actually a proper Svelte component, which would lead to errors
|
|
3603
|
+
// when accessing things like $$prop_def. Therefore widen the type
|
|
3604
|
+
// here, falling back to a any-typed component to ensure the user doesn't
|
|
3605
|
+
// get weird follup-errors all over the place. The diagnostic error
|
|
3606
|
+
// will be on the __sveltets_2_ensureComponent part, giving a more helpful message
|
|
3607
|
+
this._name = '$$_' + sanitizePropName(this.node.name) + this.computeDepth();
|
|
3608
|
+
const constructorName = this._name + 'C';
|
|
3609
|
+
const nodeNameStart = isSvelteComponentTag
|
|
3610
|
+
? this.node.expression.start
|
|
3611
|
+
: this.str.original.indexOf(this.node.name, this.node.start);
|
|
3612
|
+
const nodeNameEnd = isSvelteComponentTag
|
|
3613
|
+
? this.node.expression.end
|
|
3614
|
+
: nodeNameStart + this.node.name.length;
|
|
3615
|
+
this.startTransformation.push(`{ const ${constructorName} = __sveltets_2_ensureComponent(`, [nodeNameStart, nodeNameEnd], `); new ${constructorName}({ target: __sveltets_2_any(), props: {`);
|
|
3616
|
+
this.addNameConstDeclaration = () => (this.startTransformation[2] = `); const ${this._name} = new ${constructorName}({ target: __sveltets_2_any(), props: {`);
|
|
3617
|
+
this.startEndTransformation.push('}});');
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
get name() {
|
|
3621
|
+
if (this.addNameConstDeclaration) {
|
|
3622
|
+
this.addNameConstDeclaration();
|
|
3623
|
+
this.addNameConstDeclaration = undefined;
|
|
3624
|
+
}
|
|
3625
|
+
return this._name;
|
|
3626
|
+
}
|
|
3627
|
+
/**
|
|
3628
|
+
* prop={foo} --> "prop": foo,
|
|
3629
|
+
* @param name Property name
|
|
3630
|
+
* @param value Attribute value, if present. If not present, this is treated as a shorthand attribute
|
|
3631
|
+
*/
|
|
3632
|
+
addProp(name, value) {
|
|
3633
|
+
if (value) {
|
|
3634
|
+
this.propsTransformation.push(...name, ':', ...value, ',');
|
|
3635
|
+
}
|
|
3636
|
+
else {
|
|
3637
|
+
this.propsTransformation.push(...name, ',');
|
|
3638
|
+
}
|
|
3639
|
+
}
|
|
3640
|
+
/**
|
|
3641
|
+
* on:click={xxx} --> $$_Component.$on("click", xxx)
|
|
3642
|
+
* @param name Event name
|
|
3643
|
+
* @param expression Event handler, if present
|
|
3644
|
+
*/
|
|
3645
|
+
addEvent([nameStart, nameEnd], expression) {
|
|
3646
|
+
this.eventsTransformation.push(`${this.name}.$on(`, surroundWith(this.str, [nameStart, nameEnd], '"', '"'), ', ', expression ? expression : '() => {}', ');');
|
|
3647
|
+
}
|
|
3648
|
+
/**
|
|
3649
|
+
* Handle the slot of `<... slot=".." />`
|
|
3650
|
+
* @param transformation Slot name transformation
|
|
3651
|
+
*/
|
|
3652
|
+
addSlotName(transformation) {
|
|
3653
|
+
this.slotLetsTransformation = this.slotLetsTransformation || [[], []];
|
|
3654
|
+
this.slotLetsTransformation[0] = transformation;
|
|
3655
|
+
}
|
|
3656
|
+
/**
|
|
3657
|
+
* Handle the let: of `<... let:xx={yy} />`
|
|
3658
|
+
* @param transformation Let transformation
|
|
3659
|
+
*/
|
|
3660
|
+
addSlotLet(transformation) {
|
|
3661
|
+
this.slotLetsTransformation = this.slotLetsTransformation || [['default'], []];
|
|
3662
|
+
this.slotLetsTransformation[1].push(...transformation, ',');
|
|
3663
|
+
}
|
|
3664
|
+
/**
|
|
3665
|
+
* Add something right after the start tag end.
|
|
3666
|
+
*/
|
|
3667
|
+
appendToStartEnd(value) {
|
|
3668
|
+
this.startEndTransformation.push(...value);
|
|
3669
|
+
}
|
|
3670
|
+
performTransformation() {
|
|
3671
|
+
const namedSlotLetTransformation = [];
|
|
3672
|
+
const defaultSlotLetTransformation = [];
|
|
3673
|
+
if (this.slotLetsTransformation) {
|
|
3674
|
+
if (this.slotLetsTransformation[0][0] === 'default') {
|
|
3675
|
+
defaultSlotLetTransformation.push(
|
|
3676
|
+
// add dummy destructuring parameter because if all parameters are unused,
|
|
3677
|
+
// the mapping will be confusing, because TS will highlight the whole destructuring
|
|
3678
|
+
`{const {${surroundWithIgnoreComments('$$_$$')},`, ...this.slotLetsTransformation[1], `} = ${this.name}.$$slot_def.default;$$_$$;`);
|
|
3679
|
+
}
|
|
3680
|
+
else {
|
|
3681
|
+
namedSlotLetTransformation.push(
|
|
3682
|
+
// See comment above
|
|
3683
|
+
`{const {${surroundWithIgnoreComments('$$_$$')},`, ...this.slotLetsTransformation[1], `} = ${this.parent.name}.$$slot_def["`, ...this.slotLetsTransformation[0], '"];$$_$$;');
|
|
3684
|
+
}
|
|
3685
|
+
this.endTransformation.push('}');
|
|
3686
|
+
}
|
|
3687
|
+
if (this.isSelfclosing) {
|
|
3688
|
+
this.endTransformation.push('}');
|
|
3689
|
+
transform(this.str, this.startTagStart, this.startTagEnd, this.startTagEnd, [
|
|
3690
|
+
// Named slot transformations go first inside a outer block scope because
|
|
3691
|
+
// <Comp let:xx {x} /> means "use the x of let:x", and without a separate
|
|
3692
|
+
// block scope this would give a "used before defined" error
|
|
3693
|
+
...namedSlotLetTransformation,
|
|
3694
|
+
...this.startTransformation,
|
|
3695
|
+
...this.propsTransformation,
|
|
3696
|
+
...this.startEndTransformation,
|
|
3697
|
+
...this.eventsTransformation,
|
|
3698
|
+
...defaultSlotLetTransformation,
|
|
3699
|
+
...this.endTransformation
|
|
3700
|
+
]);
|
|
3701
|
+
}
|
|
3702
|
+
else {
|
|
3703
|
+
const endStart = this.str.original
|
|
3704
|
+
.substring(this.node.start, this.node.end)
|
|
3705
|
+
.lastIndexOf(`</${this.node.name}`) + this.node.start;
|
|
3706
|
+
if (!this.node.name.startsWith('svelte:')) {
|
|
3707
|
+
// Ensure the end tag is mapped, too. </Component> -> Component}
|
|
3708
|
+
this.endTransformation.push([endStart + 2, endStart + this.node.name.length + 2]);
|
|
3709
|
+
}
|
|
3710
|
+
this.endTransformation.push('}');
|
|
3711
|
+
transform(this.str, this.startTagStart, this.startTagEnd, this.startTagEnd, [
|
|
3712
|
+
// See comment above why this goes first
|
|
3713
|
+
...namedSlotLetTransformation,
|
|
3714
|
+
...this.startTransformation,
|
|
3715
|
+
...this.propsTransformation,
|
|
3716
|
+
...this.startEndTransformation,
|
|
3717
|
+
...this.eventsTransformation,
|
|
3718
|
+
...defaultSlotLetTransformation
|
|
3719
|
+
]);
|
|
3720
|
+
transform(this.str, endStart, this.node.end, this.node.end, this.endTransformation);
|
|
3721
|
+
}
|
|
3722
|
+
}
|
|
3723
|
+
computeStartTagEnd() {
|
|
3724
|
+
var _a;
|
|
3725
|
+
if ((_a = this.node.children) === null || _a === void 0 ? void 0 : _a.length) {
|
|
3726
|
+
return this.node.children[0].start;
|
|
3727
|
+
}
|
|
3728
|
+
return this.isSelfclosing
|
|
3729
|
+
? this.node.end
|
|
3730
|
+
: this.str.original.lastIndexOf('>', this.node.end - 2) + 1;
|
|
3731
|
+
}
|
|
3732
|
+
computeIsSelfclosing() {
|
|
3733
|
+
return this.str.original[this.node.end - 2] === '/';
|
|
3734
|
+
}
|
|
3735
|
+
computeDepth() {
|
|
3736
|
+
let idx = 0;
|
|
3737
|
+
let parent = this.parent;
|
|
3738
|
+
while (parent) {
|
|
3739
|
+
parent = parent.parent;
|
|
3740
|
+
idx++;
|
|
3741
|
+
}
|
|
3742
|
+
return idx;
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
|
|
3746
|
+
/**
|
|
3747
|
+
* List taken from `svelte-jsx.d.ts` by searching for all attributes of type number
|
|
3748
|
+
*/
|
|
3749
|
+
const numberOnlyAttributes = new Set([
|
|
3750
|
+
'cols',
|
|
3751
|
+
'colspan',
|
|
3752
|
+
'currenttime',
|
|
3753
|
+
'defaultplaybackrate',
|
|
3754
|
+
'high',
|
|
3755
|
+
'low',
|
|
3756
|
+
'marginheight',
|
|
3757
|
+
'marginwidth',
|
|
3758
|
+
'minlength',
|
|
3759
|
+
'maxlength',
|
|
3760
|
+
'optimum',
|
|
3761
|
+
'rows',
|
|
3762
|
+
'rowspan',
|
|
3763
|
+
'size',
|
|
3764
|
+
'span',
|
|
3765
|
+
'start',
|
|
3766
|
+
'tabindex',
|
|
3767
|
+
'results',
|
|
3768
|
+
'volume'
|
|
3769
|
+
]);
|
|
3770
|
+
const sapperLinkActions = ['sapper:prefetch', 'sapper:noscroll'];
|
|
3771
|
+
const sveltekitLinkActions = ['sveltekit:prefetch', 'sveltekit:noscroll'];
|
|
3772
|
+
/**
|
|
3773
|
+
* Handle various kinds of attributes and make them conform to being valid in context of a object definition
|
|
3774
|
+
* - {x} ---> x
|
|
3775
|
+
* - x="{..}" ---> x:..
|
|
3776
|
+
* - lowercase DOM attributes
|
|
3777
|
+
* - multi-value handling
|
|
3778
|
+
*/
|
|
3779
|
+
function handleAttribute(str, attr, parent, preserveCase, element) {
|
|
3780
|
+
if (parent.name === '!DOCTYPE' ||
|
|
3781
|
+
['Style', 'Script'].includes(parent.type) ||
|
|
3782
|
+
(attr.name === 'name' && parent.type === 'Slot')) {
|
|
3783
|
+
// - <!DOCTYPE html> is already removed by now from MagicString
|
|
3784
|
+
// - Don't handle script / style tag attributes (context or lang for example)
|
|
3785
|
+
// - name=".." of <slot> tag is already handled in Element
|
|
3786
|
+
return;
|
|
3787
|
+
}
|
|
3788
|
+
if (attr.name === 'slot' &&
|
|
3789
|
+
attributeValueIsOfType(attr.value, 'Text') &&
|
|
3790
|
+
element.parent instanceof InlineComponent) {
|
|
3791
|
+
// - slot=".." in context of slots with let:xx is handled differently
|
|
3792
|
+
element.addSlotName([[attr.value[0].start, attr.value[0].end]]);
|
|
3793
|
+
return;
|
|
3794
|
+
}
|
|
3795
|
+
const addAttribute = element instanceof Element
|
|
3796
|
+
? (name, value) => {
|
|
3797
|
+
if (attr.name.startsWith('data-')) {
|
|
3798
|
+
// any attribute prefixed with data- is valid, but we can't
|
|
3799
|
+
// type that statically, so we need this workaround
|
|
3800
|
+
name.unshift('...__sveltets_2_empty({');
|
|
3801
|
+
if (!value) {
|
|
3802
|
+
value = ['__sveltets_2_any()'];
|
|
3803
|
+
}
|
|
3804
|
+
value.push('})');
|
|
3805
|
+
}
|
|
3806
|
+
element.addAttribute(name, value);
|
|
3807
|
+
}
|
|
3808
|
+
: (name, value) => {
|
|
3809
|
+
if (attr.name.startsWith('--') && attr.value !== true) {
|
|
3810
|
+
// CSS custom properties are not part of the props
|
|
3811
|
+
// definition, so wrap them to not get "--xx is invalid prop" errors
|
|
3812
|
+
name.unshift('...__sveltets_2_cssProp({');
|
|
3813
|
+
if (!value) {
|
|
3814
|
+
value = ['""'];
|
|
3815
|
+
}
|
|
3816
|
+
value.push('})');
|
|
3817
|
+
}
|
|
3818
|
+
element.addProp(name, value);
|
|
3819
|
+
};
|
|
3820
|
+
/**
|
|
3821
|
+
* lowercase the attribute name to make it adhere to our intrinsic elements definition
|
|
3822
|
+
*/
|
|
3823
|
+
const transformAttributeCase = (name) => {
|
|
3824
|
+
if (!preserveCase && !svgAttributes.find((x) => x == name)) {
|
|
3825
|
+
return name.toLowerCase();
|
|
3826
|
+
}
|
|
3827
|
+
else {
|
|
3828
|
+
return name;
|
|
3829
|
+
}
|
|
3830
|
+
};
|
|
3831
|
+
// Handle attribute name
|
|
3832
|
+
const attributeName = [];
|
|
3833
|
+
if (sapperLinkActions.includes(attr.name) || sveltekitLinkActions.includes(attr.name)) {
|
|
3834
|
+
//strip ":" from out attribute name and uppercase the next letter to convert to jsx attribute
|
|
3835
|
+
const parts = attr.name.split(':');
|
|
3836
|
+
const name = parts[0] + parts[1][0].toUpperCase() + parts[1].substring(1);
|
|
3837
|
+
str.overwrite(attr.start, attr.start + attr.name.length, name);
|
|
3838
|
+
attributeName.push([attr.start, attr.start + attr.name.length]);
|
|
3839
|
+
}
|
|
3840
|
+
else if (attributeValueIsOfType(attr.value, 'AttributeShorthand')) {
|
|
3841
|
+
// For the attribute shorthand, the name will be the mapped part
|
|
3842
|
+
addAttribute([[attr.value[0].start, attr.value[0].end]]);
|
|
3843
|
+
return;
|
|
3844
|
+
}
|
|
3845
|
+
else {
|
|
3846
|
+
let name = element instanceof Element && parent.type === 'Element'
|
|
3847
|
+
? transformAttributeCase(attr.name)
|
|
3848
|
+
: attr.name;
|
|
3849
|
+
// surround with quotes because dashes or other invalid property characters could be part of the name
|
|
3850
|
+
// Overwrite first char with "+char because TS will squiggle the whole "prop" including quotes when something is wrong
|
|
3851
|
+
if (name !== attr.name) {
|
|
3852
|
+
name = '"' + name;
|
|
3853
|
+
str.overwrite(attr.start, attr.start + attr.name.length, name);
|
|
3854
|
+
}
|
|
3855
|
+
else {
|
|
3856
|
+
str.overwrite(attr.start, attr.start + 1, '"' + str.original.charAt(attr.start), {
|
|
3857
|
+
contentOnly: true
|
|
3858
|
+
});
|
|
3859
|
+
}
|
|
3860
|
+
attributeName.push([attr.start, attr.start + attr.name.length], '"');
|
|
3861
|
+
}
|
|
3862
|
+
// Handle attribute value
|
|
3863
|
+
const attributeValue = [];
|
|
3864
|
+
if (attr.value === true) {
|
|
3865
|
+
attributeValue.push('true');
|
|
3866
|
+
addAttribute(attributeName, attributeValue);
|
|
3867
|
+
return;
|
|
3868
|
+
}
|
|
3869
|
+
if (attr.value.length == 0) {
|
|
3870
|
+
// attr=""
|
|
3871
|
+
addAttribute(attributeName, ['""']);
|
|
3872
|
+
return;
|
|
3873
|
+
}
|
|
3874
|
+
//handle single value
|
|
3875
|
+
if (attr.value.length == 1) {
|
|
3876
|
+
const attrVal = attr.value[0];
|
|
3877
|
+
if (attrVal.type == 'Text') {
|
|
3878
|
+
const hasBrackets = str.original.lastIndexOf('}', attrVal.end) === attrVal.end - 1 ||
|
|
3879
|
+
str.original.lastIndexOf('}"', attrVal.end) === attrVal.end - 1 ||
|
|
3880
|
+
str.original.lastIndexOf("}'", attrVal.end) === attrVal.end - 1;
|
|
3881
|
+
const needsNumberConversion = !hasBrackets &&
|
|
3882
|
+
parent.type === 'Element' &&
|
|
3883
|
+
numberOnlyAttributes.has(attr.name.toLowerCase()) &&
|
|
3884
|
+
!isNaN(attrVal.data);
|
|
3885
|
+
const includesTemplateLiteralQuote = attrVal.data.includes('`');
|
|
3886
|
+
const quote = !includesTemplateLiteralQuote
|
|
3887
|
+
? '`'
|
|
3888
|
+
: ['"', "'"].includes(str.original[attrVal.start - 1])
|
|
3889
|
+
? str.original[attrVal.start - 1]
|
|
3890
|
+
: '"';
|
|
3891
|
+
if (!needsNumberConversion) {
|
|
3892
|
+
attributeValue.push(quote);
|
|
3893
|
+
}
|
|
3894
|
+
if (includesTemplateLiteralQuote && attrVal.data.split('\n').length > 1) {
|
|
3895
|
+
// Multiline attribute value text which can't be wrapped in a template literal
|
|
3896
|
+
// -> ensure it's still a valid transformation by transforming the actual line break
|
|
3897
|
+
str.overwrite(attrVal.start, attrVal.end, attrVal.data.split('\n').join('\\n'), {
|
|
3898
|
+
contentOnly: true
|
|
3899
|
+
});
|
|
3900
|
+
}
|
|
3901
|
+
attributeValue.push([attrVal.start, attrVal.end]);
|
|
3902
|
+
if (!needsNumberConversion) {
|
|
3903
|
+
attributeValue.push(quote);
|
|
3904
|
+
}
|
|
3905
|
+
addAttribute(attributeName, attributeValue);
|
|
3906
|
+
}
|
|
3907
|
+
else if (attrVal.type == 'MustacheTag') {
|
|
3908
|
+
attributeValue.push([attrVal.expression.start, attrVal.expression.end]);
|
|
3909
|
+
addAttribute(attributeName, attributeValue);
|
|
3910
|
+
}
|
|
3911
|
+
return;
|
|
3912
|
+
}
|
|
3913
|
+
// We have multiple attribute values, so we build a template string out of them.
|
|
3914
|
+
for (const n of attr.value) {
|
|
3915
|
+
if (n.type === 'MustacheTag') {
|
|
3916
|
+
str.appendRight(n.start, '$');
|
|
3917
|
+
}
|
|
3918
|
+
}
|
|
3919
|
+
attributeValue.push('`', [attr.value[0].start, attr.value[attr.value.length - 1].end], '`');
|
|
3920
|
+
addAttribute(attributeName, attributeValue);
|
|
3921
|
+
}
|
|
3922
|
+
function attributeValueIsOfType(value, type) {
|
|
3923
|
+
return value !== true && value.length == 1 && value[0].type == type;
|
|
3924
|
+
}
|
|
3925
|
+
|
|
3926
|
+
/**
|
|
3927
|
+
* This needs to be called on the way out, not on the way on, when walking,
|
|
3928
|
+
* because else the order of moves might get messed up with moves in
|
|
3929
|
+
* the children.
|
|
3930
|
+
*
|
|
3931
|
+
* The await block consists of these blocks:
|
|
3932
|
+
*- expression: the promise - has start and end
|
|
3933
|
+
*- value: the result of the promise - has start and end
|
|
3934
|
+
*- error: the error branch value - has start and end
|
|
3935
|
+
*- pending: start/end of the pending block (if exists), with skip boolean
|
|
3936
|
+
*- then: start/end of the then block (if exists), with skip boolean
|
|
3937
|
+
*- catch: start/end of the catch block (if exists), with skip boolean
|
|
3938
|
+
*
|
|
3939
|
+
* Implementation note:
|
|
3940
|
+
* As soon there's a `then` with a value, we transform that to
|
|
3941
|
+
* `{const $$_value = foo; {const foo = await $$_value;..}}` because
|
|
3942
|
+
*
|
|
3943
|
+
* - `{#await foo then foo}` or `{#await foo}..{:then foo}..` is valid Svelte code
|
|
3944
|
+
* - `{#await foo} {bar} {:then bar} {bar} {/await} is valid Svelte code`
|
|
3945
|
+
*
|
|
3946
|
+
* Both would throw "variable used before declaration" if we didn't do the
|
|
3947
|
+
* transformation this way.
|
|
3948
|
+
*/
|
|
3949
|
+
function handleAwait(str, awaitBlock) {
|
|
3950
|
+
var _a, _b;
|
|
3951
|
+
const transforms = ['{ '];
|
|
3952
|
+
if (!awaitBlock.pending.skip) {
|
|
3953
|
+
transforms.push([awaitBlock.pending.start, awaitBlock.pending.end]);
|
|
3954
|
+
}
|
|
3955
|
+
if (awaitBlock.error || !awaitBlock.catch.skip) {
|
|
3956
|
+
transforms.push('try { ');
|
|
3957
|
+
}
|
|
3958
|
+
if (awaitBlock.value) {
|
|
3959
|
+
transforms.push('const $$_value = ');
|
|
3960
|
+
}
|
|
3961
|
+
transforms.push('await (', [awaitBlock.expression.start, awaitBlock.expression.end], '); ');
|
|
3962
|
+
if (awaitBlock.value) {
|
|
3963
|
+
transforms.push('{ const ', [awaitBlock.value.start, awaitBlock.value.end], ' = $$_value; ');
|
|
3964
|
+
}
|
|
3965
|
+
if (!awaitBlock.then.skip) {
|
|
3966
|
+
if (awaitBlock.pending.skip) {
|
|
3967
|
+
transforms.push([awaitBlock.then.start, awaitBlock.then.end]);
|
|
3968
|
+
}
|
|
3969
|
+
else if ((_a = awaitBlock.then.children) === null || _a === void 0 ? void 0 : _a.length) {
|
|
3970
|
+
transforms.push([
|
|
3971
|
+
awaitBlock.then.children[0].start,
|
|
3972
|
+
awaitBlock.then.children[awaitBlock.then.children.length - 1].end
|
|
3973
|
+
]);
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3976
|
+
if (awaitBlock.value) {
|
|
3977
|
+
transforms.push('}');
|
|
3978
|
+
}
|
|
3979
|
+
if (awaitBlock.error || !awaitBlock.catch.skip) {
|
|
3980
|
+
transforms.push('} catch($$_e) { ');
|
|
3981
|
+
if (awaitBlock.error) {
|
|
3982
|
+
transforms.push('const ', [awaitBlock.error.start, awaitBlock.error.end], ' = __sveltets_2_any();');
|
|
3983
|
+
}
|
|
3984
|
+
if (!awaitBlock.catch.skip && ((_b = awaitBlock.catch.children) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
3985
|
+
transforms.push([
|
|
3986
|
+
awaitBlock.catch.children[0].start,
|
|
3987
|
+
awaitBlock.catch.children[awaitBlock.catch.children.length - 1].end
|
|
3988
|
+
]);
|
|
3989
|
+
}
|
|
3990
|
+
transforms.push('}');
|
|
3991
|
+
}
|
|
3992
|
+
transforms.push('}');
|
|
3993
|
+
transform(str, awaitBlock.start, awaitBlock.end, awaitBlock.end, transforms);
|
|
3994
|
+
}
|
|
3995
|
+
|
|
3996
|
+
const oneWayBindingAttributes = new Map(['clientWidth', 'clientHeight', 'offsetWidth', 'offsetHeight']
|
|
3997
|
+
.map((e) => [e, 'HTMLDivElement'])
|
|
3998
|
+
.concat(['duration', 'buffered', 'seekable', 'seeking', 'played', 'ended'].map((e) => [
|
|
3999
|
+
e,
|
|
4000
|
+
'HTMLMediaElement'
|
|
4001
|
+
])));
|
|
4002
|
+
/**
|
|
4003
|
+
* List of all binding names that are transformed to sth like `binding = variable`.
|
|
4004
|
+
* This applies to readonly bindings and the this binding.
|
|
4005
|
+
*/
|
|
4006
|
+
new Set([...oneWayBindingAttributes.keys(), 'this']);
|
|
4007
|
+
const supportsBindThis = [
|
|
4008
|
+
'InlineComponent',
|
|
4009
|
+
'Element',
|
|
4010
|
+
'Body',
|
|
4011
|
+
'Slot' // only valid for Web Components compile target
|
|
4012
|
+
];
|
|
4013
|
+
/**
|
|
4014
|
+
* Transform bind:xxx into something that conforms to JS/TS
|
|
4015
|
+
*/
|
|
4016
|
+
function handleBinding(str, attr, parent, element) {
|
|
4017
|
+
// bind group on input
|
|
4018
|
+
if (element instanceof Element && attr.name == 'group' && parent.name == 'input') {
|
|
4019
|
+
element.appendToStartEnd([[attr.expression.start, attr.expression.end], ';']);
|
|
4020
|
+
return;
|
|
4021
|
+
}
|
|
4022
|
+
// bind this
|
|
4023
|
+
if (attr.name === 'this' && supportsBindThis.includes(parent.type)) {
|
|
4024
|
+
// bind:this is effectively only works bottom up - the variable is updated by the element, not
|
|
4025
|
+
// the other way round. So we check if the instance is assignable to the variable.
|
|
4026
|
+
// Note: If the component unmounts (it's inside an if block, or svelte:component this={null},
|
|
4027
|
+
// the value becomes null, but we don't add it to the clause because it would introduce
|
|
4028
|
+
// worse DX for the 99% use case, and because null !== undefined which others might use to type the declaration.
|
|
4029
|
+
element.appendToStartEnd([
|
|
4030
|
+
[attr.expression.start, attr.expression.end],
|
|
4031
|
+
` = ${element.name};`
|
|
4032
|
+
]);
|
|
4033
|
+
return;
|
|
4034
|
+
}
|
|
4035
|
+
// one way binding
|
|
4036
|
+
if (oneWayBindingAttributes.has(attr.name) && element instanceof Element) {
|
|
4037
|
+
element.appendToStartEnd([
|
|
4038
|
+
[attr.expression.start, attr.expression.end],
|
|
4039
|
+
`= ${element.name}.${attr.name};`
|
|
4040
|
+
]);
|
|
4041
|
+
return;
|
|
4042
|
+
}
|
|
4043
|
+
// other bindings which are transformed to normal attributes/props
|
|
4044
|
+
const isShorthand = attr.expression.start === attr.start + 'bind:'.length;
|
|
4045
|
+
const name = isShorthand
|
|
4046
|
+
? [[attr.expression.start, attr.expression.end]]
|
|
4047
|
+
: [[attr.start + 'bind:'.length, str.original.lastIndexOf('=', attr.expression.start)]];
|
|
4048
|
+
const value = isShorthand
|
|
4049
|
+
? undefined
|
|
4050
|
+
: [[attr.expression.start, attr.expression.end]];
|
|
4051
|
+
if (element instanceof Element) {
|
|
4052
|
+
element.addAttribute(name, value);
|
|
4053
|
+
}
|
|
4054
|
+
else {
|
|
4055
|
+
element.addProp(name, value);
|
|
4056
|
+
}
|
|
4057
|
+
}
|
|
4058
|
+
|
|
4059
|
+
/**
|
|
4060
|
+
* class:xx={yyy} ---> yyy;
|
|
4061
|
+
*/
|
|
4062
|
+
function handleClassDirective(attr, element) {
|
|
4063
|
+
element.appendToStartEnd([[attr.expression.start, attr.expression.end], ';']);
|
|
4064
|
+
}
|
|
4065
|
+
|
|
4066
|
+
/**
|
|
4067
|
+
* Removes comment altogether as it's unimportant for the output
|
|
4068
|
+
*/
|
|
4069
|
+
function handleComment(str, node) {
|
|
4070
|
+
str.overwrite(node.start, node.end, '', { contentOnly: true });
|
|
4071
|
+
}
|
|
4072
|
+
|
|
4073
|
+
/**
|
|
4074
|
+
* `{@const x = y}` --> `const x = y;`
|
|
4075
|
+
*
|
|
4076
|
+
* The transformation happens directly in-place. This is more strict than the
|
|
4077
|
+
* Svelte compiler because the compiler moves all const declarations to the top.
|
|
4078
|
+
* This transformation results in `x used before being defined` errors if someone
|
|
4079
|
+
* uses a const variable before declaring it, which arguably is more helpful
|
|
4080
|
+
* than what the Svelte compiler does.
|
|
4081
|
+
*/
|
|
4082
|
+
function handleConstTag(str, constTag) {
|
|
4083
|
+
transform(str, constTag.start, constTag.end, constTag.end, [
|
|
4084
|
+
'const ',
|
|
4085
|
+
[constTag.expression.start, constTag.expression.end],
|
|
4086
|
+
';'
|
|
4087
|
+
]);
|
|
4088
|
+
}
|
|
4089
|
+
|
|
4090
|
+
/**
|
|
4091
|
+
* {@debug a} ---> ;a;
|
|
4092
|
+
* {@debug a, b} ---> ;a;b;
|
|
4093
|
+
*/
|
|
4094
|
+
function handleDebug(str, debugBlock) {
|
|
4095
|
+
let cursor = debugBlock.start;
|
|
4096
|
+
for (const identifier of debugBlock.identifiers) {
|
|
4097
|
+
str.overwrite(cursor, identifier.start, ';', { contentOnly: true });
|
|
4098
|
+
cursor = identifier.end;
|
|
4099
|
+
}
|
|
4100
|
+
str.overwrite(cursor, debugBlock.end, ';', { contentOnly: true });
|
|
4101
|
+
}
|
|
4102
|
+
|
|
4103
|
+
/**
|
|
4104
|
+
* Transform #each into a for-of loop
|
|
4105
|
+
*
|
|
4106
|
+
* Implementation notes:
|
|
4107
|
+
* - If code is
|
|
4108
|
+
* `{#each items as items,i (key)}`
|
|
4109
|
+
* then the transformation is
|
|
4110
|
+
* `{ const $$_each = __sveltets_2_ensureArray(items); for (const items of $$_each) { let i = 0;key;`.
|
|
4111
|
+
* Transform it this way because `{#each items as items}` is valid Svelte code, but the transformation
|
|
4112
|
+
* `for(const items of items){..}` is invalid ("variable used before declaration"). Don't do the transformation
|
|
4113
|
+
* like this everytime because `$$_each` could turn up in the auto completion.
|
|
4114
|
+
*
|
|
4115
|
+
* - The `ensureArray` method checks that only `ArrayLike` objects are passed to `#each`.
|
|
4116
|
+
* `for (const ..)` wouldn't error in this case because it accepts any kind of iterable.
|
|
4117
|
+
*
|
|
4118
|
+
* - `{#each true, items as item}` is valid, we need to add braces around that expression, else
|
|
4119
|
+
* `ensureArray` will error that there are more args than expected
|
|
4120
|
+
*/
|
|
4121
|
+
function handleEach(str, eachBlock) {
|
|
4122
|
+
var _a;
|
|
4123
|
+
const startEnd = str.original.indexOf('}', ((_a = eachBlock.key) === null || _a === void 0 ? void 0 : _a.end) || eachBlock.context.end) + 1;
|
|
4124
|
+
let transforms;
|
|
4125
|
+
// {#each true, [1,2]} is valid but for (const x of true, [1,2]) is not if not wrapped with braces
|
|
4126
|
+
const containsComma = str.original
|
|
4127
|
+
.substring(eachBlock.expression.start, eachBlock.expression.end)
|
|
4128
|
+
.includes(',');
|
|
4129
|
+
const arrayAndItemVarTheSame = str.original.substring(eachBlock.expression.start, eachBlock.expression.end) ===
|
|
4130
|
+
str.original.substring(eachBlock.context.start, eachBlock.context.end);
|
|
4131
|
+
if (arrayAndItemVarTheSame) {
|
|
4132
|
+
transforms = [
|
|
4133
|
+
`{ const $$_each = __sveltets_2_ensureArray(${containsComma ? '(' : ''}`,
|
|
4134
|
+
[eachBlock.expression.start, eachBlock.expression.end],
|
|
4135
|
+
`${containsComma ? ')' : ''}); for(const `,
|
|
4136
|
+
[eachBlock.context.start, eachBlock.context.end],
|
|
4137
|
+
' of $$_each){'
|
|
4138
|
+
];
|
|
2760
4139
|
}
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
4140
|
+
else {
|
|
4141
|
+
transforms = [
|
|
4142
|
+
'for(const ',
|
|
4143
|
+
[eachBlock.context.start, eachBlock.context.end],
|
|
4144
|
+
` of __sveltets_2_ensureArray(${containsComma ? '(' : ''}`,
|
|
4145
|
+
[eachBlock.expression.start, eachBlock.expression.end],
|
|
4146
|
+
`${containsComma ? ')' : ''})){`
|
|
4147
|
+
];
|
|
4148
|
+
}
|
|
4149
|
+
if (eachBlock.key) {
|
|
4150
|
+
transforms.push([eachBlock.key.start, eachBlock.key.end], ';');
|
|
4151
|
+
}
|
|
4152
|
+
if (eachBlock.index) {
|
|
4153
|
+
const indexStart = str.original.indexOf(eachBlock.index, eachBlock.context.end);
|
|
4154
|
+
const indexEnd = indexStart + eachBlock.index.length;
|
|
4155
|
+
transforms.push('let ', [indexStart, indexEnd], ' = 1;');
|
|
4156
|
+
}
|
|
4157
|
+
transform(str, eachBlock.start, startEnd, startEnd, transforms);
|
|
4158
|
+
const endEach = str.original.lastIndexOf('{', eachBlock.end - 1);
|
|
4159
|
+
// {/each} -> } or {:else} -> }
|
|
4160
|
+
if (eachBlock.else) {
|
|
4161
|
+
const elseEnd = str.original.lastIndexOf('}', eachBlock.else.start);
|
|
4162
|
+
const elseStart = str.original.lastIndexOf('{', elseEnd);
|
|
4163
|
+
str.overwrite(elseStart, elseEnd + 1, '}' + (arrayAndItemVarTheSame ? '}' : ''), {
|
|
4164
|
+
contentOnly: true
|
|
4165
|
+
});
|
|
4166
|
+
str.remove(endEach, eachBlock.end);
|
|
4167
|
+
}
|
|
4168
|
+
else {
|
|
4169
|
+
str.overwrite(endEach, eachBlock.end, '}' + (arrayAndItemVarTheSame ? '}' : ''), {
|
|
4170
|
+
contentOnly: true
|
|
4171
|
+
});
|
|
2764
4172
|
}
|
|
2765
4173
|
}
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
4174
|
+
|
|
4175
|
+
/**
|
|
4176
|
+
* Transform on:xxx={yyy}
|
|
4177
|
+
* - For DOM elements: ---> onxxx: yyy,
|
|
4178
|
+
* - For Svelte components/special elements: ---> componentInstance.$on("xxx", yyy)}
|
|
4179
|
+
*/
|
|
4180
|
+
function handleEventHandler(str, attr, element) {
|
|
4181
|
+
const nameStart = str.original.indexOf(':', attr.start) + 1;
|
|
4182
|
+
// If there's no expression, it's event bubbling (on:click)
|
|
4183
|
+
const nameEnd = nameStart + attr.name.length;
|
|
4184
|
+
if (element instanceof Element) {
|
|
4185
|
+
// Prefix with "on" for better mapping.
|
|
4186
|
+
// Surround with quotes because event name could contain invalid prop chars.
|
|
4187
|
+
surroundWith(str, [nameStart, nameEnd], '"on', '"');
|
|
4188
|
+
element.addAttribute([[nameStart, nameEnd]], attr.expression ? [[attr.expression.start, attr.expression.end]] : ['undefined']);
|
|
2769
4189
|
}
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
if (node.context) {
|
|
2773
|
-
this.handleScope(node.context);
|
|
2774
|
-
}
|
|
2775
|
-
if (node.index) {
|
|
2776
|
-
this.value.inits.add(node.index);
|
|
2777
|
-
}
|
|
4190
|
+
else {
|
|
4191
|
+
element.addEvent([nameStart, nameEnd], attr.expression ? [attr.expression.start, attr.expression.end] : undefined);
|
|
2778
4192
|
}
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
4193
|
+
}
|
|
4194
|
+
|
|
4195
|
+
/**
|
|
4196
|
+
* Transforms #if and :else if to a regular if control block.
|
|
4197
|
+
*/
|
|
4198
|
+
function handleIf(str, ifBlock) {
|
|
4199
|
+
if (ifBlock.elseif) {
|
|
4200
|
+
// {:else if expr} --> } else if(expr) {
|
|
4201
|
+
const start = str.original.lastIndexOf('{:', ifBlock.expression.start);
|
|
4202
|
+
str.overwrite(start, ifBlock.expression.start, '} else if (');
|
|
2783
4203
|
}
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
if
|
|
2787
|
-
this.handleScope(node.value);
|
|
2788
|
-
}
|
|
2789
|
-
if (node.error) {
|
|
2790
|
-
this.handleScope(node.error);
|
|
2791
|
-
}
|
|
4204
|
+
else {
|
|
4205
|
+
// {#if expr} --> if (expr){
|
|
4206
|
+
str.overwrite(ifBlock.start, ifBlock.expression.start, 'if(');
|
|
2792
4207
|
}
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
4208
|
+
const end = str.original.indexOf('}', ifBlock.expression.end);
|
|
4209
|
+
str.overwrite(ifBlock.expression.end, end + 1, '){');
|
|
4210
|
+
// {/if} -> }
|
|
4211
|
+
const endif = str.original.lastIndexOf('{', ifBlock.end - 1);
|
|
4212
|
+
str.overwrite(endif, ifBlock.end, '}');
|
|
4213
|
+
}
|
|
4214
|
+
/**
|
|
4215
|
+
* {:else} ---> } else {
|
|
4216
|
+
*/
|
|
4217
|
+
function handleElse(str, elseBlock, parent) {
|
|
4218
|
+
if (parent.type !== 'IfBlock') {
|
|
4219
|
+
// This is the else branch of an #each block which is handled elsewhere
|
|
4220
|
+
return;
|
|
2799
4221
|
}
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
4222
|
+
const elseEnd = str.original.lastIndexOf('}', elseBlock.start);
|
|
4223
|
+
const elseword = str.original.lastIndexOf(':else', elseEnd);
|
|
4224
|
+
const elseStart = str.original.lastIndexOf('{', elseword);
|
|
4225
|
+
str.overwrite(elseStart, elseStart + 1, '}');
|
|
4226
|
+
str.overwrite(elseEnd, elseEnd + 1, '{');
|
|
4227
|
+
const colon = str.original.indexOf(':', elseword);
|
|
4228
|
+
str.remove(colon, colon + 1);
|
|
4229
|
+
}
|
|
4230
|
+
|
|
4231
|
+
/**
|
|
4232
|
+
* {#key expr}content{/key} ---> expr; content
|
|
4233
|
+
*/
|
|
4234
|
+
function handleKey(str, keyBlock) {
|
|
4235
|
+
// {#key expr} -> expr;
|
|
4236
|
+
str.overwrite(keyBlock.start, keyBlock.expression.start, '', { contentOnly: true });
|
|
4237
|
+
const end = str.original.indexOf('}', keyBlock.expression.end);
|
|
4238
|
+
str.overwrite(keyBlock.expression.end, end + 1, '; ');
|
|
4239
|
+
// {/key} ->
|
|
4240
|
+
const endKey = str.original.lastIndexOf('{', keyBlock.end - 1);
|
|
4241
|
+
str.overwrite(endKey, keyBlock.end, '', { contentOnly: true });
|
|
4242
|
+
}
|
|
4243
|
+
|
|
4244
|
+
/**
|
|
4245
|
+
* `let:foo={bar}` --> `foo:bar`, which becomes `const {foo:bar} = $$_parent.$$slotDef['slotName'];`
|
|
4246
|
+
* @param node
|
|
4247
|
+
* @param element
|
|
4248
|
+
*/
|
|
4249
|
+
function handleLet(str, node, parent, preserveCase, element) {
|
|
4250
|
+
if (element instanceof InlineComponent) {
|
|
4251
|
+
// let:xx belongs to either the default slot or a named slot,
|
|
4252
|
+
// which is determined in Attribute.ts
|
|
4253
|
+
addSlotLet(node, element);
|
|
2810
4254
|
}
|
|
2811
|
-
|
|
2812
|
-
if (
|
|
2813
|
-
|
|
4255
|
+
else {
|
|
4256
|
+
if (element.parent instanceof InlineComponent) {
|
|
4257
|
+
// let:xx is on a HTML element and belongs to a (named slot of a parent component
|
|
4258
|
+
addSlotLet(node, element);
|
|
2814
4259
|
}
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
4260
|
+
else {
|
|
4261
|
+
// let:xx is a regular HTML attribute (probably a mistake by the user)
|
|
4262
|
+
handleAttribute(str, {
|
|
4263
|
+
start: node.start,
|
|
4264
|
+
end: node.end,
|
|
4265
|
+
type: 'Attribute',
|
|
4266
|
+
name: 'let:' + node.name,
|
|
4267
|
+
value: node.expression
|
|
4268
|
+
? [
|
|
4269
|
+
{
|
|
4270
|
+
type: 'MustacheTag',
|
|
4271
|
+
start: node.expression.start,
|
|
4272
|
+
end: node.expression.end,
|
|
4273
|
+
expression: node.expression
|
|
4274
|
+
}
|
|
4275
|
+
]
|
|
4276
|
+
: true
|
|
4277
|
+
}, parent, preserveCase, element);
|
|
2820
4278
|
}
|
|
2821
4279
|
}
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
4280
|
+
}
|
|
4281
|
+
function addSlotLet(node, element) {
|
|
4282
|
+
const letTransformation = [
|
|
4283
|
+
[node.start + 'let:'.length, node.start + 'let:'.length + node.name.length]
|
|
4284
|
+
];
|
|
4285
|
+
if (node.expression) {
|
|
4286
|
+
letTransformation.push(':', [node.expression.start, node.expression.end]);
|
|
2829
4287
|
}
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
4288
|
+
element.addSlotLet(letTransformation);
|
|
4289
|
+
}
|
|
4290
|
+
|
|
4291
|
+
/**
|
|
4292
|
+
* Handle mustache tags that are not part of attributes
|
|
4293
|
+
* {a} --> a;
|
|
4294
|
+
*/
|
|
4295
|
+
function handleMustacheTag(str, node, parent) {
|
|
4296
|
+
if (parent.type === 'Attribute') {
|
|
4297
|
+
// handles inside Attribute.ts
|
|
4298
|
+
return;
|
|
2834
4299
|
}
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
4300
|
+
str.overwrite(node.start, node.start + 1, '', { contentOnly: true });
|
|
4301
|
+
str.overwrite(node.end - 1, node.end, ';', { contentOnly: true });
|
|
4302
|
+
}
|
|
4303
|
+
|
|
4304
|
+
/**
|
|
4305
|
+
* {@html ...} ---> ...;
|
|
4306
|
+
*/
|
|
4307
|
+
function handleRawHtml(str, node) {
|
|
4308
|
+
transform(str, node.start, node.end, node.end, [
|
|
4309
|
+
[node.expression.start, node.expression.end],
|
|
4310
|
+
';'
|
|
4311
|
+
]);
|
|
4312
|
+
}
|
|
4313
|
+
|
|
4314
|
+
/**
|
|
4315
|
+
* Handle spreaded attributes/props on elements/components by removing the braces.
|
|
4316
|
+
* That way they can be added as a regular object spread.
|
|
4317
|
+
* `{...xx}` -> `...x`
|
|
4318
|
+
*/
|
|
4319
|
+
function handleSpread(node, element) {
|
|
4320
|
+
const transformation = [[node.start + 1, node.end - 1]];
|
|
4321
|
+
if (element instanceof Element) {
|
|
4322
|
+
element.addAttribute(transformation);
|
|
2839
4323
|
}
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
this.value.inits.add(identifierDef.name);
|
|
2843
|
-
}
|
|
2844
|
-
if (isDestructuringPatterns(identifierDef)) {
|
|
2845
|
-
// the node object is returned as-it with no mutation
|
|
2846
|
-
const identifiers = extract_identifiers(identifierDef);
|
|
2847
|
-
identifiers.forEach((id) => this.value.inits.add(id.name));
|
|
2848
|
-
}
|
|
4324
|
+
else {
|
|
4325
|
+
element.addProp(transformation);
|
|
2849
4326
|
}
|
|
2850
4327
|
}
|
|
2851
4328
|
|
|
2852
|
-
|
|
2853
|
-
|
|
4329
|
+
/**
|
|
4330
|
+
* style:xx ---> __sveltets_2_ensureType(String, Number, xx);
|
|
4331
|
+
* style:xx={yy} ---> __sveltets_2_ensureType(String, Number, yy);
|
|
4332
|
+
* style:xx="yy" ---> __sveltets_2_ensureType(String, Number, "yy");
|
|
4333
|
+
* style:xx="a{b}" ---> __sveltets_2_ensureType(String, Number, `a${b}`);
|
|
4334
|
+
*/
|
|
4335
|
+
function handleStyleDirective(str, style, element) {
|
|
4336
|
+
const htmlx = str.original;
|
|
4337
|
+
if (style.value === true || style.value.length === 0) {
|
|
4338
|
+
element.appendToStartEnd([
|
|
4339
|
+
'__sveltets_2_ensureType(String, Number, ',
|
|
4340
|
+
[htmlx.indexOf(':', style.start) + 1, style.end],
|
|
4341
|
+
');'
|
|
4342
|
+
]);
|
|
2854
4343
|
return;
|
|
2855
4344
|
}
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
4345
|
+
let start = style.value[0].start;
|
|
4346
|
+
if (style.value[0].type === 'MustacheTag') {
|
|
4347
|
+
start++;
|
|
4348
|
+
}
|
|
4349
|
+
const last = style.value[style.value.length - 1];
|
|
4350
|
+
let end = last.end;
|
|
4351
|
+
if (last.type === 'MustacheTag') {
|
|
4352
|
+
end--;
|
|
4353
|
+
}
|
|
4354
|
+
if (style.value.length > 1) {
|
|
4355
|
+
// We have multiple attribute values, so we build a template string out of them.
|
|
4356
|
+
for (const n of style.value) {
|
|
4357
|
+
if (n.type === 'MustacheTag') {
|
|
4358
|
+
str.appendRight(n.start, '$');
|
|
4359
|
+
}
|
|
2862
4360
|
}
|
|
4361
|
+
element.appendToStartEnd([
|
|
4362
|
+
'__sveltets_2_ensureType(String, Number, `',
|
|
4363
|
+
[start, end],
|
|
4364
|
+
'`);'
|
|
4365
|
+
]);
|
|
4366
|
+
return;
|
|
4367
|
+
}
|
|
4368
|
+
const styleVal = style.value[0];
|
|
4369
|
+
if (styleVal.type === 'Text') {
|
|
4370
|
+
const quote = ['"', "'"].includes(str.original[styleVal.start - 1])
|
|
4371
|
+
? str.original[styleVal.start - 1]
|
|
4372
|
+
: '"';
|
|
4373
|
+
element.appendToStartEnd([
|
|
4374
|
+
`__sveltets_2_ensureType(String, Number, ${quote}`,
|
|
4375
|
+
[start, end],
|
|
4376
|
+
`${quote});`
|
|
4377
|
+
]);
|
|
4378
|
+
}
|
|
4379
|
+
else {
|
|
4380
|
+
// MustacheTag
|
|
4381
|
+
element.appendToStartEnd(['__sveltets_2_ensureType(String, Number, ', [start, end], ');']);
|
|
2863
4382
|
}
|
|
2864
4383
|
}
|
|
2865
4384
|
|
|
2866
4385
|
/**
|
|
2867
|
-
*
|
|
4386
|
+
* Handles a text node transformation.
|
|
4387
|
+
* Removes everything except whitespace (for better visual output) when it's normal HTML text for example inside an element
|
|
4388
|
+
* to not clutter up the output. For attributes it leaves the text as is.
|
|
2868
4389
|
*/
|
|
2869
|
-
function
|
|
2870
|
-
|
|
2871
|
-
if (attr.modifiers.length) {
|
|
2872
|
-
const local = htmlx.indexOf('|', attr.start);
|
|
2873
|
-
str.remove(local, attr.expression ? attr.expression.start : attr.end);
|
|
2874
|
-
}
|
|
2875
|
-
const nodeType = `__sveltets_1_mapElementTag('${parent.name}')`;
|
|
2876
|
-
if (!attr.expression) {
|
|
2877
|
-
str.appendLeft(attr.end, `(${nodeType},{}))}`);
|
|
4390
|
+
function handleText(str, node, parent) {
|
|
4391
|
+
if (!node.data || parent.type === 'Attribute') {
|
|
2878
4392
|
return;
|
|
2879
4393
|
}
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
4394
|
+
let replacement = node.data.replace(/\S/g, '');
|
|
4395
|
+
if (!replacement && node.data.length) {
|
|
4396
|
+
// minimum of 1 whitespace which ensure hover or other things don't give weird results
|
|
4397
|
+
// where for example you hover over a text and get a hover info about the containing tag.
|
|
4398
|
+
replacement = ' ';
|
|
4399
|
+
}
|
|
4400
|
+
str.overwrite(node.start, node.end, replacement, {
|
|
4401
|
+
contentOnly: true
|
|
4402
|
+
});
|
|
4403
|
+
}
|
|
4404
|
+
|
|
4405
|
+
/**
|
|
4406
|
+
* transition|modifier:xxx(yyy) ---> __sveltets_2_ensureTransition(xxx(svelte.mapElementTag('..'),(yyy)));
|
|
4407
|
+
*/
|
|
4408
|
+
function handleTransitionDirective(str, attr, element) {
|
|
4409
|
+
const transformations = [
|
|
4410
|
+
'__sveltets_2_ensureTransition(',
|
|
4411
|
+
getDirectiveNameStartEndIdx(str, attr),
|
|
4412
|
+
`(${element.typingsNamespace}.mapElementTag('${element.tagName}')`
|
|
4413
|
+
];
|
|
4414
|
+
if (attr.expression) {
|
|
4415
|
+
transformations.push(',(', [attr.expression.start, attr.expression.end], ')');
|
|
2884
4416
|
}
|
|
4417
|
+
transformations.push('));');
|
|
4418
|
+
element.appendToStartEnd(transformations);
|
|
2885
4419
|
}
|
|
2886
4420
|
|
|
2887
4421
|
function stripDoctype(str) {
|
|
@@ -2896,107 +4430,101 @@ function stripDoctype(str) {
|
|
|
2896
4430
|
* and converts it to JSX
|
|
2897
4431
|
*/
|
|
2898
4432
|
function convertHtmlxToJsx(str, ast, onWalk = null, onLeave = null, options = {}) {
|
|
2899
|
-
|
|
4433
|
+
str.original;
|
|
4434
|
+
options = { preserveAttributeCase: false, ...options };
|
|
4435
|
+
options.typingsNamespace = options.typingsNamespace || 'svelteHTML';
|
|
2900
4436
|
stripDoctype(str);
|
|
2901
|
-
|
|
2902
|
-
str.append('</>');
|
|
2903
|
-
const templateScopeManager = new TemplateScopeManager();
|
|
2904
|
-
let ifScope = new IfScope(templateScopeManager);
|
|
4437
|
+
let element;
|
|
2905
4438
|
compiler.walk(ast, {
|
|
2906
4439
|
enter: (node, parent, prop, index) => {
|
|
2907
4440
|
try {
|
|
2908
4441
|
switch (node.type) {
|
|
2909
4442
|
case 'IfBlock':
|
|
2910
|
-
handleIf(
|
|
2911
|
-
if (!node.elseif) {
|
|
2912
|
-
ifScope = ifScope.getChild();
|
|
2913
|
-
}
|
|
4443
|
+
handleIf(str, node);
|
|
2914
4444
|
break;
|
|
2915
4445
|
case 'EachBlock':
|
|
2916
|
-
|
|
2917
|
-
handleEach(htmlx, str, node, ifScope);
|
|
4446
|
+
handleEach(str, node);
|
|
2918
4447
|
break;
|
|
2919
4448
|
case 'ElseBlock':
|
|
2920
|
-
|
|
2921
|
-
handleElse(htmlx, str, node, parent, ifScope);
|
|
2922
|
-
break;
|
|
2923
|
-
case 'AwaitBlock':
|
|
2924
|
-
handleAwait(htmlx, str, node, ifScope, templateScopeManager);
|
|
2925
|
-
break;
|
|
2926
|
-
case 'PendingBlock':
|
|
2927
|
-
templateScopeManager.awaitPendingEnter(node, parent);
|
|
2928
|
-
handleAwaitPending(parent, htmlx, str, ifScope);
|
|
2929
|
-
break;
|
|
2930
|
-
case 'ThenBlock':
|
|
2931
|
-
templateScopeManager.awaitThenEnter(node, parent);
|
|
2932
|
-
handleAwaitThen(parent, htmlx, str, ifScope);
|
|
2933
|
-
break;
|
|
2934
|
-
case 'CatchBlock':
|
|
2935
|
-
templateScopeManager.awaitCatchEnter(node, parent);
|
|
2936
|
-
handleAwaitCatch(parent, htmlx, str, ifScope);
|
|
4449
|
+
handleElse(str, node, parent);
|
|
2937
4450
|
break;
|
|
2938
4451
|
case 'KeyBlock':
|
|
2939
|
-
handleKey(
|
|
4452
|
+
handleKey(str, node);
|
|
4453
|
+
break;
|
|
4454
|
+
case 'MustacheTag':
|
|
4455
|
+
handleMustacheTag(str, node, parent);
|
|
2940
4456
|
break;
|
|
2941
4457
|
case 'RawMustacheTag':
|
|
2942
|
-
handleRawHtml(
|
|
4458
|
+
handleRawHtml(str, node);
|
|
2943
4459
|
break;
|
|
2944
4460
|
case 'DebugTag':
|
|
2945
|
-
handleDebug(
|
|
4461
|
+
handleDebug(str, node);
|
|
4462
|
+
break;
|
|
4463
|
+
case 'ConstTag':
|
|
4464
|
+
handleConstTag(str, node);
|
|
2946
4465
|
break;
|
|
2947
4466
|
case 'InlineComponent':
|
|
2948
|
-
|
|
2949
|
-
|
|
4467
|
+
if (element) {
|
|
4468
|
+
element.child = new InlineComponent(str, node, element);
|
|
4469
|
+
element = element.child;
|
|
4470
|
+
}
|
|
4471
|
+
else {
|
|
4472
|
+
element = new InlineComponent(str, node);
|
|
4473
|
+
}
|
|
2950
4474
|
break;
|
|
2951
4475
|
case 'Element':
|
|
2952
|
-
|
|
2953
|
-
|
|
4476
|
+
case 'Options':
|
|
4477
|
+
case 'Window':
|
|
4478
|
+
case 'Head':
|
|
4479
|
+
case 'Title':
|
|
4480
|
+
case 'Body':
|
|
4481
|
+
case 'Slot':
|
|
4482
|
+
case 'SlotTemplate':
|
|
4483
|
+
if (node.name !== '!DOCTYPE') {
|
|
4484
|
+
if (element) {
|
|
4485
|
+
element.child = new Element(str, node, options.typingsNamespace, element);
|
|
4486
|
+
element = element.child;
|
|
4487
|
+
}
|
|
4488
|
+
else {
|
|
4489
|
+
element = new Element(str, node, options.typingsNamespace);
|
|
4490
|
+
}
|
|
4491
|
+
}
|
|
2954
4492
|
break;
|
|
2955
4493
|
case 'Comment':
|
|
2956
4494
|
handleComment(str, node);
|
|
2957
4495
|
break;
|
|
2958
4496
|
case 'Binding':
|
|
2959
|
-
handleBinding(
|
|
4497
|
+
handleBinding(str, node, parent, element);
|
|
2960
4498
|
break;
|
|
2961
4499
|
case 'Class':
|
|
2962
|
-
handleClassDirective(
|
|
4500
|
+
handleClassDirective(node, element);
|
|
4501
|
+
break;
|
|
4502
|
+
case 'StyleDirective':
|
|
4503
|
+
handleStyleDirective(str, node, element);
|
|
2963
4504
|
break;
|
|
2964
4505
|
case 'Action':
|
|
2965
|
-
handleActionDirective(
|
|
4506
|
+
handleActionDirective(str, node, element);
|
|
2966
4507
|
break;
|
|
2967
4508
|
case 'Transition':
|
|
2968
|
-
handleTransitionDirective(
|
|
4509
|
+
handleTransitionDirective(str, node, element);
|
|
2969
4510
|
break;
|
|
2970
4511
|
case 'Animation':
|
|
2971
|
-
handleAnimateDirective(
|
|
4512
|
+
handleAnimateDirective(str, node, element);
|
|
2972
4513
|
break;
|
|
2973
4514
|
case 'Attribute':
|
|
2974
|
-
handleAttribute(
|
|
2975
|
-
break;
|
|
2976
|
-
case 'EventHandler':
|
|
2977
|
-
handleEventHandler(htmlx, str, node, parent);
|
|
2978
|
-
break;
|
|
2979
|
-
case 'Options':
|
|
2980
|
-
handleSvelteTag(htmlx, str, node);
|
|
2981
|
-
break;
|
|
2982
|
-
case 'Window':
|
|
2983
|
-
handleSvelteTag(htmlx, str, node);
|
|
4515
|
+
handleAttribute(str, node, parent, options.preserveAttributeCase, element);
|
|
2984
4516
|
break;
|
|
2985
|
-
case '
|
|
2986
|
-
|
|
4517
|
+
case 'Spread':
|
|
4518
|
+
handleSpread(node, element);
|
|
2987
4519
|
break;
|
|
2988
|
-
case '
|
|
2989
|
-
|
|
4520
|
+
case 'EventHandler':
|
|
4521
|
+
handleEventHandler(str, node, element);
|
|
2990
4522
|
break;
|
|
2991
|
-
case '
|
|
2992
|
-
|
|
2993
|
-
templateScopeManager.componentOrSlotTemplateOrElementEnter(node);
|
|
2994
|
-
if (usesLet(node)) {
|
|
2995
|
-
handleSlot(htmlx, str, node, parent, getSlotName(node) || 'default', ifScope, templateScopeManager.value);
|
|
2996
|
-
}
|
|
4523
|
+
case 'Let':
|
|
4524
|
+
handleLet(str, node, parent, options.preserveAttributeCase, element);
|
|
2997
4525
|
break;
|
|
2998
4526
|
case 'Text':
|
|
2999
|
-
handleText(str, node);
|
|
4527
|
+
handleText(str, node, parent);
|
|
3000
4528
|
break;
|
|
3001
4529
|
}
|
|
3002
4530
|
if (onWalk) {
|
|
@@ -3004,7 +4532,7 @@ function convertHtmlxToJsx(str, ast, onWalk = null, onLeave = null, options = {}
|
|
|
3004
4532
|
}
|
|
3005
4533
|
}
|
|
3006
4534
|
catch (e) {
|
|
3007
|
-
console.error('Error walking node ', node);
|
|
4535
|
+
console.error('Error walking node ', node, e);
|
|
3008
4536
|
throw e;
|
|
3009
4537
|
}
|
|
3010
4538
|
},
|
|
@@ -3012,20 +4540,25 @@ function convertHtmlxToJsx(str, ast, onWalk = null, onLeave = null, options = {}
|
|
|
3012
4540
|
try {
|
|
3013
4541
|
switch (node.type) {
|
|
3014
4542
|
case 'IfBlock':
|
|
3015
|
-
if (!node.elseif) {
|
|
3016
|
-
ifScope = ifScope.getParent();
|
|
3017
|
-
}
|
|
3018
4543
|
break;
|
|
3019
4544
|
case 'EachBlock':
|
|
3020
|
-
templateScopeManager.eachLeave(node);
|
|
3021
4545
|
break;
|
|
3022
4546
|
case 'AwaitBlock':
|
|
3023
|
-
|
|
4547
|
+
handleAwait(str, node);
|
|
3024
4548
|
break;
|
|
3025
4549
|
case 'InlineComponent':
|
|
3026
4550
|
case 'Element':
|
|
4551
|
+
case 'Options':
|
|
4552
|
+
case 'Window':
|
|
4553
|
+
case 'Head':
|
|
4554
|
+
case 'Title':
|
|
4555
|
+
case 'Body':
|
|
4556
|
+
case 'Slot':
|
|
3027
4557
|
case 'SlotTemplate':
|
|
3028
|
-
|
|
4558
|
+
if (node.name !== '!DOCTYPE') {
|
|
4559
|
+
element.performTransformation();
|
|
4560
|
+
element = element.parent;
|
|
4561
|
+
}
|
|
3029
4562
|
break;
|
|
3030
4563
|
}
|
|
3031
4564
|
if (onLeave) {
|
|
@@ -4080,7 +5613,8 @@ class ImplicitStoreValues {
|
|
|
4080
5613
|
class Scripts {
|
|
4081
5614
|
constructor(htmlxAst) {
|
|
4082
5615
|
this.htmlxAst = htmlxAst;
|
|
4083
|
-
// All script tags, no matter at what level, are listed within the root children
|
|
5616
|
+
// All script tags, no matter at what level, are listed within the root children, because
|
|
5617
|
+
// of the logic in htmlxparser.ts
|
|
4084
5618
|
// To get the top level scripts, filter out all those that are part of children's children.
|
|
4085
5619
|
// Those have another type ('Element' with name 'script').
|
|
4086
5620
|
this.scriptTags = this.htmlxAst.children.filter((child) => child.type === 'Script');
|
|
@@ -5002,7 +6536,8 @@ function processInstanceScriptContent(str, script, events, implicitStoreValues,
|
|
|
5002
6536
|
}
|
|
5003
6537
|
// Defensively call function (checking for undefined) because it got added only recently (TS 4.0)
|
|
5004
6538
|
// and therefore might break people using older TS versions
|
|
5005
|
-
|
|
6539
|
+
// Don't transform in ts mode because <type>value type assertions are valid in this case
|
|
6540
|
+
if (mode !== 'ts' && ((_a = ts__namespace.isTypeAssertionExpression) === null || _a === void 0 ? void 0 : _a.call(ts__namespace, node))) {
|
|
5006
6541
|
handleTypeAssertion(str, node, astOffset);
|
|
5007
6542
|
}
|
|
5008
6543
|
//to save a bunch of condition checks on each node, we recurse into processChild which skips all the checks for top level items
|
|
@@ -5061,7 +6596,7 @@ function transformInterfacesToTypes(tsAst, str, astOffset) {
|
|
|
5061
6596
|
});
|
|
5062
6597
|
}
|
|
5063
6598
|
|
|
5064
|
-
function processModuleScriptTag(str, script, implicitStoreValues) {
|
|
6599
|
+
function processModuleScriptTag(str, script, implicitStoreValues, useNewTransformation) {
|
|
5065
6600
|
const htmlx = str.original;
|
|
5066
6601
|
const scriptContent = htmlx.substring(script.content.start, script.content.end);
|
|
5067
6602
|
const tsAst = ts__default['default'].createSourceFile('component.module.ts.svelte', scriptContent, ts__default['default'].ScriptTarget.Latest, true, ts__default['default'].ScriptKind.TS);
|
|
@@ -5081,8 +6616,12 @@ function processModuleScriptTag(str, script, implicitStoreValues) {
|
|
|
5081
6616
|
implicitStoreValues.modifyCode(astOffset, str);
|
|
5082
6617
|
const scriptStartTagEnd = htmlx.indexOf('>', script.start) + 1;
|
|
5083
6618
|
const scriptEndTagStart = htmlx.lastIndexOf('<', script.end - 1);
|
|
5084
|
-
str.overwrite(script.start, scriptStartTagEnd, '</>;'
|
|
5085
|
-
|
|
6619
|
+
str.overwrite(script.start, scriptStartTagEnd, useNewTransformation ? ';' : '</>;', {
|
|
6620
|
+
contentOnly: true
|
|
6621
|
+
});
|
|
6622
|
+
str.overwrite(scriptEndTagStart, script.end, useNewTransformation ? ';' : ';<>', {
|
|
6623
|
+
contentOnly: true
|
|
6624
|
+
});
|
|
5086
6625
|
}
|
|
5087
6626
|
function resolveImplicitStoreValue(node, implicitStoreValues, str, astOffset) {
|
|
5088
6627
|
var _a;
|
|
@@ -5254,6 +6793,7 @@ function classNameFromFilename(filename, appendSuffix) {
|
|
|
5254
6793
|
}
|
|
5255
6794
|
|
|
5256
6795
|
function createRenderFunction({ str, scriptTag, scriptDestination, slots, events, exportedNames, isTsFile, uses$$props, uses$$restProps, uses$$slots, uses$$SlotsInterface, generics, mode }) {
|
|
6796
|
+
const useNewTransformation = mode === 'ts';
|
|
5257
6797
|
const htmlx = str.original;
|
|
5258
6798
|
let propsDecl = '';
|
|
5259
6799
|
if (uses$$props) {
|
|
@@ -5272,24 +6812,30 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
5272
6812
|
}
|
|
5273
6813
|
const slotsDeclaration = slots.size > 0 && mode !== 'dts'
|
|
5274
6814
|
? '\n' +
|
|
5275
|
-
surroundWithIgnoreComments(
|
|
5276
|
-
|
|
5277
|
-
|
|
6815
|
+
surroundWithIgnoreComments(useNewTransformation
|
|
6816
|
+
? ';const __sveltets_createSlot = __sveltets_2_createCreateSlot' +
|
|
6817
|
+
(uses$$SlotsInterface ? '<$$Slots>' : '') +
|
|
6818
|
+
'();'
|
|
6819
|
+
: ';const __sveltets_ensureSlot = __sveltets_1_createEnsureSlot' +
|
|
6820
|
+
(uses$$SlotsInterface ? '<$$Slots>' : '') +
|
|
6821
|
+
'();')
|
|
5278
6822
|
: '';
|
|
5279
6823
|
if (scriptTag) {
|
|
5280
6824
|
//I couldn't get magicstring to let me put the script before the <> we prepend during conversion of the template to jsx, so we just close it instead
|
|
5281
6825
|
const scriptTagEnd = htmlx.lastIndexOf('>', scriptTag.content.start) + 1;
|
|
5282
|
-
str.overwrite(scriptTag.start, scriptTag.start + 1, '</>;');
|
|
6826
|
+
str.overwrite(scriptTag.start, scriptTag.start + 1, useNewTransformation ? ';' : '</>;');
|
|
5283
6827
|
str.overwrite(scriptTag.start + 1, scriptTagEnd, `function render${generics.toDefinitionString(true)}() {${propsDecl}\n`);
|
|
5284
6828
|
const scriptEndTagStart = htmlx.lastIndexOf('<', scriptTag.end - 1);
|
|
5285
6829
|
// wrap template with callback
|
|
5286
|
-
str.overwrite(scriptEndTagStart, scriptTag.end,
|
|
6830
|
+
str.overwrite(scriptEndTagStart, scriptTag.end, useNewTransformation
|
|
6831
|
+
? `${slotsDeclaration};\nasync () => {`
|
|
6832
|
+
: `${slotsDeclaration};\n() => (<>`, {
|
|
5287
6833
|
contentOnly: true
|
|
5288
6834
|
});
|
|
5289
6835
|
}
|
|
5290
6836
|
else {
|
|
5291
|
-
str.prependRight(scriptDestination,
|
|
5292
|
-
`${propsDecl}${slotsDeclaration}\n
|
|
6837
|
+
str.prependRight(scriptDestination, `${useNewTransformation ? '' : '</>'};function render${generics.toDefinitionString(true)}() {` +
|
|
6838
|
+
`${propsDecl}${slotsDeclaration}\n${useNewTransformation ? 'async () => {' : '<>'}`);
|
|
5293
6839
|
}
|
|
5294
6840
|
const slotsAsDef = uses$$SlotsInterface
|
|
5295
6841
|
? '{} as unknown as $$Slots'
|
|
@@ -5310,14 +6856,20 @@ function createRenderFunction({ str, scriptTag, scriptDestination, slots, events
|
|
|
5310
6856
|
`, getters: ${exportedNames.createRenderFunctionGetterStr()}` +
|
|
5311
6857
|
`, events: ${events.toDefString()} }}`;
|
|
5312
6858
|
// wrap template with callback
|
|
5313
|
-
if (
|
|
6859
|
+
if (useNewTransformation) {
|
|
6860
|
+
str.append('};');
|
|
6861
|
+
}
|
|
6862
|
+
else if (scriptTag) {
|
|
5314
6863
|
str.append(');');
|
|
5315
6864
|
}
|
|
5316
6865
|
str.append(returnString);
|
|
5317
6866
|
}
|
|
5318
6867
|
|
|
5319
6868
|
function processSvelteTemplate(str, options) {
|
|
5320
|
-
const { htmlxAst, tags } = parseHtmlx(str.original,
|
|
6869
|
+
const { htmlxAst, tags } = parseHtmlx(str.original, {
|
|
6870
|
+
...options,
|
|
6871
|
+
useNewTransformation: (options === null || options === void 0 ? void 0 : options.mode) === 'ts'
|
|
6872
|
+
});
|
|
5321
6873
|
let uses$$props = false;
|
|
5322
6874
|
let uses$$restProps = false;
|
|
5323
6875
|
let uses$$slots = false;
|
|
@@ -5497,9 +7049,17 @@ function processSvelteTemplate(str, options) {
|
|
|
5497
7049
|
break;
|
|
5498
7050
|
}
|
|
5499
7051
|
};
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
7052
|
+
if (options.mode === 'ts') {
|
|
7053
|
+
convertHtmlxToJsx(str, htmlxAst, onHtmlxWalk, onHtmlxLeave, {
|
|
7054
|
+
preserveAttributeCase: (options === null || options === void 0 ? void 0 : options.namespace) == 'foreign',
|
|
7055
|
+
typingsNamespace: options.typingsNamespace
|
|
7056
|
+
});
|
|
7057
|
+
}
|
|
7058
|
+
else {
|
|
7059
|
+
convertHtmlxToJsx$1(str, htmlxAst, onHtmlxWalk, onHtmlxLeave, {
|
|
7060
|
+
preserveAttributeCase: (options === null || options === void 0 ? void 0 : options.namespace) == 'foreign'
|
|
7061
|
+
});
|
|
7062
|
+
}
|
|
5503
7063
|
// resolve scripts
|
|
5504
7064
|
const { scriptTag, moduleScriptTag } = scripts.getTopLevelScriptTags();
|
|
5505
7065
|
scripts.blankOtherScriptTags(str);
|
|
@@ -5519,6 +7079,8 @@ function processSvelteTemplate(str, options) {
|
|
|
5519
7079
|
};
|
|
5520
7080
|
}
|
|
5521
7081
|
function svelte2tsx(svelte, options = {}) {
|
|
7082
|
+
// TODO temporary
|
|
7083
|
+
options.mode = options.mode || 'ts';
|
|
5522
7084
|
const str = new MagicString(svelte);
|
|
5523
7085
|
// process the htmlx as a svelte template
|
|
5524
7086
|
let { moduleScriptTag, scriptTag, slots, uses$$props, uses$$slots, uses$$restProps, events, componentDocumentation, resolvedStores, usesAccessors } = processSvelteTemplate(str, options);
|
|
@@ -5575,7 +7137,7 @@ function svelte2tsx(svelte, options = {}) {
|
|
|
5575
7137
|
});
|
|
5576
7138
|
// we need to process the module script after the instance script has moved otherwise we get warnings about moving edited items
|
|
5577
7139
|
if (moduleScriptTag) {
|
|
5578
|
-
processModuleScriptTag(str, moduleScriptTag, new ImplicitStoreValues(implicitStoreValues.getAccessedStores(), renderFunctionStart, scriptTag ? undefined : (input) => `</>;${input}<>`));
|
|
7140
|
+
processModuleScriptTag(str, moduleScriptTag, new ImplicitStoreValues(implicitStoreValues.getAccessedStores(), renderFunctionStart, scriptTag || options.mode === 'ts' ? undefined : (input) => `</>;${input}<>`), options.mode === 'ts');
|
|
5579
7141
|
}
|
|
5580
7142
|
addComponentExport({
|
|
5581
7143
|
str,
|