Skip to content

Commit 6d00f2b

Browse files
authored
Merge pull request #1453 from sveltejs/deferred-transitions
Deferred transitions
2 parents 8d9a3ef + f02177d commit 6d00f2b

File tree

90 files changed

+280
-215
lines changed

Some content is hidden

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

90 files changed

+280
-215
lines changed

src/compile/dom/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ export default function dom(
228228
this._fragment.c();
229229
this._fragment.${block.hasIntroMethod ? 'i' : 'm'}(this.shadowRoot, null);
230230
231-
if (options.target) this._mount(options.target, options.anchor, ${options.skipIntroByDefault ? `options.intro` : 'true'});
231+
if (options.target) this._mount(options.target, options.anchor);
232232
` : deindent`
233233
if (options.target) {
234234
${compiler.options.hydratable
@@ -241,7 +241,7 @@ export default function dom(
241241
${options.dev && `if (options.hydrate) throw new Error("options.hydrate only works if the component was compiled with the \`hydratable: true\` option");`}
242242
this._fragment.c();
243243
`}
244-
this._mount(options.target, options.anchor, ${options.skipIntroByDefault ? `options.intro` : 'true'});
244+
this._mount(options.target, options.anchor);
245245
246246
${(compiler.hasComponents || target.hasComplexBindings || hasInitHooks || target.hasIntroTransitions) && deindent`
247247
${compiler.hasComponents && `this._lock = true;`}

src/compile/nodes/Component.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ export default class Component extends Node {
387387

388388
block.builders.mount.addBlock(deindent`
389389
if (${name}) {
390-
${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'}, ${compiler.options.skipIntroByDefault ? '#component._intro' : 'true'});
390+
${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});
391391
${this.ref && `#component.refs.${this.ref} = ${name};`}
392392
}
393393
`);
@@ -409,7 +409,7 @@ export default class Component extends Node {
409409
${name}._fragment.c();
410410
411411
${this.children.map(child => child.remount(name))}
412-
${name}._mount(${updateMountNode}, ${anchor}, true);
412+
${name}._mount(${updateMountNode}, ${anchor});
413413
414414
${this.handlers.map(handler => deindent`
415415
${name}.on("${handler.name}", ${handler.var});
@@ -468,7 +468,7 @@ export default class Component extends Node {
468468
}
469469

470470
block.builders.mount.addLine(
471-
`${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'}, ${compiler.options.skipIntroByDefault ? '#component._intro' : 'true'});`
471+
`${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});`
472472
);
473473

474474
if (updates.length) {
@@ -493,7 +493,7 @@ export default class Component extends Node {
493493
}
494494

495495
remount(name: string) {
496-
return `${this.var}._mount(${name}._slotted.default, null, false);`;
496+
return `${this.var}._mount(${name}._slotted.default, null);`;
497497
}
498498

499499
ssr() {

src/compile/nodes/Element.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ export default class Element extends Node {
699699

700700
const fn = `%transitions-${intro.name}`;
701701

702-
block.builders.intro.addBlock(deindent`
702+
block.builders.intro.addConditional(`#component._intro`, deindent`
703703
if (${name}) ${name}.invalidate();
704704
705705
#component.root._aftercreate.push(() => {
@@ -709,6 +709,7 @@ export default class Element extends Node {
709709
`);
710710

711711
block.builders.outro.addBlock(deindent`
712+
if (!${name}) ${name} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, false);
712713
${name}.run(0, () => {
713714
#outrocallback();
714715
${name} = null;
@@ -733,7 +734,7 @@ export default class Element extends Node {
733734
`);
734735
}
735736

736-
block.builders.intro.addBlock(deindent`
737+
block.builders.intro.addConditional(`#component._intro`, deindent`
737738
#component.root._aftercreate.push(() => {
738739
${introName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true);
739740
${introName}.run(1);

src/shared/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ export function callAll(fns) {
128128
while (fns && fns.length) fns.shift()();
129129
}
130130

131-
export function _mount(target, anchor, intro) {
132-
this._fragment[intro && this._fragment.i ? 'i' : 'm'](target, anchor || null);
131+
export function _mount(target, anchor) {
132+
this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null);
133133
}
134134

135135
export var PENDING = {};

src/shared/transitions.js

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,12 @@ export function hash(str) {
2727
}
2828

2929
export function wrapTransition(component, node, fn, params, intro) {
30-
const obj = fn(node, params);
31-
const duration = obj.duration || 300;
32-
const ease = obj.easing || linear;
30+
let obj = fn(node, params);
31+
let duration;
32+
let ease;
3333
let cssText;
3434

35-
if (intro) {
36-
if (obj.css && obj.delay) {
37-
cssText = node.style.cssText;
38-
node.style.cssText += obj.css(0, 1);
39-
}
40-
41-
if (obj.tick) obj.tick(0, 1);
42-
}
35+
let initialised = false;
4336

4437
return {
4538
t: intro ? 0 : 1,
@@ -48,12 +41,36 @@ export function wrapTransition(component, node, fn, params, intro) {
4841
pending: null,
4942

5043
run(b, callback) {
44+
if (typeof obj === 'function') {
45+
transitionManager.wait().then(() => {
46+
obj = obj();
47+
this._run(b, callback);
48+
});
49+
} else {
50+
this._run(b, callback);
51+
}
52+
},
53+
54+
_run(b, callback) {
55+
duration = obj.duration || 300;
56+
ease = obj.easing || linear;
57+
5158
const program = {
5259
start: window.performance.now() + (obj.delay || 0),
5360
b,
5461
callback: callback || noop
5562
};
5663

64+
if (intro && !initialised) {
65+
if (obj.css && obj.delay) {
66+
cssText = node.style.cssText;
67+
node.style.cssText += obj.css(0, 1);
68+
}
69+
70+
if (obj.tick) obj.tick(0, 1);
71+
initialised = true;
72+
}
73+
5774
if (!b) {
5875
program.group = transitionManager.outros;
5976
transitionManager.outros.remaining += 1;
@@ -154,6 +171,7 @@ export var transitionManager = {
154171
bound: null,
155172
stylesheet: null,
156173
activeRules: {},
174+
promise: null,
157175

158176
add(transition) {
159177
this.transitions.push(transition);
@@ -223,5 +241,16 @@ export var transitionManager = {
223241
remaining: 0,
224242
callbacks: []
225243
};
244+
},
245+
246+
wait() {
247+
if (!transitionManager.promise) {
248+
transitionManager.promise = Promise.resolve();
249+
transitionManager.promise.then(() => {
250+
transitionManager.promise = null;
251+
});
252+
}
253+
254+
return transitionManager.promise;
226255
}
227256
};

test/cli/samples/basic/expected/Main.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function Main(options) {
3232

3333
if (options.target) {
3434
this._fragment.c();
35-
this._mount(options.target, options.anchor, true);
35+
this._mount(options.target, options.anchor);
3636
}
3737
}
3838

@@ -150,8 +150,8 @@ function _set(newState) {
150150
}
151151
}
152152

153-
function _mount(target, anchor, intro) {
154-
this._fragment[intro && this._fragment.i ? 'i' : 'm'](target, anchor || null);
153+
function _mount(target, anchor) {
154+
this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null);
155155
}
156156

157157
function _differs(a, b) {

test/cli/samples/custom-element/expected/Main.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class Main extends HTMLElement {
3838
this._fragment.c();
3939
this._fragment.m(this.shadowRoot, null);
4040

41-
if (options.target) this._mount(options.target, options.anchor, true);
41+
if (options.target) this._mount(options.target, options.anchor);
4242
}
4343

4444
static get observedAttributes() {
@@ -171,8 +171,8 @@ function _set(newState) {
171171
}
172172
}
173173

174-
function _mount(target, anchor, intro) {
175-
this._fragment[intro && this._fragment.i ? 'i' : 'm'](target, anchor || null);
174+
function _mount(target, anchor) {
175+
this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null);
176176
}
177177

178178
function _differs(a, b) {

test/cli/samples/dev/expected/Main.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function Main(options) {
3535
if (options.target) {
3636
if (options.hydrate) throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
3737
this._fragment.c();
38-
this._mount(options.target, options.anchor, true);
38+
this._mount(options.target, options.anchor);
3939
}
4040
}
4141

@@ -154,8 +154,8 @@ function _set(newState) {
154154
}
155155
}
156156

157-
function _mount(target, anchor, intro) {
158-
this._fragment[intro && this._fragment.i ? 'i' : 'm'](target, anchor || null);
157+
function _mount(target, anchor) {
158+
this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null);
159159
}
160160

161161
function _differs(a, b) {

test/cli/samples/dir-sourcemap/expected/Main.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/cli/samples/dir-sourcemap/expected/Widget.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/cli/samples/dir-subdir/expected/Main.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function create_main_fragment(component, ctx) {
1515
},
1616

1717
m(target, anchor) {
18-
widget._mount(target, anchor, true);
18+
widget._mount(target, anchor);
1919
},
2020

2121
p: noop,
@@ -41,7 +41,7 @@ function Main(options) {
4141

4242
if (options.target) {
4343
this._fragment.c();
44-
this._mount(options.target, options.anchor, true);
44+
this._mount(options.target, options.anchor);
4545

4646
this._lock = true;
4747
callAll(this._beforecreate);
@@ -157,8 +157,8 @@ function _set(newState) {
157157
}
158158
}
159159

160-
function _mount(target, anchor, intro) {
161-
this._fragment[intro && this._fragment.i ? 'i' : 'm'](target, anchor || null);
160+
function _mount(target, anchor) {
161+
this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null);
162162
}
163163

164164
function _differs(a, b) {

test/cli/samples/dir-subdir/expected/widget/Widget.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function Widget(options) {
3232

3333
if (options.target) {
3434
this._fragment.c();
35-
this._mount(options.target, options.anchor, true);
35+
this._mount(options.target, options.anchor);
3636
}
3737
}
3838

@@ -150,8 +150,8 @@ function _set(newState) {
150150
}
151151
}
152152

153-
function _mount(target, anchor, intro) {
154-
this._fragment[intro && this._fragment.i ? 'i' : 'm'](target, anchor || null);
153+
function _mount(target, anchor) {
154+
this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null);
155155
}
156156

157157
function _differs(a, b) {

test/cli/samples/dir/expected/Main.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function create_main_fragment(component, ctx) {
1515
},
1616

1717
m(target, anchor) {
18-
widget._mount(target, anchor, true);
18+
widget._mount(target, anchor);
1919
},
2020

2121
p: noop,
@@ -41,7 +41,7 @@ function Main(options) {
4141

4242
if (options.target) {
4343
this._fragment.c();
44-
this._mount(options.target, options.anchor, true);
44+
this._mount(options.target, options.anchor);
4545

4646
this._lock = true;
4747
callAll(this._beforecreate);
@@ -157,8 +157,8 @@ function _set(newState) {
157157
}
158158
}
159159

160-
function _mount(target, anchor, intro) {
161-
this._fragment[intro && this._fragment.i ? 'i' : 'm'](target, anchor || null);
160+
function _mount(target, anchor) {
161+
this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null);
162162
}
163163

164164
function _differs(a, b) {

test/cli/samples/dir/expected/Widget.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function Widget(options) {
3232

3333
if (options.target) {
3434
this._fragment.c();
35-
this._mount(options.target, options.anchor, true);
35+
this._mount(options.target, options.anchor);
3636
}
3737
}
3838

@@ -150,8 +150,8 @@ function _set(newState) {
150150
}
151151
}
152152

153-
function _mount(target, anchor, intro) {
154-
this._fragment[intro && this._fragment.i ? 'i' : 'm'](target, anchor || null);
153+
function _mount(target, anchor) {
154+
this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null);
155155
}
156156

157157
function _differs(a, b) {

0 commit comments

Comments
 (0)