all files / popper/utils/ debounce.js

92.31% Statements 24/26
75% Branches 6/8
100% Functions 6/6
92.31% Lines 24/26
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65    21×             109× 109× 109×         109× 119× 119×     109×   109× 122× 119× 119× 119×                                                    
import isNative from './isNative';
 
const longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];
let timeoutDuration = 0;
for (let i = 0; i < longerTimeoutBrowsers.length; i += 1) {
    Iif (navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {
        timeoutDuration = 1;
        break;
    }
}
 
export function microtaskDebounce(fn) {
    let scheduled = false;
    let i = 0;
    const elem = document.createElement('span');
 
    // MutationObserver provides a mechanism for scheduling microtasks, which
    // are scheduled *before* the next task. This gives us a way to debounce
    // a function but ensure it's called *before* the next paint.
    const observer = new MutationObserver(() => {
        fn();
        scheduled = false;
    });
 
    observer.observe(elem, { attributes: true });
 
    return () => {
        if (!scheduled) {
            scheduled = true;
            elem.setAttribute('x-index', i);
            i = i + 1; // don't use compund (+=) because it doesn't get optimized in V8
        }
    };
}
 
export function taskDebounce(fn) {
    let scheduled = false;
    return () => {
        if (!scheduled) {
            scheduled = true;
            setTimeout(() => {
                scheduled = false;
                fn();
            }, timeoutDuration);
        }
    };
}
 
// It's common for MutationObserver polyfills to be seen in the wild, however
// these rely on Mutation Events which only occur when an element is connected
// to the DOM. The algorithm used in this module does not use a connected element,
// and so we must ensure that a *native* MutationObserver is available.
const supportsNativeMutationObserver = isNative(window.MutationObserver);
 
/**
* Create a debounced version of a method, that's asynchronously deferred
* but called in the minimum time possible.
*
* @method
* @memberof Popper.Utils
* @argument {Function} fn
* @returns {Function}
*/
export default supportsNativeMutationObserver ? microtaskDebounce : taskDebounce;