1 | /**
|
2 | * Debounce a function to delay invoking until wait (ms) have elapsed since the last invocation.
|
3 | * @param {function(...*): *} fn The function to be debounced.
|
4 | * @param {number} wait Milliseconds to wait before invoking again.
|
5 | * @return {function(...*): void} The debounced function.
|
6 | */
|
7 | function debounce(fn, wait) {
|
8 | /**
|
9 | * A cached setTimeout handler.
|
10 | * @type {number | undefined}
|
11 | */
|
12 | let timer;
|
13 |
|
14 | /**
|
15 | * @returns {void}
|
16 | */
|
17 | function debounced() {
|
18 | const context = this;
|
19 | const args = arguments;
|
20 |
|
21 | clearTimeout(timer);
|
22 | timer = setTimeout(function () {
|
23 | return fn.apply(context, args);
|
24 | }, wait);
|
25 | }
|
26 |
|
27 | return debounced;
|
28 | }
|
29 |
|
30 | /**
|
31 | * Prettify a filename from error stacks into the desired format.
|
32 | * @param {string} filename The filename to be formatted.
|
33 | * @returns {string} The formatted filename.
|
34 | */
|
35 | function formatFilename(filename) {
|
36 | // Strip away protocol and domain for compiled files
|
37 | const htmlMatch = /^https?:\/\/(.*)\/(.*)/.exec(filename);
|
38 | if (htmlMatch && htmlMatch[1] && htmlMatch[2]) {
|
39 | return htmlMatch[2];
|
40 | }
|
41 |
|
42 | // Strip everything before the first directory for source files
|
43 | const sourceMatch = /\/.*?([^./]+[/|\\].*)$/.exec(filename);
|
44 | if (sourceMatch && sourceMatch[1]) {
|
45 | return sourceMatch[1].replace(/\?$/, '');
|
46 | }
|
47 |
|
48 | // Unknown filename type, use it as is
|
49 | return filename;
|
50 | }
|
51 |
|
52 | /**
|
53 | * Remove all children of an element.
|
54 | * @param {HTMLElement} element A valid HTML element.
|
55 | * @param {number} [skip] Number of elements to skip removing.
|
56 | * @returns {void}
|
57 | */
|
58 | function removeAllChildren(element, skip) {
|
59 | /** @type {Node[]} */
|
60 | const childList = Array.prototype.slice.call(
|
61 | element.childNodes,
|
62 | typeof skip !== 'undefined' ? skip : 0
|
63 | );
|
64 |
|
65 | for (let i = 0; i < childList.length; i += 1) {
|
66 | element.removeChild(childList[i]);
|
67 | }
|
68 | }
|
69 |
|
70 | module.exports = {
|
71 | debounce: debounce,
|
72 | formatFilename: formatFilename,
|
73 | removeAllChildren: removeAllChildren,
|
74 | };
|