separate unmount from destroy

pull/603/head
Rich Harris 8 years ago
parent 77fb38a123
commit 5c055a9f0c

@ -42,10 +42,10 @@ export default class Block {
builders: { builders: {
create: CodeBuilder; create: CodeBuilder;
mount: CodeBuilder; mount: CodeBuilder;
update: CodeBuilder;
intro: CodeBuilder; intro: CodeBuilder;
update: CodeBuilder;
outro: CodeBuilder; outro: CodeBuilder;
detach: CodeBuilder; unmount: CodeBuilder;
detachRaw: CodeBuilder; detachRaw: CodeBuilder;
destroy: CodeBuilder; destroy: CodeBuilder;
} }
@ -88,10 +88,10 @@ export default class Block {
this.builders = { this.builders = {
create: new CodeBuilder(), create: new CodeBuilder(),
mount: new CodeBuilder(), mount: new CodeBuilder(),
update: new CodeBuilder(),
intro: new CodeBuilder(), intro: new CodeBuilder(),
update: new CodeBuilder(),
outro: new CodeBuilder(), outro: new CodeBuilder(),
detach: new CodeBuilder(), unmount: new CodeBuilder(),
detachRaw: new CodeBuilder(), detachRaw: new CodeBuilder(),
destroy: new CodeBuilder() destroy: new CodeBuilder()
}; };
@ -130,7 +130,7 @@ export default class Block {
} }
if ( isToplevel ) { if ( isToplevel ) {
this.builders.detach.addLine( `${this.generator.helper( 'detachNode' )}( ${name} );` ); this.builders.unmount.addLine( `${this.generator.helper( 'detachNode' )}( ${name} );` );
} }
} }
@ -202,15 +202,7 @@ export default class Block {
// minor hack we need to ensure that any {{{triples}}} are detached // minor hack we need to ensure that any {{{triples}}} are detached
// first, so we append normal detach statements to detachRaw // first, so we append normal detach statements to detachRaw
this.builders.detachRaw.addBlock( this.builders.detach ); this.builders.detachRaw.addBlock( this.builders.unmount ); // TODO reverse this, using addBlockAtStart?
if ( !this.builders.detachRaw.isEmpty() ) {
this.builders.destroy.addBlock( deindent`
if ( detach ) {
${this.builders.detachRaw}
}
` );
}
const properties = new CodeBuilder(); const properties = new CodeBuilder();
@ -290,11 +282,22 @@ export default class Block {
} }
} }
if ( this.builders.detachRaw.isEmpty() ) {
properties.addBlock( `unmount: ${this.generator.helper('noop')},`);
} else {
properties.addBlock( deindent`
unmount: function () {
${this.builders.detachRaw}
},
` );
}
if ( this.builders.destroy.isEmpty() ) { if ( this.builders.destroy.isEmpty() ) {
properties.addBlock( `destroy: ${this.generator.helper( 'noop' )}` ); properties.addBlock( `destroy: ${this.generator.helper( 'noop' )}` );
} else { } else {
properties.addBlock( deindent` properties.addBlock( deindent`
destroy: function ( detach ) { destroy: function ( detach ) {
${!this.builders.detachRaw.isEmpty() && `if ( detach ) this.unmount();`}
${this.builders.destroy} ${this.builders.destroy}
} }
` ); ` );

@ -191,7 +191,8 @@ export default function dom ( parsed: Parsed, source: string, options: CompileOp
this.fire( 'destroy' ); this.fire( 'destroy' );
${templateProperties.ondestroy && `${generator.alias( 'template' )}.ondestroy.call( this );`} ${templateProperties.ondestroy && `${generator.alias( 'template' )}.ondestroy.call( this );`}
this._fragment.destroy( detach !== false ); if ( detach !== false ) this._fragment.unmount();
this._fragment.destroy( false ); // TODO no arguments to destroy
this._fragment = null; this._fragment = null;
this._state = {}; this._state = {};

@ -56,7 +56,7 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
update: new CodeBuilder() update: new CodeBuilder()
}; };
const isToplevel = !state.parentNode; const isTopLevel = !state.parentNode;
generator.hasComponents = true; generator.hasComponents = true;
@ -95,7 +95,7 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
} }
const componentInitProperties = [ const componentInitProperties = [
`target: ${!isToplevel ? state.parentNode: 'null'}`, `target: ${!isTopLevel ? state.parentNode: 'null'}`,
`_root: ${block.component}._root` `_root: ${block.component}._root`
]; ];
@ -121,6 +121,10 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
); );
} }
block.builders.destroy.addLine(
`${yieldFragment}.destroy( false );`
);
componentInitProperties.push( `_yield: ${yieldFragment}`); componentInitProperties.push( `_yield: ${yieldFragment}`);
} }
@ -157,7 +161,7 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
}); });
` ); ` );
if ( isToplevel ) { if ( isTopLevel ) {
block.builders.mount.addLine( `${name}._fragment.mount( ${block.target}, anchor );` ); block.builders.mount.addLine( `${name}._fragment.mount( ${block.target}, anchor );` );
} }
@ -183,7 +187,8 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
` ); ` );
} }
block.builders.destroy.addLine( `${name}.destroy( ${isToplevel ? 'detach' : 'false'} );` ); if ( isTopLevel ) block.builders.unmount.addLine( `${name}._fragment.unmount();` );
block.builders.destroy.addLine( `${name}.destroy( false );` );
block.builders.create.addBlock( local.create ); block.builders.create.addBlock( local.create );
if ( !local.update.isEmpty() ) block.builders.update.addBlock( local.update ); if ( !local.update.isEmpty() ) block.builders.update.addBlock( local.update );

@ -64,7 +64,8 @@ export default function visitEachBlock ( generator: DomGenerator, block: Block,
${each_block_else} = ${node.else._block.name}( ${params}, ${block.component} ); ${each_block_else} = ${node.else._block.name}( ${params}, ${block.component} );
${each_block_else}.${mountOrIntro}( ${parentNode}, ${anchor} ); ${each_block_else}.${mountOrIntro}( ${parentNode}, ${anchor} );
} else if ( ${each_block_else} ) { } else if ( ${each_block_else} ) {
${each_block_else}.destroy( true ); ${each_block_else}.unmount();
${each_block_else}.destroy();
${each_block_else} = null; ${each_block_else} = null;
} }
` ); ` );
@ -72,7 +73,8 @@ export default function visitEachBlock ( generator: DomGenerator, block: Block,
block.builders.update.addBlock( deindent` block.builders.update.addBlock( deindent`
if ( ${each_block_value}.length ) { if ( ${each_block_value}.length ) {
if ( ${each_block_else} ) { if ( ${each_block_else} ) {
${each_block_else}.destroy( true ); ${each_block_else}.unmount();
${each_block_else}.destroy();
${each_block_else} = null; ${each_block_else} = null;
} }
} else if ( !${each_block_else} ) { } else if ( !${each_block_else} ) {
@ -82,11 +84,12 @@ export default function visitEachBlock ( generator: DomGenerator, block: Block,
` ); ` );
} }
block.builders.unmount.addLine(
`if ( ${each_block_else} ) ${each_block_else}.unmount()`
);
block.builders.destroy.addBlock( deindent` block.builders.destroy.addBlock( deindent`
if ( ${each_block_else} ) { if ( ${each_block_else} ) ${each_block_else}.destroy( false );
${each_block_else}.destroy( ${isToplevel ? 'detach' : 'false'} );
}
` ); ` );
} }
@ -154,7 +157,8 @@ function keyed ( generator: DomGenerator, block: Block, state: State, node: Node
block.builders.create.addBlock( deindent` block.builders.create.addBlock( deindent`
function ${fn} ( iteration ) { function ${fn} ( iteration ) {
iteration.outro( function () { iteration.outro( function () {
iteration.destroy( true ); iteration.unmount();
iteration.destroy();
${lookup}[iteration.key] = null; ${lookup}[iteration.key] = null;
}); });
} }
@ -176,7 +180,8 @@ function keyed ( generator: DomGenerator, block: Block, state: State, node: Node
const fn = block.getUniqueName( `${each_block}_destroy` ); const fn = block.getUniqueName( `${each_block}_destroy` );
block.builders.create.addBlock( deindent` block.builders.create.addBlock( deindent`
function ${fn} ( iteration ) { function ${fn} ( iteration ) {
iteration.destroy( true ); iteration.unmount();
iteration.destroy();
${lookup}[iteration.key] = null; ${lookup}[iteration.key] = null;
} }
` ); ` );
@ -262,10 +267,20 @@ function keyed ( generator: DomGenerator, block: Block, state: State, node: Node
${head} = ${lookup}[${each_block_value}[0] && ${each_block_value}[0].${node.key}]; ${head} = ${lookup}[${each_block_value}[0] && ${each_block_value}[0].${node.key}];
` ); ` );
if ( !state.parentNode ) {
block.builders.unmount.addBlock( deindent`
var ${iteration} = ${head};
while ( ${iteration} ) {
${iteration}.unmount();
${iteration} = ${iteration}.next;
}
` );
}
block.builders.destroy.addBlock( deindent` block.builders.destroy.addBlock( deindent`
var ${iteration} = ${head}; var ${iteration} = ${head};
while ( ${iteration} ) { while ( ${iteration} ) {
${iteration}.destroy( ${state.parentNode ? 'false' : 'detach'} ); ${iteration}.destroy( false );
${iteration} = ${iteration}.next; ${iteration} = ${iteration}.next;
} }
` ); ` );
@ -334,7 +349,8 @@ function unkeyed ( generator: DomGenerator, block: Block, state: State, node: No
function ${outro} ( i ) { function ${outro} ( i ) {
if ( ${iterations}[i] ) { if ( ${iterations}[i] ) {
${iterations}[i].outro( function () { ${iterations}[i].outro( function () {
${iterations}[i].destroy( true ); ${iterations}[i].unmount();
${iterations}[i].destroy();
${iterations}[i] = null; ${iterations}[i] = null;
}); });
} }
@ -343,7 +359,10 @@ function unkeyed ( generator: DomGenerator, block: Block, state: State, node: No
for ( ; ${i} < ${iterations}.length; ${i} += 1 ) ${outro}( ${i} ); for ( ; ${i} < ${iterations}.length; ${i} += 1 ) ${outro}( ${i} );
` : ` :
deindent` deindent`
${generator.helper( 'destroyEach' )}( ${iterations}, true, ${each_block_value}.length ); for ( ; ${i} < ${iterations}.length; ${i} += 1 ) {
${iterations}[${i}].unmount();
${iterations}[${i}].destroy();
}
${iterations}.length = ${each_block_value}.length; ${iterations}.length = ${each_block_value}.length;
`; `;
@ -360,7 +379,13 @@ function unkeyed ( generator: DomGenerator, block: Block, state: State, node: No
` ); ` );
} }
block.builders.unmount.addBlock( deindent`
for ( var ${i} = 0; ${i} < ${iterations}.length; ${i} += 1 ) {
${iterations}[${i}].unmount();
}
` );
block.builders.destroy.addBlock( block.builders.destroy.addBlock(
`${generator.helper( 'destroyEach' )}( ${iterations}, ${state.parentNode ? 'false' : 'detach'}, 0 );` `${generator.helper( 'destroyEach' )}( ${iterations}, false, 0 );`
); );
} }

@ -103,7 +103,7 @@ export default function visitElement ( generator: DomGenerator, block: Block, st
if ( !state.parentNode ) { if ( !state.parentNode ) {
// TODO we eventually need to consider what happens to elements // TODO we eventually need to consider what happens to elements
// that belong to the same outgroup as an outroing element... // that belong to the same outgroup as an outroing element...
block.builders.detach.addLine( `${generator.helper( 'detachNode' )}( ${name} );` ); block.builders.unmount.addLine( `${generator.helper( 'detachNode' )}( ${name} );` );
} }
if ( node.name !== 'select' ) { if ( node.name !== 'select' ) {

@ -135,12 +135,14 @@ function simple ( generator: DomGenerator, block: Block, state: State, node: Nod
const exit = branch.hasOutroMethod ? const exit = branch.hasOutroMethod ?
deindent` deindent`
${name}.outro( function () { ${name}.outro( function () {
${name}.destroy( true ); ${name}.unmount();
${name}.destroy();
${name} = null; ${name} = null;
}); });
` : ` :
deindent` deindent`
${name}.destroy( true ); ${name}.unmount();
${name}.destroy();
${name} = null; ${name} = null;
`; `;
@ -152,8 +154,12 @@ function simple ( generator: DomGenerator, block: Block, state: State, node: Nod
} }
` ); ` );
block.builders.unmount.addLine(
`${if_name}${name}.unmount();`
);
block.builders.destroy.addLine( block.builders.destroy.addLine(
`${if_name}${name}.destroy( ${state.parentNode ? 'false' : 'detach'} );` `${if_name}${name}.destroy( false );`
); );
} }
@ -185,7 +191,10 @@ function compound ( generator: DomGenerator, block: Block, state: State, node: N
const parentNode = state.parentNode || `${anchor}.parentNode`; const parentNode = state.parentNode || `${anchor}.parentNode`;
const changeBlock = deindent` const changeBlock = deindent`
${if_name}${name}.destroy( true ); ${if_name}{
${name}.unmount();
${name}.destroy();
}
${name} = ${current_block_and}${current_block}( ${params}, ${block.component} ); ${name} = ${current_block_and}${current_block}( ${params}, ${block.component} );
${if_name}${name}.${mountOrIntro}( ${parentNode}, ${anchor} ); ${if_name}${name}.${mountOrIntro}( ${parentNode}, ${anchor} );
`; `;
@ -207,7 +216,10 @@ function compound ( generator: DomGenerator, block: Block, state: State, node: N
} }
block.builders.destroy.addLine( block.builders.destroy.addLine(
`${if_name}${name}.destroy( ${state.parentNode ? 'false' : 'detach'} );` `${if_name}{
${name}.unmount();
${name}.destroy();
}`
); );
} }

@ -10,6 +10,6 @@ export default function visitYieldTag ( generator: DomGenerator, block: Block, s
); );
block.builders.destroy.addLine( block.builders.destroy.addLine(
`if ( ${block.component}._yield ) ${block.component}._yield.destroy( detach );` `if ( ${block.component}._yield ) ${block.component}._yield.unmount();`
); );
} }

@ -0,0 +1,14 @@
export default {
html: `
One
Inner
`,
test ( assert, component, target ) {
component.set({ foo: false });
assert.htmlEqual( target.innerHTML, `` );
component.set({ foo: true });
assert.htmlEqual( target.innerHTML, `One\nInner` );
}
};

@ -1,8 +0,0 @@
export default {
test ( assert, component ) {
component.set({ foo: false });
component.set({ foo: true });
}
};

@ -107,10 +107,12 @@ describe( 'ssr', () => {
} }
} }
const resolved = require.resolve( `../runtime/samples/${dir}/main.html` ); fs.readdirSync( `test/runtime/samples/${dir}` ).forEach( file => {
delete require.cache[ resolved ]; const resolved = require.resolve( `../runtime/samples/${dir}/${file}` );
delete require.cache[ resolved ];
});
const component = require( resolved ); const component = require( `../runtime/samples/${dir}/main.html` );
let html; let html;
try { try {

Loading…
Cancel
Save