|
@@ -1,4 +1,4 @@
|
|
-import { arrayUnique, walkSkippingNestedComponents, keyToModifier, saferEval, saferEvalNoReturn, getXAttrs, debounce, transitionIn, transitionOut } from './utils'
|
|
|
|
|
|
+import { arrayUnique, walk, keyToModifier, saferEval, saferEvalNoReturn, getXAttrs, debounce, transitionIn, transitionOut } from './utils'
|
|
|
|
|
|
export default class Component {
|
|
export default class Component {
|
|
constructor(el) {
|
|
constructor(el) {
|
|
@@ -42,7 +42,7 @@ export default class Component {
|
|
}
|
|
}
|
|
|
|
|
|
// Register all our listeners and set all our attribute bindings.
|
|
// Register all our listeners and set all our attribute bindings.
|
|
- this.initializeElements()
|
|
|
|
|
|
+ this.initializeElements(this.$el)
|
|
|
|
|
|
// Use mutation observer to detect new elements being added within this component at run-time.
|
|
// Use mutation observer to detect new elements being added within this component at run-time.
|
|
// Alpine's just so darn flexible amirite?
|
|
// Alpine's just so darn flexible amirite?
|
|
@@ -73,7 +73,7 @@ export default class Component {
|
|
if (self.pauseReactivity) return
|
|
if (self.pauseReactivity) return
|
|
|
|
|
|
debounce(() => {
|
|
debounce(() => {
|
|
- self.refresh()
|
|
|
|
|
|
+ self.updateElements(self.$el)
|
|
|
|
|
|
// Walk through the $nextTick stack and clear it as we go.
|
|
// Walk through the $nextTick stack and clear it as we go.
|
|
while (self.nextTickStack.length > 0) {
|
|
while (self.nextTickStack.length > 0) {
|
|
@@ -105,9 +105,29 @@ export default class Component {
|
|
return new Proxy(data, proxyHandler)
|
|
return new Proxy(data, proxyHandler)
|
|
}
|
|
}
|
|
|
|
|
|
- initializeElements() {
|
|
|
|
- walkSkippingNestedComponents(this.$el, el => {
|
|
|
|
|
|
+ walkAndSkipNestedComponents(el, callback, initializeComponentCallback = () => {}) {
|
|
|
|
+ walk(el, el => {
|
|
|
|
+ // We've hit a component.
|
|
|
|
+ if (el.hasAttribute('x-data')) {
|
|
|
|
+ // If it's not the current one.
|
|
|
|
+ if (! el.isSameNode(this.$el)) {
|
|
|
|
+ // Initialize it if it's not.
|
|
|
|
+ if (! el.__x) initializeComponentCallback(el)
|
|
|
|
+
|
|
|
|
+ // Now we'll let that sub-component deal with itself.
|
|
|
|
+ return false
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ callback(el)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ initializeElements(rootEl) {
|
|
|
|
+ this.walkAndSkipNestedComponents(rootEl, el => {
|
|
this.initializeElement(el)
|
|
this.initializeElement(el)
|
|
|
|
+ }, el => {
|
|
|
|
+ el.__x = new Component(el)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
@@ -122,6 +142,18 @@ export default class Component {
|
|
this.resolveBoundAttributes(el, true)
|
|
this.resolveBoundAttributes(el, true)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ updateElements(rootEl) {
|
|
|
|
+ this.walkAndSkipNestedComponents(rootEl, el => {
|
|
|
|
+ this.updateElement(el)
|
|
|
|
+ }, el => {
|
|
|
|
+ el.__x = new Component(el)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ updateElement(el) {
|
|
|
|
+ this.resolveBoundAttributes(el)
|
|
|
|
+ }
|
|
|
|
+
|
|
registerListeners(el) {
|
|
registerListeners(el) {
|
|
getXAttrs(el).forEach(({ type, value, modifiers, expression }) => {
|
|
getXAttrs(el).forEach(({ type, value, modifiers, expression }) => {
|
|
switch (type) {
|
|
switch (type) {
|
|
@@ -221,11 +253,12 @@ export default class Component {
|
|
mutations[i].addedNodes.forEach(node => {
|
|
mutations[i].addedNodes.forEach(node => {
|
|
if (node.nodeType !== 1) return
|
|
if (node.nodeType !== 1) return
|
|
|
|
|
|
- if (node.matches('[x-data]')) return
|
|
|
|
-
|
|
|
|
- if (getXAttrs(node).length > 0) {
|
|
|
|
- this.initializeElement(node)
|
|
|
|
|
|
+ if (node.matches('[x-data]')) {
|
|
|
|
+ node.__x = new Component(node)
|
|
|
|
+ return
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ this.initializeElements(node)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -234,12 +267,6 @@ export default class Component {
|
|
observer.observe(targetNode, observerOptions);
|
|
observer.observe(targetNode, observerOptions);
|
|
}
|
|
}
|
|
|
|
|
|
- refresh() {
|
|
|
|
- walkSkippingNestedComponents(this.$el, el => {
|
|
|
|
- this.resolveBoundAttributes(el)
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
generateExpressionForXModelListener(el, modifiers, dataKey) {
|
|
generateExpressionForXModelListener(el, modifiers, dataKey) {
|
|
var rightSideOfExpression = ''
|
|
var rightSideOfExpression = ''
|
|
if (el.type === 'checkbox') {
|
|
if (el.type === 'checkbox') {
|
|
@@ -466,7 +493,7 @@ export default class Component {
|
|
|
|
|
|
// We can't just query the DOM because it's hard to filter out refs in
|
|
// We can't just query the DOM because it's hard to filter out refs in
|
|
// nested components.
|
|
// nested components.
|
|
- walkSkippingNestedComponents(self.$el, el => {
|
|
|
|
|
|
+ self.walkAndSkipNestedComponents(self.$el, el => {
|
|
if (el.hasAttribute('x-ref') && el.getAttribute('x-ref') === property) {
|
|
if (el.hasAttribute('x-ref') && el.getAttribute('x-ref') === property) {
|
|
ref = el
|
|
ref = el
|
|
}
|
|
}
|