| 1 | import * as initializer from "./initializer.js"; |
| 2 | import * as _modals from "./modals.js"; |
| 3 | import "./surfaces.js"; |
| 4 | import * as _components from "./components.js"; |
| 5 | import * as extensions from "./extensions.js"; |
| 6 | import { registerAlpineMagic } from "./confirmClick.js"; |
| 7 | |
| 8 | // process extensions |
| 9 | await extensions.callJsExtensions("initFw_start") |
| 10 | |
| 11 | // initialize required elements |
| 12 | await initializer.initialize(); |
| 13 | |
| 14 | // import alpine library |
| 15 | // @ts-ignore |
| 16 | await import("../vendor/alpine/alpine.min.js"); |
| 17 | |
| 18 | const Alpine = globalThis.Alpine; |
| 19 | |
| 20 | // register $confirmClick magic helper for inline button confirmations |
| 21 | registerAlpineMagic(); |
| 22 | |
| 23 | // add x-destroy directive to alpine |
| 24 | Alpine.directive( |
| 25 | "destroy", |
| 26 | (_el, { expression }, { evaluateLater, cleanup }) => { |
| 27 | const onDestroy = evaluateLater(expression); |
| 28 | cleanup(() => onDestroy()); |
| 29 | } |
| 30 | ); |
| 31 | |
| 32 | // add x-create directive to alpine |
| 33 | Alpine.directive( |
| 34 | "create", |
| 35 | (_el, { expression }, { evaluateLater }) => { |
| 36 | const onCreate = evaluateLater(expression); |
| 37 | onCreate(); |
| 38 | } |
| 39 | ); |
| 40 | |
| 41 | const resolveSelector = (expression, evaluateLater, cb) => { |
| 42 | if (typeof expression !== "string" || !expression.trim()) return; |
| 43 | |
| 44 | if (/^[\s]*["']/.test(expression)) { |
| 45 | const getSelector = evaluateLater(expression); |
| 46 | getSelector((evaluated) => { |
| 47 | if (typeof evaluated !== "string" || !evaluated.trim()) return; |
| 48 | cb(evaluated.trim()); |
| 49 | }); |
| 50 | return; |
| 51 | } |
| 52 | |
| 53 | cb(expression.trim()); |
| 54 | }; |
| 55 | |
| 56 | const moveOnNextTick = (el, expression, evaluateLater, fn) => { |
| 57 | Alpine.nextTick(() => { |
| 58 | resolveSelector(expression, evaluateLater, (selector) => fn(el, selector)); |
| 59 | }); |
| 60 | }; |
| 61 | |
| 62 | Alpine.directive( |
| 63 | "move-to-start", |
| 64 | (el, { expression }, { evaluateLater }) => { |
| 65 | moveOnNextTick(el, expression, evaluateLater, (_el, selector) => { |
| 66 | const parent = document.querySelector(selector); |
| 67 | if (!parent) return; |
| 68 | parent.insertBefore(_el, parent.firstChild); |
| 69 | }); |
| 70 | } |
| 71 | ); |
| 72 | |
| 73 | Alpine.directive( |
| 74 | "move-to-end", |
| 75 | (el, { expression }, { evaluateLater }) => { |
| 76 | moveOnNextTick(el, expression, evaluateLater, (_el, selector) => { |
| 77 | const parent = document.querySelector(selector); |
| 78 | if (!parent) return; |
| 79 | parent.appendChild(_el); |
| 80 | }); |
| 81 | } |
| 82 | ); |
| 83 | |
| 84 | Alpine.directive( |
| 85 | "move-to", |
| 86 | (el, { expression, modifiers, value }, { evaluateLater }) => { |
| 87 | const orderModifier = Array.isArray(modifiers) |
| 88 | ? modifiers.find((m) => /^\d+$/.test(m)) |
| 89 | : null; |
| 90 | |
| 91 | const orderRaw = orderModifier ?? value; |
| 92 | const order = Number(orderRaw); |
| 93 | if (!Number.isFinite(order)) return; |
| 94 | |
| 95 | moveOnNextTick(el, expression, evaluateLater, (_el, selector) => { |
| 96 | const parent = document.querySelector(selector); |
| 97 | if (!parent) return; |
| 98 | |
| 99 | const index = Math.max(0, Math.floor(order)); |
| 100 | const beforeNode = parent.children.item(index) ?? null; |
| 101 | parent.insertBefore(_el, beforeNode); |
| 102 | }); |
| 103 | } |
| 104 | ); |
| 105 | |
| 106 | Alpine.directive( |
| 107 | "move-before", |
| 108 | (el, { expression }, { evaluateLater }) => { |
| 109 | moveOnNextTick(el, expression, evaluateLater, (_el, selector) => { |
| 110 | const ref = document.querySelector(selector); |
| 111 | if (!ref || !ref.parentElement) return; |
| 112 | ref.parentElement.insertBefore(_el, ref); |
| 113 | }); |
| 114 | } |
| 115 | ); |
| 116 | |
| 117 | Alpine.directive( |
| 118 | "move-after", |
| 119 | (el, { expression }, { evaluateLater }) => { |
| 120 | moveOnNextTick(el, expression, evaluateLater, (_el, selector) => { |
| 121 | const ref = document.querySelector(selector); |
| 122 | if (!ref || !ref.parentElement) return; |
| 123 | ref.parentElement.insertBefore(_el, ref.nextSibling); |
| 124 | }); |
| 125 | } |
| 126 | ); |
| 127 | |
| 128 | // run every second if the component is active |
| 129 | Alpine.directive( |
| 130 | "every-second", |
| 131 | (_el, { expression }, { evaluateLater, cleanup }) => { |
| 132 | const onTick = evaluateLater(expression); |
| 133 | const intervalId = setInterval(() => onTick(), 1000); |
| 134 | cleanup(() => clearInterval(intervalId)); |
| 135 | } |
| 136 | ); |
| 137 | |
| 138 | // run every minute if the component is active |
| 139 | Alpine.directive( |
| 140 | "every-minute", |
| 141 | (_el, { expression }, { evaluateLater, cleanup }) => { |
| 142 | const onTick = evaluateLater(expression); |
| 143 | const intervalId = setInterval(() => onTick(), 60_000); |
| 144 | cleanup(() => clearInterval(intervalId)); |
| 145 | } |
| 146 | ); |
| 147 | |
| 148 | // run every hour if the component is active |
| 149 | Alpine.directive( |
| 150 | "every-hour", |
| 151 | (_el, { expression }, { evaluateLater, cleanup }) => { |
| 152 | const onTick = evaluateLater(expression); |
| 153 | const intervalId = setInterval(() => onTick(), 3_600_000); |
| 154 | cleanup(() => clearInterval(intervalId)); |
| 155 | } |
| 156 | ); |
| 157 | |
| 158 | |
| 159 | // clone existing global store into standalone instance |
| 160 | globalThis.Alpine.magic('instantiate', () => (src) => { |
| 161 | const out = {}; |
| 162 | const desc = Object.getOwnPropertyDescriptors(src); |
| 163 | |
| 164 | for (const k in desc) { |
| 165 | const d = desc[k]; |
| 166 | |
| 167 | if (d.get || d.set || typeof d.value === "function") { |
| 168 | Object.defineProperty(out, k, d); |
| 169 | } else { |
| 170 | const v = d.value; |
| 171 | Object.defineProperty(out, k, { |
| 172 | ...d, |
| 173 | value: Array.isArray(v) |
| 174 | ? v.map(i => (i && typeof i === "object" ? { ...i } : i)) |
| 175 | : v && typeof v === "object" |
| 176 | ? { ...v } |
| 177 | : v |
| 178 | }); |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | return out; |
| 183 | }); |
| 184 | |
| 185 | // process extensions |
| 186 | await extensions.callJsExtensions("initFw_end") |