Explorar o código

Refactor test and implementation

Caleb Porzio %!s(int64=5) %!d(string=hai) anos
pai
achega
39f0b48a06
Modificáronse 4 ficheiros con 27 adicións e 69 borrados
  1. 5 9
      dist/alpine-ie11.js
  2. 5 9
      dist/alpine.js
  3. 4 8
      src/directives/for.js
  4. 13 43
      test/for.spec.js

+ 5 - 9
dist/alpine-ie11.js

@@ -5800,9 +5800,8 @@
       _newArrowCheck(this, _this);
 
       var iterationScopeVariables = getIterationScopeVariables(iteratorNames, item, index, items, extraVars());
-      var currentKey = generateKeyForIteration(component, templateEl, index, iterationScopeVariables); // Look ahead for the right element to update
-
-      var nextEl = lookAheadForMatchingKeyedElementAndMoveItIfFound(currentEl.nextElementSibling, currentKey); // If we haven't found a matching key, just insert the element at the current position
+      var currentKey = generateKeyForIteration(component, templateEl, index, iterationScopeVariables);
+      var nextEl = lookAheadForMatchingKeyedElementAndMoveItIfFound(currentEl.nextElementSibling, currentKey); // If we haven't found a matching key, insert the element at the current position.
 
       if (!nextEl) {
         nextEl = addElementInLoopAfterCurrentEl(templateEl, currentEl); // And transition it in if it's not the first page load.
@@ -5815,9 +5814,9 @@
           _newArrowCheck(this, _this2);
 
           return nextEl.__x_for;
-        }.bind(this)); // otherwise update the element we found
+        }.bind(this)); // Otherwise update the element we found.
       } else {
-        // 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, function () {
@@ -5906,8 +5905,7 @@
   }
 
   function lookAheadForMatchingKeyedElementAndMoveItIfFound(nextEl, currentKey) {
-    // We don't know if nextEl is actually an element so we check that it's not a falsy value first
-    if (!nextEl) return false; // 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.
@@ -5921,8 +5919,6 @@
 
       tmpNextEl = tmpNextEl.nextElementSibling && tmpNextEl.nextElementSibling.__x_for_key !== undefined ? tmpNextEl.nextElementSibling : false;
     }
-
-    return false;
   }
 
   function removeAnyLeftOverElementsFromPreviousUpdate(currentEl) {

+ 5 - 9
dist/alpine.js

@@ -395,18 +395,17 @@
     let currentEl = templateEl;
     items.forEach((item, index) => {
       let iterationScopeVariables = getIterationScopeVariables(iteratorNames, item, index, items, extraVars());
-      let currentKey = generateKeyForIteration(component, templateEl, index, iterationScopeVariables); // Look ahead for the right element to update
-
-      let nextEl = lookAheadForMatchingKeyedElementAndMoveItIfFound(currentEl.nextElementSibling, currentKey); // If we haven't found a matching key, just insert the element at the current position
+      let currentKey = generateKeyForIteration(component, templateEl, index, iterationScopeVariables);
+      let nextEl = lookAheadForMatchingKeyedElementAndMoveItIfFound(currentEl.nextElementSibling, currentKey); // If we haven't found a matching key, insert the element at the current position.
 
       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); // otherwise update the element we found
+        component.initializeElements(nextEl, () => nextEl.__x_for); // Otherwise update the element we found.
       } else {
-        // 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);
@@ -481,8 +480,7 @@
   }
 
   function lookAheadForMatchingKeyedElementAndMoveItIfFound(nextEl, currentKey) {
-    // We don't know if nextEl is actually an element so we check that it's not a falsy value first
-    if (!nextEl) return false; // 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.
@@ -496,8 +494,6 @@
 
       tmpNextEl = tmpNextEl.nextElementSibling && tmpNextEl.nextElementSibling.__x_for_key !== undefined ? tmpNextEl.nextElementSibling : false;
     }
-
-    return false;
   }
 
   function removeAnyLeftOverElementsFromPreviousUpdate(currentEl) {

+ 4 - 8
src/directives/for.js

@@ -12,10 +12,9 @@ export function handleForDirective(component, templateEl, expression, initialUpd
     items.forEach((item, index) => {
         let iterationScopeVariables = getIterationScopeVariables(iteratorNames, item, index, items, extraVars())
         let currentKey = generateKeyForIteration(component, templateEl, index, iterationScopeVariables)
-        // Look ahead for the right element to update
         let nextEl = lookAheadForMatchingKeyedElementAndMoveItIfFound(currentEl.nextElementSibling, currentKey)
 
-        // If we haven't found a matching key, just insert the element at the current position
+        // If we haven't found a matching key, insert the element at the current position.
         if (! nextEl) {
             nextEl = addElementInLoopAfterCurrentEl(templateEl, currentEl)
 
@@ -24,9 +23,9 @@ export function handleForDirective(component, templateEl, expression, initialUpd
 
             nextEl.__x_for = iterationScopeVariables
             component.initializeElements(nextEl, () => nextEl.__x_for)
-        // otherwise update the element we found
+        // Otherwise update the element we found.
         } else {
-            // 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
@@ -109,8 +108,7 @@ function addElementInLoopAfterCurrentEl(templateEl, currentEl) {
 }
 
 function lookAheadForMatchingKeyedElementAndMoveItIfFound(nextEl, currentKey) {
-    // We don't know if nextEl is actually an element so we check that it's not a falsy value first
-    if(!nextEl) return false
+    if (! nextEl) return
 
     // If the the key's DO match, no need to look ahead.
     if (nextEl.__x_for_key === currentKey) return nextEl
@@ -126,8 +124,6 @@ function lookAheadForMatchingKeyedElementAndMoveItIfFound(nextEl, currentKey) {
 
         tmpNextEl = (tmpNextEl.nextElementSibling && tmpNextEl.nextElementSibling.__x_for_key !== undefined) ? tmpNextEl.nextElementSibling : false
     }
-
-    return false
 }
 
 function removeAnyLeftOverElementsFromPreviousUpdate(currentEl) {

+ 13 - 43
test/for.spec.js

@@ -449,61 +449,31 @@ test('nested x-for event listeners', async () => {
     })
 })
 
-
-test('listeners are bound correctly on update', async () => {
-    global.data = function() {
-        return {
-            page: 0,
-            received: 0,
-            items: [
-                {'num': 1},
-                {'num': 2},
-                {'num': 3},
-                {'num': 4},
-                {'num': 5}
-            ],
-            click: function(num) {
-                this.received = num
-            }
-        }
+test('make sure new elements with different keys added to the beginning of a loop are initialized instead of just updated', async () => {
+    let clickCount = 0
+    window.registerClick = () => {
+        clickCount++
     }
 
     document.body.innerHTML = `
-        <div x-data="data()">
-            <button @click="page+=page<1?1:0">Next page</button>
-
-            <span x-text="received"></span>
+        <div x-data="{ items: ['foo'] }">
+            <button @click="items = ['bar']">Change</button>
 
-            <ul>
-              <template x-for="item in items.slice(page*3, (page+1)*3 )" :key="item.num">
-                <li @click="click(item.num)" x-text="item.num"></li>
-              </template>
-            </ul>
+            <template x-for="item in items" :key="item">
+                <h1 @click="registerClick()"></h1>
+            </template>
         </div>
     `
 
     Alpine.start()
 
-    await wait(() => { expect(document.querySelectorAll('li').length).toEqual(3) })
-    expect(document.querySelectorAll('li')[0].innerText).toEqual(1)
-    expect(document.querySelectorAll('li')[1].innerText).toEqual(2)
-    expect(document.querySelectorAll('li')[2].innerText).toEqual(3)
+    document.querySelector('h1').click()
 
-    document.querySelectorAll('li')[0].click()
-    await wait(() => { expect(document.querySelector('span').innerText).toEqual(1) })
-    document.querySelectorAll('li')[1].click()
-    await wait(() => { expect(document.querySelector('span').innerText).toEqual(2) })
-    document.querySelectorAll('li')[2].click()
-    await wait(() => { expect(document.querySelector('span').innerText).toEqual(3) })
+    expect(clickCount).toEqual(1)
 
     document.querySelector('button').click()
 
-    await wait(() => { expect(document.querySelectorAll('li').length).toEqual(2) })
-    expect(document.querySelectorAll('li')[0].innerText).toEqual(4)
-    expect(document.querySelectorAll('li')[1].innerText).toEqual(5)
+    document.querySelector('h1').click()
 
-    document.querySelectorAll('li')[0].click()
-    await wait(() => { expect(document.querySelector('span').innerText).toEqual(4) })
-    document.querySelectorAll('li')[1].click()
-    await wait(() => { expect(document.querySelector('span').innerText).toEqual(5) })
+    expect(clickCount).toEqual(2)
 })