utils.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Thanks @stimulus:
  2. // https://github.com/stimulusjs/stimulus/blob/master/packages/%40stimulus/core/src/application.ts
  3. export function domReady() {
  4. return new Promise(resolve => {
  5. if (document.readyState == "loading") {
  6. document.addEventListener("DOMContentLoaded", resolve)
  7. } else {
  8. resolve()
  9. }
  10. })
  11. }
  12. export function isTesting() {
  13. return navigator.userAgent, navigator.userAgent.includes("Node.js")
  14. || navigator.userAgent.includes("jsdom")
  15. }
  16. export function walkSkippingNestedComponents(el, callback) {
  17. callback(el)
  18. let node = el.firstElementChild
  19. while (node) {
  20. if (node.hasAttribute('x-data')) return
  21. walk(node, callback)
  22. node = node.nextElementSibling
  23. }
  24. }
  25. export function debounce(func, wait, immediate) {
  26. var timeout;
  27. return function () {
  28. var context = this, args = arguments;
  29. var later = function () {
  30. timeout = null;
  31. if (!immediate) func.apply(context, args);
  32. };
  33. var callNow = immediate && !timeout;
  34. clearTimeout(timeout);
  35. timeout = setTimeout(later, wait);
  36. if (callNow) func.apply(context, args);
  37. };
  38. };
  39. export function onlyUnique(value, index, self) {
  40. return self.indexOf(value) === index;
  41. }
  42. export function saferEval(expression, dataContext, additionalHelperVariables = {}) {
  43. return (new Function(['$data', ...Object.keys(additionalHelperVariables)], `var result; with($data) { result = ${expression} }; return result`))(
  44. dataContext, ...Object.values(additionalHelperVariables)
  45. )
  46. }
  47. export function saferEvalNoReturn(expression, dataContext, additionalHelperVariables = {}) {
  48. return (new Function(['$data', ...Object.keys(additionalHelperVariables)], `with($data) { ${expression} }`))(
  49. dataContext, ...Object.values(additionalHelperVariables)
  50. )
  51. }
  52. export function isXAttr(attr) {
  53. const xAttrRE = /x-(on|bind|data|text|model|cloak)/
  54. return xAttrRE.test(attr.name)
  55. }
  56. export function getXAttrs(el, type) {
  57. return Array.from(el.attributes)
  58. .filter(isXAttr)
  59. .map(attr => {
  60. const typeMatch = attr.name.match(/x-(on|bind|data|text|model|cloak)/)
  61. const valueMatch = attr.name.match(/:([a-zA-Z\-]+)/)
  62. const modifiers = attr.name.match(/\.[^.\]]+(?=[^\]]*$)/g) || []
  63. return {
  64. type: typeMatch ? typeMatch[1] : null,
  65. value: valueMatch ? valueMatch[1] : null,
  66. modifiers: modifiers.map(i => i.replace('.', '')),
  67. expression: attr.value,
  68. }
  69. })
  70. .filter(i => {
  71. // If no type is passed in for filtering, bypassfilter
  72. if (! type) return true
  73. return i.type === name
  74. })
  75. }