From bb19637aa1aaffa640140a8edd7912a552dc2a09 Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Tue, 27 Jul 2021 21:58:32 +0800 Subject: [PATCH] [feat] allow shorthand {#await ... then/catch} (#6564) --- src/compiler/parse/state/mustache.ts | 20 +++++-- .../await-catch-no-expression/_config.js | 47 ++++++++++++++++ .../await-catch-no-expression/main.svelte | 15 +++++ .../await-then-no-expression/_config.js | 55 +++++++++++++++++++ .../await-then-no-expression/main.svelte | 23 ++++++++ 5 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 test/runtime/samples/await-catch-no-expression/_config.js create mode 100644 test/runtime/samples/await-catch-no-expression/main.svelte create mode 100644 test/runtime/samples/await-then-no-expression/_config.js create mode 100644 test/runtime/samples/await-then-no-expression/main.svelte diff --git a/src/compiler/parse/state/mustache.ts b/src/compiler/parse/state/mustache.ts index cc3c24349c..584f9d6e9a 100644 --- a/src/compiler/parse/state/mustache.ts +++ b/src/compiler/parse/state/mustache.ts @@ -290,16 +290,24 @@ export default function mustache(parser: Parser) { const await_block_shorthand = type === 'AwaitBlock' && parser.eat('then'); if (await_block_shorthand) { - parser.require_whitespace(); - block.value = read_context(parser); - parser.allow_whitespace(); + if (parser.match_regex(/\s*}/)) { + parser.allow_whitespace(); + } else { + parser.require_whitespace(); + block.value = read_context(parser); + parser.allow_whitespace(); + } } const await_block_catch_shorthand = !await_block_shorthand && type === 'AwaitBlock' && parser.eat('catch'); if (await_block_catch_shorthand) { - parser.require_whitespace(); - block.error = read_context(parser); - parser.allow_whitespace(); + if (parser.match_regex(/\s*}/)) { + parser.allow_whitespace(); + } else { + parser.require_whitespace(); + block.error = read_context(parser); + parser.allow_whitespace(); + } } parser.eat('}', true); diff --git a/test/runtime/samples/await-catch-no-expression/_config.js b/test/runtime/samples/await-catch-no-expression/_config.js new file mode 100644 index 0000000000..5274e60e2d --- /dev/null +++ b/test/runtime/samples/await-catch-no-expression/_config.js @@ -0,0 +1,47 @@ +let fulfil; + +let thePromise = new Promise(f => { + fulfil = f; +}); + +export default { + props: { + thePromise + }, + + html: ` +
+

the promise is pending

+ `, + + async test({ assert, component, target }) { + fulfil(42); + + await thePromise; + + assert.htmlEqual(target.innerHTML, '
'); + + let reject; + + thePromise = new Promise((f, r) => { + reject = r; + }); + + component.thePromise = thePromise; + + assert.htmlEqual(target.innerHTML, ` +
+

the promise is pending

+ `); + + reject(new Error()); + + await thePromise.catch(() => {}); + + assert.htmlEqual(target.innerHTML, ` +

oh no! Something broke!

+
+

oh no! Something broke!

+ `); + } +}; diff --git a/test/runtime/samples/await-catch-no-expression/main.svelte b/test/runtime/samples/await-catch-no-expression/main.svelte new file mode 100644 index 0000000000..0da0d12092 --- /dev/null +++ b/test/runtime/samples/await-catch-no-expression/main.svelte @@ -0,0 +1,15 @@ + + +{#await thePromise catch} +

oh no! Something broke!

+{/await} + +
+ +{#await thePromise} +

the promise is pending

+{:catch} +

oh no! Something broke!

+{/await} diff --git a/test/runtime/samples/await-then-no-expression/_config.js b/test/runtime/samples/await-then-no-expression/_config.js new file mode 100644 index 0000000000..f684da52ed --- /dev/null +++ b/test/runtime/samples/await-then-no-expression/_config.js @@ -0,0 +1,55 @@ +let fulfil; + +let thePromise = new Promise(f => { + fulfil = f; +}); + +export default { + props: { + thePromise + }, + + html: ` +
+
+

the promise is pending

+ `, + + async test({ assert, component, target }) { + fulfil(); + + await thePromise; + + assert.htmlEqual(target.innerHTML, ` +

the promise is resolved

+
+

the promise is resolved

+
+

the promise is resolved

+ `); + + let reject; + + thePromise = new Promise((f, r) => { + reject = r; + }); + + component.thePromise = thePromise; + + assert.htmlEqual(target.innerHTML, ` +
+
+

the promise is pending

+ `); + + reject(new Error('something broke')); + + await thePromise.catch(() => {}); + + assert.htmlEqual(target.innerHTML, ` +

oh no! something broke

+
+
+ `); + } +}; diff --git a/test/runtime/samples/await-then-no-expression/main.svelte b/test/runtime/samples/await-then-no-expression/main.svelte new file mode 100644 index 0000000000..fedc7cd2b7 --- /dev/null +++ b/test/runtime/samples/await-then-no-expression/main.svelte @@ -0,0 +1,23 @@ + + +{#await thePromise then} +

the promise is resolved

+{:catch theError} +

oh no! {theError.message}

+{/await} + +
+ +{#await thePromise then} +

the promise is resolved

+{/await} + +
+ +{#await thePromise} +

the promise is pending

+{:then} +

the promise is resolved

+{/await} \ No newline at end of file