diff --git a/src/generators/nodes/AwaitBlock.ts b/src/generators/nodes/AwaitBlock.ts index 02847d93d6..a919f7b1e6 100644 --- a/src/generators/nodes/AwaitBlock.ts +++ b/src/generators/nodes/AwaitBlock.ts @@ -6,16 +6,31 @@ import PendingBlock from './PendingBlock'; import ThenBlock from './ThenBlock'; import CatchBlock from './CatchBlock'; import createDebuggingComment from '../../utils/createDebuggingComment'; +import Expression from './shared/Expression'; export default class AwaitBlock extends Node { + expression: Expression; value: string; error: string; - expression: Node; pending: PendingBlock; then: ThenBlock; catch: CatchBlock; + constructor(compiler, parent, scope, info) { + super(compiler, parent, scope, info); + + this.expression = new Expression(compiler, this, scope, info.expression); + const deps = this.expression.dependencies; + + this.value = info.value; + this.error = info.error; + + this.pending = new PendingBlock(compiler, this, scope, info.pending); + this.then = new ThenBlock(compiler, this, scope.add(this.value, deps), info.then); + this.catch = new CatchBlock(compiler, this, scope.add(this.error, deps), info.catch); + } + init( block: Block, stripWhitespace: boolean, @@ -24,7 +39,7 @@ export default class AwaitBlock extends Node { this.cannotUseInnerHTML(); this.var = block.getUniqueName('await_block'); - block.addDependencies(this.metadata.dependencies); + block.addDependencies(this.expression.dependencies); let dynamic = false; @@ -36,8 +51,8 @@ export default class AwaitBlock extends Node { const child = this[status]; child.block = block.child({ - comment: createDebuggingComment(child, this.generator), - name: this.generator.getUniqueName(`create_${status}_block`), + comment: createDebuggingComment(child, this.compiler), + name: this.compiler.getUniqueName(`create_${status}_block`), contexts: new Map(block.contexts), contextTypes: new Map(block.contextTypes) }); @@ -49,7 +64,7 @@ export default class AwaitBlock extends Node { } child.initChildren(child.block, stripWhitespace, nextSibling); - this.generator.blocks.push(child.block); + this.compiler.blocks.push(child.block); if (child.block.dependencies.size > 0) { dynamic = true; @@ -72,8 +87,7 @@ export default class AwaitBlock extends Node { const anchor = this.getOrCreateAnchor(block, parentNode, parentNodes); const updateMountNode = this.getUpdateMountNode(anchor); - block.contextualise(this.expression); - const { snippet } = this.metadata; + const { snippet } = this.expression; const promise = block.getUniqueName(`promise`); const resolved = block.getUniqueName(`resolved`); @@ -101,11 +115,11 @@ export default class AwaitBlock extends Node { // but it's probably not worth it block.builders.init.addBlock(deindent` - function ${replace_await_block}(${token}, type, state) { + function ${replace_await_block}(${token}, type, ctx) { if (${token} !== ${await_token}) return; var ${old_block} = ${await_block}; - ${await_block} = type && (${await_block_type} = type)(#component, state); + ${await_block} = type && (${await_block_type} = type)(#component, ctx); if (${old_block}) { ${old_block}.u(); @@ -117,23 +131,23 @@ export default class AwaitBlock extends Node { } } - function ${handle_promise}(${promise}, state) { + function ${handle_promise}(${promise}, ctx) { var ${token} = ${await_token} = {}; if (@isPromise(${promise})) { ${promise}.then(function(${value}) { - ${this.then.block.context ? deindent` - var state = #component.get(); - ${resolved} = { ${this.then.block.context}: ${value} }; - ${replace_await_block}(${token}, ${create_then_block}, @assign(@assign({}, state), ${resolved})); + ${this.value ? deindent` + var ctx = #component.get(); + ${resolved} = { ${this.value}: ${value} }; + ${replace_await_block}(${token}, ${create_then_block}, @assign(@assign({}, ctx), ${resolved})); ` : deindent` ${replace_await_block}(${token}, null, null); `} }, function (${error}) { - ${this.catch.block.context ? deindent` - var state = #component.get(); - ${resolved} = { ${this.catch.block.context}: ${error} }; - ${replace_await_block}(${token}, ${create_catch_block}, @assign(@assign({}, state), ${resolved})); + ${this.error ? deindent` + var ctx = #component.get(); + ${resolved} = { ${this.error}: ${error} }; + ${replace_await_block}(${token}, ${create_catch_block}, @assign(@assign({}, ctx), ${resolved})); ` : deindent` ${replace_await_block}(${token}, null, null); `} @@ -141,19 +155,19 @@ export default class AwaitBlock extends Node { // if we previously had a then/catch block, destroy it if (${await_block_type} !== ${create_pending_block}) { - ${replace_await_block}(${token}, ${create_pending_block}, state); + ${replace_await_block}(${token}, ${create_pending_block}, ctx); return true; } } else { - ${resolved} = { ${this.then.block.context}: ${promise} }; + ${resolved} = { ${this.value}: ${promise} }; if (${await_block_type} !== ${create_then_block}) { - ${replace_await_block}(${token}, ${create_then_block}, @assign(@assign({}, state), ${resolved})); + ${replace_await_block}(${token}, ${create_then_block}, @assign(@assign({}, ctx), ${resolved})); return true; } } } - ${handle_promise}(${promise} = ${snippet}, state); + ${handle_promise}(${promise} = ${snippet}, ctx); `); block.builders.create.addBlock(deindent` @@ -174,15 +188,15 @@ export default class AwaitBlock extends Node { `); const conditions = []; - if (this.metadata.dependencies) { + if (this.expression.dependencies.size > 0) { conditions.push( - `(${this.metadata.dependencies.map(dep => `'${dep}' in changed`).join(' || ')})` + `(${[...this.expression.dependencies].map(dep => `'${dep}' in changed`).join(' || ')})` ); } conditions.push( `${promise} !== (${promise} = ${snippet})`, - `${handle_promise}(${promise}, state)` + `${handle_promise}(${promise}, ctx)` ); if (this.pending.block.hasUpdateMethod) { @@ -190,7 +204,7 @@ export default class AwaitBlock extends Node { if (${conditions.join(' && ')}) { // nothing } else { - ${await_block}.p(changed, @assign(@assign({}, state), ${resolved})); + ${await_block}.p(changed, @assign(@assign({}, ctx), ${resolved})); } `); } else { diff --git a/src/generators/nodes/CatchBlock.ts b/src/generators/nodes/CatchBlock.ts index 2ba5709eeb..db15f7ceb1 100644 --- a/src/generators/nodes/CatchBlock.ts +++ b/src/generators/nodes/CatchBlock.ts @@ -1,7 +1,13 @@ import Node from './shared/Node'; import Block from '../dom/Block'; +import mapChildren from './shared/mapChildren'; export default class CatchBlock extends Node { block: Block; children: Node[]; + + constructor(compiler, parent, scope, info) { + super(compiler, parent, scope, info); + this.children = mapChildren(compiler, parent, scope, info.children); + } } \ No newline at end of file diff --git a/src/generators/nodes/Fragment.ts b/src/generators/nodes/Fragment.ts index a7ba6a094f..5d3b1c5fb6 100644 --- a/src/generators/nodes/Fragment.ts +++ b/src/generators/nodes/Fragment.ts @@ -19,6 +19,7 @@ class TemplateScope { add(name, dependencies) { this.names.add(name); this.dependenciesForName.set(name, dependencies); + return this; } child() { diff --git a/src/generators/nodes/PendingBlock.ts b/src/generators/nodes/PendingBlock.ts index fc7a3dd1c0..5359d3de65 100644 --- a/src/generators/nodes/PendingBlock.ts +++ b/src/generators/nodes/PendingBlock.ts @@ -1,7 +1,13 @@ import Node from './shared/Node'; import Block from '../dom/Block'; +import mapChildren from './shared/mapChildren'; export default class PendingBlock extends Node { block: Block; children: Node[]; + + constructor(compiler, parent, scope, info) { + super(compiler, parent, scope, info); + this.children = mapChildren(compiler, parent, scope, info.children); + } } \ No newline at end of file diff --git a/src/generators/nodes/ThenBlock.ts b/src/generators/nodes/ThenBlock.ts index d7d8cedc03..735f48a73a 100644 --- a/src/generators/nodes/ThenBlock.ts +++ b/src/generators/nodes/ThenBlock.ts @@ -1,7 +1,13 @@ import Node from './shared/Node'; import Block from '../dom/Block'; +import mapChildren from './shared/mapChildren'; export default class ThenBlock extends Node { block: Block; children: Node[]; + + constructor(compiler, parent, scope, info) { + super(compiler, parent, scope, info); + this.children = mapChildren(compiler, parent, scope, info.children); + } } \ No newline at end of file diff --git a/src/generators/nodes/shared/mapChildren.ts b/src/generators/nodes/shared/mapChildren.ts index 41d52ef5c5..6bb76383b8 100644 --- a/src/generators/nodes/shared/mapChildren.ts +++ b/src/generators/nodes/shared/mapChildren.ts @@ -1,3 +1,4 @@ +import AwaitBlock from '../AwaitBlock'; import Component from '../Component'; import EachBlock from '../EachBlock'; import Element from '../Element'; @@ -11,6 +12,7 @@ import Node from './Node'; function getConstructor(type): typeof Node { switch (type) { + case 'AwaitBlock': return AwaitBlock; case 'Component': return Component; case 'EachBlock': return EachBlock; case 'Element': return Element;