Skip to content

Commit c3fb711

Browse files
authored
Merge pull request #603 from sveltejs/gh-592
[WIP] Separate unmount from destroy
2 parents 6636ea3 + 3b70920 commit c3fb711

File tree

42 files changed

+446
-2365
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+446
-2365
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ coverage.lcov
1212
test/sourcemaps/samples/*/output.js
1313
test/sourcemaps/samples/*/output.js.map
1414
_actual.*
15+
_actual-bundle.*
1516
src/generators/dom/shared.ts

src/generators/dom/Block.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ export default class Block {
4242
builders: {
4343
create: CodeBuilder;
4444
mount: CodeBuilder;
45-
update: CodeBuilder;
4645
intro: CodeBuilder;
46+
update: CodeBuilder;
4747
outro: CodeBuilder;
48-
detach: CodeBuilder;
48+
unmount: CodeBuilder;
4949
detachRaw: CodeBuilder;
5050
destroy: CodeBuilder;
5151
}
@@ -88,10 +88,10 @@ export default class Block {
8888
this.builders = {
8989
create: new CodeBuilder(),
9090
mount: new CodeBuilder(),
91-
update: new CodeBuilder(),
9291
intro: new CodeBuilder(),
92+
update: new CodeBuilder(),
9393
outro: new CodeBuilder(),
94-
detach: new CodeBuilder(),
94+
unmount: new CodeBuilder(),
9595
detachRaw: new CodeBuilder(),
9696
destroy: new CodeBuilder()
9797
};
@@ -130,7 +130,7 @@ export default class Block {
130130
}
131131

132132
if ( isToplevel ) {
133-
this.builders.detach.addLine( `${this.generator.helper( 'detachNode' )}( ${name} );` );
133+
this.builders.unmount.addLine( `${this.generator.helper( 'detachNode' )}( ${name} );` );
134134
}
135135
}
136136

@@ -200,17 +200,8 @@ export default class Block {
200200
this.builders.create.addLine( `${this.autofocus}.focus();` );
201201
}
202202

203-
// minor hack – we need to ensure that any {{{triples}}} are detached
204-
// first, so we append normal detach statements to detachRaw
205-
this.builders.detachRaw.addBlock( this.builders.detach );
206-
207-
if ( !this.builders.detachRaw.isEmpty() ) {
208-
this.builders.destroy.addBlock( deindent`
209-
if ( detach ) {
210-
${this.builders.detachRaw}
211-
}
212-
` );
213-
}
203+
// minor hack – we need to ensure that any {{{triples}}} are detached first
204+
this.builders.unmount.addBlockAtStart( this.builders.detachRaw );
214205

215206
const properties = new CodeBuilder();
216207

@@ -290,11 +281,21 @@ export default class Block {
290281
}
291282
}
292283

284+
if ( this.builders.unmount.isEmpty() ) {
285+
properties.addBlock( `unmount: ${this.generator.helper('noop')},`);
286+
} else {
287+
properties.addBlock( deindent`
288+
unmount: function () {
289+
${this.builders.unmount}
290+
},
291+
` );
292+
}
293+
293294
if ( this.builders.destroy.isEmpty() ) {
294295
properties.addBlock( `destroy: ${this.generator.helper( 'noop' )}` );
295296
} else {
296297
properties.addBlock( deindent`
297-
destroy: function ( detach ) {
298+
destroy: function () {
298299
${this.builders.destroy}
299300
}
300301
` );

src/generators/dom/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ export default function dom ( parsed: Parsed, source: string, options: CompileOp
191191
this.fire( 'destroy' );
192192
${templateProperties.ondestroy && `${generator.alias( 'template' )}.ondestroy.call( this );`}
193193
194-
this._fragment.destroy( detach !== false );
194+
if ( detach !== false ) this._fragment.unmount();
195+
this._fragment.destroy();
195196
this._fragment = null;
196197
197198
this._state = {};

src/generators/dom/visitors/Component/Component.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
5656
update: new CodeBuilder()
5757
};
5858

59-
const isToplevel = !state.parentNode;
59+
const isTopLevel = !state.parentNode;
6060

6161
generator.hasComponents = true;
6262

@@ -95,7 +95,7 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
9595
}
9696

9797
const componentInitProperties = [
98-
`target: ${!isToplevel ? state.parentNode: 'null'}`,
98+
`target: ${!isTopLevel ? state.parentNode: 'null'}`,
9999
`_root: ${block.component}._root`
100100
];
101101

@@ -121,6 +121,10 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
121121
);
122122
}
123123

124+
block.builders.destroy.addLine(
125+
`${yieldFragment}.destroy();`
126+
);
127+
124128
componentInitProperties.push( `_yield: ${yieldFragment}`);
125129
}
126130

@@ -157,7 +161,7 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
157161
});
158162
` );
159163

160-
if ( isToplevel ) {
164+
if ( isTopLevel ) {
161165
block.builders.mount.addLine( `${name}._fragment.mount( ${block.target}, anchor );` );
162166
}
163167

@@ -183,7 +187,8 @@ export default function visitComponent ( generator: DomGenerator, block: Block,
183187
` );
184188
}
185189

186-
block.builders.destroy.addLine( `${name}.destroy( ${isToplevel ? 'detach' : 'false'} );` );
190+
if ( isTopLevel ) block.builders.unmount.addLine( `${name}._fragment.unmount();` );
191+
block.builders.destroy.addLine( `${name}.destroy( false );` );
187192

188193
block.builders.create.addBlock( local.create );
189194
if ( !local.update.isEmpty() ) block.builders.update.addBlock( local.update );

src/generators/dom/visitors/EachBlock.ts

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,17 @@ export default function visitEachBlock ( generator: DomGenerator, block: Block,
6464
${each_block_else} = ${node.else._block.name}( ${params}, ${block.component} );
6565
${each_block_else}.${mountOrIntro}( ${parentNode}, ${anchor} );
6666
} else if ( ${each_block_else} ) {
67-
${each_block_else}.destroy( true );
67+
${each_block_else}.unmount();
68+
${each_block_else}.destroy();
6869
${each_block_else} = null;
6970
}
7071
` );
7172
} else {
7273
block.builders.update.addBlock( deindent`
7374
if ( ${each_block_value}.length ) {
7475
if ( ${each_block_else} ) {
75-
${each_block_else}.destroy( true );
76+
${each_block_else}.unmount();
77+
${each_block_else}.destroy();
7678
${each_block_else} = null;
7779
}
7880
} else if ( !${each_block_else} ) {
@@ -82,11 +84,12 @@ export default function visitEachBlock ( generator: DomGenerator, block: Block,
8284
` );
8385
}
8486

87+
block.builders.unmount.addLine(
88+
`if ( ${each_block_else} ) ${each_block_else}.unmount()`
89+
);
8590

8691
block.builders.destroy.addBlock( deindent`
87-
if ( ${each_block_else} ) {
88-
${each_block_else}.destroy( ${isToplevel ? 'detach' : 'false'} );
89-
}
92+
if ( ${each_block_else} ) ${each_block_else}.destroy( false );
9093
` );
9194
}
9295

@@ -154,7 +157,8 @@ function keyed ( generator: DomGenerator, block: Block, state: State, node: Node
154157
block.builders.create.addBlock( deindent`
155158
function ${fn} ( iteration ) {
156159
iteration.outro( function () {
157-
iteration.destroy( true );
160+
iteration.unmount();
161+
iteration.destroy();
158162
${lookup}[iteration.key] = null;
159163
});
160164
}
@@ -176,7 +180,8 @@ function keyed ( generator: DomGenerator, block: Block, state: State, node: Node
176180
const fn = block.getUniqueName( `${each_block}_destroy` );
177181
block.builders.create.addBlock( deindent`
178182
function ${fn} ( iteration ) {
179-
iteration.destroy( true );
183+
iteration.unmount();
184+
iteration.destroy();
180185
${lookup}[iteration.key] = null;
181186
}
182187
` );
@@ -262,10 +267,20 @@ function keyed ( generator: DomGenerator, block: Block, state: State, node: Node
262267
${head} = ${lookup}[${each_block_value}[0] && ${each_block_value}[0].${node.key}];
263268
` );
264269

270+
if ( !state.parentNode ) {
271+
block.builders.unmount.addBlock( deindent`
272+
var ${iteration} = ${head};
273+
while ( ${iteration} ) {
274+
${iteration}.unmount();
275+
${iteration} = ${iteration}.next;
276+
}
277+
` );
278+
}
279+
265280
block.builders.destroy.addBlock( deindent`
266281
var ${iteration} = ${head};
267282
while ( ${iteration} ) {
268-
${iteration}.destroy( ${state.parentNode ? 'false' : 'detach'} );
283+
${iteration}.destroy( false );
269284
${iteration} = ${iteration}.next;
270285
}
271286
` );
@@ -334,7 +349,8 @@ function unkeyed ( generator: DomGenerator, block: Block, state: State, node: No
334349
function ${outro} ( i ) {
335350
if ( ${iterations}[i] ) {
336351
${iterations}[i].outro( function () {
337-
${iterations}[i].destroy( true );
352+
${iterations}[i].unmount();
353+
${iterations}[i].destroy();
338354
${iterations}[i] = null;
339355
});
340356
}
@@ -343,7 +359,10 @@ function unkeyed ( generator: DomGenerator, block: Block, state: State, node: No
343359
for ( ; ${i} < ${iterations}.length; ${i} += 1 ) ${outro}( ${i} );
344360
` :
345361
deindent`
346-
${generator.helper( 'destroyEach' )}( ${iterations}, true, ${each_block_value}.length );
362+
for ( ; ${i} < ${iterations}.length; ${i} += 1 ) {
363+
${iterations}[${i}].unmount();
364+
${iterations}[${i}].destroy();
365+
}
347366
${iterations}.length = ${each_block_value}.length;
348367
`;
349368

@@ -360,7 +379,13 @@ function unkeyed ( generator: DomGenerator, block: Block, state: State, node: No
360379
` );
361380
}
362381

382+
block.builders.unmount.addBlock( deindent`
383+
for ( var ${i} = 0; ${i} < ${iterations}.length; ${i} += 1 ) {
384+
${iterations}[${i}].unmount();
385+
}
386+
` );
387+
363388
block.builders.destroy.addBlock(
364-
`${generator.helper( 'destroyEach' )}( ${iterations}, ${state.parentNode ? 'false' : 'detach'}, 0 );`
389+
`${generator.helper( 'destroyEach' )}( ${iterations}, false, 0 );`
365390
);
366391
}

src/generators/dom/visitors/Element/Element.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export default function visitElement ( generator: DomGenerator, block: Block, st
103103
if ( !state.parentNode ) {
104104
// TODO we eventually need to consider what happens to elements
105105
// that belong to the same outgroup as an outroing element...
106-
block.builders.detach.addLine( `${generator.helper( 'detachNode' )}( ${name} );` );
106+
block.builders.unmount.addLine( `${generator.helper( 'detachNode' )}( ${name} );` );
107107
}
108108

109109
if ( node.name !== 'select' ) {

src/generators/dom/visitors/IfBlock.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,14 @@ function simple ( generator: DomGenerator, block: Block, state: State, node: Nod
135135
const exit = branch.hasOutroMethod ?
136136
deindent`
137137
${name}.outro( function () {
138-
${name}.destroy( true );
138+
${name}.unmount();
139+
${name}.destroy();
139140
${name} = null;
140141
});
141142
` :
142143
deindent`
143-
${name}.destroy( true );
144+
${name}.unmount();
145+
${name}.destroy();
144146
${name} = null;
145147
`;
146148

@@ -152,8 +154,12 @@ function simple ( generator: DomGenerator, block: Block, state: State, node: Nod
152154
}
153155
` );
154156

157+
block.builders.unmount.addLine(
158+
`${if_name}${name}.unmount();`
159+
);
160+
155161
block.builders.destroy.addLine(
156-
`${if_name}${name}.destroy( ${state.parentNode ? 'false' : 'detach'} );`
162+
`${if_name}${name}.destroy();`
157163
);
158164
}
159165

@@ -185,7 +191,10 @@ function compound ( generator: DomGenerator, block: Block, state: State, node: N
185191
const parentNode = state.parentNode || `${anchor}.parentNode`;
186192

187193
const changeBlock = deindent`
188-
${if_name}${name}.destroy( true );
194+
${if_name}{
195+
${name}.unmount();
196+
${name}.destroy();
197+
}
189198
${name} = ${current_block_and}${current_block}( ${params}, ${block.component} );
190199
${if_name}${name}.${mountOrIntro}( ${parentNode}, ${anchor} );
191200
`;
@@ -207,7 +216,10 @@ function compound ( generator: DomGenerator, block: Block, state: State, node: N
207216
}
208217

209218
block.builders.destroy.addLine(
210-
`${if_name}${name}.destroy( ${state.parentNode ? 'false' : 'detach'} );`
219+
`${if_name}{
220+
${name}.unmount();
221+
${name}.destroy();
222+
}`
211223
);
212224
}
213225

@@ -265,7 +277,8 @@ function compoundWithOutros ( generator: DomGenerator, block: Block, state: Stat
265277

266278
const destroyOldBlock = deindent`
267279
${name}.outro( function () {
268-
${if_blocks}[ ${previous_block_index} ].destroy( true );
280+
${if_blocks}[ ${previous_block_index} ].unmount();
281+
${if_blocks}[ ${previous_block_index} ].destroy();
269282
${if_blocks}[ ${previous_block_index} ] = null;
270283
});
271284
`;
@@ -313,7 +326,10 @@ function compoundWithOutros ( generator: DomGenerator, block: Block, state: Stat
313326
` );
314327
}
315328

316-
block.builders.destroy.addLine(
317-
`${if_current_block_index}${if_blocks}[ ${current_block_index} ].destroy( ${state.parentNode ? 'false' : 'detach'} );`
318-
);
329+
block.builders.destroy.addLine( deindent`
330+
${if_current_block_index}{
331+
${if_blocks}[ ${current_block_index} ].unmount();
332+
${if_blocks}[ ${current_block_index} ].destroy();
333+
}
334+
` );
319335
}

src/generators/dom/visitors/YieldTag.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ export default function visitYieldTag ( generator: DomGenerator, block: Block, s
1010
);
1111

1212
block.builders.destroy.addLine(
13-
`if ( ${block.component}._yield ) ${block.component}._yield.destroy( detach );`
13+
`if ( ${block.component}._yield ) ${block.component}._yield.unmount();`
1414
);
1515
}

src/shared/dom.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export function detachBetween ( before, after ) {
1616
}
1717
}
1818

19+
// TODO this is out of date
1920
export function destroyEach ( iterations, detach, start ) {
2021
for ( var i = start; i < iterations.length; i += 1 ) {
2122
if ( iterations[i] ) iterations[i].destroy( detach );

test/js/index.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@ describe( 'js', () => {
3434
const expected = fs.readFileSync( `${dir}/expected.js`, 'utf-8' );
3535
const expectedBundle = fs.readFileSync( `${dir}/expected-bundle.js`, 'utf-8' );
3636

37-
assert.equal(
38-
actual.trim().replace( /^\s+$/gm, '' ),
39-
expected.trim().replace( /^\s+$/gm, '' )
40-
);
41-
4237
return rollup({
4338
entry: `${dir}/_actual.js`,
4439
plugins: [{
@@ -52,6 +47,11 @@ describe( 'js', () => {
5247
const actualBundle = bundle.generate({ format: 'es' }).code;
5348
fs.writeFileSync( `${dir}/_actual-bundle.js`, actualBundle );
5449

50+
assert.equal(
51+
actual.trim().replace( /^\s+$/gm, '' ),
52+
expected.trim().replace( /^\s+$/gm, '' )
53+
);
54+
5555
assert.equal(
5656
actualBundle.trim().replace( /^\s+$/gm, '' ),
5757
expectedBundle.trim().replace( /^\s+$/gm, '' )

0 commit comments

Comments
 (0)