UNPKG

@vaadin/component-base

Version:

Vaadin component base mixins

205 lines (196 loc) 5.43 kB
/** * @license * Copyright (c) 2017 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ /** * @fileoverview * * This module provides a number of strategies for enqueuing asynchronous * tasks. Each sub-module provides a standard `run(fn)` interface that returns a * handle, and a `cancel(handle)` interface for canceling async tasks before * they run. * * @summary Module that provides a number of strategies for enqueuing * asynchronous tasks. */ let microtaskCurrHandle = 0; let microtaskLastHandle = 0; const microtaskCallbacks = []; let microtaskScheduled = false; function microtaskFlush() { microtaskScheduled = false; const len = microtaskCallbacks.length; for (let i = 0; i < len; i++) { const cb = microtaskCallbacks[i]; if (cb) { try { cb(); } catch (e) { setTimeout(() => { throw e; }); } } } microtaskCallbacks.splice(0, len); microtaskLastHandle += len; } /** * Async interface wrapper around `setTimeout`. * * @namespace * @summary Async interface wrapper around `setTimeout`. */ const timeOut = { /** * Returns a sub-module with the async interface providing the provided * delay. * * @memberof timeOut * @param {number=} delay Time to wait before calling callbacks in ms * @return {!AsyncInterface} An async timeout interface */ after(delay) { return { run(fn) { return window.setTimeout(fn, delay); }, cancel(handle) { window.clearTimeout(handle); }, }; }, /** * Enqueues a function called in the next task. * * @memberof timeOut * @param {!Function} fn Callback to run * @param {number=} delay Delay in milliseconds * @return {number} Handle used for canceling task */ run(fn, delay) { return window.setTimeout(fn, delay); }, /** * Cancels a previously enqueued `timeOut` callback. * * @memberof timeOut * @param {number} handle Handle returned from `run` of callback to cancel * @return {void} */ cancel(handle) { window.clearTimeout(handle); }, }; export { timeOut }; /** * Async interface wrapper around `requestAnimationFrame`. * * @namespace * @summary Async interface wrapper around `requestAnimationFrame`. */ const animationFrame = { /** * Enqueues a function called at `requestAnimationFrame` timing. * * @memberof animationFrame * @param {function(number):void} fn Callback to run * @return {number} Handle used for canceling task */ run(fn) { return window.requestAnimationFrame(fn); }, /** * Cancels a previously enqueued `animationFrame` callback. * * @memberof animationFrame * @param {number} handle Handle returned from `run` of callback to cancel * @return {void} */ cancel(handle) { window.cancelAnimationFrame(handle); }, }; export { animationFrame }; /** * Async interface wrapper around `requestIdleCallback`. Falls back to * `setTimeout` on browsers that do not support `requestIdleCallback`. * * @namespace * @summary Async interface wrapper around `requestIdleCallback`. */ const idlePeriod = { /** * Enqueues a function called at `requestIdleCallback` timing. * * @memberof idlePeriod * @param {function(!IdleDeadline):void} fn Callback to run * @return {number} Handle used for canceling task */ run(fn) { return window.requestIdleCallback ? window.requestIdleCallback(fn) : window.setTimeout(fn, 16); }, /** * Cancels a previously enqueued `idlePeriod` callback. * * @memberof idlePeriod * @param {number} handle Handle returned from `run` of callback to cancel * @return {void} */ cancel(handle) { if (window.cancelIdleCallback) { window.cancelIdleCallback(handle); } else { window.clearTimeout(handle); } }, }; export { idlePeriod }; /** * Async interface for enqueuing callbacks that run at microtask timing. * * @namespace * @summary Async interface for enqueuing callbacks that run at microtask * timing. */ const microTask = { /** * Enqueues a function called at microtask timing. * * @memberof microTask * @param {!Function=} callback Callback to run * @return {number} Handle used for canceling task */ run(callback) { if (!microtaskScheduled) { microtaskScheduled = true; queueMicrotask(() => microtaskFlush()); } microtaskCallbacks.push(callback); const result = microtaskCurrHandle; microtaskCurrHandle += 1; return result; }, /** * Cancels a previously enqueued `microTask` callback. * * @memberof microTask * @param {number} handle Handle returned from `run` of callback to cancel * @return {void} */ cancel(handle) { const idx = handle - microtaskLastHandle; if (idx >= 0) { if (!microtaskCallbacks[idx]) { throw new Error(`invalid async handle: ${handle}`); } microtaskCallbacks[idx] = null; } }, }; export { microTask };