Skip to content

Commit

Permalink
(fix) await without then (#432)
Browse files Browse the repository at this point in the history
* (fix) await without then

#427

* (refactor) move htmlxtojsx into own folder
  • Loading branch information
dummdidumm committed Aug 6, 2020
1 parent a032ff2 commit 7a732e7
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 89 deletions.
79 changes: 47 additions & 32 deletions packages/svelte2tsx/rollup.config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,51 @@ import json from 'rollup-plugin-json';
import del from 'rollup-plugin-delete';
import builtins from 'builtin-modules';

export default [{
input: ['src/index.ts'],
output: {
sourcemap: true,
format: 'commonjs',
file: 'test/build/index.js'
},
plugins: [
del({ targets: 'test/build/index.*' }),
resolve({ browser: false, preferBuiltins: true }),
commonjs(),
json(),
typescript()
],
external: [...builtins, 'typescript', 'svelte', 'svelte/compiler', 'parse5', 'magic-string']
}, {
input: ['src/htmlxtojsx.ts'],
output: {
sourcemap: true,
format: 'commonjs',
file: 'test/build/htmlxtojsx.js'
},
plugins: [
del({ targets: 'test/build/htmlxtojsx.*' }),
resolve({ browser: false, preferBuiltins: true }),
commonjs(),
json(),
typescript()
],
external: [...builtins, 'typescript', 'svelte', 'svelte/compiler', 'parse5', 'magic-string']

}
export default [
{
input: ['src/index.ts'],
output: {
sourcemap: true,
format: 'commonjs',
file: 'test/build/index.js',
},
plugins: [
del({ targets: 'test/build/index.*' }),
resolve({ browser: false, preferBuiltins: true }),
commonjs(),
json(),
typescript(),
],
external: [
...builtins,
'typescript',
'svelte',
'svelte/compiler',
'parse5',
'magic-string',
],
},
{
input: ['src/htmlxtojsx/index.ts'],
output: {
sourcemap: true,
format: 'commonjs',
file: 'test/build/htmlxtojsx.js',
},
plugins: [
del({ targets: 'test/build/htmlxtojsx.*' }),
resolve({ browser: false, preferBuiltins: true }),
commonjs(),
json(),
typescript(),
],
external: [
...builtins,
'typescript',
'svelte',
'svelte/compiler',
'parse5',
'magic-string',
],
},
];
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import MagicString from 'magic-string';
import svelte from 'svelte/compiler';
import { Node } from 'estree-walker';
import { parseHtmlx } from './htmlxparser';
import { parseHtmlx } from '../htmlxparser';
import svgAttributes from './svgattributes';
import { getTypeForComponent } from './nodes/component-type';
import { handleAwait } from './nodes/await-block';

type ElementType = string;
const oneWayBindingAttributes: Map<string, ElementType> = new Map(
Expand Down Expand Up @@ -544,61 +545,6 @@ export function convertHtmlxToJsx(
}
};

// {#await somePromise then value} ->
// {() => {let _$$p = (somePromise);
const handleAwait = (awaitBlock: Node) => {
str.overwrite(awaitBlock.start, awaitBlock.expression.start, '{() => {let _$$p = (');
// then value } | {:then value} ->
// __sveltets_awaitThen(_$$p, (value) => {<>
let thenStart: number;
let thenEnd: number;
if (!awaitBlock.pending.skip) {
//thenBlock includes the {:then}
thenStart = awaitBlock.then.start;
if (awaitBlock.value) {
thenEnd = htmlx.indexOf('}', awaitBlock.value.end) + 1;
} else {
thenEnd = htmlx.indexOf('}', awaitBlock.then.start) + 1;
}
str.prependLeft(thenStart, '</>; ');
// add the start tag too
const awaitEnd = htmlx.indexOf('}', awaitBlock.expression.end);

// somePromise} -> somePromise);
str.overwrite(awaitBlock.expression.end, awaitEnd + 1, ');');
str.appendRight(awaitEnd + 1, ' <>');
} else {
thenEnd = htmlx.lastIndexOf('}', awaitBlock.then.start) + 1;
thenStart = htmlx.indexOf('then', awaitBlock.expression.end);

// somePromise then -> somePromise); then
str.overwrite(awaitBlock.expression.end, thenStart, '); ');
}
if (awaitBlock.value) {
str.overwrite(thenStart, awaitBlock.value.start, '__sveltets_awaitThen(_$$p, (');
str.overwrite(awaitBlock.value.end, thenEnd, ') => {<>');
} else {
str.overwrite(thenStart, thenEnd, '__sveltets_awaitThen(_$$p, () => {<>');
}
//{:catch error} ->
//</>}, (error) => {<>
if (!awaitBlock.catch.skip) {
//catch block includes the {:catch}
const catchStart = awaitBlock.catch.start;
const catchSymbolEnd = htmlx.indexOf(':catch', catchStart) + ':catch'.length;

const errorStart = awaitBlock.error ? awaitBlock.error.start : catchSymbolEnd;
const errorEnd = awaitBlock.error ? awaitBlock.error.end : errorStart;
const catchEnd = htmlx.indexOf('}', errorEnd) + 1;
str.overwrite(catchStart, errorStart, '</>}, (');
str.overwrite(errorEnd, catchEnd, ') => {<>');
}
// {/await} ->
// <>})}
const awaitEndStart = htmlx.lastIndexOf('{', awaitBlock.end);
str.overwrite(awaitEndStart, awaitBlock.end, '</>})}}');
};

const handleComment = (node: Node) => {
str.remove(node.start, node.end);
};
Expand Down Expand Up @@ -628,7 +574,7 @@ export function convertHtmlxToJsx(
handleElse(node, parent);
break;
case 'AwaitBlock':
handleAwait(node);
handleAwait(htmlx, str, node);
break;
case 'RawMustacheTag':
handleRaw(node);
Expand Down
83 changes: 83 additions & 0 deletions packages/svelte2tsx/src/htmlxtojsx/nodes/await-block.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import MagicString from 'magic-string';
import { Node } from 'estree-walker';

/**
* Transform {#await ...} into something JSX understands
*/
export function handleAwait(htmlx: string, str: MagicString, awaitBlock: Node): void {
// {#await somePromise then value} ->
// {() => {let _$$p = (somePromise);
str.overwrite(awaitBlock.start, awaitBlock.expression.start, '{() => {let _$$p = (');

// then value } | {:then value} | {await ..} .. {/await} ->
// __sveltets_awaitThen(_$$p, (value) => {<>
let thenStart: number;
let thenEnd: number;
if (!awaitBlock.then.skip) {
// then value } | {:then value}
if (!awaitBlock.pending.skip) {
// {await ...} ... {:then ...}
// thenBlock includes the {:then}
thenStart = awaitBlock.then.start;
if (awaitBlock.value) {
thenEnd = htmlx.indexOf('}', awaitBlock.value.end) + 1;
} else {
thenEnd = htmlx.indexOf('}', awaitBlock.then.start) + 1;
}
str.prependLeft(thenStart, '</>; ');
// add the start tag too
const awaitEnd = htmlx.indexOf('}', awaitBlock.expression.end);

// somePromise} -> somePromise);
str.overwrite(awaitBlock.expression.end, awaitEnd + 1, ');');
str.appendRight(awaitEnd + 1, ' <>');
} else {
// {await ... then ...}
thenStart = htmlx.indexOf('then', awaitBlock.expression.end);
thenEnd = htmlx.lastIndexOf('}', awaitBlock.then.start) + 1;
// somePromise then -> somePromise); then
str.overwrite(awaitBlock.expression.end, thenStart, '); ');
}
} else {
// {await ..} ... ({:catch ..}) {/await} -> no then block, no value, but always a pending block
thenEnd = awaitBlock.catch.skip
? htmlx.lastIndexOf('{', awaitBlock.end)
: awaitBlock.catch.start;
thenStart = Math.min(awaitBlock.pending.end + 1, thenEnd);

const awaitEnd = htmlx.indexOf('}', awaitBlock.expression.end);
str.overwrite(awaitBlock.expression.end, awaitEnd + 1, ');');
str.appendRight(awaitEnd + 1, ' <>');
str.appendLeft(thenEnd, '</>; ');
}

if (awaitBlock.value) {
str.overwrite(thenStart, awaitBlock.value.start, '__sveltets_awaitThen(_$$p, (');
str.overwrite(awaitBlock.value.end, thenEnd, ') => {<>');
} else {
const awaitThenFn = '__sveltets_awaitThen(_$$p, () => {<>';
if (thenStart === thenEnd) {
str.appendLeft(thenStart, awaitThenFn);
} else {
str.overwrite(thenStart, thenEnd, awaitThenFn);
}
}

//{:catch error} ->
//</>}, (error) => {<>
if (!awaitBlock.catch.skip) {
//catch block includes the {:catch}
const catchStart = awaitBlock.catch.start;
const catchSymbolEnd = htmlx.indexOf(':catch', catchStart) + ':catch'.length;

const errorStart = awaitBlock.error ? awaitBlock.error.start : catchSymbolEnd;
const errorEnd = awaitBlock.error ? awaitBlock.error.end : errorStart;
const catchEnd = htmlx.indexOf('}', errorEnd) + 1;
str.overwrite(catchStart, errorStart, '</>}, (');
str.overwrite(errorEnd, catchEnd, ') => {<>');
}
// {/await} ->
// <>})}
const awaitEndStart = htmlx.lastIndexOf('{', awaitBlock.end);
str.overwrite(awaitEndStart, awaitBlock.end, '</>})}}');
}
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<>{() => {let _$$p = (aPromise); <>
<div>Spinner...</div>
</>; __sveltets_awaitThen(_$$p, () => {<></>})}}

{() => {let _$$p = (aPromise); <>
<div>Spinner...</div>
</>; __sveltets_awaitThen(_$$p, () => {<></>}, (error) => {<>
<div>Ups: {error}</div>
</>})}}</>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{#await aPromise}
<div>Spinner...</div>
{/await}

{#await aPromise}
<div>Spinner...</div>
{:catch error}
<div>Ups: {error}</div>
{/await}

0 comments on commit 7a732e7

Please sign in to comment.