|
@@ -396,22 +396,16 @@
|
|
|
items.forEach((item, index) => {
|
|
|
let iterationScopeVariables = getIterationScopeVariables(iteratorNames, item, index, items, extraVars());
|
|
|
let currentKey = generateKeyForIteration(component, templateEl, index, iterationScopeVariables);
|
|
|
- let nextEl = currentEl.nextElementSibling; // If there's no previously x-for processed element ahead, add one.
|
|
|
+ let nextEl = lookAheadForMatchingKeyedElementAndMoveItIfFound(currentEl.nextElementSibling, currentKey); // If we haven't found a matching key, insert the element at the current position.
|
|
|
|
|
|
- if (!nextEl || nextEl.__x_for_key === undefined) {
|
|
|
+ if (!nextEl) {
|
|
|
nextEl = addElementInLoopAfterCurrentEl(templateEl, currentEl); // And transition it in if it's not the first page load.
|
|
|
|
|
|
transitionIn(nextEl, () => {}, initialUpdate);
|
|
|
nextEl.__x_for = iterationScopeVariables;
|
|
|
- component.initializeElements(nextEl, () => nextEl.__x_for);
|
|
|
+ component.initializeElements(nextEl, () => nextEl.__x_for); // Otherwise update the element we found.
|
|
|
} else {
|
|
|
- nextEl = lookAheadForMatchingKeyedElementAndMoveItIfFound(nextEl, currentKey); // If we haven't found a matching key, just insert the element at the current position
|
|
|
-
|
|
|
- if (!nextEl) {
|
|
|
- nextEl = addElementInLoopAfterCurrentEl(templateEl, currentEl);
|
|
|
- } // Temporarily remove the key indicator to allow the normal "updateElements" to work
|
|
|
-
|
|
|
-
|
|
|
+ // Temporarily remove the key indicator to allow the normal "updateElements" to work.
|
|
|
delete nextEl.__x_for_key;
|
|
|
nextEl.__x_for = iterationScopeVariables;
|
|
|
component.updateElements(nextEl, () => nextEl.__x_for);
|
|
@@ -486,7 +480,8 @@
|
|
|
}
|
|
|
|
|
|
function lookAheadForMatchingKeyedElementAndMoveItIfFound(nextEl, currentKey) {
|
|
|
- // If the the key's DO match, no need to look ahead.
|
|
|
+ if (!nextEl) return; // If the the key's DO match, no need to look ahead.
|
|
|
+
|
|
|
if (nextEl.__x_for_key === currentKey) return nextEl; // If they don't, we'll look ahead for a match.
|
|
|
// If we find it, we'll move it to the current position in the loop.
|
|
|
|
|
@@ -557,9 +552,8 @@
|
|
|
} else if (el.tagName === 'SELECT') {
|
|
|
updateSelect(el, value);
|
|
|
} else {
|
|
|
- if (el.value !== value) {
|
|
|
- el.value = value;
|
|
|
- }
|
|
|
+ if (el.value === value) return;
|
|
|
+ el.value = value;
|
|
|
}
|
|
|
} else if (attrName === 'class') {
|
|
|
if (Array.isArray(value)) {
|
|
@@ -571,14 +565,14 @@
|
|
|
const keysSortedByBooleanValue = Object.keys(value).sort((a, b) => value[a] - value[b]);
|
|
|
keysSortedByBooleanValue.forEach(classNames => {
|
|
|
if (value[classNames]) {
|
|
|
- classNames.split(' ').forEach(className => el.classList.add(className));
|
|
|
+ classNames.split(' ').filter(Boolean).forEach(className => el.classList.add(className));
|
|
|
} else {
|
|
|
- classNames.split(' ').forEach(className => el.classList.remove(className));
|
|
|
+ classNames.split(' ').filter(Boolean).forEach(className => el.classList.remove(className));
|
|
|
}
|
|
|
});
|
|
|
} else {
|
|
|
const originalClasses = el.__x_original_classes || [];
|
|
|
- const newClasses = value.split(' ');
|
|
|
+ const newClasses = value.split(' ').filter(Boolean);
|
|
|
el.setAttribute('class', arrayUnique(originalClasses.concat(newClasses)).join(' '));
|
|
|
}
|
|
|
} else if (isBooleanAttr(attrName)) {
|
|
@@ -1571,7 +1565,7 @@
|
|
|
for (let i = 0; i < mutations.length; i++) {
|
|
|
// Filter out mutations triggered from child components.
|
|
|
const closestParentComponent = mutations[i].target.closest('[x-data]');
|
|
|
- if (!(closestParentComponent && closestParentComponent.isSameNode(this.$el))) return;
|
|
|
+ if (!(closestParentComponent && closestParentComponent.isSameNode(this.$el))) continue;
|
|
|
|
|
|
if (mutations[i].type === 'attributes' && mutations[i].attributeName === 'x-data') {
|
|
|
const rawData = saferEval(mutations[i].target.getAttribute('x-data'), {});
|
|
@@ -1627,7 +1621,7 @@
|
|
|
}
|
|
|
|
|
|
const Alpine = {
|
|
|
- version: "2.3.1",
|
|
|
+ version: "2.3.3",
|
|
|
start: async function start() {
|
|
|
if (!isTesting()) {
|
|
|
await domReady();
|