Просмотр исходного кода

Refactor transition interruption code

Caleb Porzio 5 лет назад
Родитель
Сommit
173311a757
5 измененных файлов с 43 добавлено и 44 удалено
  1. 9 14
      dist/alpine.js
  2. 1 0
      examples/index.html
  3. 8 8
      src/directives/show.js
  4. 7 10
      src/utils.js
  5. 18 12
      test/transition.spec.js

+ 9 - 14
dist/alpine.js

@@ -183,7 +183,6 @@
     return name;
   }
   function transitionIn(el, show, component, forceSkip = false) {
-    // We don't want to transition on the initial page load.
     if (forceSkip) return show();
     const attrs = getXAttrs(el, component, 'transition');
     const showAttr = getXAttrs(el, component, 'show')[0]; // If this is triggered by a x-show.transition.
@@ -412,7 +411,7 @@
 
       stages.show();
       requestAnimationFrame(() => {
-        stages.end(); // Assign current transition to el in case we need to force it
+        stages.end(); // Assign current transition to el in case we need to force it.
 
         el.__x_transition_remaining = once(() => {
           stages.hide(); // Adding an "isConnected" check, in case the callback
@@ -420,7 +419,7 @@
 
           if (el.isConnected) {
             stages.cleanup();
-          } // Safe to remove transition from el since it is completed
+          } // Safe to remove transition from el since it is completed.
 
 
           delete el.__x_transition_remaining;
@@ -432,16 +431,12 @@
   function isNumeric(subject) {
     return !isNaN(subject);
   }
-  /**
-   * Ensure a function is called only once.
-   */
-
-  function once(fn) {
+  function once(callback) {
     let called = false;
     return function () {
       if (!called) {
         called = true;
-        fn.apply(this, arguments);
+        callback.apply(this, arguments);
       }
     };
   }
@@ -656,7 +651,7 @@
   }
 
   function handleShowDirective(component, el, value, modifiers, initialUpdate = false) {
-    // if value is changed resolve any previous pending transitions before starting a new one
+    // if value is changed resolve any previous pending transitions before starting a new one.
     if (el.__x_transition_remaining && el.__x_transition_last_value !== value) {
       el.__x_transition_remaining();
     }
@@ -674,7 +669,7 @@
     };
 
     if (initialUpdate === true) {
-      // Assign current value to el to check later on for preventing transition overlaps
+      // Assign current value to el to check later on for preventing transition overlaps.
       el.__x_transition_last_value = value;
 
       if (value) {
@@ -702,7 +697,7 @@
         } else {
           resolve(() => {});
         }
-      } // Assign current value to el
+      } // Assign current value to el.
 
 
       el.__x_transition_last_value = value;
@@ -722,10 +717,10 @@
 
     if (component.showDirectiveLastElement && !component.showDirectiveLastElement.contains(el)) {
       component.executeAndClearRemainingShowDirectiveStack();
-    } // If x-show value changed from previous transition we'll push the handler onto a stack to be handled later.
-
+    }
 
     if (el.__x_transition_last_value !== value) {
+      // We'll push the handler onto a stack to be handled later.
       component.showDirectiveStack.push(handle);
       component.showDirectiveLastElement = el;
     }

+ 1 - 0
examples/index.html

@@ -36,6 +36,7 @@
         </style>
 
         <script src="/dist/alpine.js" defer></script>
+        <!-- <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script> -->
     </head>
     <body>
         <table>

+ 8 - 8
src/directives/show.js

@@ -1,7 +1,7 @@
 import { transitionIn, transitionOut } from '../utils'
 
 export function handleShowDirective(component, el, value, modifiers, initialUpdate = false) {
-    // if value is changed resolve any previous pending transitions before starting a new one
+    // if value is changed resolve any previous pending transitions before starting a new one.
     if (el.__x_transition_remaining && el.__x_transition_last_value !== value) {
         el.__x_transition_remaining()
     }
@@ -19,7 +19,7 @@ export function handleShowDirective(component, el, value, modifiers, initialUpda
     }
 
     if (initialUpdate === true) {
-        // Assign current value to el to check later on for preventing transition overlaps
+        // Assign current value to el to check later on for preventing transition overlaps.
         el.__x_transition_last_value = value
 
         if (value) {
@@ -31,28 +31,27 @@ export function handleShowDirective(component, el, value, modifiers, initialUpda
     }
 
     const handle = (resolve) => {
-        if(value) {
+        if (value) {
             transitionIn(el,() => {
                 show()
             }, component)
             resolve(() => {})
         } else {
-            if ( el.style.display !== 'none' ) {
+            if (el.style.display !== 'none' ) {
                 transitionOut(el, () => {
                     resolve(() => {
                         hide()
                     })
-                },component)
+                }, component)
             } else {
                 resolve(() => {})
             }
         }
 
-        // Assign current value to el
+        // Assign current value to el.
         el.__x_transition_last_value = value
     }
 
-
     // The working of x-show is a bit complex because we need to
     // wait for any child transitions to finish before hiding
     // some element. Also, this has to be done recursively.
@@ -70,9 +69,10 @@ export function handleShowDirective(component, el, value, modifiers, initialUpda
         component.executeAndClearRemainingShowDirectiveStack()
     }
 
-    // If x-show value changed from previous transition we'll push the handler onto a stack to be handled later.
     if (el.__x_transition_last_value !== value) {
+        // We'll push the handler onto a stack to be handled later.
         component.showDirectiveStack.push(handle)
+
         component.showDirectiveLastElement = el
     }
 }

+ 7 - 10
src/utils.js

@@ -158,7 +158,6 @@ export function replaceAtAndColonWithStandardSyntax(name) {
 }
 
 export function transitionIn(el, show, component, forceSkip = false) {
-    // We don't want to transition on the initial page load.
     if (forceSkip) return show()
 
     const attrs = getXAttrs(el, component, 'transition')
@@ -407,7 +406,7 @@ export function transition(el, stages) {
         requestAnimationFrame(() => {
             stages.end()
 
-            // Assign current transition to el in case we need to force it
+            // Assign current transition to el in case we need to force it.
             el.__x_transition_remaining = once(() => {
                 stages.hide()
 
@@ -417,7 +416,7 @@ export function transition(el, stages) {
                     stages.cleanup()
                 }
 
-                 // Safe to remove transition from el since it is completed
+                 // Safe to remove transition from el since it is completed.
                  delete el.__x_transition_remaining
             })
 
@@ -430,15 +429,13 @@ export function isNumeric(subject){
     return ! isNaN(subject)
 }
 
-/**
- * Ensure a function is called only once.
- */
-export function once(fn) {
+export function once(callback) {
     let called = false
+
     return function () {
-        if (!called) {
+        if (! called) {
             called = true
-            fn.apply(this, arguments)
+            callback.apply(this, arguments)
         }
     }
-}
+}

+ 18 - 12
test/transition.spec.js

@@ -627,7 +627,7 @@ test('remaining transitions forced to complete if they exists', async () => {
         setTimeout(callback, 0)
     });
 
-    // (hardcoding 10ms animation time for later assertions)
+    // Hardcoding 10ms animation time for later assertions.
     jest.spyOn(window, 'getComputedStyle').mockImplementation(el => {
         return {
             transitionDuration: '0s',
@@ -651,70 +651,76 @@ test('remaining transitions forced to complete if they exists', async () => {
 
     await wait(() => { expect(document.querySelector('span').getAttribute('style')).toEqual('display: none;') })
 
-    // trigger animation in
+    // Trigger animation in.
     document.querySelector('button').click()
 
-    // Wait for the first requestAnimationFrame
+    // Wait for the first requestAnimationFrame.
     await new Promise((resolve) =>
         setTimeout(() => {
             resolve();
         }, 0)
     )
+
     expect(document.querySelector('span').classList.contains('animation-enter')).toEqual(true)
 
-    // trigger animation out
+    // Trigger animation out.
     document.querySelector('button').click()
 
-    // Wait for the next requestAnimationFrame
+    // Wait for the next requestAnimationFrame.
     await new Promise((resolve) =>
         setTimeout(() => {
             resolve();
         }, 0)
     )
+
     expect(document.querySelector('span').classList.contains('animation-leave')).toEqual(true)
 
-    // Wait for the next requestAnimationFrame
+    // Wait for the next requestAnimationFrame.
         await new Promise((resolve) =>
         setTimeout(() => {
             resolve();
         }, 0)
     )
 
-    // trigger animation in
+    // Trigger animation in.
     document.querySelector('button').click()
 
-    // Wait for the next requestAnimationFrame
+    // Wait for the next requestAnimationFrame.
     await new Promise((resolve) =>
         setTimeout(() => {
             resolve();
         }, 0)
     )
+
     expect(document.querySelector('span').classList.contains('animation-enter')).toEqual(true)
 
-    // trigger animation out
+    // Trigger animation out.
     document.querySelector('button').click()
 
-    // Wait for the next requestAnimationFrame
+    // Wait for the next requestAnimationFrame.
     await new Promise((resolve) =>
         setTimeout(() => {
             resolve();
         }, 0)
     )
+
     expect(document.querySelector('span').classList.contains('animation-leave')).toEqual(true)
 
-    // The leave class should still be there since the animationDuration property is 100ms
+    // The leave class should still be there since the animationDuration property is 100ms.
     await new Promise((resolve) =>
         setTimeout(() => {
             resolve();
         }, 99)
     )
+
     expect(document.querySelector('span').classList.contains('animation-leave')).toEqual(true)
 
-    // The class shouldn't be there anymore
+    // The class shouldn't be there anymore.
     await new Promise((resolve) =>
         setTimeout(() => {
             resolve();
         }, 10)
     )
+
     expect(document.querySelector('span').classList.contains('animation-leave')).toEqual(false)
 })