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: {
create: CodeBuilder;
mount: CodeBuilder;
update: CodeBuilder;
intro: CodeBuilder;
update: CodeBuilder;
outro: CodeBuilder;
detach: CodeBuilder;
unmount: CodeBuilder;
detachRaw: CodeBuilder;
destroy: CodeBuilder;
}
@ -88,10 +88,10 @@ export default class Block {
this.builders = {
create: new CodeBuilder(),
mount: new CodeBuilder(),
update: new CodeBuilder(),
intro: new CodeBuilder(),
update: new CodeBuilder(),
outro: new CodeBuilder(),
detach: new CodeBuilder(),
unmount: new CodeBuilder(),
detachRaw: new CodeBuilder(),
destroy: new CodeBuilder()
};
@ -130,7 +130,7 @@ export default class Block {
}
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
// first, so we append normal detach statements to detachRaw
this.builders.detachRaw.addBlock( this.builders.detach );
if ( !this.builders.detachRaw.isEmpty() ) {
this.builders.destroy.addBlock( deindent`
if ( detach ) {
${this.builders.detachRaw}
}
` );
}
this.builders.detachRaw.addBlock( this.builders.unmount ); // TODO reverse this, using addBlockAtStart?
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() ) {
properties.addBlock( `destroy: ${this.generator.helper( 'noop' )}` );
} else {
properties.addBlock( deindent`
destroy: function ( detach ) {
${!this.builders.detachRaw.isEmpty() && `if ( detach ) this.unmount();`}
${this.builders.destroy}
}
` );

@ -191,7 +191,8 @@ export default function dom ( parsed: Parsed, source: string, options: CompileOp
this.fire( 'destroy' );
${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._state = {};

@ -56,7 +56,7 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
update: new CodeBuilder()
};
const isToplevel = !state.parentNode;
const isTopLevel = !state.parentNode;
generator.hasComponents = true;
@ -95,7 +95,7 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
}
const componentInitProperties = [
`target: ${!isToplevel ? state.parentNode: 'null'}`,
`target: ${!isTopLevel ? state.parentNode: 'null'}`,
`_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}`);
}
@ -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 );` );
}
@ -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 );
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}.${mountOrIntro}( ${parentNode}, ${anchor} );
} else if ( ${each_block_else} ) {
${each_block_else}.destroy( true );
${each_block_else}.unmount();
${each_block_else}.destroy();
${each_block_else} = null;
}
` );
@ -72,7 +73,8 @@ export default function visitEachBlock ( generator: DomGenerator, block: Block,
block.builders.update.addBlock( deindent`
if ( ${each_block_value}.length ) {
if ( ${each_block_else} ) {
${each_block_else}.destroy( true );
${each_block_else}.unmount();
${each_block_else}.destroy();
${each_block_else} = null;
}
} 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`
if ( ${each_block_else} ) {
${each_block_else}.destroy( ${isToplevel ? 'detach' : 'false'} );
}
if ( ${each_block_else} ) ${each_block_else}.destroy( false );
` );
}
@ -154,7 +157,8 @@ function keyed ( generator: DomGenerator, block: Block, state: State, node: Node
block.builders.create.addBlock( deindent`
function ${fn} ( iteration ) {
iteration.outro( function () {
iteration.destroy( true );
iteration.unmount();
iteration.destroy();
${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` );
block.builders.create.addBlock( deindent`
function ${fn} ( iteration ) {
iteration.destroy( true );
iteration.unmount();
iteration.destroy();
${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}];
` );
if ( !state.parentNode ) {
block.builders.unmount.addBlock( deindent`
var ${iteration} = ${head};
while ( ${iteration} ) {
${iteration}.unmount();
${iteration} = ${iteration}.next;
}
` );
}
block.builders.destroy.addBlock( deindent`
var ${iteration} = ${head};
while ( ${iteration} ) {
${iteration}.destroy( ${state.parentNode ? 'false' : 'detach'} );
${iteration}.destroy( false );
${iteration} = ${iteration}.next;
}
` );
@ -334,7 +349,8 @@ function unkeyed ( generator: DomGenerator, block: Block, state: State, node: No
function ${outro} ( i ) {
if ( ${iterations}[i] ) {
${iterations}[i].outro( function () {
${iterations}[i].destroy( true );
${iterations}[i].unmount();
${iterations}[i].destroy();
${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} );
` :
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;
`;
@ -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(
`${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 ) {
// TODO we eventually need to consider what happens to elements
// 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' ) {

@ -135,12 +135,14 @@ function simple ( generator: DomGenerator, block: Block, state: State, node: Nod
const exit = branch.hasOutroMethod ?
deindent`
${name}.outro( function () {
${name}.destroy( true );
${name}.unmount();
${name}.destroy();
${name} = null;
});
` :
deindent`
${name}.destroy( true );
${name}.unmount();
${name}.destroy();
${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(
`${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 changeBlock = deindent`
${if_name}${name}.destroy( true );
${if_name}{
${name}.unmount();
${name}.destroy();
}
${name} = ${current_block_and}${current_block}( ${params}, ${block.component} );
${if_name}${name}.${mountOrIntro}( ${parentNode}, ${anchor} );
`;
@ -207,7 +216,10 @@ function compound ( generator: DomGenerator, block: Block, state: State, node: N
}
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(
`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 => {
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;
try {

Loading…
Cancel
Save