/**
* Delay.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
/**
* Utility class for working with delayed actions like setTimeout.
*
* @class tinymce.util.Delay
*/
define(
'tinymce.core.util.Delay',
[
'global!clearInterval',
'global!clearTimeout',
'global!document',
'global!setInterval',
'global!setTimeout',
'global!window',
'tinymce.core.util.Promise'
],
function (clearInterval, clearTimeout, document, setInterval, setTimeout, window, Promise) {
var requestAnimationFramePromise;
var requestAnimationFrame = function (callback, element) {
var i, requestAnimationFrameFunc = window.requestAnimationFrame, vendors = ['ms', 'moz', 'webkit'];
var featurefill = function (callback) {
window.setTimeout(callback, 0);
};
for (i = 0; i < vendors.length && !requestAnimationFrameFunc; i++) {
requestAnimationFrameFunc = window[vendors[i] + 'RequestAnimationFrame'];
}
if (!requestAnimationFrameFunc) {
requestAnimationFrameFunc = featurefill;
}
requestAnimationFrameFunc(callback, element);
};
var wrappedSetTimeout = function (callback, time) {
if (typeof time != 'number') {
time = 0;
}
return setTimeout(callback, time);
};
var wrappedSetInterval = function (callback, time) {
if (typeof time != 'number') {
time = 1; // IE 8 needs it to be > 0
}
return setInterval(callback, time);
};
var wrappedClearTimeout = function (id) {
return clearTimeout(id);
};
var wrappedClearInterval = function (id) {
return clearInterval(id);
};
var debounce = function (callback, time) {
var timer, func;
func = function () {
var args = arguments;
clearTimeout(timer);
timer = wrappedSetTimeout(function () {
callback.apply(this, args);
}, time);
};
func.stop = function () {
clearTimeout(timer);
};
return func;
};
return {
/**
* Requests an animation frame and fallbacks to a timeout on older browsers.
*
* @method requestAnimationFrame
* @param {function} callback Callback to execute when a new frame is available.
* @param {DOMElement} element Optional element to scope it to.
*/
requestAnimationFrame: function (callback, element) {
if (requestAnimationFramePromise) {
requestAnimationFramePromise.then(callback);
return;
}
requestAnimationFramePromise = new Promise(function (resolve) {
if (!element) {
element = document.body;
}
requestAnimationFrame(resolve, element);
}).then(callback);
},
/**
* Sets a timer in ms and executes the specified callback when the timer runs out.
*
* @method setTimeout
* @param {function} callback Callback to execute when timer runs out.
* @param {Number} time Optional time to wait before the callback is executed, defaults to 0.
* @return {Number} Timeout id number.
*/
setTimeout: wrappedSetTimeout,
/**
* Sets an interval timer in ms and executes the specified callback at every interval of that time.
*
* @method setInterval
* @param {function} callback Callback to execute when interval time runs out.
* @param {Number} time Optional time to wait before the callback is executed, defaults to 0.
* @return {Number} Timeout id number.
*/
setInterval: wrappedSetInterval,
/**
* Sets an editor timeout it's similar to setTimeout except that it checks if the editor instance is
* still alive when the callback gets executed.
*
* @method setEditorTimeout
* @param {tinymce.Editor} editor Editor instance to check the removed state on.
* @param {function} callback Callback to execute when timer runs out.
* @param {Number} time Optional time to wait before the callback is executed, defaults to 0.
* @return {Number} Timeout id number.
*/
setEditorTimeout: function (editor, callback, time) {
return wrappedSetTimeout(function () {
if (!editor.removed) {
callback();
}
}, time);
},
/**
* Sets an interval timer it's similar to setInterval except that it checks if the editor instance is
* still alive when the callback gets executed.
*
* @method setEditorInterval
* @param {function} callback Callback to execute when interval time runs out.
* @param {Number} time Optional time to wait before the callback is executed, defaults to 0.
* @return {Number} Timeout id number.
*/
setEditorInterval: function (editor, callback, time) {
var timer;
timer = wrappedSetInterval(function () {
if (!editor.removed) {
callback();
} else {
clearInterval(timer);
}
}, time);
return timer;
},
/**
* Creates debounced callback function that only gets executed once within the specified time.
*
* @method debounce
* @param {function} callback Callback to execute when timer finishes.
* @param {Number} time Optional time to wait before the callback is executed, defaults to 0.
* @return {Function} debounced function callback.
*/
debounce: debounce,
// Throttle needs to be debounce due to backwards compatibility.
throttle: debounce,
/**
* Clears an interval timer so it won't execute.
*
* @method clearInterval
* @param {Number} Interval timer id number.
*/
clearInterval: wrappedClearInterval,
/**
* Clears an timeout timer so it won't execute.
*
* @method clearTimeout
* @param {Number} Timeout timer id number.
*/
clearTimeout: wrappedClearTimeout
};
}
);
|