Browse Source

Bug Fix: Must reposition the slider before the Slide component checks the visibility.

NaotoshiFujita 3 years ago
parent
commit
cc25ab403c

+ 33 - 21
dist/js/splide.cjs.js

@@ -464,9 +464,12 @@ const EVENT_AUTOPLAY_PLAYING = "autoplay:playing";
 const EVENT_AUTOPLAY_PAUSE = "autoplay:pause";
 const EVENT_LAZYLOAD_LOADED = "lazyload:loaded";
 
+const DEFAULT_EVENT_PRIORITY = 10;
+const DEFAULT_USER_EVENT_PRIORITY = 20;
+
 function EventBus() {
   let handlers = {};
-  function on(events, callback, key, priority = 10) {
+  function on(events, callback, key, priority = DEFAULT_EVENT_PRIORITY) {
     forEachEvent(events, (event, namespace) => {
       handlers[event] = handlers[event] || [];
       push(handlers[event], {
@@ -788,25 +791,16 @@ function Slide$1(Splide2, index, slideIndex, slide) {
   const { resolve } = Components.Direction;
   const isClone = slideIndex > -1;
   const container = child(slide, `.${CLASS_CONTAINER}`);
+  let destroyed;
   function mount() {
     init();
     bind(slide, "click keydown", (e) => {
       emit(e.type === "click" ? EVENT_CLICK : EVENT_SLIDE_KEYDOWN, this, e);
     });
-    on(EVENT_MOUNTED, onMounted.bind(this));
-  }
-  function onMounted() {
-    const boundUpdate = update.bind(this);
-    boundUpdate();
-    on([EVENT_MOVED, EVENT_UPDATED, EVENT_RESIZED, EVENT_SCROLLED], boundUpdate);
+    on([EVENT_RESIZED, EVENT_MOVED, EVENT_UPDATED, EVENT_REFRESH, EVENT_SCROLLED], update.bind(this));
     if (updateOnMove) {
       on(EVENT_MOVE, onMove.bind(this));
     }
-  }
-  function onMove(next, prev, dest) {
-    if (dest === index) {
-      updateActivity.call(this, true);
-    }
     update.call(this);
   }
   function init() {
@@ -825,16 +819,27 @@ function Slide$1(Splide2, index, slideIndex, slide) {
     }
   }
   function destroy() {
+    destroyed = true;
     destroyEvents();
     removeClass(slide, STATUS_CLASSES);
     removeAttribute(slide, ALL_ATTRIBUTES);
   }
+  function onMove(next, prev, dest) {
+    if (!destroyed) {
+      if (dest === index) {
+        updateActivity.call(this, true);
+      }
+      update.call(this);
+    }
+  }
   function update() {
-    const { index: currIndex } = Splide2;
-    updateActivity.call(this, isActive());
-    updateVisibility.call(this, isVisible());
-    toggleClass(slide, CLASS_PREV, index === currIndex - 1);
-    toggleClass(slide, CLASS_NEXT, index === currIndex + 1);
+    if (!destroyed) {
+      const { index: currIndex } = Splide2;
+      updateActivity.call(this, isActive());
+      updateVisibility.call(this, isVisible());
+      toggleClass(slide, CLASS_PREV, index === currIndex - 1);
+      toggleClass(slide, CLASS_NEXT, index === currIndex + 1);
+    }
   }
   function updateActivity(active) {
     if (active !== hasClass(slide, CLASS_ACTIVE)) {
@@ -1221,6 +1226,9 @@ function Move(Splide2, Components2, options) {
     }
   }
   function jump(index) {
+    waiting = false;
+    looping = false;
+    Components2.Transition.cancel();
     translate(toPosition(index, true));
   }
   function translate(position) {
@@ -1327,14 +1335,18 @@ function Controller(Splide2, Components2, options) {
     init();
     Move.jump(currIndex);
     on([EVENT_UPDATED, EVENT_REFRESH], init);
-    on(EVENT_SCROLLED, () => {
-      setIndex(Move.toIndex(Move.getPosition()));
-    }, 0);
+    on(EVENT_SCROLLED, reindex, 0);
   }
   function init() {
     slideCount = getLength(true);
     perMove = options.perMove;
     perPage = options.perPage;
+    if (currIndex >= slideCount) {
+      Move.jump(currIndex = slideCount - 1);
+    }
+  }
+  function reindex() {
+    setIndex(Move.toIndex(Move.getPosition()));
   }
   function go(control, allowSameIndex) {
     const dest = parse(control);
@@ -2308,7 +2320,7 @@ const _Splide = class {
     this.Components.Controller.go(control);
   }
   on(events, callback) {
-    this.event.on(events, callback);
+    this.event.on(events, callback, null, DEFAULT_USER_EVENT_PRIORITY);
     return this;
   }
   off(events) {

+ 33 - 21
dist/js/splide.esm.js

@@ -460,9 +460,12 @@ const EVENT_AUTOPLAY_PLAYING = "autoplay:playing";
 const EVENT_AUTOPLAY_PAUSE = "autoplay:pause";
 const EVENT_LAZYLOAD_LOADED = "lazyload:loaded";
 
+const DEFAULT_EVENT_PRIORITY = 10;
+const DEFAULT_USER_EVENT_PRIORITY = 20;
+
 function EventBus() {
   let handlers = {};
-  function on(events, callback, key, priority = 10) {
+  function on(events, callback, key, priority = DEFAULT_EVENT_PRIORITY) {
     forEachEvent(events, (event, namespace) => {
       handlers[event] = handlers[event] || [];
       push(handlers[event], {
@@ -784,25 +787,16 @@ function Slide$1(Splide2, index, slideIndex, slide) {
   const { resolve } = Components.Direction;
   const isClone = slideIndex > -1;
   const container = child(slide, `.${CLASS_CONTAINER}`);
+  let destroyed;
   function mount() {
     init();
     bind(slide, "click keydown", (e) => {
       emit(e.type === "click" ? EVENT_CLICK : EVENT_SLIDE_KEYDOWN, this, e);
     });
-    on(EVENT_MOUNTED, onMounted.bind(this));
-  }
-  function onMounted() {
-    const boundUpdate = update.bind(this);
-    boundUpdate();
-    on([EVENT_MOVED, EVENT_UPDATED, EVENT_RESIZED, EVENT_SCROLLED], boundUpdate);
+    on([EVENT_RESIZED, EVENT_MOVED, EVENT_UPDATED, EVENT_REFRESH, EVENT_SCROLLED], update.bind(this));
     if (updateOnMove) {
       on(EVENT_MOVE, onMove.bind(this));
     }
-  }
-  function onMove(next, prev, dest) {
-    if (dest === index) {
-      updateActivity.call(this, true);
-    }
     update.call(this);
   }
   function init() {
@@ -821,16 +815,27 @@ function Slide$1(Splide2, index, slideIndex, slide) {
     }
   }
   function destroy() {
+    destroyed = true;
     destroyEvents();
     removeClass(slide, STATUS_CLASSES);
     removeAttribute(slide, ALL_ATTRIBUTES);
   }
+  function onMove(next, prev, dest) {
+    if (!destroyed) {
+      if (dest === index) {
+        updateActivity.call(this, true);
+      }
+      update.call(this);
+    }
+  }
   function update() {
-    const { index: currIndex } = Splide2;
-    updateActivity.call(this, isActive());
-    updateVisibility.call(this, isVisible());
-    toggleClass(slide, CLASS_PREV, index === currIndex - 1);
-    toggleClass(slide, CLASS_NEXT, index === currIndex + 1);
+    if (!destroyed) {
+      const { index: currIndex } = Splide2;
+      updateActivity.call(this, isActive());
+      updateVisibility.call(this, isVisible());
+      toggleClass(slide, CLASS_PREV, index === currIndex - 1);
+      toggleClass(slide, CLASS_NEXT, index === currIndex + 1);
+    }
   }
   function updateActivity(active) {
     if (active !== hasClass(slide, CLASS_ACTIVE)) {
@@ -1217,6 +1222,9 @@ function Move(Splide2, Components2, options) {
     }
   }
   function jump(index) {
+    waiting = false;
+    looping = false;
+    Components2.Transition.cancel();
     translate(toPosition(index, true));
   }
   function translate(position) {
@@ -1323,14 +1331,18 @@ function Controller(Splide2, Components2, options) {
     init();
     Move.jump(currIndex);
     on([EVENT_UPDATED, EVENT_REFRESH], init);
-    on(EVENT_SCROLLED, () => {
-      setIndex(Move.toIndex(Move.getPosition()));
-    }, 0);
+    on(EVENT_SCROLLED, reindex, 0);
   }
   function init() {
     slideCount = getLength(true);
     perMove = options.perMove;
     perPage = options.perPage;
+    if (currIndex >= slideCount) {
+      Move.jump(currIndex = slideCount - 1);
+    }
+  }
+  function reindex() {
+    setIndex(Move.toIndex(Move.getPosition()));
   }
   function go(control, allowSameIndex) {
     const dest = parse(control);
@@ -2304,7 +2316,7 @@ const _Splide = class {
     this.Components.Controller.go(control);
   }
   on(events, callback) {
-    this.event.on(events, callback);
+    this.event.on(events, callback, null, DEFAULT_USER_EVENT_PRIORITY);
     return this;
   }
   off(events) {

+ 49 - 25
dist/js/splide.js

@@ -517,13 +517,15 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
   var EVENT_AUTOPLAY_PLAYING = "autoplay:playing";
   var EVENT_AUTOPLAY_PAUSE = "autoplay:pause";
   var EVENT_LAZYLOAD_LOADED = "lazyload:loaded";
+  var DEFAULT_EVENT_PRIORITY = 10;
+  var DEFAULT_USER_EVENT_PRIORITY = 20;
 
   function EventBus() {
     var handlers = {};
 
     function on(events, callback, key, priority) {
       if (priority === void 0) {
-        priority = 10;
+        priority = DEFAULT_EVENT_PRIORITY;
       }
 
       forEachEvent(events, function (event, namespace) {
@@ -905,6 +907,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     var resolve = Components.Direction.resolve;
     var isClone = slideIndex > -1;
     var container = child(slide, "." + CLASS_CONTAINER);
+    var destroyed;
 
     function mount() {
       var _this2 = this;
@@ -913,12 +916,13 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       bind(slide, "click keydown", function (e) {
         emit(e.type === "click" ? EVENT_CLICK : EVENT_SLIDE_KEYDOWN, _this2, e);
       });
-      on([EVENT_MOUNTED, EVENT_MOVED, EVENT_UPDATED, EVENT_SCROLLED], update.bind(this));
-      on(EVENT_RESIZED, onResized.bind(this));
+      on([EVENT_RESIZED, EVENT_MOVED, EVENT_UPDATED, EVENT_REFRESH, EVENT_SCROLLED], update.bind(this));
 
       if (updateOnMove) {
         on(EVENT_MOVE, onMove.bind(this));
       }
+
+      update.call(this);
     }
 
     function init() {
@@ -942,31 +946,30 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function destroy() {
+      destroyed = true;
       destroyEvents();
       removeClass(slide, STATUS_CLASSES);
       removeAttribute(slide, ALL_ATTRIBUTES);
     }
 
-    function onResized() {
-      if (!Splide2.state.is(CREATED)) {
-        update.call(this);
-      }
-    }
-
     function onMove(next, prev, dest) {
-      if (dest === index) {
-        updateActivity.call(this, true);
-      }
+      if (!destroyed) {
+        if (dest === index) {
+          updateActivity.call(this, true);
+        }
 
-      update.call(this);
+        update.call(this);
+      }
     }
 
     function update() {
-      var currIndex = Splide2.index;
-      updateActivity.call(this, isActive());
-      updateVisibility.call(this, isVisible());
-      toggleClass(slide, CLASS_PREV, index === currIndex - 1);
-      toggleClass(slide, CLASS_NEXT, index === currIndex + 1);
+      if (!destroyed) {
+        var currIndex = Splide2.index;
+        updateActivity.call(this, isActive());
+        updateVisibility.call(this, isVisible());
+        toggleClass(slide, CLASS_PREV, index === currIndex - 1);
+        toggleClass(slide, CLASS_NEXT, index === currIndex + 1);
+      }
     }
 
     function updateActivity(active) {
@@ -1009,7 +1012,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       var slideRect = rect(slide);
       var left = resolve("left");
       var right = resolve("right");
-      return floor(trackRect[left]) <= slideRect[left] && slideRect[right] <= ceil(trackRect[right]);
+      return floor(trackRect[left]) <= ceil(slideRect[left]) && floor(slideRect[right]) <= ceil(trackRect[right]);
     }
 
     function isWithin(from, distance) {
@@ -1399,6 +1402,8 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     };
   }
 
+  var SNAP_THRESHOLD = 10;
+
   function Move(Splide2, Components2, options) {
     var _EventInterface6 = EventInterface(Splide2),
         on = _EventInterface6.on,
@@ -1422,7 +1427,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     var positionRate = 0;
 
     function mount() {
-      on([EVENT_RESIZE, EVENT_UPDATED, EVENT_REFRESH], reposition);
+      on([EVENT_RESIZE, EVENT_RESIZED, EVENT_UPDATED, EVENT_REFRESH], reposition, DEFAULT_EVENT_PRIORITY - 1);
     }
 
     function reposition() {
@@ -1435,10 +1440,21 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
 
         if (isExceededMax(currPosition)) {
           translate(getLimit(true));
+        } else {
+          snap(SNAP_THRESHOLD);
         }
       }
     }
 
+    function snap(threshold) {
+      var position = getPosition();
+      var index = toIndex(position);
+
+      if (abs(position - toPosition(index)) < threshold) {
+        jump(index);
+      }
+    }
+
     function move(dest, index, prev) {
       if (!isBusy()) {
         var position = getPosition();
@@ -1455,7 +1471,6 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     function onMoved(dest, index, prev, oldPosition) {
       if (looping) {
         jump(index);
-        looping = false;
       }
 
       waiting = false;
@@ -1468,6 +1483,9 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     }
 
     function jump(index) {
+      waiting = false;
+      looping = false;
+      Components2.Transition.cancel();
       translate(toPosition(index, true));
     }
 
@@ -1601,15 +1619,21 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
       init();
       Move.jump(currIndex);
       on([EVENT_UPDATED, EVENT_REFRESH], init);
-      on(EVENT_SCROLLED, function () {
-        setIndex(Move.toIndex(Move.getPosition()));
-      }, 0);
+      on(EVENT_SCROLLED, reindex, 0);
     }
 
     function init() {
       slideCount = getLength(true);
       perMove = options.perMove;
       perPage = options.perPage;
+
+      if (currIndex >= slideCount) {
+        Move.jump(currIndex = slideCount - 1);
+      }
+    }
+
+    function reindex() {
+      setIndex(Move.toIndex(Move.getPosition()));
     }
 
     function go(control, allowSameIndex) {
@@ -2844,7 +2868,7 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
     };
 
     _proto.on = function on(events, callback) {
-      this.event.on(events, callback);
+      this.event.on(events, callback, null, DEFAULT_USER_EVENT_PRIORITY);
       return this;
     };
 

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


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


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


+ 1 - 1
dist/types/components/Controller/Controller.d.ts.map

@@ -1 +1 @@
-{"version":3,"file":"Controller.d.ts","sourceRoot":"","sources":["Controller.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAIjE;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,EAAE,CAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,GAAI,IAAI,CAAC;IAC/D,OAAO,CAAE,WAAW,CAAC,EAAE,OAAO,GAAI,MAAM,CAAC;IACzC,OAAO,CAAE,WAAW,CAAC,EAAE,OAAO,GAAI,MAAM,CAAC;IACzC,MAAM,IAAI,MAAM,CAAC;IACjB,QAAQ,CAAE,KAAK,EAAE,MAAM,GAAI,IAAI,CAAC;IAChC,QAAQ,CAAE,IAAI,CAAC,EAAE,OAAO,GAAI,MAAM,CAAC;IACnC,OAAO,CAAE,IAAI,EAAE,MAAM,GAAI,MAAM,CAAC;IAChC,MAAM,CAAE,KAAK,EAAE,MAAM,GAAI,MAAM,CAAC;IAChC,QAAQ,IAAI,OAAO,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAI,mBAAmB,CA+R1G"}
+{"version":3,"file":"Controller.d.ts","sourceRoot":"","sources":["Controller.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAIjE;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,EAAE,CAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,GAAI,IAAI,CAAC;IAC/D,OAAO,CAAE,WAAW,CAAC,EAAE,OAAO,GAAI,MAAM,CAAC;IACzC,OAAO,CAAE,WAAW,CAAC,EAAE,OAAO,GAAI,MAAM,CAAC;IACzC,MAAM,IAAI,MAAM,CAAC;IACjB,QAAQ,CAAE,KAAK,EAAE,MAAM,GAAI,IAAI,CAAC;IAChC,QAAQ,CAAE,IAAI,CAAC,EAAE,OAAO,GAAI,MAAM,CAAC;IACnC,OAAO,CAAE,IAAI,EAAE,MAAM,GAAI,MAAM,CAAC;IAChC,MAAM,CAAE,KAAK,EAAE,MAAM,GAAI,MAAM,CAAC;IAChC,QAAQ,IAAI,OAAO,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAI,mBAAmB,CAuS1G"}

+ 1 - 1
dist/types/components/Move/Move.d.ts.map

@@ -1 +1 @@
-{"version":3,"file":"Move.d.ts","sourceRoot":"","sources":["Move.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAIjE;;;;GAIG;AACH,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,IAAI,CAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAI,IAAI,CAAC;IACxD,IAAI,CAAE,KAAK,EAAE,MAAM,GAAI,IAAI,CAAC;IAC5B,SAAS,CAAE,QAAQ,EAAE,MAAM,GAAI,IAAI,CAAC;IACpC,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,CAAE,QAAQ,EAAE,MAAM,GAAI,MAAM,CAAC;IACpC,UAAU,CAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAI,MAAM,CAAC;IACxD,WAAW,IAAI,MAAM,CAAC;IACtB,QAAQ,CAAE,GAAG,EAAE,OAAO,GAAI,MAAM,CAAC;IACjC,MAAM,IAAI,OAAO,CAAC;IAClB,UAAU,IAAI,OAAO,CAAC;IACtB,aAAa,CAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAI,OAAO,CAAC;IAC5D,aAAa,CAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAI,OAAO,CAAC;CAC7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAI,aAAa,CAqS9F"}
+{"version":3,"file":"Move.d.ts","sourceRoot":"","sources":["Move.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAIjE;;;;GAIG;AACH,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,IAAI,CAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAI,IAAI,CAAC;IACxD,IAAI,CAAE,KAAK,EAAE,MAAM,GAAI,IAAI,CAAC;IAC5B,SAAS,CAAE,QAAQ,EAAE,MAAM,GAAI,IAAI,CAAC;IACpC,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,CAAE,QAAQ,EAAE,MAAM,GAAI,MAAM,CAAC;IACpC,UAAU,CAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAI,MAAM,CAAC;IACxD,WAAW,IAAI,MAAM,CAAC;IACtB,QAAQ,CAAE,GAAG,EAAE,OAAO,GAAI,MAAM,CAAC;IACjC,MAAM,IAAI,OAAO,CAAC;IAClB,UAAU,IAAI,OAAO,CAAC;IACtB,aAAa,CAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAI,OAAO,CAAC;IAC5D,aAAa,CAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAI,OAAO,CAAC;CAC7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAI,aAAa,CAwS9F"}

+ 1 - 1
dist/types/components/Slides/Slide.d.ts.map

@@ -1 +1 @@
-{"version":3,"file":"Slide.d.ts","sourceRoot":"","sources":["Slide.ts"],"names":[],"mappings":"AAiCA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAmB5C;;;;GAIG;AACH,MAAM,WAAY,cAAe,SAAQ,aAAa;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,WAAW,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAI,IAAI,CAAA;IAC1E,QAAQ,CAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAI,OAAO,CAAC;CACrD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAI,cAAc,CAkM7G"}
+{"version":3,"file":"Slide.d.ts","sourceRoot":"","sources":["Slide.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAmB5C;;;;GAIG;AACH,MAAM,WAAY,cAAe,SAAQ,aAAa;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,WAAW,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAI,IAAI,CAAA;IAC1E,QAAQ,CAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAI,OAAO,CAAC;CACrD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAI,cAAc,CAoM7G"}

+ 13 - 0
dist/types/constants/priority.d.ts

@@ -0,0 +1,13 @@
+/**
+ * The default priority for internal handlers.
+ *
+ * @since 3.0.0
+ */
+export declare const DEFAULT_EVENT_PRIORITY = 10;
+/**
+ * The default priority for users' handlers.
+ *
+ * @since 3.0.0
+ */
+export declare const DEFAULT_USER_EVENT_PRIORITY = 20;
+//# sourceMappingURL=../../../src/js/constants/priority.d.ts.map

+ 1 - 0
dist/types/constants/priority.d.ts.map

@@ -0,0 +1 @@
+{"version":3,"file":"priority.d.ts","sourceRoot":"","sources":["priority.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC"}

+ 1 - 1
dist/types/constructors/EventBus/EventBus.d.ts.map

@@ -1 +1 @@
-{"version":3,"file":"EventBus.d.ts","sourceRoot":"","sources":["EventBus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI1C;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAI,IAAI,CAAC;IACnG,GAAG,CAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,GAAI,IAAI,CAAC;IACrD,KAAK,CAAE,GAAG,EAAE,MAAM,GAAI,IAAI,CAAC;IAC3B,IAAI,CAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAI,IAAI,CAAC;IAC5C,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,WAAW,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,oBAAY,gBAAgB,GAAG,WAAW,CAAC;AAE3C;;;;;;GAMG;AACH,wBAAgB,QAAQ,IAAI,cAAc,CAkGzC"}
+{"version":3,"file":"EventBus.d.ts","sourceRoot":"","sources":["EventBus.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI1C;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAI,IAAI,CAAC;IACnG,GAAG,CAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,GAAI,IAAI,CAAC;IACrD,KAAK,CAAE,GAAG,EAAE,MAAM,GAAI,IAAI,CAAC;IAC3B,IAAI,CAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAI,IAAI,CAAC;IAC5C,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,WAAW,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,oBAAY,gBAAgB,GAAG,WAAW,CAAC;AAE3C;;;;;;GAMG;AACH,wBAAgB,QAAQ,IAAI,cAAc,CAuGzC"}

+ 1 - 1
dist/types/core/Splide/Splide.d.ts.map

@@ -1 +1 @@
-{"version":3,"file":"Splide.d.ts","sourceRoot":"","sources":["Splide.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAM9D,OAAO,EAAY,gBAAgB,EAAE,cAAc,EAAS,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEpG,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAIxE;;;;GAIG;AACH,qBAAa,MAAM;IACjB;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAM;IAE9B;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,MAAM;;;;;;MAAU;IAEhC;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAE3B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAc;IAE5C;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAoB;IAEnD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAoB;IAE/C;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAM;IAEhC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IAExC;;OAEG;IACH,OAAO,CAAC,WAAW,CAA4C;IAE/D;;OAEG;IACH,OAAO,CAAC,WAAW,CAAuB;IAE1C;;;;;OAKG;gBACU,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO;IAU5D;;;;;;;OAOG;IACH,KAAK,CAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAAE,UAAU,CAAC,EAAE,oBAAoB,GAAI,IAAI;IAiCnG;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAI,CAAE,MAAM,EAAE,MAAM,GAAI,IAAI;IAM5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,EAAE,CAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAI,IAAI;IAIpC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,EAAE,CAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAI,IAAI;IAKtD;;;;;;;;;;;;;;;;;;OAkBG;IACH,GAAG,CAAE,MAAM,EAAE,MAAM,GAAI,IAAI;IAK3B;;;;;;;OAOG;IACH,IAAI,CAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAI,IAAI;IAK3C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,GAAG,CAAE,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAI,IAAI;IAKvF;;;;;OAKG;IACH,MAAM,CAAE,OAAO,EAAE,YAAY,GAAI,IAAI;IAKrC;;;;;;OAMG;IACH,EAAE,CAAE,IAAI,EAAE,MAAM,GAAI,OAAO;IAI3B;;;;OAIG;IACH,OAAO,IAAI,IAAI;IAKf;;;;;;OAMG;IACH,OAAO,CAAE,UAAU,CAAC,EAAE,OAAO,GAAI,IAAI;IAoBrC;;;;OAIG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;OAIG;IACH,IAAI,OAAO,CAAE,OAAO,EAAE,OAAO,EAO5B;IAED;;;;OAIG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;;OAIG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;CACF"}
+{"version":3,"file":"Splide.d.ts","sourceRoot":"","sources":["Splide.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAO9D,OAAO,EAAY,gBAAgB,EAAE,cAAc,EAAS,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEpG,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAIxE;;;;GAIG;AACH,qBAAa,MAAM;IACjB;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAM;IAE9B;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,MAAM;;;;;;MAAU;IAEhC;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAE3B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAc;IAE5C;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAoB;IAEnD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAoB;IAE/C;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAM;IAEhC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IAExC;;OAEG;IACH,OAAO,CAAC,WAAW,CAA4C;IAE/D;;OAEG;IACH,OAAO,CAAC,WAAW,CAAuB;IAE1C;;;;;OAKG;gBACU,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO;IAU5D;;;;;;;OAOG;IACH,KAAK,CAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAAE,UAAU,CAAC,EAAE,oBAAoB,GAAI,IAAI;IAkCnG;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAI,CAAE,MAAM,EAAE,MAAM,GAAI,IAAI;IAM5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,EAAE,CAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAI,IAAI;IAIpC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,EAAE,CAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAI,IAAI;IAKtD;;;;;;;;;;;;;;;;;;OAkBG;IACH,GAAG,CAAE,MAAM,EAAE,MAAM,GAAI,IAAI;IAK3B;;;;;;;OAOG;IACH,IAAI,CAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAI,IAAI;IAK3C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,GAAG,CAAE,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAI,IAAI;IAKvF;;;;;OAKG;IACH,MAAM,CAAE,OAAO,EAAE,YAAY,GAAI,IAAI;IAKrC;;;;;;OAMG;IACH,EAAE,CAAE,IAAI,EAAE,MAAM,GAAI,OAAO;IAI3B;;;;OAIG;IACH,OAAO,IAAI,IAAI;IAKf;;;;;;OAMG;IACH,OAAO,CAAE,UAAU,CAAC,EAAE,OAAO,GAAI,IAAI;IAoBrC;;;;OAIG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;OAIG;IACH,IAAI,OAAO,CAAE,OAAO,EAAE,OAAO,EAO5B;IAED;;;;OAIG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;;OAIG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;CACF"}

+ 14 - 6
src/js/components/Controller/Controller.ts

@@ -71,21 +71,29 @@ export function Controller( Splide: Splide, Components: Components, options: Opt
   function mount(): void {
     init();
     Move.jump( currIndex );
-
     on( [ EVENT_UPDATED, EVENT_REFRESH ], init );
-
-    on( EVENT_SCROLLED, () => {
-      setIndex( Move.toIndex( Move.getPosition() ) );
-    }, 0 );
+    on( EVENT_SCROLLED, reindex, 0 );
   }
 
   /**
-   * Initializes the component.
+   * Initializes some parameters.
+   * Needs to check the slides length since the current index may be out of the range after refresh.
    */
   function init(): void {
     slideCount = getLength( true );
     perMove    = options.perMove;
     perPage    = options.perPage;
+
+    if ( currIndex >= slideCount ) {
+      Move.jump( ( currIndex = slideCount - 1 ) );
+    }
+  }
+
+  /**
+   * Calculates the index by the current position and updates the current index.
+   */
+  function reindex(): void {
+    setIndex( Move.toIndex( Move.getPosition() ) );
   }
 
   /**

+ 31 - 3
src/js/components/Move/Move.ts

@@ -1,10 +1,19 @@
-import { EVENT_MOVE, EVENT_MOVED, EVENT_REFRESH, EVENT_RESIZE, EVENT_UPDATED } from '../../constants/events';
+import {
+  EVENT_MOVE,
+  EVENT_MOVED,
+  EVENT_REFRESH,
+  EVENT_RESIZE,
+  EVENT_RESIZED,
+  EVENT_UPDATED,
+} from '../../constants/events';
+import { DEFAULT_EVENT_PRIORITY } from '../../constants/priority';
 import { IDLE, MOVING } from '../../constants/states';
 import { LOOP, SLIDE } from '../../constants/types';
 import { EventInterface } from '../../constructors';
 import { Splide } from '../../core/Splide/Splide';
 import { BaseComponent, Components, Options } from '../../types';
 import { abs, clamp, rect } from '../../utils';
+import { SNAP_THRESHOLD } from './constants';
 
 
 /**
@@ -68,11 +77,12 @@ export function Move( Splide: Splide, Components: Components, options: Options )
    * Called when the component is mounted.
    */
   function mount(): void {
-    on( [ EVENT_RESIZE, EVENT_UPDATED, EVENT_REFRESH ], reposition );
+    on( [ EVENT_RESIZE, EVENT_RESIZED, EVENT_UPDATED, EVENT_REFRESH ], reposition, DEFAULT_EVENT_PRIORITY - 1 );
   }
 
   /**
    * Repositions the slider.
+   * This must be called before the Slide component checks the visibility.
    */
   function reposition(): void {
     if ( options.drag !== 'free' ) {
@@ -84,10 +94,26 @@ export function Move( Splide: Splide, Components: Components, options: Options )
 
       if ( isExceededMax( currPosition ) ) {
         translate( getLimit( true ) );
+      } else {
+        snap( SNAP_THRESHOLD );
       }
     }
   }
 
+  /**
+   * Snaps the slider position to the closest slide if the difference between them is less than the threshold.
+   *
+   * @param threshold - The threshold value.
+   */
+  function snap( threshold: number ): void {
+    const position = getPosition();
+    const index    = toIndex( position );
+
+    if ( abs( position - toPosition( index ) ) < threshold ) {
+      jump( index );
+    }
+  }
+
   /**
    * Goes to the slide at the specified index with the Transition component.
    *
@@ -122,7 +148,6 @@ export function Move( Splide: Splide, Components: Components, options: Options )
   function onMoved( dest: number, index: number, prev: number, oldPosition: number ) {
     if ( looping ) {
       jump( index );
-      looping = false;
     }
 
     waiting = false;
@@ -140,6 +165,9 @@ export function Move( Splide: Splide, Components: Components, options: Options )
    * @param index - An index to jump to.
    */
   function jump( index: number ): void {
+    waiting = false;
+    looping = false;
+    Components.Transition.cancel();
     translate( toPosition( index, true ) );
   }
 

+ 6 - 0
src/js/components/Move/constants.ts

@@ -0,0 +1,6 @@
+/**
+ * The threshold for snapping the slider to the closest slide.
+ *
+ * @since 3.0.0
+ */
+export const SNAP_THRESHOLD = 10;

+ 25 - 25
src/js/components/Slides/Slide.ts

@@ -20,16 +20,15 @@ import {
   EVENT_CLICK,
   EVENT_HIDDEN,
   EVENT_INACTIVE,
-  EVENT_MOUNTED,
   EVENT_MOVE,
   EVENT_MOVED,
+  EVENT_REFRESH,
   EVENT_RESIZED,
   EVENT_SCROLLED,
   EVENT_SLIDE_KEYDOWN,
   EVENT_UPDATED,
   EVENT_VISIBLE,
 } from '../../constants/events';
-import { CREATED } from '../../constants/states';
 import { FADE, SLIDE } from '../../constants/types';
 import { EventInterface } from '../../constructors';
 import { Splide } from '../../core/Splide/Splide';
@@ -87,6 +86,11 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
   const isClone   = slideIndex > -1;
   const container = child( slide, `.${ CLASS_CONTAINER }` );
 
+  /**
+   * Turns into `true` when the component is destroyed.
+   */
+  let destroyed: boolean;
+
   /**
    * Called when the component is mounted.
    */
@@ -97,12 +101,13 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
       emit( e.type === 'click' ? EVENT_CLICK : EVENT_SLIDE_KEYDOWN, this, e );
     } );
 
-    on( [ EVENT_MOUNTED, EVENT_MOVED, EVENT_UPDATED, EVENT_SCROLLED ], update.bind( this ) );
-    on( EVENT_RESIZED, onResized.bind( this ) );
+    on( [ EVENT_RESIZED, EVENT_MOVED, EVENT_UPDATED, EVENT_REFRESH, EVENT_SCROLLED ], update.bind( this ) );
 
     if ( updateOnMove ) {
       on( EVENT_MOVE, onMove.bind( this ) );
     }
+
+    update.call( this );
   }
 
   /**
@@ -131,22 +136,12 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
    * Destroys the component.
    */
   function destroy(): void {
+    destroyed = true;
     destroyEvents();
     removeClass( slide, STATUS_CLASSES );
     removeAttribute( slide, ALL_ATTRIBUTES );
   }
 
-  /**
-   * Called when the Layout component resizes the slider.
-   * Needs to check the `created` state because this is also called on initialization of the component,
-   * and it's too early to notify others of the active slide.
-   */
-  function onResized( this: SlideComponent ): void {
-    if ( ! Splide.state.is( CREATED ) ) {
-      update.call( this );
-    }
-  }
-
   /**
    * If the `updateOnMove` option is `true`, called when the slider starts moving.
    *
@@ -155,24 +150,28 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
    * @param dest - A destination index.
    */
   function onMove( this: SlideComponent, next: number, prev: number, dest: number ): void {
-    if ( dest === index ) {
-      updateActivity.call( this, true );
-    }
+    if ( ! destroyed ) {
+      if ( dest === index ) {
+        updateActivity.call( this, true );
+      }
 
-    update.call( this );
+      update.call( this );
+    }
   }
 
   /**
    * Updates attribute and classes of the slide.
    */
   function update( this: SlideComponent ): void {
-    const { index: currIndex } = Splide;
+    if ( ! destroyed ) {
+      const { index: currIndex } = Splide;
 
-    updateActivity.call( this, isActive() );
-    updateVisibility.call( this, isVisible() );
+      updateActivity.call( this, isActive() );
+      updateVisibility.call( this, isVisible() );
 
-    toggleClass( slide, CLASS_PREV, index === currIndex - 1 );
-    toggleClass( slide, CLASS_NEXT, index === currIndex + 1 );
+      toggleClass( slide, CLASS_PREV, index === currIndex - 1 );
+      toggleClass( slide, CLASS_NEXT, index === currIndex + 1 );
+    }
   }
 
   /**
@@ -242,7 +241,8 @@ export function Slide( Splide: Splide, index: number, slideIndex: number, slide:
     const left      = resolve( 'left' );
     const right     = resolve( 'right' );
 
-    return floor( trackRect[ left ] ) <= slideRect[ left ] && slideRect[ right ] <= ceil( trackRect[ right ] );
+    return floor( trackRect[ left ] ) <= ceil( slideRect[ left ] )
+      && floor( slideRect[ right ] ) <= ceil( trackRect[ right ] );
   }
 
   /**

+ 1 - 1
src/js/components/Slides/test/slide.test.ts

@@ -243,7 +243,7 @@ describe( 'Slide', () => {
 
     const component = ( Splide: Splide ) => {
       return {
-        mount() {
+        setup() {
           Splide.on( EVENT_ACTIVE, Slide => {
             expect( Slide.index ).toBe( 1 );
             callback();

+ 13 - 0
src/js/constants/priority.ts

@@ -0,0 +1,13 @@
+/**
+ * The default priority for internal handlers.
+ *
+ * @since 3.0.0
+ */
+export const DEFAULT_EVENT_PRIORITY = 10;
+
+/**
+ * The default priority for users' handlers.
+ *
+ * @since 3.0.0
+ */
+export const DEFAULT_USER_EVENT_PRIORITY = 20;

+ 7 - 1
src/js/constructors/EventBus/EventBus.ts

@@ -1,3 +1,4 @@
+import { DEFAULT_EVENT_PRIORITY } from '../../constants/priority';
 import { AnyFunction } from '../../types';
 import { forOwn, push, slice, toArray } from '../../utils';
 
@@ -57,7 +58,12 @@ export function EventBus(): EventBusObject {
    * @param priority - Optional. A priority number for the order in which the callbacks are invoked.
    *                   Lower numbers correspond with earlier execution. The default value is 10.
    */
-  function on( events: string | string[], callback: EventBusCallback, key?: object, priority = 10 ): void {
+  function on(
+    events: string | string[],
+    callback: EventBusCallback,
+    key?: object,
+    priority = DEFAULT_EVENT_PRIORITY
+  ): void {
     forEachEvent( events, ( event, namespace ) => {
       handlers[ event ] = handlers[ event ] || [];
 

+ 3 - 1
src/js/core/Splide/Splide.ts

@@ -3,6 +3,7 @@ import { SlideMatcher } from '../../components/Slides/Slides';
 import { CLASS_INITIALIZED } from '../../constants/classes';
 import { DEFAULTS } from '../../constants/defaults';
 import { EVENT_DESTROY, EVENT_MOUNTED, EVENT_READY, EVENT_REFRESH, EVENT_UPDATED } from '../../constants/events';
+import { DEFAULT_USER_EVENT_PRIORITY } from '../../constants/priority';
 import { CREATED, DESTROYED, IDLE, STATES } from '../../constants/states';
 import { FADE } from '../../constants/types';
 import { EventBus, EventBusCallback, EventBusObject, State, StateObject } from '../../constructors';
@@ -110,6 +111,7 @@ export class Splide {
       component.mount && component.mount();
     } );
 
+    // todo unnecessary anymore
     forOwn( Components, component => {
       component.mounted && component.mounted();
     } );
@@ -209,7 +211,7 @@ export class Splide {
    * @return `this`
    */
   on( events: string, callback: EventBusCallback ): this {
-    this.event.on( events, callback );
+    this.event.on( events, callback, null, DEFAULT_USER_EVENT_PRIORITY );
     return this;
   }
 

+ 3 - 2
src/js/test/php/examples/default.php

@@ -14,14 +14,15 @@ $settings = get_settings();
 
   <link rel="stylesheet" href="../../../../../dist/css/themes/splide-<?php echo $settings['theme'] ?>.min.css">
   <link rel="stylesheet" href="../../assets/css/styles.css">
-  <script type="text/javascript" src="../../../../../dist/js/splide.min.js"></script>
+  <script type="text/javascript" src="../../../../../dist/js/splide.js"></script>
 
   <script>
     document.addEventListener( 'DOMContentLoaded', function () {
       var splide = new Splide( '#splide01', {
-        perPage: 2,
+        perPage: 1,
         gap    : '1rem',
         drag   : 'free',
+        // speed  : 0,
       } );
 
       splide.on( 'moved', () => {

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

@@ -115,7 +115,7 @@ export function parseTransform( elm: HTMLElement ): { left: number, top: number
   const rule     = findRuleBy( elm );
   const position = { left: 0, top: 0 };
 
-  if ( rule ) {
+  if ( rule && rule.style.transform ) {
     const { transform } = rule.style;
 
     if ( transform.includes( 'translateX' ) ) {

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