pull/3539/head
Richard Harris 6 years ago
parent 605c5d271c
commit 3470005c29

@ -252,7 +252,11 @@ export default class Block {
const noop = x`@noop`; const noop = x`@noop`;
properties.key = key properties.key = key
properties.first = this.first;
if (this.first) {
properties.first = x`null`;
this.chunks.hydrate.push(b`this.first = ${this.first};`);
}
if (this.chunks.create.length === 0 && this.chunks.hydrate.length === 0) { if (this.chunks.create.length === 0 && this.chunks.hydrate.length === 0) {
properties.create = noop; properties.create = noop;

@ -3,12 +3,13 @@ import Renderer from '../Renderer';
import Block from '../Block'; import Block from '../Block';
import AwaitBlock from '../../nodes/AwaitBlock'; import AwaitBlock from '../../nodes/AwaitBlock';
import create_debugging_comment from './shared/create_debugging_comment'; import create_debugging_comment from './shared/create_debugging_comment';
import { b } from 'code-red'; import { b, x } from 'code-red';
import FragmentWrapper from './Fragment'; import FragmentWrapper from './Fragment';
import PendingBlock from '../../nodes/PendingBlock'; import PendingBlock from '../../nodes/PendingBlock';
import ThenBlock from '../../nodes/ThenBlock'; import ThenBlock from '../../nodes/ThenBlock';
import CatchBlock from '../../nodes/CatchBlock'; import CatchBlock from '../../nodes/CatchBlock';
import { Identifier } from '../../../interfaces'; import { Identifier } from '../../../interfaces';
import { changed } from './shared/changed';
class AwaitBlockBranch extends Wrapper { class AwaitBlockBranch extends Wrapper {
node: PendingBlock | ThenBlock | CatchBlock; node: PendingBlock | ThenBlock | CatchBlock;
@ -136,22 +137,23 @@ export default class AwaitBlockWrapper extends Wrapper {
block.maintain_context = true; block.maintain_context = true;
const info_props = [ const info_props: any = x`{
'#ctx', ctx: #ctx,
'current: null', current: null,
'token: null', token: null,
this.pending.block.name && `pending: ${this.pending.block.name}`, pending: ${this.pending.block.name},
this.then.block.name && `then: ${this.then.block.name}`, then: ${this.then.block.name},
this.catch.block.name && `catch: ${this.catch.block.name}`, catch: ${this.catch.block.name},
this.then.block.name && `value: '${this.node.value}'`, value: ${this.then.block.name && this.node.value},
this.catch.block.name && `error: '${this.node.error}'`, error: ${this.catch.block.name && this.node.error},
this.pending.block.has_outro_method && `blocks: [,,,]` blocks: ${this.pending.block.has_outro_method && x`[,,,]`}
].filter(Boolean); }`;
// TODO move this into code-red
info_props.properties = info_props.properties.filter(prop => prop.value);
block.chunks.init.push(b` block.chunks.init.push(b`
let ${info} = { let ${info} = ${info_props};
${info_props.join(',\n')}
};
`); `);
block.chunks.init.push(b` block.chunks.init.push(b`
@ -183,18 +185,13 @@ export default class AwaitBlockWrapper extends Wrapper {
block.chunks.intro.push(b`@transition_in(${info}.block);`); block.chunks.intro.push(b`@transition_in(${info}.block);`);
} }
const conditions = [];
const dependencies = this.node.expression.dynamic_dependencies(); const dependencies = this.node.expression.dynamic_dependencies();
if (dependencies.length > 0) { if (dependencies.length > 0) {
conditions.push( let condition = x`
`(${dependencies.map(dep => `'${dep}' in changed`).join(' || ')})` ${changed(dependencies)} &&
); ${promise} !== (${promise} = ${snippet}) &&
@handle_promise(${promise}, ${info})`;
conditions.push(
`${promise} !== (${promise} = ${snippet})`,
`@handle_promise(${promise}, ${info})`
);
block.chunks.update.push( block.chunks.update.push(
b`${info}.ctx = #ctx;` b`${info}.ctx = #ctx;`
@ -202,21 +199,21 @@ export default class AwaitBlockWrapper extends Wrapper {
if (this.pending.block.has_update_method) { if (this.pending.block.has_update_method) {
block.chunks.update.push(b` block.chunks.update.push(b`
if (${conditions.join(' && ')}) { if (${condition}) {
// nothing // nothing
} else { } else {
${info}.block.p(changed, @assign(@assign({}, #ctx), ${info}.resolved)); ${info}.block.p(#changed, @assign(@assign({}, #ctx), ${info}.resolved));
} }
`); `);
} else { } else {
block.chunks.update.push(b` block.chunks.update.push(b`
${conditions.join(' && ')} ${condition}
`); `);
} }
} else { } else {
if (this.pending.block.has_update_method) { if (this.pending.block.has_update_method) {
block.chunks.update.push(b` block.chunks.update.push(b`
${info}.block.p(changed, @assign(@assign({}, #ctx), ${info}.resolved)); ${info}.block.p(#changed, @assign(@assign({}, #ctx), ${info}.resolved));
`); `);
} }
} }
@ -231,7 +228,7 @@ export default class AwaitBlockWrapper extends Wrapper {
} }
block.chunks.destroy.push(b` block.chunks.destroy.push(b`
${info}.block.d(${parent_node ? '' : 'detaching'}); ${info}.block.d(${parent_node ? null : 'detaching'});
${info}.token = null; ${info}.token = null;
${info} = null; ${info} = null;
`); `);

@ -56,9 +56,9 @@ class IfBlockBranch extends Wrapper {
if (should_cache) { if (should_cache) {
this.condition = block.get_unique_name(`show_if`); this.condition = block.get_unique_name(`show_if`);
this.snippet = expression.node; this.snippet = (expression.manipulate(block) as Node);
} else { } else {
this.condition = expression.node; this.condition = expression.manipulate(block);
} }
} }
@ -181,14 +181,14 @@ export default class IfBlockWrapper extends Wrapper {
: (this.next && this.next.var) || 'null'; : (this.next && this.next.var) || 'null';
const has_else = !(this.branches[this.branches.length - 1].condition); const has_else = !(this.branches[this.branches.length - 1].condition);
const if_name = has_else ? '' : `if (${name}) `; const if_exists_condition = has_else ? x`true` : name;
const dynamic = this.branches[0].block.has_update_method; // can use [0] as proxy for all, since they necessarily have the same value const dynamic = this.branches[0].block.has_update_method; // can use [0] as proxy for all, since they necessarily have the same value
const has_intros = this.branches[0].block.has_intro_method; const has_intros = this.branches[0].block.has_intro_method;
const has_outros = this.branches[0].block.has_outro_method; const has_outros = this.branches[0].block.has_outro_method;
const has_transitions = has_intros || has_outros; const has_transitions = has_intros || has_outros;
const vars = { name, anchor, if_name, has_else, has_transitions }; const vars = { name, anchor, if_exists_condition, has_else, has_transitions };
const detaching = (parent_node && parent_node !== '@_document.head') ? '' : 'detaching'; const detaching = (parent_node && parent_node !== '@_document.head') ? '' : 'detaching';
@ -212,11 +212,11 @@ export default class IfBlockWrapper extends Wrapper {
} }
} }
block.chunks.create.push(b`${if_name}${name}.c();`); block.chunks.create.push(b`if (${if_exists_condition}) ${name}.c();`);
if (parent_nodes && this.renderer.options.hydratable) { if (parent_nodes && this.renderer.options.hydratable) {
block.chunks.claim.push( block.chunks.claim.push(
b`${if_name}${name}.l(${parent_nodes});` b`if (${if_exists_condition}) ${name}.l(${parent_nodes});`
); );
} }
@ -243,7 +243,7 @@ export default class IfBlockWrapper extends Wrapper {
parent_node: string, parent_node: string,
_parent_nodes: string, _parent_nodes: string,
dynamic, dynamic,
{ name, anchor, has_else, if_name, has_transitions }, { name, anchor, has_else, if_exists_condition, has_transitions },
detaching detaching
) { ) {
const select_block_type = this.renderer.component.get_unique_name(`select_block_type`); const select_block_type = this.renderer.component.get_unique_name(`select_block_type`);
@ -253,7 +253,7 @@ export default class IfBlockWrapper extends Wrapper {
/* eslint-disable @typescript-eslint/indent,indent */ /* eslint-disable @typescript-eslint/indent,indent */
if (this.needs_update) { if (this.needs_update) {
block.chunks.init.push(b` block.chunks.init.push(b`
function ${select_block_type}(changed, ctx) { function ${select_block_type}(#changed, #ctx) {
${this.branches.map(({ dependencies, condition, snippet, block }) => condition ${this.branches.map(({ dependencies, condition, snippet, block }) => condition
? b` ? b`
${snippet && ( ${snippet && (
@ -267,7 +267,7 @@ export default class IfBlockWrapper extends Wrapper {
`); `);
} else { } else {
block.chunks.init.push(b` block.chunks.init.push(b`
function ${select_block_type}(changed, ctx) { function ${select_block_type}(#changed, #ctx) {
${this.branches.map(({ condition, snippet, block }) => condition ${this.branches.map(({ condition, snippet, block }) => condition
? `if (${snippet || condition}) return ${block.name};` ? `if (${snippet || condition}) return ${block.name};`
: `return ${block.name};`)} : `return ${block.name};`)}
@ -277,22 +277,22 @@ export default class IfBlockWrapper extends Wrapper {
/* eslint-enable @typescript-eslint/indent,indent */ /* eslint-enable @typescript-eslint/indent,indent */
block.chunks.init.push(b` block.chunks.init.push(b`
var ${current_block_type} = ${select_block_type}(null, ctx); let ${current_block_type} = ${select_block_type}(null, #ctx);
var ${name} = ${current_block_type_and}${current_block_type}(ctx); let ${name} = ${current_block_type_and}${current_block_type}(#ctx);
`); `);
const initial_mount_node = parent_node || '#target'; const initial_mount_node = parent_node || '#target';
const anchor_node = parent_node ? 'null' : 'anchor'; const anchor_node = parent_node ? 'null' : 'anchor';
block.chunks.mount.push( block.chunks.mount.push(
b`${if_name}${name}.m(${initial_mount_node}, ${anchor_node});` b`if (${if_exists_condition}) ${name}.m(${initial_mount_node}, ${anchor_node});`
); );
if (this.needs_update) { if (this.needs_update) {
const update_mount_node = this.get_update_mount_node(anchor); const update_mount_node = this.get_update_mount_node(anchor);
const change_block = b` const change_block = b`
${if_name}${name}.d(1); ${if_exists_condition}${name}.d(1);
${name} = ${current_block_type_and}${current_block_type}(ctx); ${name} = ${current_block_type_and}${current_block_type}(#ctx);
if (${name}) { if (${name}) {
${name}.c(); ${name}.c();
${has_transitions && `@transition_in(${name}, 1);`} ${has_transitions && `@transition_in(${name}, 1);`}
@ -302,24 +302,24 @@ export default class IfBlockWrapper extends Wrapper {
if (dynamic) { if (dynamic) {
block.chunks.update.push(b` block.chunks.update.push(b`
if (${current_block_type} === (${current_block_type} = ${select_block_type}(changed, ctx)) && ${name}) { if (${current_block_type} === (${current_block_type} = ${select_block_type}(#changed, #ctx)) && ${name}) {
${name}.p(changed, ctx); ${name}.p(#changed, #ctx);
} else { } else {
${change_block} ${change_block}
} }
`); `);
} else { } else {
block.chunks.update.push(b` block.chunks.update.push(b`
if (${current_block_type} !== (${current_block_type} = ${select_block_type}(changed, ctx))) { if (${current_block_type} !== (${current_block_type} = ${select_block_type}(#changed, #ctx))) {
${change_block} ${change_block}
} }
`); `);
} }
} else if (dynamic) { } else if (dynamic) {
block.chunks.update.push(b`${name}.p(changed, ctx);`); block.chunks.update.push(b`${name}.p(#changed, #ctx);`);
} }
block.chunks.destroy.push(b`${if_name}${name}.d(${detaching});`); block.chunks.destroy.push(b`if (${if_exists_condition}) ${name}.d(${detaching});`);
} }
// if any of the siblings have outros, we need to keep references to the blocks // if any of the siblings have outros, we need to keep references to the blocks
@ -347,15 +347,15 @@ export default class IfBlockWrapper extends Wrapper {
/* eslint-disable @typescript-eslint/indent,indent */ /* eslint-disable @typescript-eslint/indent,indent */
block.chunks.init.push(b` block.chunks.init.push(b`
var ${if_block_creators} = [ const ${if_block_creators} = [
${this.branches.map(branch => branch.block.name).join(',\n')} ${this.branches.map(branch => branch.block.name).join(',\n')}
]; ];
var ${if_blocks} = []; const ${if_blocks} = [];
${this.needs_update ${this.needs_update
? b` ? b`
function ${select_block_type}(changed, ctx) { function ${select_block_type}(#changed, #ctx) {
${this.branches.map(({ dependencies, condition, snippet }, i) => condition ${this.branches.map(({ dependencies, condition, snippet }, i) => condition
? b` ? b`
${snippet && `if ((${condition} == null) || ${dependencies.map(n => `changed.${n}`).join(' || ')}) ${condition} = !!(${snippet})`} ${snippet && `if ((${condition} == null) || ${dependencies.map(n => `changed.${n}`).join(' || ')}) ${condition} = !!(${snippet})`}
@ -365,7 +365,7 @@ export default class IfBlockWrapper extends Wrapper {
} }
` `
: b` : b`
function ${select_block_type}(changed, ctx) { function ${select_block_type}(#changed, #ctx) {
${this.branches.map(({ condition, snippet }, i) => condition ${this.branches.map(({ condition, snippet }, i) => condition
? `if (${snippet || condition}) return ${String(i)};` ? `if (${snippet || condition}) return ${String(i)};`
: `return ${i};`)} : `return ${i};`)}
@ -377,13 +377,13 @@ export default class IfBlockWrapper extends Wrapper {
if (has_else) { if (has_else) {
block.chunks.init.push(b` block.chunks.init.push(b`
${current_block_type_index} = ${select_block_type}(null, ctx); ${current_block_type_index} = ${select_block_type}(null, #ctx);
${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](ctx); ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#ctx);
`); `);
} else { } else {
block.chunks.init.push(b` block.chunks.init.push(b`
if (~(${current_block_type_index} = ${select_block_type}(null, ctx))) { if (~(${current_block_type_index} = ${select_block_type}(null, #ctx))) {
${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](ctx); ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#ctx);
} }
`); `);
} }
@ -409,7 +409,7 @@ export default class IfBlockWrapper extends Wrapper {
const create_new_block = b` const create_new_block = b`
${name} = ${if_blocks}[${current_block_type_index}]; ${name} = ${if_blocks}[${current_block_type_index}];
if (!${name}) { if (!${name}) {
${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](ctx); ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#ctx);
${name}.c(); ${name}.c();
} }
${has_transitions && `@transition_in(${name}, 1);`} ${has_transitions && `@transition_in(${name}, 1);`}
@ -436,25 +436,25 @@ export default class IfBlockWrapper extends Wrapper {
if (dynamic) { if (dynamic) {
block.chunks.update.push(b` block.chunks.update.push(b`
var ${previous_block_index} = ${current_block_type_index}; let ${previous_block_index} = ${current_block_type_index};
${current_block_type_index} = ${select_block_type}(changed, ctx); ${current_block_type_index} = ${select_block_type}(#changed, #ctx);
if (${current_block_type_index} === ${previous_block_index}) { if (${current_block_type_index} === ${previous_block_index}) {
${if_current_block_type_index}${if_blocks}[${current_block_type_index}].p(changed, ctx); ${if_current_block_type_index}${if_blocks}[${current_block_type_index}].p(#changed, #ctx);
} else { } else {
${change_block} ${change_block}
} }
`); `);
} else { } else {
block.chunks.update.push(b` block.chunks.update.push(b`
var ${previous_block_index} = ${current_block_type_index}; let ${previous_block_index} = ${current_block_type_index};
${current_block_type_index} = ${select_block_type}(changed, ctx); ${current_block_type_index} = ${select_block_type}(#changed, #ctx);
if (${current_block_type_index} !== ${previous_block_index}) { if (${current_block_type_index} !== ${previous_block_index}) {
${change_block} ${change_block}
} }
`); `);
} }
} else if (dynamic) { } else if (dynamic) {
block.chunks.update.push(b`${name}.p(changed, ctx);`); block.chunks.update.push(b`${name}.p(#changed, #ctx);`);
} }
block.chunks.destroy.push(b` block.chunks.destroy.push(b`
@ -467,7 +467,7 @@ export default class IfBlockWrapper extends Wrapper {
parent_node: string, parent_node: string,
_parent_nodes: string, _parent_nodes: string,
dynamic, dynamic,
{ name, anchor, if_name, has_transitions }, { name, anchor, if_exists_condition, has_transitions },
detaching detaching
) { ) {
const branch = this.branches[0]; const branch = this.branches[0];
@ -475,7 +475,7 @@ export default class IfBlockWrapper extends Wrapper {
if (branch.snippet) block.add_variable(branch.condition, branch.snippet); if (branch.snippet) block.add_variable(branch.condition, branch.snippet);
block.chunks.init.push(b` block.chunks.init.push(b`
var ${name} = (${branch.condition}) && ${branch.block.name}(ctx); let ${name} = ${branch.condition} && ${branch.block.name}(#ctx);
`); `);
const initial_mount_node = parent_node || '#target'; const initial_mount_node = parent_node || '#target';
@ -491,10 +491,10 @@ export default class IfBlockWrapper extends Wrapper {
const enter = dynamic const enter = dynamic
? b` ? b`
if (${name}) { if (${name}) {
${name}.p(changed, ctx); ${name}.p(#changed, #ctx);
${has_transitions && `@transition_in(${name}, 1);`} ${has_transitions && `@transition_in(${name}, 1);`}
} else { } else {
${name} = ${branch.block.name}(ctx); ${name} = ${branch.block.name}(#ctx);
${name}.c(); ${name}.c();
${has_transitions && `@transition_in(${name}, 1);`} ${has_transitions && `@transition_in(${name}, 1);`}
${name}.m(${update_mount_node}, ${anchor}); ${name}.m(${update_mount_node}, ${anchor});
@ -502,7 +502,7 @@ export default class IfBlockWrapper extends Wrapper {
` `
: b` : b`
if (!${name}) { if (!${name}) {
${name} = ${branch.block.name}(ctx); ${name} = ${branch.block.name}(#ctx);
${name}.c(); ${name}.c();
${has_transitions && `@transition_in(${name}, 1);`} ${has_transitions && `@transition_in(${name}, 1);`}
${name}.m(${update_mount_node}, ${anchor}); ${name}.m(${update_mount_node}, ${anchor});
@ -539,10 +539,10 @@ export default class IfBlockWrapper extends Wrapper {
} }
} else if (dynamic) { } else if (dynamic) {
block.chunks.update.push( block.chunks.update.push(
b`if (${branch.condition}) ${name}.p(changed, ctx);` b`if (${branch.condition}) ${name}.p(#changed, #ctx);`
); );
} }
block.chunks.destroy.push(b`${if_name}${name}.d(${detaching});`); block.chunks.destroy.push(b`if (${if_exists_condition}) ${name}.d(${detaching});`);
} }
} }

@ -15,6 +15,7 @@ import TemplateScope from '../../../nodes/shared/TemplateScope';
import is_dynamic from '../shared/is_dynamic'; import is_dynamic from '../shared/is_dynamic';
import bind_this from '../shared/bind_this'; import bind_this from '../shared/bind_this';
import { Identifier } from '../../../../interfaces'; import { Identifier } from '../../../../interfaces';
import { changed } from '../shared/changed';
export default class InlineComponentWrapper extends Wrapper { export default class InlineComponentWrapper extends Wrapper {
var: Identifier; var: Identifier;
@ -119,7 +120,7 @@ export default class InlineComponentWrapper extends Wrapper {
const updates: string[] = []; const updates: string[] = [];
let props; let props;
const name_changes = block.get_unique_name(`${name}_changes`); const name_changes = block.get_unique_name(`${name.name}_changes`);
const uses_spread = !!this.node.attributes.find(a => a.is_spread); const uses_spread = !!this.node.attributes.find(a => a.is_spread);
@ -214,7 +215,7 @@ export default class InlineComponentWrapper extends Wrapper {
const dynamic_attributes = this.node.attributes.filter(a => a.get_dependencies().length > 0); const dynamic_attributes = this.node.attributes.filter(a => a.get_dependencies().length > 0);
if (!uses_spread && (dynamic_attributes.length > 0 || this.node.bindings.length > 0 || non_let_dependencies.length > 0)) { if (!uses_spread && (dynamic_attributes.length > 0 || this.node.bindings.length > 0 || non_let_dependencies.length > 0)) {
updates.push(`const ${name_changes} = {};`); updates.push(b`const ${name_changes} = {};`);
} }
if (this.node.attributes.length) { if (this.node.attributes.length) {
@ -224,7 +225,7 @@ export default class InlineComponentWrapper extends Wrapper {
const initial_props = []; const initial_props = [];
const changes = []; const changes = [];
const all_dependencies = new Set(); const all_dependencies: Set<string> = new Set();
this.node.attributes.forEach(attr => { this.node.attributes.forEach(attr => {
add_to_set(all_dependencies, attr.dependencies); add_to_set(all_dependencies, attr.dependencies);
@ -266,18 +267,24 @@ export default class InlineComponentWrapper extends Wrapper {
} }
`); `);
const conditions = Array.from(all_dependencies).map(dep => `changed.${dep}`).join(' || '); if (all_dependencies.size) {
const condition = changed(Array.from(all_dependencies));
updates.push(b` updates.push(b`
const ${name_changes} = ${conditions ? `(${conditions}) ? @get_spread_update(${levels}, [ const ${name_changes} = ${condition} ? @get_spread_update(${levels}, [
${changes.join(',\n')} ${changes.join(',\n')}
]) : {}` : '{}'}; ]) : {}
`); `);
} else {
updates.push(b`
const ${name_changes} = {};
`);
}
} else { } else {
dynamic_attributes.forEach((attribute: Attribute) => { dynamic_attributes.forEach((attribute: Attribute) => {
const dependencies = attribute.get_dependencies(); const dependencies = attribute.get_dependencies();
if (dependencies.length > 0) { if (dependencies.length > 0) {
const condition = dependencies.map(dependency => `changed.${dependency}`).join(' || '); const condition = changed(dependencies);
updates.push(b` updates.push(b`
if (${condition}) ${name_changes}${quote_prop_if_necessary(attribute.name)} = ${attribute.get_value(block)}; if (${condition}) ${name_changes}${quote_prop_if_necessary(attribute.name)} = ${attribute.get_value(block)};
@ -288,7 +295,7 @@ export default class InlineComponentWrapper extends Wrapper {
} }
if (non_let_dependencies.length > 0) { if (non_let_dependencies.length > 0) {
updates.push(`if (${non_let_dependencies.map(n => `changed.${n}`).join(' || ')}) ${name_changes}.$$scope = { changed: #changed, ctx: #ctx };`); updates.push(`if (${changed(non_let_dependencies)} ${name_changes}.$$scope = { changed: #changed, ctx: #ctx };`);
} }
const munged_bindings = this.node.bindings.map(binding => { const munged_bindings = this.node.bindings.map(binding => {

Loading…
Cancel
Save