]> BookStack Code Mirror - bookstack/blob - resources/js/services/util.js
0a8966f15c638031e3a4c4685ebe8e6b2be93b47
[bookstack] / resources / js / services / util.js
1 /**
2  * Returns a function, that, as long as it continues to be invoked, will not
3  * be triggered. The function will be called after it stops being called for
4  * N milliseconds. If `immediate` is passed, trigger the function on the
5  * leading edge, instead of the trailing.
6  * @attribution https://davidwalsh.name/javascript-debounce-function
7  * @param {Function} func
8  * @param {Number} wait
9  * @param {Boolean} immediate
10  * @returns {Function}
11  */
12 export function debounce(func, wait, immediate) {
13     let timeout;
14     return function debouncedWrapper(...args) {
15         const context = this;
16         const later = function debouncedTimeout() {
17             timeout = null;
18             if (!immediate) func.apply(context, args);
19         };
20         const callNow = immediate && !timeout;
21         clearTimeout(timeout);
22         timeout = setTimeout(later, wait);
23         if (callNow) func.apply(context, args);
24     };
25 }
26
27 /**
28  * Scroll and highlight an element.
29  * @param {HTMLElement} element
30  */
31 export function scrollAndHighlightElement(element) {
32     if (!element) return;
33     element.scrollIntoView({behavior: 'smooth'});
34
35     const color = getComputedStyle(document.body).getPropertyValue('--color-primary-light');
36     const initColor = window.getComputedStyle(element).getPropertyValue('background-color');
37     element.style.backgroundColor = color;
38     setTimeout(() => {
39         element.classList.add('selectFade');
40         element.style.backgroundColor = initColor;
41     }, 10);
42     setTimeout(() => {
43         element.classList.remove('selectFade');
44         element.style.backgroundColor = '';
45     }, 3000);
46 }
47
48 /**
49  * Escape any HTML in the given 'unsafe' string.
50  * Take from https://stackoverflow.com/a/6234804.
51  * @param {String} unsafe
52  * @returns {string}
53  */
54 export function escapeHtml(unsafe) {
55     return unsafe
56         .replace(/&/g, '&')
57         .replace(/</g, '&lt;')
58         .replace(/>/g, '&gt;')
59         .replace(/"/g, '&quot;')
60         .replace(/'/g, '&#039;');
61 }
62
63 /**
64  * Generate a random unique ID.
65  *
66  * @returns {string}
67  */
68 export function uniqueId() {
69     // eslint-disable-next-line no-bitwise
70     const S4 = () => (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
71     return (`${S4() + S4()}-${S4()}-${S4()}-${S4()}-${S4()}${S4()}${S4()}`);
72 }
73
74 /**
75  * Create a promise that resolves after the given time.
76  * @param {int} timeMs
77  * @returns {Promise}
78  */
79 export function wait(timeMs) {
80     return new Promise(res => {
81         setTimeout(res, timeMs);
82     });
83 }