From 25550c65b6af716693c24361a89f45713ca080a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Tue, 12 Oct 2021 15:08:41 +0200 Subject: alpinejs: Patch for mutator body removal See https://github.com/alpinejs/alpine/issues/2126#issuecomment-940942921 --- alpinejs/packages/alpinejs/builds/cdn.js | 7 + alpinejs/packages/alpinejs/builds/module.js | 3 + alpinejs/packages/alpinejs/dist/cdn.js | 42 +- alpinejs/packages/alpinejs/dist/cdn.min.js | 4 +- alpinejs/packages/alpinejs/dist/dist/cdn.js | 2660 ++++++++++++++++ alpinejs/packages/alpinejs/dist/dist/cdn.min.js | 5 + alpinejs/packages/alpinejs/dist/dist/module.cjs.js | 3245 +++++++++++++++++++ alpinejs/packages/alpinejs/dist/dist/module.esm.js | 3238 +++++++++++++++++++ alpinejs/packages/alpinejs/dist/module.cjs.js | 42 +- alpinejs/packages/alpinejs/dist/module.esm.js | 42 +- alpinejs/packages/alpinejs/package.json | 13 + alpinejs/packages/alpinejs/src/alpine.js | 54 + alpinejs/packages/alpinejs/src/clone.js | 65 + alpinejs/packages/alpinejs/src/datas.js | 22 + alpinejs/packages/alpinejs/src/directives.js | 179 ++ alpinejs/packages/alpinejs/src/directives/index.js | 15 + .../packages/alpinejs/src/directives/x-bind.js | 54 + .../packages/alpinejs/src/directives/x-cloak.js | 4 + .../packages/alpinejs/src/directives/x-data.js | 43 + .../packages/alpinejs/src/directives/x-effect.js | 4 + alpinejs/packages/alpinejs/src/directives/x-for.js | 262 ++ .../packages/alpinejs/src/directives/x-html.js | 13 + alpinejs/packages/alpinejs/src/directives/x-if.js | 43 + .../packages/alpinejs/src/directives/x-ignore.js | 17 + .../packages/alpinejs/src/directives/x-init.js | 14 + .../packages/alpinejs/src/directives/x-model.js | 107 + alpinejs/packages/alpinejs/src/directives/x-on.js | 16 + alpinejs/packages/alpinejs/src/directives/x-ref.js | 16 + .../packages/alpinejs/src/directives/x-show.js | 56 + .../packages/alpinejs/src/directives/x-text.js | 14 + .../alpinejs/src/directives/x-transition.js | 325 ++ alpinejs/packages/alpinejs/src/evaluator.js | 125 + alpinejs/packages/alpinejs/src/index.js | 74 + alpinejs/packages/alpinejs/src/interceptor.js | 77 + alpinejs/packages/alpinejs/src/lifecycle.js | 75 + alpinejs/packages/alpinejs/src/magics.js | 26 + alpinejs/packages/alpinejs/src/magics/$dispatch.js | 4 + alpinejs/packages/alpinejs/src/magics/$el.js | 3 + alpinejs/packages/alpinejs/src/magics/$nextTick.js | 4 + alpinejs/packages/alpinejs/src/magics/$refs.js | 25 + alpinejs/packages/alpinejs/src/magics/$root.js | 4 + alpinejs/packages/alpinejs/src/magics/$store.js | 4 + alpinejs/packages/alpinejs/src/magics/$watch.js | 37 + alpinejs/packages/alpinejs/src/magics/index.js | 7 + alpinejs/packages/alpinejs/src/mutation.js | 195 ++ alpinejs/packages/alpinejs/src/nextTick.js | 24 + alpinejs/packages/alpinejs/src/plugin.js | 5 + alpinejs/packages/alpinejs/src/reactivity.js | 62 + alpinejs/packages/alpinejs/src/scheduler.js | 33 + alpinejs/packages/alpinejs/src/scope.js | 105 + alpinejs/packages/alpinejs/src/store.js | 20 + alpinejs/packages/alpinejs/src/utils/bind.js | 129 + alpinejs/packages/alpinejs/src/utils/classes.js | 58 + alpinejs/packages/alpinejs/src/utils/debounce.js | 18 + alpinejs/packages/alpinejs/src/utils/dispatch.js | 12 + alpinejs/packages/alpinejs/src/utils/on.js | 163 + alpinejs/packages/alpinejs/src/utils/once.js | 14 + alpinejs/packages/alpinejs/src/utils/styles.js | 45 + alpinejs/packages/alpinejs/src/utils/throttle.js | 16 + alpinejs/packages/alpinejs/src/utils/walk.js | 38 + alpinejs/packages/alpinejs/src/utils/warn.js | 4 + alpinejs/packages/collapse/builds/cdn.js | 5 + alpinejs/packages/collapse/builds/module.js | 3 + alpinejs/packages/collapse/dist/dist/cdn.js | 74 + alpinejs/packages/collapse/dist/dist/cdn.min.js | 1 + alpinejs/packages/collapse/dist/dist/module.cjs.js | 83 + alpinejs/packages/collapse/dist/dist/module.esm.js | 73 + alpinejs/packages/collapse/package.json | 11 + alpinejs/packages/collapse/src/index.js | 73 + alpinejs/packages/csp/builds/cdn.js | 7 + alpinejs/packages/csp/builds/module.js | 3 + alpinejs/packages/csp/dist/cdn.js | 42 +- alpinejs/packages/csp/dist/cdn.min.js | 4 +- alpinejs/packages/csp/dist/dist/cdn.js | 2676 ++++++++++++++++ alpinejs/packages/csp/dist/dist/cdn.min.js | 5 + alpinejs/packages/csp/dist/dist/module.cjs.js | 3261 ++++++++++++++++++++ alpinejs/packages/csp/dist/dist/module.esm.js | 3254 +++++++++++++++++++ alpinejs/packages/csp/dist/module.cjs.js | 42 +- alpinejs/packages/csp/dist/module.esm.js | 42 +- alpinejs/packages/csp/package.json | 12 + alpinejs/packages/csp/src/index.js | 37 + alpinejs/packages/docs/package.json | 7 + alpinejs/packages/docs/src/en/advanced.md | 5 + alpinejs/packages/docs/src/en/advanced/async.md | 40 + alpinejs/packages/docs/src/en/advanced/csp.md | 72 + .../packages/docs/src/en/advanced/extending.md | 360 +++ .../packages/docs/src/en/advanced/reactivity.md | 101 + alpinejs/packages/docs/src/en/directives.md | 7 + alpinejs/packages/docs/src/en/directives/bind.md | 189 ++ alpinejs/packages/docs/src/en/directives/cloak.md | 38 + alpinejs/packages/docs/src/en/directives/data.md | 170 + alpinejs/packages/docs/src/en/directives/effect.md | 20 + alpinejs/packages/docs/src/en/directives/for.md | 87 + alpinejs/packages/docs/src/en/directives/html.md | 29 + alpinejs/packages/docs/src/en/directives/if.md | 20 + alpinejs/packages/docs/src/en/directives/ignore.md | 20 + alpinejs/packages/docs/src/en/directives/init.md | 74 + alpinejs/packages/docs/src/en/directives/model.md | 338 ++ alpinejs/packages/docs/src/en/directives/on.md | 276 ++ alpinejs/packages/docs/src/en/directives/ref.md | 24 + alpinejs/packages/docs/src/en/directives/show.md | 39 + alpinejs/packages/docs/src/en/directives/text.md | 26 + .../packages/docs/src/en/directives/transition.md | 175 ++ alpinejs/packages/docs/src/en/essentials.md | 5 + alpinejs/packages/docs/src/en/essentials/events.md | 101 + .../docs/src/en/essentials/installation.md | 68 + .../packages/docs/src/en/essentials/lifecycle.md | 96 + alpinejs/packages/docs/src/en/essentials/state.md | 133 + .../packages/docs/src/en/essentials/templating.md | 368 +++ alpinejs/packages/docs/src/en/globals.md | 7 + .../packages/docs/src/en/globals/alpine-data.md | 136 + .../packages/docs/src/en/globals/alpine-store.md | 115 + alpinejs/packages/docs/src/en/magics.md | 7 + alpinejs/packages/docs/src/en/magics/dispatch.md | 106 + alpinejs/packages/docs/src/en/magics/el.md | 21 + alpinejs/packages/docs/src/en/magics/nextTick.md | 23 + alpinejs/packages/docs/src/en/magics/refs.md | 27 + alpinejs/packages/docs/src/en/magics/root.md | 21 + alpinejs/packages/docs/src/en/magics/store.md | 60 + alpinejs/packages/docs/src/en/magics/watch.md | 37 + alpinejs/packages/docs/src/en/plugins.md | 6 + alpinejs/packages/docs/src/en/plugins/collapse.md | 109 + alpinejs/packages/docs/src/en/plugins/intersect.md | 106 + alpinejs/packages/docs/src/en/plugins/persist.md | 196 ++ alpinejs/packages/docs/src/en/plugins/trap.md | 180 ++ alpinejs/packages/docs/src/en/start-here.md | 326 ++ alpinejs/packages/docs/src/en/upgrade-guide.md | 375 +++ alpinejs/packages/history/builds/cdn.js | 5 + alpinejs/packages/history/builds/module.js | 3 + alpinejs/packages/history/dist/dist/cdn.js | 67 + alpinejs/packages/history/dist/dist/cdn.min.js | 1 + alpinejs/packages/history/dist/dist/module.cjs.js | 76 + alpinejs/packages/history/dist/dist/module.esm.js | 66 + alpinejs/packages/history/package.json | 12 + alpinejs/packages/history/src/index.js | 76 + alpinejs/packages/history/src/url.js | 36 + alpinejs/packages/intersect/builds/cdn.js | 5 + alpinejs/packages/intersect/builds/module.js | 3 + alpinejs/packages/intersect/dist/dist/cdn.js | 35 + alpinejs/packages/intersect/dist/dist/cdn.min.js | 1 + .../packages/intersect/dist/dist/module.cjs.js | 44 + .../packages/intersect/dist/dist/module.esm.js | 34 + alpinejs/packages/intersect/package.json | 11 + alpinejs/packages/intersect/src/index.js | 37 + alpinejs/packages/morph/builds/cdn.js | 5 + alpinejs/packages/morph/builds/module.js | 5 + alpinejs/packages/morph/dist/dist/cdn.js | 219 ++ alpinejs/packages/morph/dist/dist/cdn.min.js | 1 + alpinejs/packages/morph/dist/dist/module.cjs.js | 229 ++ alpinejs/packages/morph/dist/dist/module.esm.js | 219 ++ alpinejs/packages/morph/package.json | 12 + alpinejs/packages/morph/src/index.js | 17 + alpinejs/packages/morph/src/morph.js | 370 +++ alpinejs/packages/persist/builds/cdn.js | 5 + alpinejs/packages/persist/builds/module.js | 3 + alpinejs/packages/persist/dist/dist/cdn.js | 42 + alpinejs/packages/persist/dist/dist/cdn.min.js | 1 + alpinejs/packages/persist/dist/dist/module.cjs.js | 51 + alpinejs/packages/persist/dist/dist/module.esm.js | 41 + alpinejs/packages/persist/package.json | 11 + alpinejs/packages/persist/src/index.js | 42 + alpinejs/packages/trap/.gitignore | 0 alpinejs/packages/trap/builds/cdn.js | 5 + alpinejs/packages/trap/builds/module.js | 3 + alpinejs/packages/trap/dist/dist/cdn.js | 650 ++++ alpinejs/packages/trap/dist/dist/cdn.min.js | 9 + alpinejs/packages/trap/dist/dist/module.cjs.js | 712 +++++ alpinejs/packages/trap/dist/dist/module.esm.js | 705 +++++ alpinejs/packages/trap/package.json | 13 + alpinejs/packages/trap/src/index.js | 32 + 170 files changed, 30292 insertions(+), 106 deletions(-) create mode 100644 alpinejs/packages/alpinejs/builds/cdn.js create mode 100644 alpinejs/packages/alpinejs/builds/module.js create mode 100644 alpinejs/packages/alpinejs/dist/dist/cdn.js create mode 100644 alpinejs/packages/alpinejs/dist/dist/cdn.min.js create mode 100644 alpinejs/packages/alpinejs/dist/dist/module.cjs.js create mode 100644 alpinejs/packages/alpinejs/dist/dist/module.esm.js create mode 100644 alpinejs/packages/alpinejs/package.json create mode 100644 alpinejs/packages/alpinejs/src/alpine.js create mode 100644 alpinejs/packages/alpinejs/src/clone.js create mode 100644 alpinejs/packages/alpinejs/src/datas.js create mode 100644 alpinejs/packages/alpinejs/src/directives.js create mode 100644 alpinejs/packages/alpinejs/src/directives/index.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-bind.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-cloak.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-data.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-effect.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-for.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-html.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-if.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-ignore.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-init.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-model.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-on.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-ref.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-show.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-text.js create mode 100644 alpinejs/packages/alpinejs/src/directives/x-transition.js create mode 100644 alpinejs/packages/alpinejs/src/evaluator.js create mode 100644 alpinejs/packages/alpinejs/src/index.js create mode 100644 alpinejs/packages/alpinejs/src/interceptor.js create mode 100644 alpinejs/packages/alpinejs/src/lifecycle.js create mode 100644 alpinejs/packages/alpinejs/src/magics.js create mode 100644 alpinejs/packages/alpinejs/src/magics/$dispatch.js create mode 100644 alpinejs/packages/alpinejs/src/magics/$el.js create mode 100644 alpinejs/packages/alpinejs/src/magics/$nextTick.js create mode 100644 alpinejs/packages/alpinejs/src/magics/$refs.js create mode 100644 alpinejs/packages/alpinejs/src/magics/$root.js create mode 100644 alpinejs/packages/alpinejs/src/magics/$store.js create mode 100644 alpinejs/packages/alpinejs/src/magics/$watch.js create mode 100644 alpinejs/packages/alpinejs/src/magics/index.js create mode 100644 alpinejs/packages/alpinejs/src/mutation.js create mode 100644 alpinejs/packages/alpinejs/src/nextTick.js create mode 100644 alpinejs/packages/alpinejs/src/plugin.js create mode 100644 alpinejs/packages/alpinejs/src/reactivity.js create mode 100644 alpinejs/packages/alpinejs/src/scheduler.js create mode 100644 alpinejs/packages/alpinejs/src/scope.js create mode 100644 alpinejs/packages/alpinejs/src/store.js create mode 100644 alpinejs/packages/alpinejs/src/utils/bind.js create mode 100644 alpinejs/packages/alpinejs/src/utils/classes.js create mode 100644 alpinejs/packages/alpinejs/src/utils/debounce.js create mode 100644 alpinejs/packages/alpinejs/src/utils/dispatch.js create mode 100644 alpinejs/packages/alpinejs/src/utils/on.js create mode 100644 alpinejs/packages/alpinejs/src/utils/once.js create mode 100644 alpinejs/packages/alpinejs/src/utils/styles.js create mode 100644 alpinejs/packages/alpinejs/src/utils/throttle.js create mode 100644 alpinejs/packages/alpinejs/src/utils/walk.js create mode 100644 alpinejs/packages/alpinejs/src/utils/warn.js create mode 100644 alpinejs/packages/collapse/builds/cdn.js create mode 100644 alpinejs/packages/collapse/builds/module.js create mode 100644 alpinejs/packages/collapse/dist/dist/cdn.js create mode 100644 alpinejs/packages/collapse/dist/dist/cdn.min.js create mode 100644 alpinejs/packages/collapse/dist/dist/module.cjs.js create mode 100644 alpinejs/packages/collapse/dist/dist/module.esm.js create mode 100644 alpinejs/packages/collapse/package.json create mode 100644 alpinejs/packages/collapse/src/index.js create mode 100644 alpinejs/packages/csp/builds/cdn.js create mode 100644 alpinejs/packages/csp/builds/module.js create mode 100644 alpinejs/packages/csp/dist/dist/cdn.js create mode 100644 alpinejs/packages/csp/dist/dist/cdn.min.js create mode 100644 alpinejs/packages/csp/dist/dist/module.cjs.js create mode 100644 alpinejs/packages/csp/dist/dist/module.esm.js create mode 100644 alpinejs/packages/csp/package.json create mode 100644 alpinejs/packages/csp/src/index.js create mode 100644 alpinejs/packages/docs/package.json create mode 100644 alpinejs/packages/docs/src/en/advanced.md create mode 100644 alpinejs/packages/docs/src/en/advanced/async.md create mode 100644 alpinejs/packages/docs/src/en/advanced/csp.md create mode 100644 alpinejs/packages/docs/src/en/advanced/extending.md create mode 100644 alpinejs/packages/docs/src/en/advanced/reactivity.md create mode 100644 alpinejs/packages/docs/src/en/directives.md create mode 100644 alpinejs/packages/docs/src/en/directives/bind.md create mode 100644 alpinejs/packages/docs/src/en/directives/cloak.md create mode 100644 alpinejs/packages/docs/src/en/directives/data.md create mode 100644 alpinejs/packages/docs/src/en/directives/effect.md create mode 100644 alpinejs/packages/docs/src/en/directives/for.md create mode 100644 alpinejs/packages/docs/src/en/directives/html.md create mode 100644 alpinejs/packages/docs/src/en/directives/if.md create mode 100644 alpinejs/packages/docs/src/en/directives/ignore.md create mode 100644 alpinejs/packages/docs/src/en/directives/init.md create mode 100644 alpinejs/packages/docs/src/en/directives/model.md create mode 100644 alpinejs/packages/docs/src/en/directives/on.md create mode 100644 alpinejs/packages/docs/src/en/directives/ref.md create mode 100644 alpinejs/packages/docs/src/en/directives/show.md create mode 100644 alpinejs/packages/docs/src/en/directives/text.md create mode 100644 alpinejs/packages/docs/src/en/directives/transition.md create mode 100644 alpinejs/packages/docs/src/en/essentials.md create mode 100644 alpinejs/packages/docs/src/en/essentials/events.md create mode 100644 alpinejs/packages/docs/src/en/essentials/installation.md create mode 100644 alpinejs/packages/docs/src/en/essentials/lifecycle.md create mode 100644 alpinejs/packages/docs/src/en/essentials/state.md create mode 100644 alpinejs/packages/docs/src/en/essentials/templating.md create mode 100644 alpinejs/packages/docs/src/en/globals.md create mode 100644 alpinejs/packages/docs/src/en/globals/alpine-data.md create mode 100644 alpinejs/packages/docs/src/en/globals/alpine-store.md create mode 100644 alpinejs/packages/docs/src/en/magics.md create mode 100644 alpinejs/packages/docs/src/en/magics/dispatch.md create mode 100644 alpinejs/packages/docs/src/en/magics/el.md create mode 100644 alpinejs/packages/docs/src/en/magics/nextTick.md create mode 100644 alpinejs/packages/docs/src/en/magics/refs.md create mode 100644 alpinejs/packages/docs/src/en/magics/root.md create mode 100644 alpinejs/packages/docs/src/en/magics/store.md create mode 100644 alpinejs/packages/docs/src/en/magics/watch.md create mode 100644 alpinejs/packages/docs/src/en/plugins.md create mode 100644 alpinejs/packages/docs/src/en/plugins/collapse.md create mode 100644 alpinejs/packages/docs/src/en/plugins/intersect.md create mode 100644 alpinejs/packages/docs/src/en/plugins/persist.md create mode 100644 alpinejs/packages/docs/src/en/plugins/trap.md create mode 100644 alpinejs/packages/docs/src/en/start-here.md create mode 100644 alpinejs/packages/docs/src/en/upgrade-guide.md create mode 100644 alpinejs/packages/history/builds/cdn.js create mode 100644 alpinejs/packages/history/builds/module.js create mode 100644 alpinejs/packages/history/dist/dist/cdn.js create mode 100644 alpinejs/packages/history/dist/dist/cdn.min.js create mode 100644 alpinejs/packages/history/dist/dist/module.cjs.js create mode 100644 alpinejs/packages/history/dist/dist/module.esm.js create mode 100644 alpinejs/packages/history/package.json create mode 100644 alpinejs/packages/history/src/index.js create mode 100644 alpinejs/packages/history/src/url.js create mode 100644 alpinejs/packages/intersect/builds/cdn.js create mode 100644 alpinejs/packages/intersect/builds/module.js create mode 100644 alpinejs/packages/intersect/dist/dist/cdn.js create mode 100644 alpinejs/packages/intersect/dist/dist/cdn.min.js create mode 100644 alpinejs/packages/intersect/dist/dist/module.cjs.js create mode 100644 alpinejs/packages/intersect/dist/dist/module.esm.js create mode 100644 alpinejs/packages/intersect/package.json create mode 100644 alpinejs/packages/intersect/src/index.js create mode 100644 alpinejs/packages/morph/builds/cdn.js create mode 100644 alpinejs/packages/morph/builds/module.js create mode 100644 alpinejs/packages/morph/dist/dist/cdn.js create mode 100644 alpinejs/packages/morph/dist/dist/cdn.min.js create mode 100644 alpinejs/packages/morph/dist/dist/module.cjs.js create mode 100644 alpinejs/packages/morph/dist/dist/module.esm.js create mode 100644 alpinejs/packages/morph/package.json create mode 100644 alpinejs/packages/morph/src/index.js create mode 100644 alpinejs/packages/morph/src/morph.js create mode 100644 alpinejs/packages/persist/builds/cdn.js create mode 100644 alpinejs/packages/persist/builds/module.js create mode 100644 alpinejs/packages/persist/dist/dist/cdn.js create mode 100644 alpinejs/packages/persist/dist/dist/cdn.min.js create mode 100644 alpinejs/packages/persist/dist/dist/module.cjs.js create mode 100644 alpinejs/packages/persist/dist/dist/module.esm.js create mode 100644 alpinejs/packages/persist/package.json create mode 100644 alpinejs/packages/persist/src/index.js create mode 100644 alpinejs/packages/trap/.gitignore create mode 100644 alpinejs/packages/trap/builds/cdn.js create mode 100644 alpinejs/packages/trap/builds/module.js create mode 100644 alpinejs/packages/trap/dist/dist/cdn.js create mode 100644 alpinejs/packages/trap/dist/dist/cdn.min.js create mode 100644 alpinejs/packages/trap/dist/dist/module.cjs.js create mode 100644 alpinejs/packages/trap/dist/dist/module.esm.js create mode 100644 alpinejs/packages/trap/package.json create mode 100644 alpinejs/packages/trap/src/index.js diff --git a/alpinejs/packages/alpinejs/builds/cdn.js b/alpinejs/packages/alpinejs/builds/cdn.js new file mode 100644 index 0000000..a54e7e0 --- /dev/null +++ b/alpinejs/packages/alpinejs/builds/cdn.js @@ -0,0 +1,7 @@ +import Alpine from './../src/index' + +window.Alpine = Alpine + +queueMicrotask(() => { + Alpine.start() +}) diff --git a/alpinejs/packages/alpinejs/builds/module.js b/alpinejs/packages/alpinejs/builds/module.js new file mode 100644 index 0000000..0382080 --- /dev/null +++ b/alpinejs/packages/alpinejs/builds/module.js @@ -0,0 +1,3 @@ +import Alpine from './../src/index' + +export default Alpine diff --git a/alpinejs/packages/alpinejs/dist/cdn.js b/alpinejs/packages/alpinejs/dist/cdn.js index 50d3328..90b1dc6 100644 --- a/alpinejs/packages/alpinejs/dist/cdn.js +++ b/alpinejs/packages/alpinejs/dist/cdn.js @@ -77,6 +77,23 @@ }]; } + // packages/alpinejs/src/utils/walk.js + function walk(el, callback) { + if (typeof ShadowRoot === "function" && el instanceof ShadowRoot) { + Array.from(el.children).forEach((el2) => walk(el2, callback)); + return; + } + let skip = false; + callback(el, () => skip = true); + if (skip) + return; + let node = el.firstElementChild; + while (node) { + walk(node, callback, false); + node = node.nextElementSibling; + } + } + // packages/alpinejs/src/mutation.js var onAttributeAddeds = []; var onElRemoveds = []; @@ -207,6 +224,14 @@ if (addedNodes.includes(node)) continue; onElRemoveds.forEach((i) => i(node)); + if (node.localName === "body") { + node.querySelectorAll("[x-data]").forEach((el) => { + walk(el, (el2) => { + onElRemoveds.forEach((i) => i(el2)); + el2.remove(); + }); + }); + } } addedNodes = null; removedNodes = null; @@ -617,23 +642,6 @@ Expression: "${expression}" isHolding = true; } - // packages/alpinejs/src/utils/walk.js - function walk(el, callback) { - if (typeof ShadowRoot === "function" && el instanceof ShadowRoot) { - Array.from(el.children).forEach((el2) => walk(el2, callback)); - return; - } - let skip = false; - callback(el, () => skip = true); - if (skip) - return; - let node = el.firstElementChild; - while (node) { - walk(node, callback, false); - node = node.nextElementSibling; - } - } - // packages/alpinejs/src/utils/warn.js function warn(message, ...args) { console.warn(`Alpine Warning: ${message}`, ...args); diff --git a/alpinejs/packages/alpinejs/dist/cdn.min.js b/alpinejs/packages/alpinejs/dist/cdn.min.js index c714f97..0477350 100644 --- a/alpinejs/packages/alpinejs/dist/cdn.min.js +++ b/alpinejs/packages/alpinejs/dist/cdn.min.js @@ -1,5 +1,5 @@ -(()=>{var Ke=!1,ze=!1,Z=[];function Ot(e){Vr(e)}function Vr(e){Z.includes(e)||Z.push(e),Br()}function Br(){!ze&&!Ke&&(Ke=!0,queueMicrotask(Hr))}function Hr(){Ke=!1,ze=!0;for(let e=0;ee.effect(t,{scheduler:r=>{Be?Ot(r):r()}}),Ve=e.raw}function He(e){L=e}function me(e){let t=()=>{};return[n=>{let i=L(n);e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),V(i))}},()=>{t()}]}var Ct=[],Mt=[],Nt=[];function kt(e){Nt.push(e)}function Dt(e){Mt.push(e)}function Pt(e){Ct.push(e)}function B(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function qe(e,t){!e._x_attributeCleanups||Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}var We=new MutationObserver(Ue),Ge=!1;function Ye(){We.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),Ge=!0}function Je(){qr(),We.disconnect(),Ge=!1}var Q=[],Ze=!1;function qr(){Q=Q.concat(We.takeRecords()),Q.length&&!Ze&&(Ze=!0,queueMicrotask(()=>{Ur(),Ze=!1}))}function Ur(){Ue(Q),Q.length=0}function m(e){if(!Ge)return e();Je();let t=e();return Ye(),t}var Qe=!1,he=[];function It(){Qe=!0}function Lt(){Qe=!1,Ue(he),he=[]}function Ue(e){if(Qe){he=he.concat(e);return}let t=[],r=[],n=new Map,i=new Map;for(let o=0;os.nodeType===1&&t.push(s)),e[o].removedNodes.forEach(s=>s.nodeType===1&&r.push(s))),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{qe(s,o)}),n.forEach((o,s)=>{Ct.forEach(a=>a(s,o))});for(let o of t)r.includes(o)||Nt.forEach(s=>s(o));for(let o of r)t.includes(o)||Mt.forEach(s=>s(o));t=null,r=null,n=null,i=null}function H(e,t,r){return e._x_dataStack=[t,...X(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function Xe(e,t){let r=e._x_dataStack[0];Object.entries(t).forEach(([n,i])=>{r[n]=i})}function X(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?X(e.host):e.parentNode?X(e.parentNode):[]}function ee(e){let t=new Proxy({},{ownKeys:()=>Array.from(new Set(e.flatMap(r=>Object.keys(r)))),has:(r,n)=>e.some(i=>i.hasOwnProperty(n)),get:(r,n)=>(e.find(i=>{if(i.hasOwnProperty(n)){let o=Object.getOwnPropertyDescriptor(i,n);if(o.get&&o.get._x_alreadyBound||o.set&&o.set._x_alreadyBound)return!0;if((o.get||o.set)&&o.enumerable){let s=o.get,a=o.set,c=o;s=s&&s.bind(t),a=a&&a.bind(t),s&&(s._x_alreadyBound=!0),a&&(a._x_alreadyBound=!0),Object.defineProperty(i,n,{...c,get:s,set:a})}return!0}return!1})||{})[n],set:(r,n,i)=>{let o=e.find(s=>s.hasOwnProperty(n));return o?o[n]=i:e[e.length-1][n]=i,!0}});return t}function $t(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function ge(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>Wr(n,i),s=>et(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function Wr(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function et(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),et(e[t[0]],t.slice(1),r)}}var Ft={};function x(e,t){Ft[e]=t}function te(e,t){return Object.entries(Ft).forEach(([r,n])=>{Object.defineProperty(e,`$${r}`,{get(){return n(t,{Alpine:S,interceptor:ge})},enumerable:!1})}),{obj:e,cleanup:()=>{t=null}}}function b(e,t,r={}){let n;return h(e,t)(i=>n=i,r),n}function h(...e){return jt(...e)}var jt=tt;function Kt(e){jt=e}function tt(e,t){let r={},n=te(r,e).cleanup;B(e,"evaluator",n);let i=[r,...X(e)];if(typeof t=="function")return Gr(i,t);let o=Yr(i,t);return Jr.bind(null,e,t,o)}function Gr(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(ee([n,...e]),i);_e(r,o)}}var rt={};function Zr(e){if(rt[e])return rt[e];let t=Object.getPrototypeOf(async function(){}).constructor,r=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)/.test(e)?`(() => { ${e} })()`:e,n=new t(["__self","scope"],`with (scope) { __self.result = ${r} }; __self.finished = true; return __self.result;`);return rt[e]=n,n}function Yr(e,t){let r=Zr(t);return(n=()=>{},{scope:i={},params:o=[]}={})=>{r.result=void 0,r.finished=!1;let s=ee([i,...e]),a=r(r,s);r.finished?_e(n,r.result,s,o):a.then(c=>{_e(n,c,s,o)})}}function _e(e,t,r,n){if(typeof t=="function"){let i=t.apply(r,n);i instanceof Promise?i.then(o=>_e(e,o,r,n)):e(i)}else e(t)}function Jr(e,t,r,...n){try{return r(...n)}catch(i){throw console.warn(`Alpine Expression Error: ${i.message} +(()=>{var Ke=!1,ze=!1,Z=[];function Tt(e){Vr(e)}function Vr(e){Z.includes(e)||Z.push(e),Br()}function Br(){!ze&&!Ke&&(Ke=!0,queueMicrotask(Hr))}function Hr(){Ke=!1,ze=!0;for(let e=0;ee.effect(t,{scheduler:r=>{Be?Tt(r):r()}}),Ve=e.raw}function He(e){L=e}function me(e){let t=()=>{};return[n=>{let i=L(n);e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),V(i))}},()=>{t()}]}function S(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>S(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)S(n,t,!1),n=n.nextElementSibling}var Mt=[],qe=[],Nt=[];function kt(e){Nt.push(e)}function Dt(e){qe.push(e)}function Pt(e){Mt.push(e)}function B(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function Ue(e,t){!e._x_attributeCleanups||Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}var Ge=new MutationObserver(We),Ye=!1;function Je(){Ge.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),Ye=!0}function Ze(){qr(),Ge.disconnect(),Ye=!1}var Q=[],Qe=!1;function qr(){Q=Q.concat(Ge.takeRecords()),Q.length&&!Qe&&(Qe=!0,queueMicrotask(()=>{Ur(),Qe=!1}))}function Ur(){We(Q),Q.length=0}function m(e){if(!Ye)return e();Ze();let t=e();return Je(),t}var Xe=!1,he=[];function It(){Xe=!0}function Lt(){Xe=!1,We(he),he=[]}function We(e){if(Xe){he=he.concat(e);return}let t=[],r=[],n=new Map,i=new Map;for(let o=0;os.nodeType===1&&t.push(s)),e[o].removedNodes.forEach(s=>s.nodeType===1&&r.push(s))),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{Ue(s,o)}),n.forEach((o,s)=>{Mt.forEach(a=>a(s,o))});for(let o of t)r.includes(o)||Nt.forEach(s=>s(o));for(let o of r)t.includes(o)||(qe.forEach(s=>s(o)),o.localName==="body"&&o.querySelectorAll("[x-data]").forEach(s=>{S(s,a=>{qe.forEach(c=>c(a)),a.remove()})}));t=null,r=null,n=null,i=null}function H(e,t,r){return e._x_dataStack=[t,...X(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function et(e,t){let r=e._x_dataStack[0];Object.entries(t).forEach(([n,i])=>{r[n]=i})}function X(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?X(e.host):e.parentNode?X(e.parentNode):[]}function ee(e){let t=new Proxy({},{ownKeys:()=>Array.from(new Set(e.flatMap(r=>Object.keys(r)))),has:(r,n)=>e.some(i=>i.hasOwnProperty(n)),get:(r,n)=>(e.find(i=>{if(i.hasOwnProperty(n)){let o=Object.getOwnPropertyDescriptor(i,n);if(o.get&&o.get._x_alreadyBound||o.set&&o.set._x_alreadyBound)return!0;if((o.get||o.set)&&o.enumerable){let s=o.get,a=o.set,c=o;s=s&&s.bind(t),a=a&&a.bind(t),s&&(s._x_alreadyBound=!0),a&&(a._x_alreadyBound=!0),Object.defineProperty(i,n,{...c,get:s,set:a})}return!0}return!1})||{})[n],set:(r,n,i)=>{let o=e.find(s=>s.hasOwnProperty(n));return o?o[n]=i:e[e.length-1][n]=i,!0}});return t}function $t(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function ge(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>Wr(n,i),s=>tt(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function Wr(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function tt(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),tt(e[t[0]],t.slice(1),r)}}var Ft={};function x(e,t){Ft[e]=t}function te(e,t){return Object.entries(Ft).forEach(([r,n])=>{Object.defineProperty(e,`$${r}`,{get(){return n(t,{Alpine:A,interceptor:ge})},enumerable:!1})}),{obj:e,cleanup:()=>{t=null}}}function b(e,t,r={}){let n;return h(e,t)(i=>n=i,r),n}function h(...e){return jt(...e)}var jt=rt;function Kt(e){jt=e}function rt(e,t){let r={},n=te(r,e).cleanup;B(e,"evaluator",n);let i=[r,...X(e)];if(typeof t=="function")return Gr(i,t);let o=Yr(i,t);return Jr.bind(null,e,t,o)}function Gr(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(ee([n,...e]),i);_e(r,o)}}var nt={};function Zr(e){if(nt[e])return nt[e];let t=Object.getPrototypeOf(async function(){}).constructor,r=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)/.test(e)?`(() => { ${e} })()`:e,n=new t(["__self","scope"],`with (scope) { __self.result = ${r} }; __self.finished = true; return __self.result;`);return nt[e]=n,n}function Yr(e,t){let r=Zr(t);return(n=()=>{},{scope:i={},params:o=[]}={})=>{r.result=void 0,r.finished=!1;let s=ee([i,...e]),a=r(r,s);r.finished?_e(n,r.result,s,o):a.then(c=>{_e(n,c,s,o)})}}function _e(e,t,r,n){if(typeof t=="function"){let i=t.apply(r,n);i instanceof Promise?i.then(o=>_e(e,o,r,n)):e(i)}else e(t)}function Jr(e,t,r,...n){try{return r(...n)}catch(i){throw console.warn(`Alpine Expression Error: ${i.message} Expression: "${t}" -`,e),i}}var nt="x-";function A(e=""){return nt+e}function zt(e){nt=e}var Vt={};function d(e,t){Vt[e]=t}function re(e,t,r){let n={};return Array.from(t).map(Bt((o,s)=>n[o]=s)).filter(Ht).map(Xr(n,r)).sort(en).map(o=>Qr(e,o))}function qt(e){return Array.from(e).map(Bt()).filter(t=>!Ht(t))}var it=!1,ne=new Map,Ut=Symbol();function Wt(e){it=!0;let t=Symbol();Ut=t,ne.set(t,[]);let r=()=>{for(;ne.get(t).length;)ne.get(t).shift()();ne.delete(t)},n=()=>{it=!1,r()};e(r),n()}function Qr(e,t){let r=()=>{},n=Vt[t.type]||r,i=[],o=p=>i.push(p),[s,a]=me(e);i.push(a);let c={Alpine:S,effect:s,cleanup:o,evaluateLater:h.bind(h,e),evaluate:b.bind(b,e)},l=()=>i.forEach(p=>p());B(e,t.original,l);let u=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,c),n=n.bind(n,e,t,c),it?ne.get(Ut).push(n):n())};return u.runCleanups=l,u}var ye=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),xe=e=>e;function Bt(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=Gt.reduce((o,s)=>s(o),{name:t,value:r});return n!==t&&e(n,t),{name:n,value:i}}}var Gt=[];function q(e){Gt.push(e)}function Ht({name:e}){return Yt().test(e)}var Yt=()=>new RegExp(`^${nt}([^:^.]+)\\b`);function Xr(e,t){return({name:r,value:n})=>{let i=r.match(Yt()),o=r.match(/:([a-zA-Z0-9\-:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var ot="DEFAULT",be=["ignore","ref","data","bind","init","for","model","transition","show","if",ot,"element"];function en(e,t){let r=be.indexOf(e.type)===-1?ot:e.type,n=be.indexOf(t.type)===-1?ot:t.type;return be.indexOf(r)-be.indexOf(n)}function $(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}var st=[],at=!1;function U(e){st.push(e),queueMicrotask(()=>{at||setTimeout(()=>{ve()})})}function ve(){for(at=!1;st.length;)st.shift()()}function Jt(){at=!0}function M(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>M(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)M(n,t,!1),n=n.nextElementSibling}function we(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}function Qt(){document.body||we("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` + +``` + + +### Module import + +```js +import Alpine from '@alpinejs/csp' + +window.Alpine = Alpine +window.Alpine.start() +``` + + +## Restrictions + +Since Alpine can no longer interpret strings as plain JavaScript, it has to parse and construct JavaScript functions from them manually. + +Due to this limitation, you must use `Alpine.data` to register your `x-data` objects, and must reference properties and methods from it by key only. + +For example, an inline component like this will not work. + +```alpine + +
+ + + +
+``` + +However, breaking out the expressions into external APIs, the following is valid with the CSP build: + +```alpine + +
+ + + +
+``` +```js +Alpine.data('counter', () => ({ + count: 1, + + increment() { this.count++ } +})) +``` diff --git a/alpinejs/packages/docs/src/en/advanced/extending.md b/alpinejs/packages/docs/src/en/advanced/extending.md new file mode 100644 index 0000000..d75948c --- /dev/null +++ b/alpinejs/packages/docs/src/en/advanced/extending.md @@ -0,0 +1,360 @@ +--- +order: 2 +title: Extending +--- + +# Extending + +Alpine has a very open codebase that allows for extension in a number of ways. In fact, every available directive and magic in Alpine itself uses these exact APIs. In theory you could rebuild all of Alpine's functionality using them yourself. + + +## Lifecycle concerns +Before we dive into each individual API, let's first talk about where in your codebase you should consume these APIs. + +Because these APIs have an impact on how Alpine initializes the page, they must be registered AFTER Alpine is downloaded and available on the page, but BEFORE it has initialized the page itself. + +There are two different techniques depending on if you are importing Alpine into a bundle, or including it directly via a ` + +
+ + + +``` + +If you want to extract your extension code into an external file, you will need to make sure that file's ` + + +
+ +``` + + +### Via an NPM module + +If you imported Alpine into a bundle, you have to make sure you are registering any extension code IN BETWEEN when you import the `Alpine` global object, and when you initialize Alpine by calling `Alpine.start()`. For example: + +```js +import Alpine from 'alpinejs' + +Alpine.directive('foo', ...) + +window.Alpine = Alpine +window.Alpine.start() +``` + +Now that we know where to use these extension APIs, let's look more closely at how to use each one: + + +## Custom directives + +Alpine allows you to register your own custom directives using the `Alpine.directive()` API. + + +### Method Signature + +```js +Alpine.directive('[name]', (el, { value, modifiers, expression }, { Alpine, effect, cleanup }) => {}) +``` + +  |   +---|--- +name | The name of the directive. The name "foo" for example would be consumed as `x-foo` +el | The DOM element the directive is added to +value | If provided, the part of the directive after a colon. Ex: `'bar'` in `x-foo:bar` +modifiers | An array of dot-separated trailing additions to the directive. Ex: `['baz', 'lob']` from `x-foo.baz.lob` +expression | The attribute value portion of the directive. Ex: `law` from `x-foo="law"` +Alpine | The Alpine global object +effect | A function to create reactive effects that will auto-cleanup after this directive is removed from the DOM +cleanup | A function you can pass bespoke callbacks to that will run when this directive is removed from the DOM + + +### Simple Example + +Here's an example of a simple directive we're going to create called: `x-uppercase`: + +```js +Alpine.directive('uppercase', el => { + el.textContent = el.textContent.toUpperCase() +}) +``` +```alpine +
+ Hello World! +
+``` + + +### Evaluating expressions + +When registering a custom directive, you may want to evaluate a user-supplied JavaScript expression: + +For example, let's say you wanted to create a custom directive as a shortcut to `console.log()`. Something like: + +```alpine +
+
+
+``` + +You need to retrieve the actual value of `message` by evaluating it as a JavaScript expression with the `x-data` scope. + +Fortunately, Alpine exposes its system for evaluating JavaScript expressions with an `evaluate()` API. Here's an example: + +```js +Alpine.directive('log', (el, { expression }, { evaluate }) => { + // expression === 'message' + + console.log( + evaluate(expression) + ) +}) +``` + +Now, when Alpine initializes the `
`, it will retrieve the expression passed into the directive ("message" in this case), and evaluate it in the context of the current element's Alpine component scope. + + +### Introducing reactivity + +Building on the `x-log` example from before, let's say we wanted `x-log` to log the value of `message` and also log it if the value changes. + +Given the following template: + +```alpine +
+
+ + +
+``` + +We want "Hello World!" to be logged initially, then we want "yolo" to be logged after pressing the ` +``` + +Now that accessing `$clipboard` returns a function itself, we can immediately call it and pass it an argument like we see in the template with `$clipboard('hello world')`. + +You can use the more brief syntax (a double arrow function) for returning a function from a function if you'd prefer: + +```js +Alpine.magic('clipboard', () => subject => { + navigator.clipboard.writeText(subject) +}) +``` + + +## Writing and sharing plugins + +By now you should see how friendly and simple it is to register your own custom directives and magics in your application, but what about sharing that functionality with others via an NPM package or something? + +You can get started quickly with Alpine's official "plugin-blueprint" package. It's as simple as cloning the repository and running `npm install && npm run build` to get a plugin authored. + +For demonstration purposes, let's create a pretend Alpine plugin from scratch called `Foo` that includes both a directive (`x-foo`) and a magic (`$foo`). + +We'll start producing this plugin for consumption as a simple ` + + +
+ +
+ +``` + +Notice how our script is included BEFORE Alpine itself. This is important, otherwise, Alpine would have already been initialized by the time our plugin got loaded. + +Now let's look inside of `/js/foo.js`'s contents: + +```js +document.addEventListener('alpine:init', () => { + window.Alpine.directive('foo', ...) + + window.Alpine.magic('foo', ...) +}) +``` + +That's it! Authoring a plugin for inclusion via a script tag is extremely simple with Alpine. + + +### Bundle module + +Now let's say you wanted to author a plugin that someone could install via NPM and include into their bundle. + +Like the last example, we'll walk through this in reverse, starting with what it will look like to consume this plugin: + +```js +import Alpine from 'alpinejs' + +import foo from 'foo' +Alpine.plugin(foo) + +window.Alpine = Alpine +window.Alpine.start() +``` + +You'll notice a new API here: `Alpine.plugin()`. This is a convenience method Alpine exposes to prevent consumers of your plugin from having to register multiple different directives and magics themselves. + +Now let's look at the source of the plugin and what gets exported from `foo`: + +```js +export default function (Alpine) { + Alpine.directive('foo', ...) + Alpine.magic('foo', ...) +} +``` + +You'll see that `Alpine.plugin` is incredibly simple. It accepts a callback and immediately invokes it while providing the `Alpine` global as a parameter for use inside of it. + +Then you can go about extending Alpine as you please. diff --git a/alpinejs/packages/docs/src/en/advanced/reactivity.md b/alpinejs/packages/docs/src/en/advanced/reactivity.md new file mode 100644 index 0000000..ddbb601 --- /dev/null +++ b/alpinejs/packages/docs/src/en/advanced/reactivity.md @@ -0,0 +1,101 @@ +--- +order: 1 +title: Reactivity +--- + +# Reactivity + +Alpine is "reactive" in the sense that when you change a piece of data, everything that depends on that data "reacts" automatically to that change. + +Every bit of reactivity that takes place in Alpine, happens because of two very important reactive functions in Alpine's core: `Alpine.reactive()`, and `Alpine.effect()`. + +> Alpine uses VueJS's reactivity engine under the hood to provide these functions. +> [→ Read more about @vue/reactivity](https://github.com/vuejs/vue-next/tree/master/packages/reactivity) + +Understanding these two functions will give you super powers as an Alpine developer, but also just as a web developer in general. + + +## Alpine.reactive() + +Let's first look at `Alpine.reactive()`. This function accepts a JavaScript object as its parameter and returns a "reactive" version of that object. For example: + +```js +let data = { count: 1 } + +let reactiveData = Alpine.reactive(data) +``` + +Under the hood, when `Alpine.reactive` receives `data`, it wraps it inside a custom JavaScript proxy. + +A proxy is a special kind of object in JavaScript that can intercept "get" and "set" calls to a JavaScript object. + +[→ Read more about JavaScript proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) + +At face value, `reactiveData` should behave exactly like `data`. For example: + +```js +console.log(data.count) // 1 +console.log(reactiveData.count) // 1 + +reactiveData.count = 2 + +console.log(data.count) // 2 +console.log(reactiveData.count) // 2 +``` + +What you see here is that because `reactiveData` is a thin wrapper around `data`, any attempts to get or set a property will behave exactly as if you had interacted with `data` directly. + +The main difference here is that any time you modify or retrieve (get or set) a value from `reactiveData`, Alpine is aware of it and can execute any other logic that depends on this data. + +`Alpine.reactive` is only the first half of the story. `Alpine.effect` is the other half, let's dig in. + + +## Alpine.effect() + +`Alpine.effect` accepts a single callback function. As soon as `Alpine.effect` is called, it will run the provided function, but actively look for any interactions with reactive data. If it detects an interaction (a get or set from the aforementioned reactive proxy) it will keep track of it and make sure to re-run the callback if any of reactive data changes in the future. For example: + +```js +let data = Alpine.reactive({ count: 1 }) + +Alpine.effect(() => { + console.log(data.count) +}) +``` + +When this code is first run, "1" will be logged to the console. Any time `data.count` changes, it's value will be logged to the console again. + +This is the mechanism that unlocks all of the reactivity at the core of Alpine. + +To connect the dots further, let's look at a simple "counter" component example without using Alpine syntax at all, only using `Alpine.reactive` and `Alpine.effect`: + +```alpine + + +Count: +``` +```js +let button = document.querySelector('button') +let span = document.querySelector('span') + +let data = Alpine.reactive({ count: 1 }) + +Alpine.effect(() => { + span.textContent = data.count +}) + +button.addEventListener('click', () => { + data.count = data.count + 1 +}) +``` + + +
+ + +
Count:
+
+ + +As you can see, you can make any data reactive, and you can also wrap any functionality in `Alpine.effect`. + +This combination unlocks an incredibly powerful programming paradigm for web development. Run wild and free. diff --git a/alpinejs/packages/docs/src/en/directives.md b/alpinejs/packages/docs/src/en/directives.md new file mode 100644 index 0000000..ef15b7b --- /dev/null +++ b/alpinejs/packages/docs/src/en/directives.md @@ -0,0 +1,7 @@ +--- +order: 4 +title: Directives +prefix: x- +font-type: mono +type: sub-directory +--- diff --git a/alpinejs/packages/docs/src/en/directives/bind.md b/alpinejs/packages/docs/src/en/directives/bind.md new file mode 100644 index 0000000..abe9155 --- /dev/null +++ b/alpinejs/packages/docs/src/en/directives/bind.md @@ -0,0 +1,189 @@ +--- +order: 4 +title: bind +--- + +# `x-bind` + +`x-bind` allows you to set HTML attributes on elements based on the result of JavaScript expressions. + +For example, here's a component where we will use `x-bind` to set the placeholder value of an input. + +```alpine +
+ +
+``` + + +## Shorthand syntax + +If `x-bind:` is too verbose for your liking, you can use the shorthand: `:`. For example, here is the same input element as above, but refactored to use the shorthand syntax. + +```alpine + +``` + + +## Binding classes + +`x-bind` is most often useful for setting specific classes on an element based on your Alpine state. + +Here's a simple example of a simple dropdown toggle, but instead of using `x-show`, we'll use a "hidden" class to toggle an element. + +```alpine +
+ + +
+ Dropdown Contents... +
+
+``` + +Now, when `open` is `false`, the "hidden" class will be added to the dropdown. + + +### Shorthand conditionals + +In cases like these, if you prefer a less verbose syntax you can use JavaScript's short-circuit evaluation instead of standard conditionals: + +```alpine +
+ +
+``` + +The inverse is also available to you. Suppose instead of `open`, we use a variable with the opposite value: `closed`. + +```alpine +
+ +
+``` + + +### Class object syntax + +Alpine offers an additional syntax for toggling classes if you prefer. By passing a JavaScript object where the classes are the keys and booleans are the values, Alpine will know which classes to apply and which to remove. For example: + +```alpine +
+``` + +This technique offers a unique advantage to other methods. When using object-syntax, Alpine will NOT preserve original classes applied to an element's `class` attribute. + +For example, if you wanted to apply the "hidden" class to an element before Alpine loads, AND use Alpine to toggle its existence you can only achieve that behavior using object-syntax: + +```alpine +