Преглед изворни кода

Optimization. Remove horizontal and vertical directions of the Track component.

NaotoshiFujita пре 5 година
родитељ
комит
fe53e80423

+ 131 - 231
dist/js/splide.esm.js

@@ -1,6 +1,6 @@
 /*!
  * Splide.js
- * Version  : 2.4.0
+ * Version  : 2.4.1
  * License  : MIT
  * Copyright: 2020 Naotoshi Fujita
  */
@@ -466,7 +466,7 @@ function toPixel(root, value) {
     dom_remove(div);
   }
 
-  return value;
+  return +value || 0;
 }
 // CONCATENATED MODULE: ./src/js/utils/dom.js
 /**
@@ -1134,12 +1134,19 @@ var DEFAULTS = {
   /**
    * If true, slide width will be determined by the element width itself.
    * - perPage/perMove should be 1.
-   * - lazyLoad should be false.
    *
    * @type {boolean}
    */
   autoWidth: false,
 
+  /**
+   * If true, slide height will be determined by the element width itself.
+   * - perPage/perMove should be 1.
+   *
+   * @type {boolean}
+   */
+  autoHeight: false,
+
   /**
    * Determine how many slides should be displayed per page.
    *
@@ -2068,6 +2075,7 @@ var STYLE_RESTORE_EVENTS = 'update.slide';
       Splide.off(STATUS_UPDATE_EVENTS).off(STYLE_RESTORE_EVENTS).off('click', slide);
       removeClass(slide, values(STATUS_CLASSES));
       restoreStyles();
+      removeAttribute(this.container, 'style');
     },
 
     /**
@@ -2100,15 +2108,14 @@ var STYLE_RESTORE_EVENTS = 'update.slide';
         return active;
       }
 
-      var floor = Math.floor;
-      var Components = Splide.Components;
-      var Track = Components.Track;
-      var Layout = Components.Layout;
-      var isVertical = Splide.options.direction === TTB;
-      var position = floor((Track.toPosition(index) + Track.offset(index) - Track.position) * Track.sign);
-      var edge = floor(position + Layout[isVertical ? 'slideHeight' : 'slideWidth'](index));
-      var size = Layout[isVertical ? 'height' : 'width'];
-      return 0 <= position && position <= size && 0 <= edge && edge <= size;
+      var trackRect = getRect(Splide.Components.Elements.track);
+      var slideRect = getRect(slide);
+
+      if (Splide.options.direction === TTB) {
+        return trackRect.top <= slideRect.top && slideRect.bottom <= trackRect.bottom;
+      }
+
+      return trackRect.left <= slideRect.left && slideRect.right <= trackRect.right;
     },
 
     /**
@@ -2452,7 +2459,7 @@ var UID_NAME = 'uid';
 
 
 
-var controller_floor = Math.floor;
+var floor = Math.floor;
 /**
  * The component for controlling the track.
  *
@@ -2558,7 +2565,7 @@ var controller_floor = Math.floor;
       var length = Splide.length;
       var perPage = options.perPage;
       var index = page * perPage;
-      index = index - (this.pageLength * perPage - length) * controller_floor(index / length); // Adjustment for the last page.
+      index = index - (this.pageLength * perPage - length) * floor(index / length); // Adjustment for the last page.
 
       if (length - perPage <= index && index < length) {
         index = length - perPage;
@@ -2583,10 +2590,10 @@ var controller_floor = Math.floor;
       var perPage = options.perPage; // Make the last "perPage" number of slides belong to the last page.
 
       if (length - perPage <= index && index < length) {
-        return controller_floor((length - 1) / perPage);
+        return floor((length - 1) / perPage);
       }
 
-      return controller_floor(index / perPage);
+      return floor(index / perPage);
     },
 
     /**
@@ -2753,216 +2760,47 @@ var controller_floor = Math.floor;
 
   return Controller;
 });
-// CONCATENATED MODULE: ./src/js/components/track/directions/vertical.js
+// CONCATENATED MODULE: ./src/js/components/track/index.js
 /**
- * The resolver component for vertical move.
+ * The component for moving list in the track.
  *
  * @author    Naotoshi Fujita
  * @copyright Naotoshi Fujita. All rights reserved.
  */
 
+
+
+
 /**
- * The resolver component for vertical move.
+ * The component for moving list in the track.
  *
  * @param {Splide} Splide     - A Splide instance.
  * @param {Object} Components - An object containing components.
  *
- * @return {Object} - The resolver object.
+ * @return {Object} - The component object.
  */
 
-/* harmony default export */ var vertical = (function (Splide, Components) {
+/* harmony default export */ var components_track = (function (Splide, Components) {
   /**
-   * Hold the Layout object.
+   * Hold the Layout component.
    *
    * @type {Object}
    */
   var Layout;
-  return {
-    /**
-     * Axis of translate.
-     *
-     * @type {string}
-     */
-    axis: 'Y',
-
-    /**
-     * Sign for the direction.
-     *
-     * @return {number}
-     */
-    sign: -1,
-
-    /**
-     * Initialization.
-     */
-    init: function init() {
-      Layout = Components.Layout;
-    },
-
-    /**
-     * Calculate position by index.
-     *
-     * @param {number} index - Slide index.
-     *
-     * @return {Object} - Calculated position.
-     */
-    toPosition: function toPosition(index) {
-      return -(Layout.totalHeight(index) - Layout.slideHeight() - Layout.gap + this.offset());
-    },
-
-    /**
-     * Trim redundant spaces on the left or right edge if necessary.
-     *
-     * @param {number} position - Position value to be trimmed.
-     *
-     * @return {number} - Trimmed position.
-     */
-    trim: function trim(position) {
-      var edge = -(Layout.totalHeight() - (Layout.height + Layout.gap));
-      return between(position, edge, 0);
-    },
-
-    /**
-     * Return current offset value, considering direction.
-     *
-     * @return {number} - Offset amount.
-     */
-    offset: function offset() {
-      var focus = Splide.options.focus;
-      var slideHeight = Layout.slideHeight();
-
-      if (focus === 'center') {
-        return -(Layout.height - slideHeight) / 2;
-      }
-
-      return -(parseInt(focus) || 0) * (slideHeight + Layout.gap);
-    }
-  };
-});
-// CONCATENATED MODULE: ./src/js/components/track/directions/horizontal.js
-/**
- * The resolver component for horizontal move.
- *
- * @author    Naotoshi Fujita
- * @copyright Naotoshi Fujita. All rights reserved.
- */
-
-
-/**
- * The resolver component for horizontal move.
- *
- * @param {Splide} Splide     - A Splide instance.
- * @param {Object} Components - An object containing components.
- *
- * @return {Object} - The resolver object.
- */
-
-/* harmony default export */ var horizontal = (function (Splide, Components) {
   /**
    * Hold the Layout component.
    *
    * @type {Object}
    */
-  var Layout;
-  return {
-    /**
-     * Axis of translate.
-     *
-     * @type {string}
-     */
-    axis: 'X',
-
-    /**
-     * Sign for the direction.
-     *
-     * @type {number}
-     */
-    sign: Splide.options.direction === RTL ? 1 : -1,
-
-    /**
-     * Initialization.
-     */
-    init: function init() {
-      Layout = Components.Layout;
-    },
-
-    /**
-     * Calculate the track position by a slide index.
-     *
-     * @param {number} index - Slide index.
-     *
-     * @return {Object} - Calculated position.
-     */
-    toPosition: function toPosition(index) {
-      var slidePosition = Layout.totalWidth(index) - Layout.slideWidth(index) - Layout.gap;
-      return this.sign * (slidePosition + this.offset(index));
-    },
-
-    /**
-     * Trim redundant spaces on the left or right edge if necessary.
-     *
-     * @param {number} position - Position value to be trimmed.
-     *
-     * @return {number} - Trimmed position.
-     */
-    trim: function trim(position) {
-      var edge = this.sign * (Layout.totalWidth() - (Layout.width + Layout.gap));
-      return between(position, edge, 0);
-    },
-
-    /**
-     * Return current offset value, considering direction.
-     *
-     * @return {number} - Offset amount.
-     */
-    offset: function offset(index) {
-      var focus = Splide.options.focus;
-      var slideWidth = Layout.slideWidth(index);
-
-      if (focus === 'center') {
-        return -(Layout.width - slideWidth) / 2;
-      }
-
-      return -(parseInt(focus) || 0) * (slideWidth + Layout.gap);
-    }
-  };
-});
-// CONCATENATED MODULE: ./src/js/components/track/index.js
-/**
- * The component for moving list in the track.
- *
- * @author    Naotoshi Fujita
- * @copyright Naotoshi Fujita. All rights reserved.
- */
-
-
-
 
-
-
-/**
- * The component for moving list in the track.
- *
- * @param {Splide} Splide     - A Splide instance.
- * @param {Object} Components - An object containing components.
- *
- * @return {Object} - The component object.
- */
-
-/* harmony default export */ var components_track = (function (Splide, Components) {
+  var Elements;
   /**
    * Store the list element.
    *
    * @type {Element}
    */
-  var list;
-  /**
-   * Store the current position.
-   *
-   * @type {number}
-   */
 
-  var currPosition = 0;
+  var list;
   /**
    * Whether the current direction is vertical or not.
    *
@@ -2983,13 +2821,21 @@ var controller_floor = Math.floor;
    * @type {Object}
    */
 
-  var Track = object_assign({
+  var Track = {
+    /**
+     * Sign for the direction. Only RTL mode uses the positive sign.
+     *
+     * @type {number}
+     */
+    sign: Splide.options.direction === RTL ? 1 : -1,
+
     /**
      * Called when the component is mounted.
      */
     mount: function mount() {
-      list = Components.Elements.list;
-      this.init();
+      Elements = Components.Elements;
+      Layout = Components.Layout;
+      list = Elements.list;
     },
 
     /**
@@ -3000,6 +2846,7 @@ var controller_floor = Math.floor;
       var _this = this;
 
       if (!isFade) {
+        this.jump(0);
         Splide.on('mounted resize updated', function () {
           _this.jump(Splide.index);
         });
@@ -3023,7 +2870,7 @@ var controller_floor = Math.floor;
         Splide.emit('move', newIndex, prevIndex, destIndex);
       }
 
-      if (Math.abs(newPosition - currPosition) >= 1 || isFade) {
+      if (Math.abs(newPosition - this.position) >= 1 || isFade) {
         Components.Transition.start(destIndex, newIndex, prevIndex, this.toCoord(newPosition), function () {
           onTransitionEnd(destIndex, newIndex, prevIndex, silently);
         });
@@ -3051,9 +2898,8 @@ var controller_floor = Math.floor;
      * @param {number} position - A new position value.
      */
     translate: function translate(position) {
-      currPosition = position;
       applyStyle(list, {
-        transform: "translate" + this.axis + "(" + position + "px)"
+        transform: "translate" + (isVertical ? 'Y' : 'X') + "(" + position + "px)"
       });
     },
 
@@ -3069,7 +2915,8 @@ var controller_floor = Math.floor;
         return position;
       }
 
-      return this._s.trim(position);
+      var edge = this.sign * (Layout.totalSize() - Layout.size - Layout.gap);
+      return between(position, edge, 0);
     },
 
     /**
@@ -3084,7 +2931,7 @@ var controller_floor = Math.floor;
 
       var index = 0;
       var minDistance = Infinity;
-      Components.Elements.getSlides(true).forEach(function (Slide) {
+      Elements.getSlides(true).forEach(function (Slide) {
         var slideIndex = Slide.index;
         var distance = Math.abs(_this2.toPosition(slideIndex) - position);
 
@@ -3111,15 +2958,45 @@ var controller_floor = Math.floor;
     },
 
     /**
-     * Return current position.
+     * Calculate the track position by a slide index.
+     *
+     * @param {number} index - Slide index.
+     *
+     * @return {Object} - Calculated position.
+     */
+    toPosition: function toPosition(index) {
+      var position = Layout.totalSize(index) - Layout.slideSize(index) - Layout.gap;
+      return this.sign * (position + this.offset(index));
+    },
+
+    /**
+     * Return current offset value, considering direction.
+     *
+     * @return {number} - Offset amount.
+     */
+    offset: function offset(index) {
+      var focus = Splide.options.focus;
+      var slideSize = Layout.slideSize(index);
+
+      if (focus === 'center') {
+        return -(Layout.size - slideSize) / 2;
+      }
+
+      return -(parseInt(focus) || 0) * (slideSize + Layout.gap);
+    },
+
+    /**
+     * Return the current position.
+     * This returns the correct position even while transitioning by CSS.
      *
      * @return {number} - Current position.
      */
     get position() {
-      return currPosition;
+      var prop = isVertical ? 'top' : 'left';
+      return getRect(list)[prop] - getRect(Elements.track)[prop] - Layout.padding[prop];
     }
 
-  }, isVertical ? vertical(Splide, Components) : horizontal(Splide, Components));
+  };
   /**
    * Called whenever slides arrive at a destination.
    *
@@ -3356,7 +3233,7 @@ var controller_floor = Math.floor;
  * @return {Object} - The resolver object.
  */
 
-/* harmony default export */ var directions_horizontal = (function (Splide, Components) {
+/* harmony default export */ var horizontal = (function (Splide, Components) {
   /**
    * Keep the Elements component.
    *
@@ -3407,13 +3284,11 @@ var controller_floor = Math.floor;
       track = Elements.track;
       this.gap = toPixel(root, options.gap);
       var padding = options.padding;
-      var _padding$left = padding.left,
-          left = _padding$left === void 0 ? padding : _padding$left,
-          _padding$right = padding.right,
-          right = _padding$right === void 0 ? padding : _padding$right;
+      var left = toPixel(root, padding.left || padding);
+      var right = toPixel(root, padding.right || padding);
       this.padding = {
-        left: toPixel(root, left),
-        right: toPixel(root, right)
+        left: left,
+        right: right
       };
       applyStyle(track, {
         paddingLeft: unit(left),
@@ -3509,7 +3384,7 @@ var controller_floor = Math.floor;
  * @return {Object} - The resolver object.
  */
 
-/* harmony default export */ var directions_vertical = (function (Splide, Components) {
+/* harmony default export */ var vertical = (function (Splide, Components) {
   /**
    * Keep the Elements component.
    *
@@ -3553,13 +3428,11 @@ var controller_floor = Math.floor;
       track = Elements.track;
       this.gap = toPixel(root, options.gap);
       var padding = options.padding;
-      var _padding$top = padding.top,
-          top = _padding$top === void 0 ? padding : _padding$top,
-          _padding$bottom = padding.bottom,
-          bottom = _padding$bottom === void 0 ? padding : _padding$bottom;
+      var top = toPixel(root, padding.top || padding);
+      var bottom = toPixel(root, padding.bottom || padding);
       this.padding = {
-        top: toPixel(root, top),
-        bottom: toPixel(root, bottom)
+        top: top,
+        bottom: bottom
       };
       applyStyle(track, {
         paddingTop: unit(top),
@@ -3600,9 +3473,16 @@ var controller_floor = Math.floor;
     /**
      * Return the slide height in px.
      *
+     * @param {number} index - Slide index.
+     *
      * @return {number} - The slide height.
      */
-    slideHeight: function slideHeight() {
+    slideHeight: function slideHeight(index) {
+      if (options.autoHeight) {
+        var Slide = Elements.getSlide(index);
+        return Slide ? Slide.slide.offsetHeight : 0;
+      }
+
       var height = options.fixedHeight || (this.height + this.gap) / options.perPage - this.gap;
       return toPixel(root, height);
     },
@@ -3752,6 +3632,13 @@ function createInterval(callback, interval, progress) {
    * @type {string}
    */
   var Elements = Components.Elements;
+  /**
+   * Whether the slider is vertical or not.
+   *
+   * @type {boolean}
+   */
+
+  var isVertical = Splide.options.direction === TTB;
   /**
    * Layout component object.
    *
@@ -3764,16 +3651,29 @@ function createInterval(callback, interval, progress) {
      */
     mount: function mount() {
       bind();
-      init();
+      init(); // The word "size" means width for a horizontal slider and height for a vertical slider.
+
+      this.totalSize = isVertical ? this.totalHeight : this.totalWidth;
+      this.slideSize = isVertical ? this.slideHeight : this.slideWidth;
     },
 
     /**
-     * Destroy.
+     * Destroy the component.
      */
     destroy: function destroy() {
       removeAttribute([Elements.list, Elements.track], 'style');
+    },
+
+    /**
+     * Return the slider height on the vertical mode or width on the horizontal mode.
+     *
+     * @return {number}
+     */
+    get size() {
+      return isVertical ? this.height : this.width;
     }
-  }, Splide.options.direction === TTB ? directions_vertical(Splide, Components) : directions_horizontal(Splide, Components));
+
+  }, isVertical ? vertical(Splide, Components) : horizontal(Splide, Components));
   /**
    * Init slider styles according to options.
    */
@@ -3800,21 +3700,22 @@ function createInterval(callback, interval, progress) {
     }, Splide.options.throttle), window).on('resize', resize).on('updated refresh', init);
   }
   /**
-   * Resize the list and slides including clones.
+   * Resize the track and slide elements.
    */
 
 
   function resize() {
+    var options = Splide.options;
     applyStyle(Elements.track, {
       height: unit(Layout.height)
     });
-    var slideHeight = unit(Layout.slideHeight());
+    var slideHeight = options.autoHeight ? null : unit(Layout.slideHeight());
     Elements.each(function (Slide) {
       applyStyle(Slide.container, {
         height: slideHeight
       });
       applyStyle(Slide.slide, {
-        width: Splide.options.autoWidth ? null : unit(Layout.slideWidth(Slide.index)),
+        width: options.autoWidth ? null : unit(Layout.slideWidth(Slide.index)),
         height: Slide.container ? null : slideHeight
       });
     });
@@ -4073,7 +3974,6 @@ var FRICTION_REDUCER = 7;
     var absV = abs(velocity);
 
     if (absV > 0) {
-      var Layout = Components.Layout;
       var options = Splide.options;
       var index = Splide.index;
       var sign = velocity < 0 ? -1 : 1;
@@ -4083,7 +3983,7 @@ var FRICTION_REDUCER = 7;
         var destination = Track.position;
 
         if (absV > options.flickVelocityThreshold && abs(info.offset[axis]) < options.swipeDistanceThreshold) {
-          destination += sign * Math.min(absV * options.flickPower, Layout.width * (options.flickMaxPages || 1));
+          destination += sign * Math.min(absV * options.flickPower, Components.Layout.size * (options.flickMaxPages || 1));
         }
 
         destIndex = Track.toIndex(destination);
@@ -5691,7 +5591,7 @@ var THROTTLE = 50;
      */
     mount: function mount() {
       map = Object.keys(breakpoints).sort(function (n, m) {
-        return parseInt(n) - parseInt(m);
+        return +n - +m;
       }).map(function (point) {
         return {
           point: point,

+ 131 - 231
dist/js/splide.js

@@ -1,6 +1,6 @@
 /*!
  * Splide.js
- * Version  : 2.4.0
+ * Version  : 2.4.1
  * License  : MIT
  * Copyright: 2020 Naotoshi Fujita
  */
@@ -456,7 +456,7 @@ function toPixel(root, value) {
     dom_remove(div);
   }
 
-  return value;
+  return +value || 0;
 }
 // CONCATENATED MODULE: ./src/js/utils/dom.js
 /**
@@ -1124,12 +1124,19 @@ var DEFAULTS = {
   /**
    * If true, slide width will be determined by the element width itself.
    * - perPage/perMove should be 1.
-   * - lazyLoad should be false.
    *
    * @type {boolean}
    */
   autoWidth: false,
 
+  /**
+   * If true, slide height will be determined by the element width itself.
+   * - perPage/perMove should be 1.
+   *
+   * @type {boolean}
+   */
+  autoHeight: false,
+
   /**
    * Determine how many slides should be displayed per page.
    *
@@ -2058,6 +2065,7 @@ var STYLE_RESTORE_EVENTS = 'update.slide';
       Splide.off(STATUS_UPDATE_EVENTS).off(STYLE_RESTORE_EVENTS).off('click', slide);
       removeClass(slide, values(STATUS_CLASSES));
       restoreStyles();
+      removeAttribute(this.container, 'style');
     },
 
     /**
@@ -2090,15 +2098,14 @@ var STYLE_RESTORE_EVENTS = 'update.slide';
         return active;
       }
 
-      var floor = Math.floor;
-      var Components = Splide.Components;
-      var Track = Components.Track;
-      var Layout = Components.Layout;
-      var isVertical = Splide.options.direction === TTB;
-      var position = floor((Track.toPosition(index) + Track.offset(index) - Track.position) * Track.sign);
-      var edge = floor(position + Layout[isVertical ? 'slideHeight' : 'slideWidth'](index));
-      var size = Layout[isVertical ? 'height' : 'width'];
-      return 0 <= position && position <= size && 0 <= edge && edge <= size;
+      var trackRect = getRect(Splide.Components.Elements.track);
+      var slideRect = getRect(slide);
+
+      if (Splide.options.direction === TTB) {
+        return trackRect.top <= slideRect.top && slideRect.bottom <= trackRect.bottom;
+      }
+
+      return trackRect.left <= slideRect.left && slideRect.right <= trackRect.right;
     },
 
     /**
@@ -2442,7 +2449,7 @@ var UID_NAME = 'uid';
 
 
 
-var controller_floor = Math.floor;
+var floor = Math.floor;
 /**
  * The component for controlling the track.
  *
@@ -2548,7 +2555,7 @@ var controller_floor = Math.floor;
       var length = Splide.length;
       var perPage = options.perPage;
       var index = page * perPage;
-      index = index - (this.pageLength * perPage - length) * controller_floor(index / length); // Adjustment for the last page.
+      index = index - (this.pageLength * perPage - length) * floor(index / length); // Adjustment for the last page.
 
       if (length - perPage <= index && index < length) {
         index = length - perPage;
@@ -2573,10 +2580,10 @@ var controller_floor = Math.floor;
       var perPage = options.perPage; // Make the last "perPage" number of slides belong to the last page.
 
       if (length - perPage <= index && index < length) {
-        return controller_floor((length - 1) / perPage);
+        return floor((length - 1) / perPage);
       }
 
-      return controller_floor(index / perPage);
+      return floor(index / perPage);
     },
 
     /**
@@ -2743,216 +2750,47 @@ var controller_floor = Math.floor;
 
   return Controller;
 });
-// CONCATENATED MODULE: ./src/js/components/track/directions/vertical.js
+// CONCATENATED MODULE: ./src/js/components/track/index.js
 /**
- * The resolver component for vertical move.
+ * The component for moving list in the track.
  *
  * @author    Naotoshi Fujita
  * @copyright Naotoshi Fujita. All rights reserved.
  */
 
+
+
+
 /**
- * The resolver component for vertical move.
+ * The component for moving list in the track.
  *
  * @param {Splide} Splide     - A Splide instance.
  * @param {Object} Components - An object containing components.
  *
- * @return {Object} - The resolver object.
+ * @return {Object} - The component object.
  */
 
-/* harmony default export */ var vertical = (function (Splide, Components) {
+/* harmony default export */ var components_track = (function (Splide, Components) {
   /**
-   * Hold the Layout object.
+   * Hold the Layout component.
    *
    * @type {Object}
    */
   var Layout;
-  return {
-    /**
-     * Axis of translate.
-     *
-     * @type {string}
-     */
-    axis: 'Y',
-
-    /**
-     * Sign for the direction.
-     *
-     * @return {number}
-     */
-    sign: -1,
-
-    /**
-     * Initialization.
-     */
-    init: function init() {
-      Layout = Components.Layout;
-    },
-
-    /**
-     * Calculate position by index.
-     *
-     * @param {number} index - Slide index.
-     *
-     * @return {Object} - Calculated position.
-     */
-    toPosition: function toPosition(index) {
-      return -(Layout.totalHeight(index) - Layout.slideHeight() - Layout.gap + this.offset());
-    },
-
-    /**
-     * Trim redundant spaces on the left or right edge if necessary.
-     *
-     * @param {number} position - Position value to be trimmed.
-     *
-     * @return {number} - Trimmed position.
-     */
-    trim: function trim(position) {
-      var edge = -(Layout.totalHeight() - (Layout.height + Layout.gap));
-      return between(position, edge, 0);
-    },
-
-    /**
-     * Return current offset value, considering direction.
-     *
-     * @return {number} - Offset amount.
-     */
-    offset: function offset() {
-      var focus = Splide.options.focus;
-      var slideHeight = Layout.slideHeight();
-
-      if (focus === 'center') {
-        return -(Layout.height - slideHeight) / 2;
-      }
-
-      return -(parseInt(focus) || 0) * (slideHeight + Layout.gap);
-    }
-  };
-});
-// CONCATENATED MODULE: ./src/js/components/track/directions/horizontal.js
-/**
- * The resolver component for horizontal move.
- *
- * @author    Naotoshi Fujita
- * @copyright Naotoshi Fujita. All rights reserved.
- */
-
-
-/**
- * The resolver component for horizontal move.
- *
- * @param {Splide} Splide     - A Splide instance.
- * @param {Object} Components - An object containing components.
- *
- * @return {Object} - The resolver object.
- */
-
-/* harmony default export */ var horizontal = (function (Splide, Components) {
   /**
    * Hold the Layout component.
    *
    * @type {Object}
    */
-  var Layout;
-  return {
-    /**
-     * Axis of translate.
-     *
-     * @type {string}
-     */
-    axis: 'X',
-
-    /**
-     * Sign for the direction.
-     *
-     * @type {number}
-     */
-    sign: Splide.options.direction === RTL ? 1 : -1,
-
-    /**
-     * Initialization.
-     */
-    init: function init() {
-      Layout = Components.Layout;
-    },
-
-    /**
-     * Calculate the track position by a slide index.
-     *
-     * @param {number} index - Slide index.
-     *
-     * @return {Object} - Calculated position.
-     */
-    toPosition: function toPosition(index) {
-      var slidePosition = Layout.totalWidth(index) - Layout.slideWidth(index) - Layout.gap;
-      return this.sign * (slidePosition + this.offset(index));
-    },
-
-    /**
-     * Trim redundant spaces on the left or right edge if necessary.
-     *
-     * @param {number} position - Position value to be trimmed.
-     *
-     * @return {number} - Trimmed position.
-     */
-    trim: function trim(position) {
-      var edge = this.sign * (Layout.totalWidth() - (Layout.width + Layout.gap));
-      return between(position, edge, 0);
-    },
-
-    /**
-     * Return current offset value, considering direction.
-     *
-     * @return {number} - Offset amount.
-     */
-    offset: function offset(index) {
-      var focus = Splide.options.focus;
-      var slideWidth = Layout.slideWidth(index);
-
-      if (focus === 'center') {
-        return -(Layout.width - slideWidth) / 2;
-      }
-
-      return -(parseInt(focus) || 0) * (slideWidth + Layout.gap);
-    }
-  };
-});
-// CONCATENATED MODULE: ./src/js/components/track/index.js
-/**
- * The component for moving list in the track.
- *
- * @author    Naotoshi Fujita
- * @copyright Naotoshi Fujita. All rights reserved.
- */
-
-
-
 
-
-
-/**
- * The component for moving list in the track.
- *
- * @param {Splide} Splide     - A Splide instance.
- * @param {Object} Components - An object containing components.
- *
- * @return {Object} - The component object.
- */
-
-/* harmony default export */ var components_track = (function (Splide, Components) {
+  var Elements;
   /**
    * Store the list element.
    *
    * @type {Element}
    */
-  var list;
-  /**
-   * Store the current position.
-   *
-   * @type {number}
-   */
 
-  var currPosition = 0;
+  var list;
   /**
    * Whether the current direction is vertical or not.
    *
@@ -2973,13 +2811,21 @@ var controller_floor = Math.floor;
    * @type {Object}
    */
 
-  var Track = object_assign({
+  var Track = {
+    /**
+     * Sign for the direction. Only RTL mode uses the positive sign.
+     *
+     * @type {number}
+     */
+    sign: Splide.options.direction === RTL ? 1 : -1,
+
     /**
      * Called when the component is mounted.
      */
     mount: function mount() {
-      list = Components.Elements.list;
-      this.init();
+      Elements = Components.Elements;
+      Layout = Components.Layout;
+      list = Elements.list;
     },
 
     /**
@@ -2990,6 +2836,7 @@ var controller_floor = Math.floor;
       var _this = this;
 
       if (!isFade) {
+        this.jump(0);
         Splide.on('mounted resize updated', function () {
           _this.jump(Splide.index);
         });
@@ -3013,7 +2860,7 @@ var controller_floor = Math.floor;
         Splide.emit('move', newIndex, prevIndex, destIndex);
       }
 
-      if (Math.abs(newPosition - currPosition) >= 1 || isFade) {
+      if (Math.abs(newPosition - this.position) >= 1 || isFade) {
         Components.Transition.start(destIndex, newIndex, prevIndex, this.toCoord(newPosition), function () {
           onTransitionEnd(destIndex, newIndex, prevIndex, silently);
         });
@@ -3041,9 +2888,8 @@ var controller_floor = Math.floor;
      * @param {number} position - A new position value.
      */
     translate: function translate(position) {
-      currPosition = position;
       applyStyle(list, {
-        transform: "translate" + this.axis + "(" + position + "px)"
+        transform: "translate" + (isVertical ? 'Y' : 'X') + "(" + position + "px)"
       });
     },
 
@@ -3059,7 +2905,8 @@ var controller_floor = Math.floor;
         return position;
       }
 
-      return this._s.trim(position);
+      var edge = this.sign * (Layout.totalSize() - Layout.size - Layout.gap);
+      return between(position, edge, 0);
     },
 
     /**
@@ -3074,7 +2921,7 @@ var controller_floor = Math.floor;
 
       var index = 0;
       var minDistance = Infinity;
-      Components.Elements.getSlides(true).forEach(function (Slide) {
+      Elements.getSlides(true).forEach(function (Slide) {
         var slideIndex = Slide.index;
         var distance = Math.abs(_this2.toPosition(slideIndex) - position);
 
@@ -3101,15 +2948,45 @@ var controller_floor = Math.floor;
     },
 
     /**
-     * Return current position.
+     * Calculate the track position by a slide index.
+     *
+     * @param {number} index - Slide index.
+     *
+     * @return {Object} - Calculated position.
+     */
+    toPosition: function toPosition(index) {
+      var position = Layout.totalSize(index) - Layout.slideSize(index) - Layout.gap;
+      return this.sign * (position + this.offset(index));
+    },
+
+    /**
+     * Return current offset value, considering direction.
+     *
+     * @return {number} - Offset amount.
+     */
+    offset: function offset(index) {
+      var focus = Splide.options.focus;
+      var slideSize = Layout.slideSize(index);
+
+      if (focus === 'center') {
+        return -(Layout.size - slideSize) / 2;
+      }
+
+      return -(parseInt(focus) || 0) * (slideSize + Layout.gap);
+    },
+
+    /**
+     * Return the current position.
+     * This returns the correct position even while transitioning by CSS.
      *
      * @return {number} - Current position.
      */
     get position() {
-      return currPosition;
+      var prop = isVertical ? 'top' : 'left';
+      return getRect(list)[prop] - getRect(Elements.track)[prop] - Layout.padding[prop];
     }
 
-  }, isVertical ? vertical(Splide, Components) : horizontal(Splide, Components));
+  };
   /**
    * Called whenever slides arrive at a destination.
    *
@@ -3346,7 +3223,7 @@ var controller_floor = Math.floor;
  * @return {Object} - The resolver object.
  */
 
-/* harmony default export */ var directions_horizontal = (function (Splide, Components) {
+/* harmony default export */ var horizontal = (function (Splide, Components) {
   /**
    * Keep the Elements component.
    *
@@ -3397,13 +3274,11 @@ var controller_floor = Math.floor;
       track = Elements.track;
       this.gap = toPixel(root, options.gap);
       var padding = options.padding;
-      var _padding$left = padding.left,
-          left = _padding$left === void 0 ? padding : _padding$left,
-          _padding$right = padding.right,
-          right = _padding$right === void 0 ? padding : _padding$right;
+      var left = toPixel(root, padding.left || padding);
+      var right = toPixel(root, padding.right || padding);
       this.padding = {
-        left: toPixel(root, left),
-        right: toPixel(root, right)
+        left: left,
+        right: right
       };
       applyStyle(track, {
         paddingLeft: unit(left),
@@ -3499,7 +3374,7 @@ var controller_floor = Math.floor;
  * @return {Object} - The resolver object.
  */
 
-/* harmony default export */ var directions_vertical = (function (Splide, Components) {
+/* harmony default export */ var vertical = (function (Splide, Components) {
   /**
    * Keep the Elements component.
    *
@@ -3543,13 +3418,11 @@ var controller_floor = Math.floor;
       track = Elements.track;
       this.gap = toPixel(root, options.gap);
       var padding = options.padding;
-      var _padding$top = padding.top,
-          top = _padding$top === void 0 ? padding : _padding$top,
-          _padding$bottom = padding.bottom,
-          bottom = _padding$bottom === void 0 ? padding : _padding$bottom;
+      var top = toPixel(root, padding.top || padding);
+      var bottom = toPixel(root, padding.bottom || padding);
       this.padding = {
-        top: toPixel(root, top),
-        bottom: toPixel(root, bottom)
+        top: top,
+        bottom: bottom
       };
       applyStyle(track, {
         paddingTop: unit(top),
@@ -3590,9 +3463,16 @@ var controller_floor = Math.floor;
     /**
      * Return the slide height in px.
      *
+     * @param {number} index - Slide index.
+     *
      * @return {number} - The slide height.
      */
-    slideHeight: function slideHeight() {
+    slideHeight: function slideHeight(index) {
+      if (options.autoHeight) {
+        var Slide = Elements.getSlide(index);
+        return Slide ? Slide.slide.offsetHeight : 0;
+      }
+
       var height = options.fixedHeight || (this.height + this.gap) / options.perPage - this.gap;
       return toPixel(root, height);
     },
@@ -3742,6 +3622,13 @@ function createInterval(callback, interval, progress) {
    * @type {string}
    */
   var Elements = Components.Elements;
+  /**
+   * Whether the slider is vertical or not.
+   *
+   * @type {boolean}
+   */
+
+  var isVertical = Splide.options.direction === TTB;
   /**
    * Layout component object.
    *
@@ -3754,16 +3641,29 @@ function createInterval(callback, interval, progress) {
      */
     mount: function mount() {
       bind();
-      init();
+      init(); // The word "size" means width for a horizontal slider and height for a vertical slider.
+
+      this.totalSize = isVertical ? this.totalHeight : this.totalWidth;
+      this.slideSize = isVertical ? this.slideHeight : this.slideWidth;
     },
 
     /**
-     * Destroy.
+     * Destroy the component.
      */
     destroy: function destroy() {
       removeAttribute([Elements.list, Elements.track], 'style');
+    },
+
+    /**
+     * Return the slider height on the vertical mode or width on the horizontal mode.
+     *
+     * @return {number}
+     */
+    get size() {
+      return isVertical ? this.height : this.width;
     }
-  }, Splide.options.direction === TTB ? directions_vertical(Splide, Components) : directions_horizontal(Splide, Components));
+
+  }, isVertical ? vertical(Splide, Components) : horizontal(Splide, Components));
   /**
    * Init slider styles according to options.
    */
@@ -3790,21 +3690,22 @@ function createInterval(callback, interval, progress) {
     }, Splide.options.throttle), window).on('resize', resize).on('updated refresh', init);
   }
   /**
-   * Resize the list and slides including clones.
+   * Resize the track and slide elements.
    */
 
 
   function resize() {
+    var options = Splide.options;
     applyStyle(Elements.track, {
       height: unit(Layout.height)
     });
-    var slideHeight = unit(Layout.slideHeight());
+    var slideHeight = options.autoHeight ? null : unit(Layout.slideHeight());
     Elements.each(function (Slide) {
       applyStyle(Slide.container, {
         height: slideHeight
       });
       applyStyle(Slide.slide, {
-        width: Splide.options.autoWidth ? null : unit(Layout.slideWidth(Slide.index)),
+        width: options.autoWidth ? null : unit(Layout.slideWidth(Slide.index)),
         height: Slide.container ? null : slideHeight
       });
     });
@@ -4063,7 +3964,6 @@ var FRICTION_REDUCER = 7;
     var absV = abs(velocity);
 
     if (absV > 0) {
-      var Layout = Components.Layout;
       var options = Splide.options;
       var index = Splide.index;
       var sign = velocity < 0 ? -1 : 1;
@@ -4073,7 +3973,7 @@ var FRICTION_REDUCER = 7;
         var destination = Track.position;
 
         if (absV > options.flickVelocityThreshold && abs(info.offset[axis]) < options.swipeDistanceThreshold) {
-          destination += sign * Math.min(absV * options.flickPower, Layout.width * (options.flickMaxPages || 1));
+          destination += sign * Math.min(absV * options.flickPower, Components.Layout.size * (options.flickMaxPages || 1));
         }
 
         destIndex = Track.toIndex(destination);
@@ -5681,7 +5581,7 @@ var THROTTLE = 50;
      */
     mount: function mount() {
       map = Object.keys(breakpoints).sort(function (n, m) {
-        return parseInt(n) - parseInt(m);
+        return +n - +m;
       }).map(function (point) {
         return {
           point: point,

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/js/splide.min.js


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


+ 1 - 1
package-lock.json

@@ -1,6 +1,6 @@
 {
   "name": "@splidejs/splide",
-  "version": "2.4.0",
+  "version": "2.4.1",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "@splidejs/splide",
-  "version": "2.4.0",
+  "version": "2.4.1",
   "description": "Splide is a lightweight and powerful slider without any dependencies.",
   "author": "Naotoshi Fujita",
   "license": "MIT",

+ 1 - 1
src/js/components/breakpoints/index.js

@@ -76,7 +76,7 @@ export default ( Splide ) => {
 		 */
 		mount() {
 			map = Object.keys( breakpoints )
-				.sort( ( n, m ) => parseInt( n ) - parseInt( m ) )
+				.sort( ( n, m ) => +n - +m )
 				.map( point => ( { point, mql: matchMedia( `(max-width:${ point }px)` ) } ) );
 
 			/*

+ 4 - 2
src/js/components/drag/index.js

@@ -242,7 +242,6 @@ export default ( Splide, Components ) => {
 		const absV     = abs( velocity );
 
 		if ( absV > 0 ) {
-			const Layout  = Components.Layout;
 			const options = Splide.options;
 			const index   = Splide.index;
 			const sign    = velocity < 0 ? -1 : 1;
@@ -253,7 +252,10 @@ export default ( Splide, Components ) => {
 				let destination = Track.position;
 
 				if ( absV > options.flickVelocityThreshold && abs( info.offset[ axis ] ) < options.swipeDistanceThreshold ) {
-					destination += sign * Math.min( absV * options.flickPower, Layout.width * ( options.flickMaxPages || 1 ) );
+					destination += sign * Math.min(
+						absV * options.flickPower,
+						Components.Layout.size * ( options.flickMaxPages || 1 )
+					);
 				}
 
 				destIndex = Track.toIndex( destination );

+ 19 - 10
src/js/components/elements/slide.js

@@ -5,7 +5,17 @@
  * @copyright Naotoshi Fujita. All rights reserved.
  */
 
-import { child, addClass, removeClass, hasClass, getAttribute, setAttribute, applyStyle } from '../../utils/dom';
+import {
+	child,
+	addClass,
+	removeClass,
+	hasClass,
+	getAttribute,
+	setAttribute,
+	removeAttribute,
+	applyStyle,
+	getRect,
+} from '../../utils/dom';
 import { FADE, SLIDE } from '../../constants/types';
 import { STATUS_CLASSES } from '../../constants/classes';
 import { values } from "../../utils/object";
@@ -127,6 +137,7 @@ export default ( Splide, index, realIndex, slide ) => {
 			Splide.off( STATUS_UPDATE_EVENTS ).off( STYLE_RESTORE_EVENTS ).off( 'click', slide );
 			removeClass( slide, values( STATUS_CLASSES ) );
 			restoreStyles();
+			removeAttribute( this.container, 'style' );
 		},
 
 		/**
@@ -158,16 +169,14 @@ export default ( Splide, index, realIndex, slide ) => {
 				return active;
 			}
 
-			const { floor }  = Math;
-			const Components = Splide.Components;
-			const Track      = Components.Track;
-			const Layout     = Components.Layout;
-			const isVertical = Splide.options.direction === TTB;
-			const position   = floor( ( Track.toPosition( index ) + Track.offset( index ) - Track.position ) * Track.sign );
-			const edge       = floor( position + Layout[ isVertical ? 'slideHeight' : 'slideWidth' ]( index ) );
-			const size       = Layout[ isVertical ? 'height' : 'width' ];
+			const trackRect = getRect( Splide.Components.Elements.track );
+			const slideRect = getRect( slide );
 
-			return ( 0 <= position && position <= size && 0 <= edge && edge <= size );
+			if ( Splide.options.direction === TTB ) {
+				return trackRect.top <= slideRect.top && slideRect.bottom <= trackRect.bottom;
+			}
+
+			return trackRect.left <= slideRect.left && slideRect.right <= trackRect.right;
 		},
 
 		/**

+ 6 - 15
src/js/components/layout/directions/horizontal.js

@@ -71,21 +71,12 @@ export default ( Splide, Components ) => {
 
 			this.gap = toPixel( root, options.gap );
 
-			const padding =
-				typeof options.padding === "object"
-					? { left: 0, right: 0, ...options.padding }
-					: options.padding;
-			const { left = padding, right = padding } = padding;
-
-			this.padding = {
-				left : toPixel( root, left ),
-				right: toPixel( root, right ),
-			};
-
-			applyStyle( track, {
-				paddingLeft : unit( left ),
-				paddingRight: unit( right ),
-			} );
+			const padding = options.padding;
+			const left    = toPixel( root, padding.left || padding );
+			const right   = toPixel( root, padding.right || padding );
+
+			this.padding = { left, right };
+			applyStyle( track, { paddingLeft : unit( left ), paddingRight: unit( right ) } );
 		},
 
 		/**

+ 14 - 16
src/js/components/layout/directions/vertical.js

@@ -64,21 +64,12 @@ export default ( Splide, Components ) => {
 
 			this.gap = toPixel( root, options.gap );
 
-			const padding =
-				typeof options.padding === "object"
-					? { top: 0, bottom: 0, ...options.padding }
-					: options.padding;
-			const { top = padding, bottom = padding } = padding;
-
-			this.padding = {
-				top   : toPixel( root, top ),
-				bottom: toPixel( root, bottom ),
-			};
-
-			applyStyle( track, {
-				paddingTop   : unit( top ),
-				paddingBottom: unit( bottom ),
-			} );
+			const padding = options.padding;
+			const top     = toPixel( root, padding.top || padding );
+			const bottom  = toPixel( root, padding.bottom || padding );
+
+			this.padding = { top, bottom };
+			applyStyle( track, { paddingTop : unit( top ), paddingBottom: unit( bottom ) } );
 		},
 
 		/**
@@ -110,9 +101,16 @@ export default ( Splide, Components ) => {
 		/**
 		 * Return the slide height in px.
 		 *
+		 * @param {number} index - Slide index.
+		 *
 		 * @return {number} - The slide height.
 		 */
-		slideHeight() {
+		slideHeight( index ) {
+			if ( options.autoHeight ) {
+				const Slide = Elements.getSlide( index );
+				return Slide ? Slide.slide.offsetHeight : 0;
+			}
+
 			const height = options.fixedHeight || ( this.height + this.gap ) / options.perPage - this.gap;
 			return toPixel( root, height );
 		},

+ 27 - 5
src/js/components/layout/index.js

@@ -31,6 +31,13 @@ export default ( Splide, Components ) => {
 	 */
 	const Elements = Components.Elements;
 
+	/**
+	 * Whether the slider is vertical or not.
+	 *
+	 * @type {boolean}
+	 */
+	const isVertical = Splide.options.direction === TTB;
+
 	/**
 	 * Layout component object.
 	 *
@@ -43,15 +50,28 @@ export default ( Splide, Components ) => {
 		mount() {
 			bind();
 			init();
+
+			// The word "size" means width for a horizontal slider and height for a vertical slider.
+			this.totalSize = isVertical ? this.totalHeight : this.totalWidth;
+			this.slideSize = isVertical ? this.slideHeight : this.slideWidth;
 		},
 
 		/**
-		 * Destroy.
+		 * Destroy the component.
 		 */
 		destroy() {
 			removeAttribute( [ Elements.list, Elements.track ], 'style' );
 		},
-	}, Splide.options.direction === TTB ?	Vertical( Splide, Components ) : Horizontal( Splide, Components ) );
+
+		/**
+		 * Return the slider height on the vertical mode or width on the horizontal mode.
+		 *
+		 * @return {number}
+		 */
+		get size() {
+			return isVertical ? this.height : this.width;
+		},
+	}, isVertical ?	Vertical( Splide, Components ) : Horizontal( Splide, Components ) );
 
 	/**
 	 * Init slider styles according to options.
@@ -77,18 +97,20 @@ export default ( Splide, Components ) => {
 	}
 
 	/**
-	 * Resize the list and slides including clones.
+	 * Resize the track and slide elements.
 	 */
 	function resize() {
+		const options = Splide.options;
+
 		applyStyle( Elements.track, { height: unit( Layout.height ) } );
 
-		const slideHeight = unit( Layout.slideHeight() );
+		const slideHeight = options.autoHeight ? null : unit( Layout.slideHeight() );
 
 		Elements.each( Slide => {
 			applyStyle( Slide.container, { height: slideHeight } );
 
 			applyStyle( Slide.slide, {
-				width : Splide.options.autoWidth ? null : unit( Layout.slideWidth( Slide.index ) ),
+				width : options.autoWidth ? null : unit( Layout.slideWidth( Slide.index ) ),
 				height: Slide.container ? null : slideHeight,
 			} );
 		} );

+ 0 - 90
src/js/components/track/directions/horizontal.js

@@ -1,90 +0,0 @@
-/**
- * The resolver component for horizontal move.
- *
- * @author    Naotoshi Fujita
- * @copyright Naotoshi Fujita. All rights reserved.
- */
-
-import { between } from '../../../utils/utils';
-import { RTL } from "../../../constants/directions";
-
-
-/**
- * The resolver component for horizontal move.
- *
- * @param {Splide} Splide     - A Splide instance.
- * @param {Object} Components - An object containing components.
- *
- * @return {Object} - The resolver object.
- */
-export default ( Splide, Components ) => {
-	/**
-	 * Hold the Layout component.
-	 *
-	 * @type {Object}
-	 */
-	let Layout;
-
-	return {
-		/**
-		 * Axis of translate.
-		 *
-		 * @type {string}
-		 */
-		axis: 'X',
-
-		/**
-		 * Sign for the direction.
-		 *
-		 * @type {number}
-		 */
-		sign: Splide.options.direction === RTL ? 1 : -1,
-
-		/**
-		 * Initialization.
-		 */
-		init() {
-			Layout = Components.Layout;
-		},
-
-		/**
-		 * Calculate the track position by a slide index.
-		 *
-		 * @param {number} index - Slide index.
-		 *
-		 * @return {Object} - Calculated position.
-		 */
-		toPosition( index ) {
-			const slidePosition = Layout.totalWidth( index ) - Layout.slideWidth( index ) - Layout.gap;
-			return this.sign * ( slidePosition + this.offset( index ) );
-		},
-
-		/**
-		 * Trim redundant spaces on the left or right edge if necessary.
-		 *
-		 * @param {number} position - Position value to be trimmed.
-		 *
-		 * @return {number} - Trimmed position.
-		 */
-		trim( position ) {
-			const edge = this.sign * ( Layout.totalWidth() - ( Layout.width + Layout.gap ) );
-			return between( position, edge, 0 );
-		},
-
-		/**
-		 * Return current offset value, considering direction.
-		 *
-		 * @return {number} - Offset amount.
-		 */
-		offset( index ) {
-			const { focus }  = Splide.options;
-			const slideWidth = Layout.slideWidth( index );
-
-			if ( focus === 'center' ) {
-				return - ( Layout.width - slideWidth ) / 2;
-			}
-
-			return - ( parseInt( focus ) || 0 ) * ( slideWidth + Layout.gap );
-		},
-	};
-}

+ 0 - 88
src/js/components/track/directions/vertical.js

@@ -1,88 +0,0 @@
-/**
- * The resolver component for vertical move.
- *
- * @author    Naotoshi Fujita
- * @copyright Naotoshi Fujita. All rights reserved.
- */
-
-import { between } from '../../../utils/utils';
-
-
-/**
- * The resolver component for vertical move.
- *
- * @param {Splide} Splide     - A Splide instance.
- * @param {Object} Components - An object containing components.
- *
- * @return {Object} - The resolver object.
- */
-export default ( Splide, Components ) => {
-	/**
-	 * Hold the Layout object.
-	 *
-	 * @type {Object}
-	 */
-	let Layout;
-
-	return {
-		/**
-		 * Axis of translate.
-		 *
-		 * @type {string}
-		 */
-		axis: 'Y',
-
-		/**
-		 * Sign for the direction.
-		 *
-		 * @return {number}
-		 */
-		sign: -1,
-
-		/**
-		 * Initialization.
-		 */
-		init() {
-			Layout = Components.Layout;
-		},
-
-		/**
-		 * Calculate position by index.
-		 *
-		 * @param {number} index - Slide index.
-		 *
-		 * @return {Object} - Calculated position.
-		 */
-		toPosition( index ) {
-			return - ( Layout.totalHeight( index ) - Layout.slideHeight() - Layout.gap + this.offset() );
-		},
-
-		/**
-		 * Trim redundant spaces on the left or right edge if necessary.
-		 *
-		 * @param {number} position - Position value to be trimmed.
-		 *
-		 * @return {number} - Trimmed position.
-		 */
-		trim( position ) {
-			const edge = -( Layout.totalHeight() - ( Layout.height + Layout.gap ) );
-			return between( position, edge, 0 );
-		},
-
-		/**
-		 * Return current offset value, considering direction.
-		 *
-		 * @return {number} - Offset amount.
-		 */
-		offset() {
-			const { focus }   = Splide.options;
-			const slideHeight = Layout.slideHeight();
-
-			if ( focus === 'center' ) {
-				return -( Layout.height - slideHeight ) / 2;
-			}
-
-			return -( parseInt( focus ) || 0 ) * ( slideHeight + Layout.gap );
-		},
-	};
-}  

+ 66 - 22
src/js/components/track/index.js

@@ -5,12 +5,10 @@
  * @copyright Naotoshi Fujita. All rights reserved.
  */
 
-import Vertical from './directions/vertical';
-import Horizontal from './directions/horizontal';
-import { applyStyle } from '../../utils/dom';
+import { applyStyle, getRect } from '../../utils/dom';
 import { LOOP, FADE } from '../../constants/types';
-import { TTB } from '../../constants/directions';
-import { assign } from "../../utils/object";
+import { RTL, TTB } from '../../constants/directions';
+import { between } from "../../utils/utils";
 
 
 /**
@@ -23,18 +21,25 @@ import { assign } from "../../utils/object";
  */
 export default ( Splide, Components ) => {
 	/**
-	 * Store the list element.
+	 * Hold the Layout component.
 	 *
-	 * @type {Element}
+	 * @type {Object}
 	 */
-	let list;
+	let Layout;
 
 	/**
-	 * Store the current position.
+	 * Hold the Layout component.
 	 *
-	 * @type {number}
+	 * @type {Object}
 	 */
-	let currPosition = 0;
+	let Elements;
+
+	/**
+	 * Store the list element.
+	 *
+	 * @type {Element}
+	 */
+	let list;
 
 	/**
 	 * Whether the current direction is vertical or not.
@@ -55,13 +60,21 @@ export default ( Splide, Components ) => {
 	 *
 	 * @type {Object}
 	 */
-	const Track = assign( {
+	const Track = {
+		/**
+		 * Sign for the direction. Only RTL mode uses the positive sign.
+		 *
+		 * @type {number}
+		 */
+		sign: Splide.options.direction === RTL ? 1 : -1,
+
 		/**
 		 * Called when the component is mounted.
 		 */
 		mount() {
-			list = Components.Elements.list;
-			this.init();
+			Elements = Components.Elements;
+			Layout   = Components.Layout;
+			list     = Elements.list;
 		},
 
 		/**
@@ -70,6 +83,7 @@ export default ( Splide, Components ) => {
 		 */
 		mounted() {
 			if ( ! isFade ) {
+				this.jump( 0 );
 				Splide.on( 'mounted resize updated', () => { this.jump( Splide.index ) } );
 			}
 		},
@@ -91,7 +105,7 @@ export default ( Splide, Components ) => {
 				Splide.emit( 'move', newIndex, prevIndex, destIndex );
 			}
 
-			if ( Math.abs( newPosition - currPosition ) >= 1 || isFade ) {
+			if ( Math.abs( newPosition - this.position ) >= 1 || isFade ) {
 				Components.Transition.start( destIndex, newIndex, prevIndex, this.toCoord( newPosition ), () => {
 					onTransitionEnd( destIndex, newIndex, prevIndex, silently );
 				} );
@@ -119,8 +133,7 @@ export default ( Splide, Components ) => {
 		 * @param {number} position - A new position value.
 		 */
 		translate( position ) {
-			currPosition = position;
-			applyStyle( list, { transform: `translate${ this.axis }(${ position }px)` } );
+			applyStyle( list, { transform: `translate${ isVertical ? 'Y' : 'X' }(${ position }px)` } );
 		},
 
 		/**
@@ -135,7 +148,8 @@ export default ( Splide, Components ) => {
 				return position;
 			}
 
-			return this._s.trim( position );
+			const edge = this.sign * ( Layout.totalSize() - Layout.size - Layout.gap );
+			return between( position, edge, 0 );
 		},
 
 		/**
@@ -149,7 +163,7 @@ export default ( Splide, Components ) => {
 			let index = 0;
 			let minDistance = Infinity;
 
-			Components.Elements.getSlides( true ).forEach( Slide => {
+			Elements.getSlides( true ).forEach( Slide => {
 				const slideIndex = Slide.index;
 				const distance   = Math.abs( this.toPosition( slideIndex ) - position );
 
@@ -177,14 +191,44 @@ export default ( Splide, Components ) => {
 		},
 
 		/**
-		 * Return current position.
+		 * Calculate the track position by a slide index.
+		 *
+		 * @param {number} index - Slide index.
+		 *
+		 * @return {Object} - Calculated position.
+		 */
+		toPosition( index ) {
+			const position = Layout.totalSize( index ) - Layout.slideSize( index ) - Layout.gap;
+			return this.sign * ( position + this.offset( index ) );
+		},
+
+		/**
+		 * Return current offset value, considering direction.
+		 *
+		 * @return {number} - Offset amount.
+		 */
+		offset( index ) {
+			const { focus } = Splide.options;
+			const slideSize = Layout.slideSize( index );
+
+			if ( focus === 'center' ) {
+				return -( Layout.size - slideSize ) / 2;
+			}
+
+			return -( parseInt( focus ) || 0 ) * ( slideSize + Layout.gap );
+		},
+
+		/**
+		 * Return the current position.
+		 * This returns the correct position even while transitioning by CSS.
 		 *
 		 * @return {number} - Current position.
 		 */
 		get position() {
-			return currPosition;
+			const prop = isVertical ? 'top' : 'left';
+			return getRect( list )[ prop ] - getRect( Elements.track )[ prop ] - Layout.padding[ prop ];
 		},
-	}, isVertical ? Vertical( Splide, Components ) : Horizontal( Splide, Components ) );
+	};
 
 	/**
 	 * Called whenever slides arrive at a destination.

+ 8 - 1
src/js/constants/defaults.js

@@ -83,12 +83,19 @@ export const DEFAULTS = {
 	/**
 	 * If true, slide width will be determined by the element width itself.
 	 * - perPage/perMove should be 1.
-	 * - lazyLoad should be false.
 	 *
 	 * @type {boolean}
 	 */
 	autoWidth: false,
 
+	/**
+	 * If true, slide height will be determined by the element width itself.
+	 * - perPage/perMove should be 1.
+	 *
+	 * @type {boolean}
+	 */
+	autoHeight: false,
+
 	/**
 	 * Determine how many slides should be displayed per page.
 	 *

+ 10 - 3
src/js/splide.d.ts

@@ -139,6 +139,11 @@ export interface SplideOptions extends BreakpointOptions {
 	 */
 	autoWidth?: boolean,
 
+	/**
+	 * @default false
+	 */
+	autoHeight?: boolean,
+
 	/**
 	 * @default 0
 	 */
@@ -520,16 +525,18 @@ export interface Keyboard extends Component {}
  * Layout component.
  */
 export interface Layout extends Component {
-	margin: string;
-	height: number;
-
+	readonly margin: string;
+	readonly height: number;
 	readonly width: number;
+	readonly size: number;
 
 	init(): void;
 	totalWidth( index: number | undefined ): number;
 	totalHeight( index: number | undefined ): number;
+	totalSize( index: number | undefined ): number;
 	slideWidth( index: number ): number;
 	slideHeight( index: number ): number;
+	slideSize( index: number | undefined ): number;
 }
 
 /**

+ 1 - 1
src/js/utils/utils.js

@@ -98,5 +98,5 @@ export function toPixel( root, value ) {
 		remove( div );
 	}
 
-	return value;
+	return +value || 0;
 }

+ 26 - 7
tests/functionality/autowidth.test.js

@@ -4,27 +4,45 @@ import { COMPLETE } from '../../src/js/components';
 
 
 describe( 'When the autoWidth option is true, ', () => {
-	let splide;
+	let splide, track, slides;
 	const width = 800;
 
 	beforeEach( () => {
 		document.body.innerHTML = autoWidth;
 		splide = new Splide( '#splide', { autoWidth: true }, COMPLETE );
 
-		Object.defineProperty( splide.root.querySelector( '.splide__track' ), 'clientWidth', { value: width } );
+		track  = splide.root.querySelector( '.splide__track' );
+		slides = Object.values( splide.root.querySelectorAll( '.splide__slide' ) );
 
-		let accumulatedWidth = 0;
+		Object.defineProperty( track, 'clientWidth', { value: width } );
+		track.getBoundingClientRect = jest.fn( () => ( { left: 0, right: width } ) );
 
-		splide.root.querySelectorAll( '.splide__slide' ).forEach( slide => {
+		slides.forEach( slide => {
 			const slideWidth = parseInt( slide.style.width );
 
 			Object.defineProperty( slide, 'offsetWidth', { value: slideWidth } );
 			Object.defineProperty( slide, 'clientWidth', { value: slideWidth } );
+		} );
+
+		// Move slides and a list manually because jest does not render HTML and getBoundingClientRect props are always 0.
+		splide.on( 'move', newIndex => {
+			const offset = slides.filter( ( slide, index ) => index < newIndex ).reduce( ( offset, slide ) => {
+				offset += slide.clientWidth;
+				return offset;
+			}, 0 );
+
+			let accumulatedWidth = -offset;
 
-			accumulatedWidth += slideWidth;
-			const right = accumulatedWidth;
+			slides.forEach( slide => {
+				const left = accumulatedWidth;
 
-			slide.getBoundingClientRect = jest.fn( () => ( { right } ) );
+				accumulatedWidth += slide.clientWidth;
+				const right = accumulatedWidth;
+
+				slide.getBoundingClientRect = jest.fn( () => ( { left, right } ) );
+			} );
+
+			splide.Components.Elements.list.getBoundingClientRect = jest.fn( () => ( { left: -offset } ) );
 		} );
 
 		splide.mount();
@@ -64,6 +82,7 @@ describe( 'When the autoWidth option is true, ', () => {
 		} );
 
 		splide.go( 2 );
+
 		splide.Components.Elements.list.dispatchEvent( new Event( 'transitionend' ) );
 	} );
 } );

+ 19 - 3
tests/functionality/elements.test.js → tests/functionality/slide.test.js

@@ -12,11 +12,27 @@ describe( 'The "slide" type Splide', () => {
 		document.body.innerHTML = minimum;
 		splide = new Splide( '#splide', {}, COMPLETE ).mount();
 
+		const { track, list, slides } = splide.Components.Elements;
+
 		// Set up the getBoundingClientRect.
-		splide.Components.Elements.getSlides( true ).forEach( Slide => {
-			Slide.slide.getBoundingClientRect = jest.fn( () => ( {
-				right: width * ( Slide.index + 1 + splide.Components.Clones.length  / 2 ),
+		slides.forEach( ( slide, index ) => {
+			slide.getBoundingClientRect = jest.fn( () => ( {
+				right: width * index + 1,
 			} ) );
+
+			Object.defineProperty( slide, 'offsetWidth', { value: width } );
+			Object.defineProperty( slide, 'clientWidth', { value: width } );
+		} );
+
+		track.getBoundingClientRect = jest.fn( () => ( { left: 0, right: width } ) );
+
+		splide.on( 'move', newIndex => {
+			const offset = slides.filter( ( slide, index ) => index < newIndex ).reduce( ( offset, slide ) => {
+				offset += slide.clientWidth;
+				return offset;
+			}, 0 );
+
+			list.getBoundingClientRect = jest.fn( () => ( { left: -offset } ) );
 		} );
 	} );
 

Неке датотеке нису приказане због велике количине промена