utils.js 1.9 KB

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