fire intro.start and outro.start events (#702)

pull/705/head
Rich Harris 7 years ago
parent 5eff188b55
commit e9f17f34ff

@ -1,2 +1 @@
--bail
test/test.js test/test.js

@ -122,10 +122,9 @@ export default function dom(
@dispatchObservers( this, this._observers.pre, newState, oldState ); @dispatchObservers( this, this._observers.pre, newState, oldState );
${block.hasUpdateMethod && `this._fragment.update( newState, this._state );`} ${block.hasUpdateMethod && `this._fragment.update( newState, this._state );`}
@dispatchObservers( this, this._observers.post, newState, oldState ); @dispatchObservers( this, this._observers.post, newState, oldState );
${(generator.hasComponents || generator.hasIntroTransitions) && ${(generator.hasComponents || generator.hasComplexBindings) &&
`this._flush();`} `this._flush();`}
${generator.hasComplexBindings && ${generator.hasIntroTransitions && `@callAll(this._postcreate);`}
`while ( this._bindings.length ) this._bindings.pop()();`}
`; `;
if (hasJs) { if (hasJs) {
@ -199,9 +198,9 @@ export default function dom(
${generator.css && ${generator.css &&
options.css !== false && options.css !== false &&
`if ( !document.getElementById( '${generator.cssId}-style' ) ) @add_css();`} `if ( !document.getElementById( '${generator.cssId}-style' ) ) @add_css();`}
${(generator.hasComponents || generator.hasIntroTransitions) && ${generator.hasComponents && `this._oncreate = [];`}
`this._oncreate = [];`}
${generator.hasComplexBindings && `this._bindings = [];`} ${generator.hasComplexBindings && `this._bindings = [];`}
${generator.hasIntroTransitions && `this._postcreate = [];`}
this._fragment = @create_main_fragment( this._state, this ); this._fragment = @create_main_fragment( this._state, this );
@ -219,10 +218,8 @@ export default function dom(
this._fragment.${block.hasIntroMethod ? 'intro' : 'mount'}( options.target, null ); this._fragment.${block.hasIntroMethod ? 'intro' : 'mount'}( options.target, null );
} }
${(generator.hasComponents || generator.hasIntroTransitions) && ${(generator.hasComponents || generator.hasIntroTransitions || generator.hasComplexBindings || templateProperties.oncreate) &&
`this._flush();`} `this._flush();`}
${generator.hasComplexBindings &&
`while ( this._bindings.length ) this._bindings.pop()();`}
${templateProperties.oncreate && ${templateProperties.oncreate &&
deindent` deindent`
@ -230,8 +227,9 @@ export default function dom(
options._root._oncreate.push( @template.oncreate.bind( this ) ); options._root._oncreate.push( @template.oncreate.bind( this ) );
} else { } else {
@template.oncreate.call( this ); @template.oncreate.call( this );
} }`}
`}
${generator.hasIntroTransitions && `@callAll(this._postcreate);`}
} }
@assign( ${prototypeBase}, ${proto}); @assign( ${prototypeBase}, ${proto});

@ -23,8 +23,8 @@ export default function addTransitions(
const fn = `@template.transitions.${intro.name}`; const fn = `@template.transitions.${intro.name}`;
block.builders.intro.addBlock(deindent` block.builders.intro.addBlock(deindent`
#component._oncreate.push( function () { #component._postcreate.push( function () {
if ( !${name} ) ${name} = @wrapTransition( ${state.name}, ${fn}, ${snippet}, true, null ); if ( !${name} ) ${name} = @wrapTransition( #component, ${state.name}, ${fn}, ${snippet}, true, null );
${name}.run( true, function () { ${name}.run( true, function () {
#component.fire( 'intro.end', { node: ${state.name} }); #component.fire( 'intro.end', { node: ${state.name} });
}); });
@ -58,8 +58,8 @@ export default function addTransitions(
} }
block.builders.intro.addBlock(deindent` block.builders.intro.addBlock(deindent`
#component._oncreate.push( function () { #component._postcreate.push( function () {
${introName} = @wrapTransition( ${state.name}, ${fn}, ${snippet}, true, null ); ${introName} = @wrapTransition( #component, ${state.name}, ${fn}, ${snippet}, true, null );
${introName}.run( true, function () { ${introName}.run( true, function () {
#component.fire( 'intro.end', { node: ${state.name} }); #component.fire( 'intro.end', { node: ${state.name} });
}); });
@ -78,7 +78,7 @@ export default function addTransitions(
// TODO hide elements that have outro'd (unless they belong to a still-outroing // TODO hide elements that have outro'd (unless they belong to a still-outroing
// group) prior to their removal from the DOM // group) prior to their removal from the DOM
block.builders.outro.addBlock(deindent` block.builders.outro.addBlock(deindent`
${outroName} = @wrapTransition( ${state.name}, ${fn}, ${snippet}, false, null ); ${outroName} = @wrapTransition( #component, ${state.name}, ${fn}, ${snippet}, false, null );
${outroName}.run( false, function () { ${outroName}.run( false, function () {
#component.fire( 'outro.end', { node: ${state.name} }); #component.fire( 'outro.end', { node: ${state.name} });
if ( --#outros === 0 ) #outrocallback(); if ( --#outros === 0 ) #outrocallback();

@ -109,12 +109,13 @@ export function set(newState) {
this._root._flush(); this._root._flush();
} }
export function _flush() { export function callAll(fns) {
if (!this._oncreate) return; while (fns && fns.length) fns.pop()();
while (this._oncreate.length) {
this._oncreate.pop()();
} }
export function _flush() {
callAll(this._oncreate);
callAll(this._bindings);
} }
export var proto = { export var proto = {

@ -32,7 +32,7 @@ export function hash(str) {
return hash >>> 0; return hash >>> 0;
} }
export function wrapTransition(node, fn, params, intro, outgroup) { export function wrapTransition(component, node, fn, params, intro, outgroup) {
var obj = fn(node, params); var obj = fn(node, params);
var duration = obj.duration || 300; var duration = obj.duration || 300;
var ease = obj.easing || linear; var ease = obj.easing || linear;
@ -78,6 +78,8 @@ export function wrapTransition(node, fn, params, intro, outgroup) {
} }
}, },
start: function(program) { start: function(program) {
component.fire(program.intro ? 'intro.start' : 'outro.start', { node: node });
program.a = this.t; program.a = this.t;
program.b = program.intro ? 1 : 0; program.b = program.intro ? 1 : 0;
program.delta = program.b - program.a; program.delta = program.b - program.a;
@ -149,7 +151,7 @@ export var transitionManager = {
if (!this.running) { if (!this.running) {
this.running = true; this.running = true;
this.next(); requestAnimationFrame(this.bound || (this.bound = this.next.bind(this)));
} }
}, },
@ -186,7 +188,7 @@ export var transitionManager = {
} }
if (this.running) { if (this.running) {
requestAnimationFrame(this.bound || (this.bound = this.next.bind(this))); requestAnimationFrame(this.bound);
} else if (this.stylesheet) { } else if (this.stylesheet) {
var i = this.stylesheet.cssRules.length; var i = this.stylesheet.cssRules.length;
while (i--) this.stylesheet.deleteRule(i); while (i--) this.stylesheet.deleteRule(i);

@ -118,12 +118,13 @@ function set(newState) {
this._root._flush(); this._root._flush();
} }
function _flush() { function callAll(fns) {
if (!this._oncreate) return; while (fns && fns.length) fns.pop()();
while (this._oncreate.length) {
this._oncreate.pop()();
} }
function _flush() {
callAll(this._oncreate);
callAll(this._bindings);
} }
var proto = { var proto = {

@ -94,12 +94,13 @@ function set(newState) {
this._root._flush(); this._root._flush();
} }
function _flush() { function callAll(fns) {
if (!this._oncreate) return; while (fns && fns.length) fns.pop()();
while (this._oncreate.length) {
this._oncreate.pop()();
} }
function _flush() {
callAll(this._oncreate);
callAll(this._bindings);
} }
var proto = { var proto = {

@ -127,12 +127,13 @@ function set(newState) {
this._root._flush(); this._root._flush();
} }
function _flush() { function callAll(fns) {
if (!this._oncreate) return; while (fns && fns.length) fns.pop()();
while (this._oncreate.length) {
this._oncreate.pop()();
} }
function _flush() {
callAll(this._oncreate);
callAll(this._bindings);
} }
var proto = { var proto = {

@ -112,12 +112,13 @@ function set(newState) {
this._root._flush(); this._root._flush();
} }
function _flush() { function callAll(fns) {
if (!this._oncreate) return; while (fns && fns.length) fns.pop()();
while (this._oncreate.length) {
this._oncreate.pop()();
} }
function _flush() {
callAll(this._oncreate);
callAll(this._bindings);
} }
var proto = { var proto = {

@ -118,12 +118,13 @@ function set(newState) {
this._root._flush(); this._root._flush();
} }
function _flush() { function callAll(fns) {
if (!this._oncreate) return; while (fns && fns.length) fns.pop()();
while (this._oncreate.length) {
this._oncreate.pop()();
} }
function _flush() {
callAll(this._oncreate);
callAll(this._bindings);
} }
var proto = { var proto = {

@ -118,12 +118,13 @@ function set(newState) {
this._root._flush(); this._root._flush();
} }
function _flush() { function callAll(fns) {
if (!this._oncreate) return; while (fns && fns.length) fns.pop()();
while (this._oncreate.length) {
this._oncreate.pop()();
} }
function _flush() {
callAll(this._oncreate);
callAll(this._bindings);
} }
var proto = { var proto = {

@ -106,12 +106,13 @@ function set(newState) {
this._root._flush(); this._root._flush();
} }
function _flush() { function callAll(fns) {
if (!this._oncreate) return; while (fns && fns.length) fns.pop()();
while (this._oncreate.length) {
this._oncreate.pop()();
} }
function _flush() {
callAll(this._oncreate);
callAll(this._bindings);
} }
var proto = { var proto = {

@ -94,12 +94,13 @@ function set(newState) {
this._root._flush(); this._root._flush();
} }
function _flush() { function callAll(fns) {
if (!this._oncreate) return; while (fns && fns.length) fns.pop()();
while (this._oncreate.length) {
this._oncreate.pop()();
} }
function _flush() {
callAll(this._oncreate);
callAll(this._bindings);
} }
var proto = { var proto = {
@ -155,6 +156,8 @@ function SvelteComponent ( options ) {
this._fragment.mount( options.target, null ); this._fragment.mount( options.target, null );
} }
this._flush();
if ( options._root ) { if ( options._root ) {
options._root._oncreate.push( template.oncreate.bind( this ) ); options._root._oncreate.push( template.oncreate.bind( this ) );
} else { } else {

@ -44,6 +44,8 @@ function SvelteComponent ( options ) {
this._fragment.mount( options.target, null ); this._fragment.mount( options.target, null );
} }
this._flush();
if ( options._root ) { if ( options._root ) {
options._root._oncreate.push( template.oncreate.bind( this ) ); options._root._oncreate.push( template.oncreate.bind( this ) );
} else { } else {

@ -118,12 +118,13 @@ function set(newState) {
this._root._flush(); this._root._flush();
} }
function _flush() { function callAll(fns) {
if (!this._oncreate) return; while (fns && fns.length) fns.pop()();
while (this._oncreate.length) {
this._oncreate.pop()();
} }
function _flush() {
callAll(this._oncreate);
callAll(this._bindings);
} }
var proto = { var proto = {

@ -0,0 +1,35 @@
export default {
data: {
visible: true,
things: ['a', 'b', 'c', 'd']
},
test (assert, component, target, window, raf) {
raf.tick(50);
assert.deepEqual(component.intros.sort(), ['a', 'b', 'c', 'd']);
assert.equal(component.introCount, 4);
raf.tick(100);
assert.equal(component.introCount, 0);
component.set({ visible: false });
raf.tick(150);
assert.deepEqual(component.outros.sort(), ['a', 'b', 'c', 'd']);
assert.equal(component.outroCount, 4);
raf.tick(200);
assert.equal(component.outroCount, 0);
component.set({ visible: true });
component.on('intro.start', () => {
throw new Error(`intro.start should fire during set(), not after`);
});
raf.tick(250);
assert.deepEqual(component.intros.sort(), ['a', 'a', 'b', 'b', 'c', 'c', 'd', 'd']);
assert.equal(component.introCount, 4);
component.destroy();
}
};

@ -0,0 +1,45 @@
{{#each things as thing}}
{{#if visible}}
<p transition:foo>{{thing}}</p>
{{/if}}
{{/each}}
<script>
export default {
transitions: {
foo: function ( node, params ) {
return {
duration: 100,
tick: t => {
node.foo = t;
}
};
}
},
oncreate() {
this.intros = [];
this.outros = [];
this.introCount = 0;
this.outroCount = 0;
this.on('intro.start', ({ node }) => {
this.intros.push(node.textContent);
this.introCount += 1;
});
this.on('intro.end', () => {
this.introCount -= 1;
});
this.on('outro.start', ({ node }) => {
this.outros.push(node.textContent);
this.outroCount += 1;
});
this.on('outro.end', () => {
this.outroCount -= 1;
});
}
};
</script>
Loading…
Cancel
Save