Browse Source

Calculate the valid dest index before calling `move()`.

NaotoshiFujita 3 years ago
parent
commit
ac4f590ca7

File diff suppressed because it is too large
+ 355 - 268
dist/js/splide.cjs.js


File diff suppressed because it is too large
+ 352 - 266
dist/js/splide.esm.js


+ 17 - 10
dist/js/splide.js

@@ -1383,12 +1383,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       Transition.start(index, function () {
         set(IDLE);
         emit(EVENT_MOVED, index, prev, dest);
-
-        if (options.trimSpace === "move" && dest !== prev && position === getPosition()) {
-          Components2.Controller.go(dest > prev ? ">" : "<", false, callback);
-        } else {
-          callback && callback();
-        }
+        callback && callback();
       });
     }
 
@@ -1546,7 +1541,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     function go(control, allowSameIndex, callback) {
       if (!isBusy()) {
         var dest = parse(control);
-        var index = loop(dest);
+        var index = validate(dest);
 
         if (index > -1 && (allowSameIndex || index !== currIndex)) {
           setIndex(index);
@@ -1629,14 +1624,26 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       return dest;
     }
 
-    function getEnd() {
-      return max(slideCount - (hasFocus() || isLoop && perMove ? 1 : perPage), 0);
+    function validate(dest) {
+      if (options.trimSpace === "move" && dest !== currIndex) {
+        var position = getPosition();
+
+        while (position === toPosition(dest, true) && between(dest, 0, Splide2.length - 1, true)) {
+          dest < currIndex ? --dest : ++dest;
+        }
+      }
+
+      return loop(dest);
     }
 
     function loop(index) {
       return isLoop ? (index + slideCount) % slideCount || 0 : index;
     }
 
+    function getEnd() {
+      return max(slideCount - (hasFocus() || isLoop && perMove ? 1 : perPage), 0);
+    }
+
     function toIndex(page) {
       return clamp(hasFocus() ? page : perPage * page, 0, getEnd());
     }
@@ -1666,7 +1673,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function isBusy() {
-      return Splide2.state.is([MOVING, SCROLLING]) && options.waitForTransition;
+      return Splide2.state.is([MOVING, SCROLLING]) && !!options.waitForTransition;
     }
 
     return {

File diff suppressed because it is too large
+ 0 - 0
dist/js/splide.min.js


BIN
dist/js/splide.min.js.gz


File diff suppressed because it is too large
+ 0 - 0
dist/js/splide.min.js.map


+ 11 - 2
dist/types/index.d.ts

@@ -346,12 +346,17 @@ interface Options extends ResponsiveOptions {
      */
     preloadPages?: number;
     /**
-     * Determines whether to enable keyboard shortcuts or not.
+     * Enables keyboard shortcuts for the slider control.
      * - `true` or `'global'`: Listens to the `keydown` event of the document.
      * - 'focused': Listens to the `keydown` event of the slider root element with adding `tabindex="0"` to it.
-     * - `false`: Disables keyboard shortcuts.
+     * - `false`: Disables keyboard shortcuts (default).
      */
     keyboard?: boolean | string;
+    /**
+     * Enables keyboard shortcuts for the pagination, recommended by W3C.
+     * The default value is `true`.
+     */
+    paginationKeyboard?: boolean;
     /**
      * Enables navigation by the mouse wheel.
      * Set `waitForTransition` to `ture` or provide the `sleep` duration.
@@ -576,6 +581,10 @@ interface ResponsiveOptions {
      * If `free`, the slider does not snap to a slide after drag.
      */
     drag?: boolean | 'free';
+    /**
+     * Snaps the closest slide in the drag-free mode.
+     */
+    snap?: boolean;
     /**
      * The required distance to start moving the slider by the touch action.
      * If you want to define the threshold for the mouse, provide an object.

+ 6 - 0
scripts/build-module.js

@@ -2,6 +2,8 @@ const rollup  = require( 'rollup' ).rollup;
 const resolve = require( '@rollup/plugin-node-resolve' ).nodeResolve;
 const esbuild = require( 'rollup-plugin-esbuild' ).default;
 const banner  = require( './constants/banner' );
+const babel   = require( '@rollup/plugin-babel' );
+const path    = require( 'path' );
 const name    = 'splide';
 
 
@@ -11,6 +13,10 @@ function buildModule( type ) {
     plugins: [
       resolve(),
       esbuild(),
+	    babel.getBabelOutputPlugin( {
+		    configFile: path.resolve( __dirname, '../.babelrc' ),
+		    allowAllFormats: true,
+	    } ),
     ]
   } ).then( bundle => {
     return bundle.write( {

+ 26 - 8
src/js/components/Controller/Controller.ts

@@ -113,7 +113,7 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
   function go( control: number | string, allowSameIndex?: boolean, callback?: AnyFunction ): void {
     if ( ! isBusy() ) {
       const dest  = parse( control );
-      const index = loop( dest );
+      const index = validate( dest );
 
       if ( index > -1 && ( allowSameIndex || index !== currIndex ) ) {
         setIndex( index );
@@ -242,14 +242,21 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
   }
 
   /**
-   * Returns the end index where the slider can go.
-   * For example, if the slider has 10 slides and the `perPage` option is 3,
-   * the slider can go to the slide 8 (the index is 7).
+   * Finalizes the dest index.
+   * If the `trim` option is `move`, needs to find the dest index where the slider actually moves.
    *
-   * @return An end index.
+   * @param dest - A validated dest index.
    */
-  function getEnd(): number {
-    return max( slideCount - ( hasFocus() || ( isLoop && perMove ) ? 1 : perPage ), 0 );
+  function validate( dest: number ): number {
+    if ( options.trimSpace === 'move' && dest !== currIndex ) {
+      const position = getPosition();
+
+      while ( position === toPosition( dest, true ) && between( dest, 0, Splide.length - 1, true ) ) {
+        dest < currIndex ? --dest : ++dest;
+      }
+    }
+
+    return loop( dest );
   }
 
   /**
@@ -263,6 +270,17 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
     return isLoop ? ( index + slideCount ) % slideCount || 0 : index;
   }
 
+  /**
+   * Returns the end index where the slider can go.
+   * For example, if the slider has 10 slides and the `perPage` option is 3,
+   * the slider can go to the slide 8 (the index is 7).
+   *
+   * @return An end index.
+   */
+  function getEnd(): number {
+    return max( slideCount - ( hasFocus() || ( isLoop && perMove ) ? 1 : perPage ), 0 );
+  }
+
   /**
    * Converts the page index to the slide index.
    *
@@ -333,7 +351,7 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
    * @return `true` if the slider can move, or otherwise `false`.
    */
   function isBusy(): boolean {
-    return Splide.state.is( [ MOVING, SCROLLING ] ) && options.waitForTransition;
+    return Splide.state.is( [ MOVING, SCROLLING ] ) && !! options.waitForTransition;
   }
 
   return {

+ 22 - 3
src/js/components/Controller/test/isBusy.test.ts

@@ -3,7 +3,7 @@ import { fire, init } from '../../../test';
 
 describe( 'Controller#isBusy', () => {
   test( 'can check if the slider is moving or not.', () => {
-    const splide = init( { width: 200, height: 100 } );
+    const splide = init( { width: 200, height: 100, waitForTransition: true } );
     const { Controller, Move } = splide.Components;
 
     expect( Controller.isBusy() ).toBe( false );
@@ -16,15 +16,34 @@ describe( 'Controller#isBusy', () => {
   } );
 
   test( 'can check if the slider is being scrolled or not.', () => {
-    const splide = init( { width: 200, height: 100 } );
+    const splide = init( { width: 200, height: 100, waitForTransition: true } );
     const { Controller, Scroll } = splide.Components;
 
     expect( Controller.isBusy() ).toBe( false );
 
-    Scroll.scroll( 10, 0 );
+    Scroll.scroll( 10, 10 );
     expect( Controller.isBusy() ).toBe( true );
 
     Scroll.cancel();
     expect( Controller.isBusy() ).toBe( false );
   } );
+
+  test( 'should always return true if `waitForTransition` is false.', () => {
+    const splide = init( { width: 200, height: 100, waitForTransition: false } );
+    const { Controller, Move, Scroll } = splide.Components;
+
+    expect( Controller.isBusy() ).toBe( false );
+
+    Move.move( 1, 1, -1 );
+    expect( Controller.isBusy() ).toBe( false );
+
+    Move.cancel();
+    expect( Controller.isBusy() ).toBe( false );
+
+    Scroll.scroll( 10, 10 );
+    expect( Controller.isBusy() ).toBe( false );
+
+    Scroll.cancel();
+    expect( Controller.isBusy() ).toBe( false );
+  } );
 } );

+ 1 - 6
src/js/components/Move/Move.ts

@@ -104,12 +104,7 @@ export function Move( Splide: Splide, Components: Components, options: Options )
     Transition.start( index, () => {
       set( IDLE );
       emit( EVENT_MOVED, index, prev, dest );
-
-      if ( options.trimSpace === 'move' && dest !== prev && position === getPosition() ) {
-        Components.Controller.go( dest > prev ? '>' : '<', false, callback );
-      } else {
-        callback && callback();
-      }
+      callback && callback();
     } );
   }
 

+ 1 - 2
src/js/components/Scroll/Scroll.ts

@@ -4,8 +4,7 @@ import { SLIDE } from '../../constants/types';
 import { EventInterface, RequestInterval, RequestIntervalInterface } from '../../constructors';
 import { Splide } from '../../core/Splide/Splide';
 import { AnyFunction, BaseComponent, Components, Options } from '../../types';
-import { abs, apply, between, floor, max, sign } from '../../utils';
-import { Controller } from '../Controller/Controller';
+import { abs, apply, floor, max, sign } from '../../utils';
 import { BASE_VELOCITY, BOUNCE_DIFF_THRESHOLD, BOUNCE_DURATION, FRICTION_FACTOR, MIN_DURATION } from './constants';
 
 

+ 6 - 6
src/js/test/php/examples/default.php

@@ -16,20 +16,22 @@ $settings = get_settings();
   <link rel="stylesheet" href="../../assets/css/styles.css">
   <script type="text/javascript" src="../../../../../dist/js/splide.js"></script>
 
+<!--	https://cdn.jsdelivr.net/npm/@splidejs/[email protected]/dist/js/splide.min.js-->
+
   <script>
     document.addEventListener( 'DOMContentLoaded', function () {
       var splide = new Splide( '#splide01', {
 				width: 800,
-        type   : 'loop',
+        // type   : 'loop',
         perPage: 3,
         // perMove: 1,
         rewind: true,
 	      rewindByDrag: true,
         padding: 40,
+	      // focus: 'center',
         // updateOnMove: true,
-        // focus: 'center',
 	      // keyboard: false,
-	      waitForTransition: false,
+	      // waitForTransition: false,
 	      // flickPower: 1,
 	      // flickMaxSlides: 2,
 	      // direction: 'rtl',
@@ -37,11 +39,9 @@ $settings = get_settings();
 					mouse: 20,
 		      touch: 0,
 	      },
-	      // focus: 'center',
-	      trimSpace: 'move',
+	      // trimSpace: 'move',
 	      // speed: 3000,
 	      // useScroll: true,
-				// waitForTransition: false,
         // noDrag: 'button',
       } );
 

Some files were not shown because too many files changed in this diff