Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo-mod-jslibs-dist.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'alpinejs/packages/alpinejs/src/lifecycle.js')
-rw-r--r--alpinejs/packages/alpinejs/src/lifecycle.js84
1 files changed, 84 insertions, 0 deletions
diff --git a/alpinejs/packages/alpinejs/src/lifecycle.js b/alpinejs/packages/alpinejs/src/lifecycle.js
new file mode 100644
index 0000000..75dc6c8
--- /dev/null
+++ b/alpinejs/packages/alpinejs/src/lifecycle.js
@@ -0,0 +1,84 @@
+import { startObservingMutations, onAttributesAdded, onElAdded, onElRemoved, cleanupAttributes } from "./mutation"
+import { deferHandlingDirectives, directives } from "./directives"
+import { dispatch } from './utils/dispatch'
+import { nextTick } from "./nextTick"
+import { walk } from "./utils/walk"
+import { warn } from './utils/warn'
+
+export function start() {
+ if (! document.body) warn('Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine\'s `<script>` tag?')
+
+ dispatch(document, 'alpine:init')
+ dispatch(document, 'alpine:initializing')
+
+ startObservingMutations()
+
+ onElAdded(el => initTree(el, walk))
+ onElRemoved(el => destroyTree(el))
+
+ onAttributesAdded((el, attrs) => {
+ directives(el, attrs).forEach(handle => handle())
+ })
+
+ let outNestedComponents = el => ! closestRoot(el.parentElement, true)
+ Array.from(document.querySelectorAll(allSelectors()))
+ .filter(outNestedComponents)
+ .forEach(el => {
+ initTree(el)
+ })
+
+ dispatch(document, 'alpine:initialized')
+}
+
+let rootSelectorCallbacks = []
+let initSelectorCallbacks = []
+
+export function rootSelectors() {
+ return rootSelectorCallbacks.map(fn => fn())
+}
+
+export function allSelectors() {
+ return rootSelectorCallbacks.concat(initSelectorCallbacks).map(fn => fn())
+}
+
+export function addRootSelector(selectorCallback) { rootSelectorCallbacks.push(selectorCallback) }
+export function addInitSelector(selectorCallback) { initSelectorCallbacks.push(selectorCallback) }
+
+export function closestRoot(el, includeInitSelectors = false) {
+ return findClosest(el, element => {
+ const selectors = includeInitSelectors ? allSelectors() : rootSelectors()
+
+ if (selectors.some(selector => element.matches(selector))) return true
+ })
+}
+
+export function findClosest(el, callback) {
+ if (! el) return
+
+ if (callback(el)) return el
+
+ // Support crawling up teleports.
+ if (el._x_teleportBack) el = el._x_teleportBack
+
+ if (! el.parentElement) return
+
+ return findClosest(el.parentElement, callback)
+}
+
+export function isRoot(el) {
+ return rootSelectors().some(selector => el.matches(selector))
+}
+
+export function initTree(el, walker = walk) {
+ deferHandlingDirectives(() => {
+ walker(el, (el, skip) => {
+ directives(el, el.attributes).forEach(handle => handle())
+
+ el._x_ignore && skip()
+ })
+ })
+}
+
+export function destroyTree(root) {
+ walk(root, el => cleanupAttributes(el))
+}