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.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
- const content = match[4];
1149
+ let content = match[4];
1150
1150
  if (!content) {
1151
- // Self-closing/empty tags don't need replacement
1152
- continue;
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 [...extractTag(htmlx, 'script'), ...extractTag(htmlx, 'style')];
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, `) => {${ifScope.addPossibleIfCondition()}<>`);
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 = `__sveltets_1_awaitThen(_$$p, () => {${ifScope.addPossibleIfCondition()}<>`; // eslint-disable-line
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, `) => {${ifScope.addPossibleIfCondition()}<>`);
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 (let:xx)
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 hasMoved = false;
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
- slotDefInsertionPoint =
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 (hasMoved) {
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
- hasMoved = true;
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
- if (!hasMoved) {
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}() => { let {`);
2167
- str.appendRight(slotDefInsertionPoint, `} = ${singleSlotDef}` + `;${ifScope.addPossibleIfCondition()}<>`);
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
- str.prependLeft(contextEnd, ') =>');
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
- child() {
2762
- const child = new TemplateScope$1(this);
2763
- return child;
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
- class TemplateScopeManager {
2767
- constructor() {
2768
- this.value = new TemplateScope$1();
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
- eachEnter(node) {
2771
- this.value = this.value.child();
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
- eachLeave(node) {
2780
- if (!node.else) {
2781
- this.value = this.value.parent;
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
- awaitEnter(node) {
2785
- this.value = this.value.child();
2786
- if (node.value) {
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
- awaitPendingEnter(node, parent) {
2794
- if (node.skip || parent.type !== 'AwaitBlock') {
2795
- return;
2796
- }
2797
- // Reset inits, as pending can have no inits
2798
- this.value.inits.clear();
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
- awaitThenEnter(node, parent) {
2801
- if (node.skip || parent.type !== 'AwaitBlock') {
2802
- return;
2803
- }
2804
- // Reset inits, this time only taking the then
2805
- // scope into account.
2806
- this.value.inits.clear();
2807
- if (parent.value) {
2808
- this.handleScope(parent.value);
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
- awaitCatchEnter(node, parent) {
2812
- if (node.skip || parent.type !== 'AwaitBlock') {
2813
- return;
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
- // Reset inits, this time only taking the error
2816
- // scope into account.
2817
- this.value.inits.clear();
2818
- if (parent.error) {
2819
- this.handleScope(parent.error);
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
- awaitLeave() {
2823
- this.value = this.value.parent;
2824
- }
2825
- elseEnter(parent) {
2826
- if (parent.type === 'EachBlock') {
2827
- this.value = this.value.parent;
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
- componentOrSlotTemplateOrElementEnter(node) {
2831
- if (usesLet(node)) {
2832
- this.value = this.value.child();
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
- componentOrSlotTemplateOrElementLeave(node) {
2836
- if (usesLet(node)) {
2837
- this.value = this.value.parent;
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
- handleScope(identifierDef) {
2841
- if (isIdentifier(identifierDef)) {
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
- function handleText(str, node) {
2853
- if (!node.data) {
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
- const needsRemoves = ['}', '>'];
2857
- for (const token of needsRemoves) {
2858
- let index = node.data.indexOf(token);
2859
- while (index >= 0) {
2860
- str.remove(index + node.start, index + node.start + 1);
2861
- index = node.data.indexOf(token, index + 1);
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
- * transition:xxx(yyy) ---> {...__sveltets_1_ensureTransition(xxx(__sveltets_1_mapElementTag('..'),(yyy)))}
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 handleTransitionDirective(htmlx, str, attr, parent) {
2870
- str.overwrite(attr.start, htmlx.indexOf(':', attr.start) + 1, '{...__sveltets_1_ensureTransition(');
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
- str.overwrite(htmlx.indexOf(':', attr.start) + 1 + `${attr.name}`.length, attr.expression.start, `(${nodeType},(`);
2881
- str.appendLeft(attr.expression.end, ')))');
2882
- if (isQuote(htmlx[attr.end - 1])) {
2883
- str.remove(attr.end - 1, attr.end);
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
- const htmlx = str.original;
4433
+ str.original;
4434
+ options = { preserveAttributeCase: false, ...options };
4435
+ options.typingsNamespace = options.typingsNamespace || 'svelteHTML';
2900
4436
  stripDoctype(str);
2901
- str.prepend('<>');
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(htmlx, str, node, ifScope);
2911
- if (!node.elseif) {
2912
- ifScope = ifScope.getChild();
2913
- }
4443
+ handleIf(str, node);
2914
4444
  break;
2915
4445
  case 'EachBlock':
2916
- templateScopeManager.eachEnter(node);
2917
- handleEach(htmlx, str, node, ifScope);
4446
+ handleEach(str, node);
2918
4447
  break;
2919
4448
  case 'ElseBlock':
2920
- templateScopeManager.elseEnter(parent);
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(htmlx, str, node);
4452
+ handleKey(str, node);
4453
+ break;
4454
+ case 'MustacheTag':
4455
+ handleMustacheTag(str, node, parent);
2940
4456
  break;
2941
4457
  case 'RawMustacheTag':
2942
- handleRawHtml(htmlx, str, node);
4458
+ handleRawHtml(str, node);
2943
4459
  break;
2944
4460
  case 'DebugTag':
2945
- handleDebug(htmlx, str, node);
4461
+ handleDebug(str, node);
4462
+ break;
4463
+ case 'ConstTag':
4464
+ handleConstTag(str, node);
2946
4465
  break;
2947
4466
  case 'InlineComponent':
2948
- templateScopeManager.componentOrSlotTemplateOrElementEnter(node);
2949
- handleComponent(htmlx, str, node, parent, ifScope, templateScopeManager.value);
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
- templateScopeManager.componentOrSlotTemplateOrElementEnter(node);
2953
- handleElement(htmlx, str, node, parent, ifScope, templateScopeManager.value);
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(htmlx, str, node, parent);
4497
+ handleBinding(str, node, parent, element);
2960
4498
  break;
2961
4499
  case 'Class':
2962
- handleClassDirective(str, node);
4500
+ handleClassDirective(node, element);
4501
+ break;
4502
+ case 'StyleDirective':
4503
+ handleStyleDirective(str, node, element);
2963
4504
  break;
2964
4505
  case 'Action':
2965
- handleActionDirective(htmlx, str, node, parent);
4506
+ handleActionDirective(str, node, element);
2966
4507
  break;
2967
4508
  case 'Transition':
2968
- handleTransitionDirective(htmlx, str, node, parent);
4509
+ handleTransitionDirective(str, node, element);
2969
4510
  break;
2970
4511
  case 'Animation':
2971
- handleAnimateDirective(htmlx, str, node, parent);
4512
+ handleAnimateDirective(str, node, element);
2972
4513
  break;
2973
4514
  case 'Attribute':
2974
- handleAttribute(htmlx, str, node, parent, options.preserveAttributeCase);
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 'Head':
2986
- handleSvelteTag(htmlx, str, node);
4517
+ case 'Spread':
4518
+ handleSpread(node, element);
2987
4519
  break;
2988
- case 'Body':
2989
- handleSvelteTag(htmlx, str, node);
4520
+ case 'EventHandler':
4521
+ handleEventHandler(str, node, element);
2990
4522
  break;
2991
- case 'SlotTemplate':
2992
- handleSvelteTag(htmlx, str, node);
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
- templateScopeManager.awaitLeave();
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
- templateScopeManager.componentOrSlotTemplateOrElementLeave(node);
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
- if ((_a = ts__namespace.isTypeAssertionExpression) === null || _a === void 0 ? void 0 : _a.call(ts__namespace, node)) {
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
- str.overwrite(scriptEndTagStart, script.end, ';<>');
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(';const __sveltets_ensureSlot = __sveltets_1_createEnsureSlot' +
5276
- (uses$$SlotsInterface ? '<$$Slots>' : '') +
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, `${slotsDeclaration};\n() => (<>`, {
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, `</>;function render${generics.toDefinitionString(true)}() {` +
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 (scriptTag) {
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, options);
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
- convertHtmlxToJsx(str, htmlxAst, onHtmlxWalk, onHtmlxLeave, {
5501
- preserveAttributeCase: (options === null || options === void 0 ? void 0 : options.namespace) == 'foreign'
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,