From f0a36373f604706d4f0ca891464018904e03e2a7 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 12 May 2018 18:21:36 -0400 Subject: [PATCH] allow transition functions to return a function (#1431) --- src/shared/transitions.js | 51 +++++++++++++++---- .../samples/transition-js-deferred/_config.js | 15 ++++++ .../samples/transition-js-deferred/main.html | 20 ++++++++ 3 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 test/runtime/samples/transition-js-deferred/_config.js create mode 100644 test/runtime/samples/transition-js-deferred/main.html diff --git a/src/shared/transitions.js b/src/shared/transitions.js index 8132b2b7ec..5f33c27dff 100644 --- a/src/shared/transitions.js +++ b/src/shared/transitions.js @@ -27,19 +27,12 @@ export function hash(str) { } export function wrapTransition(component, node, fn, params, intro) { - const obj = fn(node, params); - const duration = obj.duration || 300; - const ease = obj.easing || linear; + let obj = fn(node, params); + let duration; + let ease; let cssText; - if (intro) { - if (obj.css && obj.delay) { - cssText = node.style.cssText; - node.style.cssText += obj.css(0, 1); - } - - if (obj.tick) obj.tick(0, 1); - } + let initialised = false; return { t: intro ? 0 : 1, @@ -48,12 +41,36 @@ export function wrapTransition(component, node, fn, params, intro) { pending: null, run(b, callback) { + if (typeof obj === 'function') { + transitionManager.wait().then(() => { + obj = obj(); + this._run(b, callback); + }); + } else { + this._run(b, callback); + } + }, + + _run(b, callback) { + duration = obj.duration || 300; + ease = obj.easing || linear; + const program = { start: window.performance.now() + (obj.delay || 0), b, callback: callback || noop }; + if (intro && !initialised) { + if (obj.css && obj.delay) { + cssText = node.style.cssText; + node.style.cssText += obj.css(0, 1); + } + + if (obj.tick) obj.tick(0, 1); + initialised = true; + } + if (!b) { program.group = transitionManager.outros; transitionManager.outros.remaining += 1; @@ -154,6 +171,7 @@ export var transitionManager = { bound: null, stylesheet: null, activeRules: {}, + promise: null, add(transition) { this.transitions.push(transition); @@ -223,5 +241,16 @@ export var transitionManager = { remaining: 0, callbacks: [] }; + }, + + wait() { + if (!transitionManager.promise) { + transitionManager.promise = Promise.resolve(); + transitionManager.promise.then(() => { + transitionManager.promise = null; + }); + } + + return transitionManager.promise; } }; diff --git a/test/runtime/samples/transition-js-deferred/_config.js b/test/runtime/samples/transition-js-deferred/_config.js new file mode 100644 index 0000000000..79d4b41a81 --- /dev/null +++ b/test/runtime/samples/transition-js-deferred/_config.js @@ -0,0 +1,15 @@ +export default { + skipIntroByDefault: true, + + test(assert, component, target, window, raf) { + component.set({ visible: true }); + + return Promise.resolve().then(() => { + const div = target.querySelector('div'); + assert.equal(div.foo, 0); + + raf.tick(50); + assert.equal(div.foo, 0.5); + }); + }, +}; diff --git a/test/runtime/samples/transition-js-deferred/main.html b/test/runtime/samples/transition-js-deferred/main.html new file mode 100644 index 0000000000..01985384ad --- /dev/null +++ b/test/runtime/samples/transition-js-deferred/main.html @@ -0,0 +1,20 @@ +{#if visible} +
+{/if} + + \ No newline at end of file