123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- 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 => ! Root(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
- 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()
- })
- })
- }
- function destroyTree(root) {
- walk(root, el => cleanupAttributes(el))
- }
|