@gem-sdk/swiper 0.0.14 → 0.0.15-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -382,9 +382,6 @@ function updateSize() {
382
382
 
383
383
  function updateSlides() {
384
384
  const swiper = this;
385
- function getDirectionPropertyValue(node, label) {
386
- return parseFloat(node.getPropertyValue(swiper.getDirectionLabel(label)) || 0);
387
- }
388
385
  const params = swiper.params;
389
386
  const {
390
387
  wrapperEl,
@@ -393,10 +390,8 @@ function updateSlides() {
393
390
  rtlTranslate: rtl,
394
391
  wrongRTL
395
392
  } = swiper;
396
- const isVirtual = swiper.virtual && params.virtual.enabled;
397
- const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
398
393
  const slides = elementChildren(slidesEl, `.${swiper.params.slideClass}, swiper-slide`);
399
- const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
394
+ const slidesLength = slides.length;
400
395
  let snapGrid = [];
401
396
  const slidesGrid = [];
402
397
  const slidesSizesGrid = [];
@@ -414,15 +409,15 @@ function updateSlides() {
414
409
  let slidePosition = -offsetBefore;
415
410
  let prevSlideSize = 0;
416
411
  let index = 0;
417
- if (typeof swiperSize === 'undefined') {
418
- return;
419
- }
412
+ if (typeof swiperSize === 'undefined') return;
420
413
  if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
421
414
  spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
422
415
  } else if (typeof spaceBetween === 'string') {
423
416
  spaceBetween = parseFloat(spaceBetween);
424
417
  }
425
- swiper.virtualSize = -spaceBetween;
418
+
419
+ // core-lite: compute total slides size without optional modules
420
+ swiper.slidesTotalSize = -spaceBetween;
426
421
 
427
422
  // reset margins
428
423
  slides.forEach(slideEl => {
@@ -440,49 +435,34 @@ function updateSlides() {
440
435
  setCSSProperty(wrapperEl, '--swiper-centered-offset-before', '');
441
436
  setCSSProperty(wrapperEl, '--swiper-centered-offset-after', '');
442
437
  }
443
- const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
444
- if (gridEnabled) {
445
- swiper.grid.initSlides(slides);
446
- } else if (swiper.grid) {
447
- swiper.grid.unsetSlides();
448
- }
449
438
 
450
439
  // Calc slides
451
440
  let slideSize;
452
- const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => {
453
- return typeof params.breakpoints[key].slidesPerView !== 'undefined';
454
- }).length > 0;
441
+ const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params.breakpoints).filter(key => typeof params.breakpoints[key].slidesPerView !== 'undefined').length > 0;
455
442
  for (let i = 0; i < slidesLength; i += 1) {
456
443
  slideSize = 0;
457
444
  let slide;
458
445
  if (slides[i]) slide = slides[i];
459
- if (gridEnabled) {
460
- swiper.grid.updateSlide(i, slide, slides);
461
- }
462
446
  if (slides[i] && elementStyle(slide, 'display') === 'none') continue; // eslint-disable-line
463
447
 
464
448
  if (params.slidesPerView === 'auto') {
465
- if (shouldResetSlideSize) {
449
+ if (shouldResetSlideSize && slides[i]) {
466
450
  slides[i].style[swiper.getDirectionLabel('width')] = ``;
467
451
  }
468
452
  const slideStyles = getComputedStyle(slide);
469
453
  const currentTransform = slide.style.transform;
470
454
  const currentWebKitTransform = slide.style.webkitTransform;
471
- if (currentTransform) {
472
- slide.style.transform = 'none';
473
- }
474
- if (currentWebKitTransform) {
475
- slide.style.webkitTransform = 'none';
476
- }
455
+ if (currentTransform) slide.style.transform = 'none';
456
+ if (currentWebKitTransform) slide.style.webkitTransform = 'none';
477
457
  if (params.roundLengths) {
478
458
  slideSize = swiper.isHorizontal() ? elementOuterSize(slide, 'width', true) : elementOuterSize(slide, 'height', true);
479
459
  } else {
480
460
  // eslint-disable-next-line
481
- const width = getDirectionPropertyValue(slideStyles, 'width');
482
- const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
483
- const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
484
- const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
485
- const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
461
+ const width = parseFloat(slideStyles.getPropertyValue('width')) || slide.offsetWidth;
462
+ const paddingLeft = parseFloat(slideStyles.getPropertyValue('padding-left')) || 0;
463
+ const paddingRight = parseFloat(slideStyles.getPropertyValue('padding-right')) || 0;
464
+ const marginLeft = parseFloat(slideStyles.getPropertyValue('margin-left')) || 0;
465
+ const marginRight = parseFloat(slideStyles.getPropertyValue('margin-right')) || 0;
486
466
  const boxSizing = slideStyles.getPropertyValue('box-sizing');
487
467
  if (boxSizing && boxSizing === 'border-box') {
488
468
  slideSize = width + marginLeft + marginRight;
@@ -494,12 +474,8 @@ function updateSlides() {
494
474
  slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight + (offsetWidth - clientWidth);
495
475
  }
496
476
  }
497
- if (currentTransform) {
498
- slide.style.transform = currentTransform;
499
- }
500
- if (currentWebKitTransform) {
501
- slide.style.webkitTransform = currentWebKitTransform;
502
- }
477
+ if (currentTransform) slide.style.transform = currentTransform;
478
+ if (currentWebKitTransform) slide.style.webkitTransform = currentWebKitTransform;
503
479
  if (params.roundLengths) slideSize = Math.floor(slideSize);
504
480
  } else {
505
481
  slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
@@ -508,13 +484,13 @@ function updateSlides() {
508
484
  slides[i].style[swiper.getDirectionLabel('width')] = `${slideSize}px`;
509
485
  }
510
486
  }
511
- if (slides[i]) {
512
- slides[i].swiperSlideSize = slideSize;
513
- }
487
+ if (slides[i]) slides[i].swiperSlideSize = slideSize;
514
488
  slidesSizesGrid.push(slideSize);
515
489
  if (params.centeredSlides) {
516
490
  slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
517
- if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
491
+ if (prevSlideSize === 0 && i !== 0) {
492
+ slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
493
+ }
518
494
  if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
519
495
  if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
520
496
  if (params.roundLengths) slidePosition = Math.floor(slidePosition);
@@ -522,55 +498,37 @@ function updateSlides() {
522
498
  slidesGrid.push(slidePosition);
523
499
  } else {
524
500
  if (params.roundLengths) slidePosition = Math.floor(slidePosition);
525
- if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) snapGrid.push(slidePosition);
501
+ if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params.slidesPerGroup === 0) {
502
+ snapGrid.push(slidePosition);
503
+ }
526
504
  slidesGrid.push(slidePosition);
527
505
  slidePosition = slidePosition + slideSize + spaceBetween;
528
506
  }
529
- swiper.virtualSize += slideSize + spaceBetween;
507
+ swiper.slidesTotalSize += slideSize + spaceBetween;
530
508
  prevSlideSize = slideSize;
531
509
  index += 1;
532
510
  }
533
- swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
534
- if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
535
- wrapperEl.style.width = `${swiper.virtualSize + spaceBetween}px`;
511
+ swiper.slidesTotalSize = Math.max(swiper.slidesTotalSize, swiperSize) + offsetAfter;
512
+ if (rtl && wrongRTL && params.effect === 'slide') {
513
+ wrapperEl.style.width = `${swiper.slidesTotalSize + spaceBetween}px`;
536
514
  }
537
515
  if (params.setWrapperSize) {
538
- wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.virtualSize + spaceBetween}px`;
539
- }
540
- if (gridEnabled) {
541
- swiper.grid.updateWrapperSize(slideSize, snapGrid);
516
+ wrapperEl.style[swiper.getDirectionLabel('width')] = `${swiper.slidesTotalSize + spaceBetween}px`;
542
517
  }
543
518
 
544
- // Remove last grid elements depending on width
519
+ // Remove last snap points depending on width (non-centered)
545
520
  if (!params.centeredSlides) {
546
521
  const newSlidesGrid = [];
547
522
  for (let i = 0; i < snapGrid.length; i += 1) {
548
523
  let slidesGridItem = snapGrid[i];
549
524
  if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
550
- if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
525
+ if (snapGrid[i] <= swiper.slidesTotalSize - swiperSize) {
551
526
  newSlidesGrid.push(slidesGridItem);
552
527
  }
553
528
  }
554
529
  snapGrid = newSlidesGrid;
555
- if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
556
- snapGrid.push(swiper.virtualSize - swiperSize);
557
- }
558
- }
559
- if (isVirtual && params.loop) {
560
- const size = slidesSizesGrid[0] + spaceBetween;
561
- if (params.slidesPerGroup > 1) {
562
- const groups = Math.ceil((swiper.virtual.slidesBefore + swiper.virtual.slidesAfter) / params.slidesPerGroup);
563
- const groupSize = size * params.slidesPerGroup;
564
- for (let i = 0; i < groups; i += 1) {
565
- snapGrid.push(snapGrid[snapGrid.length - 1] + groupSize);
566
- }
567
- }
568
- for (let i = 0; i < swiper.virtual.slidesBefore + swiper.virtual.slidesAfter; i += 1) {
569
- if (params.slidesPerGroup === 1) {
570
- snapGrid.push(snapGrid[snapGrid.length - 1] + size);
571
- }
572
- slidesGrid.push(slidesGrid[slidesGrid.length - 1] + size);
573
- swiper.virtualSize += size;
530
+ if (Math.floor(swiper.slidesTotalSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
531
+ snapGrid.push(swiper.slidesTotalSize - swiperSize);
574
532
  }
575
533
  }
576
534
  if (snapGrid.length === 0) snapGrid = [0];
@@ -578,9 +536,7 @@ function updateSlides() {
578
536
  const key = swiper.isHorizontal() && rtl ? 'marginLeft' : swiper.getDirectionLabel('marginRight');
579
537
  slides.filter((_, slideIndex) => {
580
538
  if (!params.cssMode || params.loop) return true;
581
- if (slideIndex === slides.length - 1) {
582
- return false;
583
- }
539
+ if (slideIndex === slides.length - 1) return false;
584
540
  return true;
585
541
  }).forEach(slideEl => {
586
542
  slideEl.style[key] = `${spaceBetween}px`;
@@ -630,7 +586,9 @@ function updateSlides() {
630
586
  swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);
631
587
  swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);
632
588
  }
633
- if (slidesLength !== previousSlidesLength) {
589
+
590
+ // Emit changes
591
+ if (slidesLength !== (previousSlidesGridLength ? slides.length : slides.length)) {
634
592
  swiper.emit('slidesLengthChange');
635
593
  }
636
594
  if (snapGrid.length !== previousSnapGridLength) {
@@ -644,7 +602,7 @@ function updateSlides() {
644
602
  swiper.updateSlidesOffset();
645
603
  }
646
604
  swiper.emit('slidesUpdated');
647
- if (!isVirtual && !params.cssMode && (params.effect === 'slide' || params.effect === 'fade')) {
605
+ if (!params.cssMode && params.effect === 'slide') {
648
606
  const backFaceHiddenClass = `${params.containerModifierClass}backface-hidden`;
649
607
  const hasClassBackfaceClassAdded = swiper.el.classList.contains(backFaceHiddenClass);
650
608
  if (slidesLength <= params.maxBackfaceHiddenSlides) {
@@ -658,20 +616,13 @@ function updateSlides() {
658
616
  function updateAutoHeight(speed) {
659
617
  const swiper = this;
660
618
  const activeSlides = [];
661
- const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
662
- let newHeight = 0;
663
- let i;
664
619
  if (typeof speed === 'number') {
665
620
  swiper.setTransition(speed);
666
621
  } else if (speed === true) {
667
622
  swiper.setTransition(swiper.params.speed);
668
623
  }
669
- const getSlideByIndex = index => {
670
- if (isVirtual) {
671
- return swiper.slides[swiper.getSlideIndexByData(index)];
672
- }
673
- return swiper.slides[index];
674
- };
624
+ const getSlideByIndex = index => swiper.slides[index];
625
+
675
626
  // Find slides currently in view
676
627
  if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
677
628
  if (swiper.params.centeredSlides) {
@@ -679,9 +630,9 @@ function updateAutoHeight(speed) {
679
630
  activeSlides.push(slide);
680
631
  });
681
632
  } else {
682
- for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
633
+ for (let i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
683
634
  const index = swiper.activeIndex + i;
684
- if (index > swiper.slides.length && !isVirtual) break;
635
+ if (index > swiper.slides.length) break;
685
636
  activeSlides.push(getSlideByIndex(index));
686
637
  }
687
638
  }
@@ -690,14 +641,13 @@ function updateAutoHeight(speed) {
690
641
  }
691
642
 
692
643
  // Find new height from highest slide in view
693
- for (i = 0; i < activeSlides.length; i += 1) {
644
+ let newHeight = 0;
645
+ for (let i = 0; i < activeSlides.length; i += 1) {
694
646
  if (typeof activeSlides[i] !== 'undefined') {
695
647
  const height = activeSlides[i].offsetHeight;
696
648
  newHeight = height > newHeight ? height : newHeight;
697
649
  }
698
650
  }
699
-
700
- // Update Height
701
651
  if (newHeight || newHeight === 0) swiper.wrapperEl.style.height = `${newHeight}px`;
702
652
  }
703
653
 
@@ -842,46 +792,16 @@ function updateSlidesClasses() {
842
792
  slidesEl,
843
793
  activeIndex
844
794
  } = swiper;
845
- const isVirtual = swiper.virtual && params.virtual.enabled;
846
- const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
847
- const getFilteredSlide = selector => {
848
- return elementChildren(slidesEl, `.${params.slideClass}${selector}, swiper-slide${selector}`)[0];
849
- };
850
- let activeSlide;
851
- let prevSlide;
795
+ const getNextSlide = slideEl => elementNextAll(slideEl, `.${params.slideClass}, swiper-slide`)[0];
796
+ const getPrevSlide = slideEl => elementPrevAll(slideEl, `.${params.slideClass}, swiper-slide`)[0];
797
+ const activeSlide = slides[activeIndex];
852
798
  let nextSlide;
853
- if (isVirtual) {
854
- if (params.loop) {
855
- let slideIndex = activeIndex - swiper.virtual.slidesBefore;
856
- if (slideIndex < 0) slideIndex = swiper.virtual.slides.length + slideIndex;
857
- if (slideIndex >= swiper.virtual.slides.length) slideIndex -= swiper.virtual.slides.length;
858
- activeSlide = getFilteredSlide(`[data-swiper-slide-index="${slideIndex}"]`);
859
- } else {
860
- activeSlide = getFilteredSlide(`[data-swiper-slide-index="${activeIndex}"]`);
861
- }
862
- } else {
863
- if (gridEnabled) {
864
- activeSlide = slides.find(slideEl => slideEl.column === activeIndex);
865
- nextSlide = slides.find(slideEl => slideEl.column === activeIndex + 1);
866
- prevSlide = slides.find(slideEl => slideEl.column === activeIndex - 1);
867
- } else {
868
- activeSlide = slides[activeIndex];
869
- }
870
- }
799
+ let prevSlide;
871
800
  if (activeSlide) {
872
- if (!gridEnabled) {
873
- // Next Slide
874
- nextSlide = elementNextAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
875
- if (params.loop && !nextSlide) {
876
- nextSlide = slides[0];
877
- }
878
-
879
- // Prev Slide
880
- prevSlide = elementPrevAll(activeSlide, `.${params.slideClass}, swiper-slide`)[0];
881
- if (params.loop && !prevSlide === 0) {
882
- prevSlide = slides[slides.length - 1];
883
- }
884
- }
801
+ nextSlide = getNextSlide(activeSlide);
802
+ prevSlide = getPrevSlide(activeSlide);
803
+ if (params.loop && !nextSlide) nextSlide = slides[0];
804
+ if (params.loop && !prevSlide) prevSlide = slides[slides.length - 1];
885
805
  }
886
806
  slides.forEach(slideEl => {
887
807
  toggleSlideClasses(slideEl, slideEl === activeSlide, params.slideActiveClass);
@@ -972,7 +892,6 @@ function getActiveIndexByTranslate(swiper) {
972
892
  activeIndex = i;
973
893
  }
974
894
  }
975
- // Normalize slideIndex
976
895
  if (params.normalizeSlideIndex) {
977
896
  if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
978
897
  }
@@ -990,16 +909,6 @@ function updateActiveIndex(newActiveIndex) {
990
909
  } = swiper;
991
910
  let activeIndex = newActiveIndex;
992
911
  let snapIndex;
993
- const getVirtualRealIndex = aIndex => {
994
- let realIndex = aIndex - swiper.virtual.slidesBefore;
995
- if (realIndex < 0) {
996
- realIndex = swiper.virtual.slides.length + realIndex;
997
- }
998
- if (realIndex >= swiper.virtual.slides.length) {
999
- realIndex -= swiper.virtual.slides.length;
1000
- }
1001
- return realIndex;
1002
- };
1003
912
  if (typeof activeIndex === 'undefined') {
1004
913
  activeIndex = getActiveIndexByTranslate(swiper);
1005
914
  }
@@ -1017,32 +926,12 @@ function updateActiveIndex(newActiveIndex) {
1017
926
  }
1018
927
  return;
1019
928
  }
1020
- if (activeIndex === previousIndex && swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
1021
- swiper.realIndex = getVirtualRealIndex(activeIndex);
1022
- return;
1023
- }
1024
- const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
1025
-
1026
- // Get real index
1027
- let realIndex;
1028
- if (swiper.virtual && params.virtual.enabled && params.loop) {
1029
- realIndex = getVirtualRealIndex(activeIndex);
1030
- } else if (gridEnabled) {
1031
- const firstSlideInColumn = swiper.slides.find(slideEl => slideEl.column === activeIndex);
1032
- let activeSlideIndex = parseInt(firstSlideInColumn.getAttribute('data-swiper-slide-index'), 10);
1033
- if (Number.isNaN(activeSlideIndex)) {
1034
- activeSlideIndex = Math.max(swiper.slides.indexOf(firstSlideInColumn), 0);
1035
- }
1036
- realIndex = Math.floor(activeSlideIndex / params.grid.rows);
1037
- } else if (swiper.slides[activeIndex]) {
929
+ let realIndex = activeIndex;
930
+ if (swiper.slides[activeIndex]) {
1038
931
  const slideIndex = swiper.slides[activeIndex].getAttribute('data-swiper-slide-index');
1039
932
  if (slideIndex) {
1040
933
  realIndex = parseInt(slideIndex, 10);
1041
- } else {
1042
- realIndex = activeIndex;
1043
934
  }
1044
- } else {
1045
- realIndex = activeIndex;
1046
935
  }
1047
936
  Object.assign(swiper, {
1048
937
  previousSnapIndex,
@@ -1089,11 +978,7 @@ function updateClickedSlide(el, path) {
1089
978
  }
1090
979
  if (slide && slideFound) {
1091
980
  swiper.clickedSlide = slide;
1092
- if (swiper.virtual && swiper.params.virtual.enabled) {
1093
- swiper.clickedIndex = parseInt(slide.getAttribute('data-swiper-slide-index'), 10);
1094
- } else {
1095
- swiper.clickedIndex = slideIndex;
1096
- }
981
+ swiper.clickedIndex = slideIndex;
1097
982
  } else {
1098
983
  swiper.clickedSlide = undefined;
1099
984
  swiper.clickedIndex = undefined;
@@ -1127,9 +1012,6 @@ function getSwiperTranslate(axis) {
1127
1012
  translate,
1128
1013
  wrapperEl
1129
1014
  } = swiper;
1130
- if (params.virtualTranslate) {
1131
- return rtl ? -translate : translate;
1132
- }
1133
1015
  if (params.cssMode) {
1134
1016
  return translate;
1135
1017
  }
@@ -1163,7 +1045,7 @@ function setTranslate(translate, byController) {
1163
1045
  swiper.translate = swiper.isHorizontal() ? x : y;
1164
1046
  if (params.cssMode) {
1165
1047
  wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
1166
- } else if (!params.virtualTranslate) {
1048
+ } else {
1167
1049
  if (swiper.isHorizontal()) {
1168
1050
  x -= swiper.cssOverflowAdjustment();
1169
1051
  } else {
@@ -1400,7 +1282,6 @@ function slideTo(index, speed, runCallbacks, internal, initial) {
1400
1282
  let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
1401
1283
  if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
1402
1284
  const translate = -snapGrid[snapIndex];
1403
- // Normalize slideIndex
1404
1285
  if (params.normalizeSlideIndex) {
1405
1286
  for (let i = 0; i < slidesGrid.length; i += 1) {
1406
1287
  const normalizedTranslate = -Math.floor(translate * 100);
@@ -1417,33 +1298,24 @@ function slideTo(index, speed, runCallbacks, internal, initial) {
1417
1298
  }
1418
1299
  }
1419
1300
  }
1301
+
1420
1302
  // Directions locks
1421
1303
  if (swiper.initialized && slideIndex !== activeIndex) {
1422
1304
  if (!swiper.allowSlideNext && (rtl ? translate > swiper.translate && translate > swiper.minTranslate() : translate < swiper.translate && translate < swiper.minTranslate())) {
1423
1305
  return false;
1424
1306
  }
1425
1307
  if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
1426
- if ((activeIndex || 0) !== slideIndex) {
1427
- return false;
1428
- }
1308
+ if ((activeIndex || 0) !== slideIndex) return false;
1429
1309
  }
1430
1310
  }
1431
1311
  if (slideIndex !== (previousIndex || 0) && runCallbacks) {
1432
1312
  swiper.emit('beforeSlideChangeStart');
1433
1313
  }
1434
-
1435
- // Update progress
1436
1314
  swiper.updateProgress(translate);
1437
1315
  let direction;
1438
1316
  if (slideIndex > activeIndex) direction = 'next';else if (slideIndex < activeIndex) direction = 'prev';else direction = 'reset';
1439
-
1440
- // initial virtual
1441
- const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
1442
- const isInitialVirtual = isVirtual && initial;
1443
- // Update Index
1444
- if (!isInitialVirtual && (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate)) {
1317
+ if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {
1445
1318
  swiper.updateActiveIndex(slideIndex);
1446
- // Update Height
1447
1319
  if (params.autoHeight) {
1448
1320
  swiper.updateAutoHeight();
1449
1321
  }
@@ -1461,24 +1333,7 @@ function slideTo(index, speed, runCallbacks, internal, initial) {
1461
1333
  const isH = swiper.isHorizontal();
1462
1334
  const t = rtl ? translate : -translate;
1463
1335
  if (speed === 0) {
1464
- if (isVirtual) {
1465
- swiper.wrapperEl.style.scrollSnapType = 'none';
1466
- swiper._immediateVirtual = true;
1467
- }
1468
- if (isVirtual && !swiper._cssModeVirtualInitialSet && swiper.params.initialSlide > 0) {
1469
- swiper._cssModeVirtualInitialSet = true;
1470
- requestAnimationFrame(() => {
1471
- wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1472
- });
1473
- } else {
1474
- wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1475
- }
1476
- if (isVirtual) {
1477
- requestAnimationFrame(() => {
1478
- swiper.wrapperEl.style.scrollSnapType = '';
1479
- swiper._immediateVirtual = false;
1480
- });
1481
- }
1336
+ wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
1482
1337
  } else {
1483
1338
  if (!swiper.support.smoothScroll) {
1484
1339
  animateCSSModeScroll({
@@ -1496,10 +1351,7 @@ function slideTo(index, speed, runCallbacks, internal, initial) {
1496
1351
  return true;
1497
1352
  }
1498
1353
  const browser = getBrowser();
1499
- const isSafari = browser.isSafari;
1500
- if (isVirtual && !initial && isSafari && swiper.isElement) {
1501
- swiper.virtual.update(false, false, slideIndex);
1502
- }
1354
+ browser.isSafari;
1503
1355
  swiper.setTransition(speed);
1504
1356
  swiper.setTranslate(translate);
1505
1357
  swiper.updateActiveIndex(slideIndex);
@@ -1670,8 +1522,6 @@ function slideToLoopCenterSneakPeek(index, speed, runCallbacks, internal) {
1670
1522
  if (swiper.params?.isSneakPeekCenter && slides.length > 1 && swiper.activeIndex === 0) {
1671
1523
  const gap = Math.abs(swiper.snapGrid[1] - swiper.snapGrid[0]);
1672
1524
  const swiperTranslate = JSON.parse(JSON.stringify(swiper.snapGrid[1]));
1673
-
1674
- // Move last item to first position only if active slide is the first slide
1675
1525
  const lastSlide = slides[slides.length - 1];
1676
1526
  lastSlide.swiperLoopMoveDOM = true;
1677
1527
  swiper.slidesEl.prepend(lastSlide);
@@ -1706,11 +1556,8 @@ function slideNext(speed, runCallbacks, internal) {
1706
1556
  perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
1707
1557
  }
1708
1558
  const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
1709
- const isVirtual = swiper.virtual && params.virtual.enabled;
1710
1559
  if (params.loop) {
1711
- if (animating && !isVirtual && params.loopPreventsSliding) return false;
1712
-
1713
- // Kiểm tra xem loop có bị disable không
1560
+ if (animating && params.loopPreventsSliding) return false;
1714
1561
  const currentSlidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10));
1715
1562
  if (swiper.slides.length >= currentSlidesPerView) {
1716
1563
  swiper.loopFix({
@@ -1736,8 +1583,7 @@ function slideNext(speed, runCallbacks, internal) {
1736
1583
  const lastSnapGridIndex = swiper.snapGrid.length - 1;
1737
1584
  const gap = Math.abs(swiper.snapGrid[lastSnapGridIndex] - swiper.snapGrid[lastSnapGridIndex - 1]);
1738
1585
  const swiperTranslate = structuredClone(swiper.snapGrid[lastSnapGridIndex - 1]);
1739
-
1740
- // Move first item to last position only if active slide is the last slide
1586
+ if (!swiper.params.loop) return;
1741
1587
  const firstSlide = slides[0];
1742
1588
  firstSlide.swiperLoopMoveDOM = true;
1743
1589
  swiper.slidesEl.append(firstSlide);
@@ -1762,17 +1608,14 @@ function slidePrev(speed, runCallbacks, internal) {
1762
1608
  params,
1763
1609
  snapGrid,
1764
1610
  slidesGrid,
1765
- rtlTranslate,
1766
- enabled,
1767
- animating
1611
+ rtlTranslate: rtlTranslate,
1612
+ enabled
1768
1613
  } = swiper;
1769
1614
  if (!enabled || swiper.destroyed) return swiper;
1770
1615
  if (typeof speed === 'undefined') {
1771
1616
  speed = swiper.params.speed;
1772
1617
  }
1773
- swiper.virtual && params.virtual.enabled;
1774
1618
  if (params.loop) {
1775
- // Kiểm tra xem loop có bị disable không
1776
1619
  const currentSlidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(params.slidesPerView, 10));
1777
1620
  if (swiper.slides.length >= currentSlidesPerView) {
1778
1621
  swiper.loopFix({
@@ -1789,18 +1632,16 @@ function slidePrev(speed, runCallbacks, internal) {
1789
1632
  }
1790
1633
  const normalizedTranslate = normalize(translate);
1791
1634
  const normalizedSnapGrid = snapGrid.map(val => normalize(val));
1792
- const isFreeMode = params.freeMode && params.freeMode.enabled;
1793
1635
  let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
1794
- if (typeof prevSnap === 'undefined' && (params.cssMode || isFreeMode)) {
1636
+ if (typeof prevSnap === 'undefined' && params.cssMode) {
1795
1637
  let prevSnapIndex;
1796
1638
  snapGrid.forEach((snap, snapIndex) => {
1797
1639
  if (normalizedTranslate >= snap) {
1798
- // prevSnap = snap;
1799
1640
  prevSnapIndex = snapIndex;
1800
1641
  }
1801
1642
  });
1802
1643
  if (typeof prevSnapIndex !== 'undefined') {
1803
- prevSnap = isFreeMode ? snapGrid[prevSnapIndex] : snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
1644
+ prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
1804
1645
  }
1805
1646
  }
1806
1647
  let prevIndex = 0;
@@ -1813,7 +1654,7 @@ function slidePrev(speed, runCallbacks, internal) {
1813
1654
  }
1814
1655
  }
1815
1656
  if (params.rewind && swiper.isBeginning) {
1816
- const lastIndex = swiper.params.virtual && swiper.params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
1657
+ const lastIndex = swiper.slides.length - 1;
1817
1658
  return swiper.slideTo(lastIndex, speed, runCallbacks, internal);
1818
1659
  } else if (params.loop && swiper.activeIndex === 0 && params.cssMode) {
1819
1660
  requestAnimationFrame(() => {
@@ -1827,8 +1668,7 @@ function slidePrev(speed, runCallbacks, internal) {
1827
1668
  if (swiper.params?.isSneakPeekCenter && slides.length > 1 && swiper.activeIndex === 0) {
1828
1669
  const gap = Math.abs(swiper.snapGrid[1] - swiper.snapGrid[0]);
1829
1670
  const swiperTranslate = JSON.parse(JSON.stringify(swiper.snapGrid[1]));
1830
-
1831
- // Move last item to first position only if active slide is the first slide
1671
+ if (!swiper.params.loop) return;
1832
1672
  const lastSlide = slides[slides.length - 1];
1833
1673
  lastSlide.swiperLoopMoveDOM = true;
1834
1674
  swiper.slidesEl.prepend(lastSlide);
@@ -1904,20 +1744,19 @@ function slideToClickedSlide() {
1904
1744
  slidesEl
1905
1745
  } = swiper;
1906
1746
  const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
1907
- let slideToIndex = swiper.getSlideIndexWhenGrid(swiper.clickedIndex);
1747
+ const slideToIndex = swiper.clickedIndex;
1908
1748
  let realIndex;
1909
1749
  const slideSelector = swiper.isElement ? `swiper-slide` : `.${params.slideClass}`;
1910
- const isGrid = swiper.grid && swiper.params.grid && swiper.params.grid.rows > 1;
1911
1750
  if (params.loop) {
1912
1751
  if (swiper.animating) return;
1913
1752
  realIndex = parseInt(swiper.clickedSlide.getAttribute('data-swiper-slide-index'), 10);
1914
1753
  if (params.centeredSlides) {
1915
1754
  swiper.slideToLoop(realIndex);
1916
- } else if (slideToIndex > (isGrid ? (swiper.slides.length - slidesPerView) / 2 - (swiper.params.grid.rows - 1) : swiper.slides.length - slidesPerView)) {
1755
+ } else if (slideToIndex > swiper.slides.length - slidesPerView) {
1917
1756
  swiper.loopFix();
1918
- slideToIndex = swiper.getSlideIndex(elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0]);
1757
+ const clickedEl = elementChildren(slidesEl, `${slideSelector}[data-swiper-slide-index="${realIndex}"]`)[0];
1919
1758
  nextTick(() => {
1920
- swiper.slideTo(slideToIndex);
1759
+ if (clickedEl) swiper.slideTo(swiper.getSlideIndex(clickedEl));
1921
1760
  });
1922
1761
  } else {
1923
1762
  swiper.slideTo(slideToIndex);
@@ -1944,7 +1783,7 @@ function loopCreate(slideRealIndex, initial) {
1944
1783
  params,
1945
1784
  slidesEl
1946
1785
  } = swiper;
1947
- if (!params.loop || swiper.virtual && swiper.params.virtual.enabled) return;
1786
+ if (!params.loop) return;
1948
1787
  const initSlides = () => {
1949
1788
  const slides = elementChildren(slidesEl, `.${params.slideClass}, swiper-slide`);
1950
1789
  slides.forEach((el, index) => {
@@ -1953,21 +1792,17 @@ function loopCreate(slideRealIndex, initial) {
1953
1792
  };
1954
1793
  const clearBlankSlides = () => {
1955
1794
  const slides = elementChildren(slidesEl, `.${params.slideBlankClass}`);
1956
- slides.forEach(el => {
1957
- el.remove();
1958
- });
1795
+ slides.forEach(el => el.remove());
1959
1796
  if (slides.length > 0) {
1960
1797
  swiper.recalcSlides();
1961
1798
  swiper.updateSlides();
1962
1799
  }
1963
1800
  };
1964
- const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
1965
- if (params.loopAddBlankSlides && (params.slidesPerGroup > 1 || gridEnabled)) {
1801
+ if (params.loopAddBlankSlides && params.slidesPerGroup > 1) {
1966
1802
  clearBlankSlides();
1967
1803
  }
1968
- const slidesPerGroup = params.slidesPerGroup * (gridEnabled ? params.grid.rows : 1);
1804
+ const slidesPerGroup = params.slidesPerGroup;
1969
1805
  const shouldFillGroup = swiper.slides.length % slidesPerGroup !== 0;
1970
- const shouldFillGrid = gridEnabled && swiper.slides.length % params.grid.rows !== 0;
1971
1806
  const addBlankSlides = amountOfSlides => {
1972
1807
  for (let i = 0; i < amountOfSlides; i += 1) {
1973
1808
  const slideEl = swiper.isElement ? createElement('swiper-slide', [params.slideBlankClass]) : createElement('div', [params.slideClass, params.slideBlankClass]);
@@ -1984,16 +1819,6 @@ function loopCreate(slideRealIndex, initial) {
1984
1819
  showWarning('Swiper Loop Warning: The number of slides is not even to slidesPerGroup, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
1985
1820
  }
1986
1821
  initSlides();
1987
- } else if (shouldFillGrid) {
1988
- if (params.loopAddBlankSlides) {
1989
- const slidesToAdd = params.grid.rows - swiper.slides.length % params.grid.rows;
1990
- addBlankSlides(slidesToAdd);
1991
- swiper.recalcSlides();
1992
- swiper.updateSlides();
1993
- } else {
1994
- showWarning('Swiper Loop Warning: The number of slides is not even to grid.rows, loop mode may not function properly. You need to add more slides (or make duplicates, or empty slides)');
1995
- }
1996
- initSlides();
1997
1822
  } else {
1998
1823
  initSlides();
1999
1824
  }
@@ -2012,13 +1837,12 @@ function loopFix(_temp) {
2012
1837
  setTranslate,
2013
1838
  activeSlideIndex,
2014
1839
  initial,
2015
- byController,
2016
1840
  byMousewheel
2017
1841
  } = _temp === void 0 ? {} : _temp;
2018
1842
  const swiper = this;
2019
1843
  if (!swiper.params.loop) return;
2020
1844
 
2021
- // Disable loop mode nếu số slides ít hơn slidesPerView
1845
+ // Disable loop mode if number of slides is smaller than slidesPerView
2022
1846
  const currentSlidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
2023
1847
  if (swiper.slides.length < currentSlidesPerView) {
2024
1848
  console.warn('Swiper: Loop mode disabled - slides.length < slidesPerView');
@@ -2038,21 +1862,6 @@ function loopFix(_temp) {
2038
1862
  } = params;
2039
1863
  swiper.allowSlidePrev = true;
2040
1864
  swiper.allowSlideNext = true;
2041
- if (swiper.virtual && params.virtual.enabled) {
2042
- if (slideTo) {
2043
- if (!params.centeredSlides && swiper.snapIndex === 0) {
2044
- swiper.slideTo(swiper.virtual.slides.length, 0, false, true);
2045
- } else if (params.centeredSlides && swiper.snapIndex < params.slidesPerView) {
2046
- swiper.slideTo(swiper.virtual.slides.length + swiper.snapIndex, 0, false, true);
2047
- } else if (swiper.snapIndex === swiper.snapGrid.length - 1) {
2048
- swiper.slideTo(swiper.virtual.slidesBefore, 0, false, true);
2049
- }
2050
- }
2051
- swiper.allowSlidePrev = allowSlidePrev;
2052
- swiper.allowSlideNext = allowSlideNext;
2053
- swiper.emit('loopFix');
2054
- return;
2055
- }
2056
1865
  let slidesPerView = params.slidesPerView;
2057
1866
  if (slidesPerView === 'auto') {
2058
1867
  slidesPerView = swiper.slidesPerViewDynamic();
@@ -2062,22 +1871,19 @@ function loopFix(_temp) {
2062
1871
  slidesPerView = slidesPerView + 1;
2063
1872
  }
2064
1873
  }
2065
- const slidesPerGroup = params.slidesPerGroupAuto ? slidesPerView : params.slidesPerGroup;
1874
+ const slidesPerGroup = params.slidesPerGroup;
2066
1875
  let loopedSlides = centeredSlides ? Math.max(slidesPerGroup, Math.ceil(slidesPerView / 2)) : slidesPerGroup;
2067
1876
  if (loopedSlides % slidesPerGroup !== 0) {
2068
1877
  loopedSlides += slidesPerGroup - loopedSlides % slidesPerGroup;
2069
1878
  }
2070
1879
  loopedSlides += params.loopAdditionalSlides;
2071
1880
  swiper.loopedSlides = loopedSlides;
2072
- const gridEnabled = swiper.grid && params.grid && params.grid.rows > 1;
2073
- if (slides.length < slidesPerView + loopedSlides || swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
1881
+ if (slides.length < slidesPerView + loopedSlides) {
2074
1882
  showWarning('Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled or not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters');
2075
- } else if (gridEnabled && params.grid.fill === 'row') {
2076
- showWarning('Swiper Loop Warning: Loop mode is not compatible with grid.fill = `row`');
2077
1883
  }
2078
1884
  const prependSlidesIndexes = [];
2079
1885
  const appendSlidesIndexes = [];
2080
- const cols = gridEnabled ? Math.ceil(slides.length / params.grid.rows) : slides.length;
1886
+ const cols = slides.length;
2081
1887
  const isInitialOverflow = initial && cols - initialSlide < slidesPerView && !centeredSlides;
2082
1888
  let activeIndex = isInitialOverflow ? initialSlide : swiper.activeIndex;
2083
1889
  if (typeof activeSlideIndex === 'undefined') {
@@ -2089,24 +1895,15 @@ function loopFix(_temp) {
2089
1895
  const isPrev = direction === 'prev' || !direction;
2090
1896
  let slidesPrepended = 0;
2091
1897
  let slidesAppended = 0;
2092
- const activeColIndex = gridEnabled ? slides[activeSlideIndex].column : activeSlideIndex;
1898
+ const activeColIndex = activeSlideIndex;
2093
1899
  const activeColIndexWithShift = activeColIndex + (centeredSlides && typeof setTranslate === 'undefined' ? -slidesPerView / 2 + 0.5 : 0);
1900
+
2094
1901
  // prepend last slides before start
2095
1902
  if (activeColIndexWithShift < loopedSlides) {
2096
1903
  slidesPrepended = Math.max(loopedSlides - activeColIndexWithShift, slidesPerGroup);
2097
1904
  for (let i = 0; i < loopedSlides - activeColIndexWithShift; i += 1) {
2098
1905
  const index = i - Math.floor(i / cols) * cols;
2099
- if (gridEnabled) {
2100
- const colIndexToPrepend = cols - index - 1;
2101
- for (let i = slides.length - 1; i >= 0; i -= 1) {
2102
- if (slides[i].column === colIndexToPrepend) prependSlidesIndexes.push(i);
2103
- }
2104
- // slides.forEach((slide, slideIndex) => {
2105
- // if (slide.column === colIndexToPrepend) prependSlidesIndexes.push(slideIndex);
2106
- // });
2107
- } else {
2108
- prependSlidesIndexes.push(cols - index - 1);
2109
- }
1906
+ prependSlidesIndexes.push(cols - index - 1);
2110
1907
  }
2111
1908
  } else if (activeColIndexWithShift + slidesPerView > cols - loopedSlides) {
2112
1909
  slidesAppended = Math.max(activeColIndexWithShift - (cols - loopedSlides * 2), slidesPerGroup);
@@ -2115,27 +1912,13 @@ function loopFix(_temp) {
2115
1912
  }
2116
1913
  for (let i = 0; i < slidesAppended; i += 1) {
2117
1914
  const index = i - Math.floor(i / cols) * cols;
2118
- if (gridEnabled) {
2119
- slides.forEach((slide, slideIndex) => {
2120
- if (slide.column === index) appendSlidesIndexes.push(slideIndex);
2121
- });
2122
- } else {
2123
- appendSlidesIndexes.push(index);
2124
- }
1915
+ appendSlidesIndexes.push(index);
2125
1916
  }
2126
1917
  }
2127
1918
  swiper.__preventObserver__ = true;
2128
1919
  requestAnimationFrame(() => {
2129
1920
  swiper.__preventObserver__ = false;
2130
1921
  });
2131
- if (swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
2132
- if (appendSlidesIndexes.includes(activeSlideIndex)) {
2133
- appendSlidesIndexes.splice(appendSlidesIndexes.indexOf(activeSlideIndex), 1);
2134
- }
2135
- if (prependSlidesIndexes.includes(activeSlideIndex)) {
2136
- prependSlidesIndexes.splice(prependSlidesIndexes.indexOf(activeSlideIndex), 1);
2137
- }
2138
- }
2139
1922
  if (isPrev) {
2140
1923
  prependSlidesIndexes.forEach(index => {
2141
1924
  slides[index].swiperLoopMoveDOM = true;
@@ -2153,10 +1936,6 @@ function loopFix(_temp) {
2153
1936
  swiper.recalcSlides();
2154
1937
  if (params.slidesPerView === 'auto') {
2155
1938
  swiper.updateSlides();
2156
- } else if (gridEnabled && (prependSlidesIndexes.length > 0 && isPrev || appendSlidesIndexes.length > 0 && isNext)) {
2157
- swiper.slides.forEach((slide, slideIndex) => {
2158
- swiper.grid.updateSlide(slideIndex, slide, swiper.slides);
2159
- });
2160
1939
  }
2161
1940
  if (params.watchSlidesProgress) {
2162
1941
  swiper.updateSlidesOffset();
@@ -2176,12 +1955,10 @@ function loopFix(_temp) {
2176
1955
  swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
2177
1956
  }
2178
1957
  }
2179
- } else {
2180
- if (setTranslate) {
2181
- const shift = gridEnabled ? prependSlidesIndexes.length / params.grid.rows : prependSlidesIndexes.length;
2182
- swiper.slideTo(swiper.activeIndex + shift, 0, false, true);
2183
- swiper.touchEventsData.currentTranslate = swiper.translate;
2184
- }
1958
+ } else if (setTranslate) {
1959
+ const shift = prependSlidesIndexes.length;
1960
+ swiper.slideTo(swiper.activeIndex + shift, 0, false, true);
1961
+ swiper.touchEventsData.currentTranslate = swiper.translate;
2185
1962
  }
2186
1963
  } else if (appendSlidesIndexes.length > 0 && isNext) {
2187
1964
  if (typeof slideRealIndex === 'undefined') {
@@ -2197,36 +1974,14 @@ function loopFix(_temp) {
2197
1974
  swiper.touchEventsData.currentTranslate = swiper.touchEventsData.currentTranslate - diff;
2198
1975
  }
2199
1976
  }
2200
- } else {
2201
- const shift = gridEnabled ? appendSlidesIndexes.length / params.grid.rows : appendSlidesIndexes.length;
1977
+ } else if (setTranslate) {
1978
+ const shift = appendSlidesIndexes.length;
2202
1979
  swiper.slideTo(swiper.activeIndex - shift, 0, false, true);
2203
1980
  }
2204
1981
  }
2205
1982
  }
2206
1983
  swiper.allowSlidePrev = allowSlidePrev;
2207
1984
  swiper.allowSlideNext = allowSlideNext;
2208
- if (swiper.controller && swiper.controller.control && !byController) {
2209
- const loopParams = {
2210
- slideRealIndex,
2211
- direction,
2212
- setTranslate,
2213
- activeSlideIndex,
2214
- byController: true
2215
- };
2216
- if (Array.isArray(swiper.controller.control)) {
2217
- swiper.controller.control.forEach(c => {
2218
- if (!c.destroyed && c.params.loop) c.loopFix({
2219
- ...loopParams,
2220
- slideTo: c.params.slidesPerView === params.slidesPerView ? slideTo : false
2221
- });
2222
- });
2223
- } else if (swiper.controller.control instanceof swiper.constructor && swiper.controller.control.params.loop) {
2224
- swiper.controller.control.loopFix({
2225
- ...loopParams,
2226
- slideTo: swiper.controller.control.params.slidesPerView === params.slidesPerView ? slideTo : false
2227
- });
2228
- }
2229
- }
2230
1985
  swiper.emit('loopFix');
2231
1986
  }
2232
1987
 
@@ -2243,7 +1998,7 @@ function loopFixDot(_temp) {
2243
1998
  const swiper = this;
2244
1999
  if (!swiper.params.loop) return;
2245
2000
 
2246
- // Disable loop mode nếu số slides ít hơn slidesPerView
2001
+ // Disable loop mode if number of slides is smaller than slidesPerView
2247
2002
  const currentSlidesPerView = swiper.params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : Math.ceil(parseFloat(swiper.params.slidesPerView, 10));
2248
2003
  if (swiper.slides.length < currentSlidesPerView) {
2249
2004
  console.warn('Swiper: Loop mode disabled - slides.length < slidesPerView');
@@ -2282,7 +2037,7 @@ function loopFixDot(_temp) {
2282
2037
  }
2283
2038
  loopedSlides += params.loopAdditionalSlides;
2284
2039
  swiper.loopedSlides = loopedSlides;
2285
- if (slides.length < slidesPerView + loopedSlides || swiper.params.effect === 'cards' && slides.length < slidesPerView + loopedSlides * 2) {
2040
+ if (slides.length < slidesPerView + loopedSlides) {
2286
2041
  showWarning('Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled or not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters');
2287
2042
  }
2288
2043
  const isNext = direction === 'next' || !direction;
@@ -2308,20 +2063,16 @@ function loopFixDot(_temp) {
2308
2063
  activeSlideIndex = swiper.getSlideIndex(slides.find(el => el.classList.contains(params.slideActiveClass)));
2309
2064
  }
2310
2065
 
2311
- // Tạo DocumentFragment để chứa các slide clone
2066
+ // DocumentFragment to hold slide clones
2312
2067
  const cloneFragment = document.createDocumentFragment();
2313
2068
 
2314
- // Clone các slide theo numberOfSlidesNeedClone (đã đảo ngược) và thêm vào fragment
2069
+ // Clone slides according to numberOfSlidesNeedClone and append to fragment
2315
2070
  (isNext ? numberOfSlidesNeedClone : numberOfSlidesNeedClone.reverse()).forEach(index => {
2316
2071
  if (slides[index]) {
2317
2072
  const originalSlide = slides[index];
2318
2073
  const clonedSlide = originalSlide.cloneNode(true);
2319
-
2320
- // Đánh dấu slide clone
2321
2074
  clonedSlide.setAttribute('data-swiper-clone', 'true');
2322
2075
  clonedSlide.classList.add('swiper-slide-clone');
2323
-
2324
- // Thêm clone vào fragment
2325
2076
  cloneFragment.appendChild(clonedSlide);
2326
2077
  }
2327
2078
  });
@@ -2342,32 +2093,28 @@ function loopFixDot(_temp) {
2342
2093
  });
2343
2094
  }
2344
2095
 
2345
- // Sắp xếp cloneFragment theo data-swiper-slide-index tăng dần
2096
+ // Sort cloned slides by data-swiper-slide-index
2346
2097
  const clonedSlides = Array.from(cloneFragment.children);
2347
2098
  clonedSlides.sort((a, b) => {
2348
2099
  const indexA = parseInt(a.getAttribute('data-swiper-slide-index')) || 0;
2349
2100
  const indexB = parseInt(b.getAttribute('data-swiper-slide-index')) || 0;
2350
2101
  return indexA - indexB;
2351
2102
  });
2352
-
2353
- // Xóa tất cả children cũ và thêm lại theo thứ tự đã sắp xếp
2354
2103
  cloneFragment.innerHTML = '';
2355
2104
  clonedSlides.forEach(slide => {
2356
2105
  cloneFragment.appendChild(slide);
2357
2106
  });
2358
2107
 
2359
- // Thêm fragment vào vị trí phù hợp
2108
+ // Place fragment into the right position
2360
2109
  if (isPrev) {
2361
- // Nếu là prev, thêm fragment vào cuối slidesEl
2362
2110
  slidesEl.appendChild(cloneFragment);
2363
2111
  } else if (isNext) {
2364
- // Nếu là next, thêm fragment vào đầu slidesEl
2365
2112
  slidesEl.insertBefore(cloneFragment, slidesEl.firstChild);
2366
2113
  }
2367
2114
  swiper.recalcSlides();
2368
2115
  swiper.updateSlides();
2369
2116
 
2370
- // Tìm slide data-swiper-slide-index tương ứng
2117
+ // Find old active slide index after recalculation
2371
2118
  let oldActiveIndex = null;
2372
2119
  for (let i = 0; i < slidesEl.children.length; i++) {
2373
2120
  const child = slidesEl.children[i];
@@ -2380,7 +2127,7 @@ function loopFixDot(_temp) {
2380
2127
  swiper.slideTo(oldActiveIndex, 0);
2381
2128
  }
2382
2129
 
2383
- // Tìm vị trí slide sau khi remove clone để set lại translate tạo hiệu ứng animate
2130
+ // Update translate after removing clones for animation
2384
2131
  const skip = Math.min(swiper.params.slidesPerGroupSkip, newIndex);
2385
2132
  let snapIndex = skip + Math.floor((newIndex - skip) / swiper.params.slidesPerGroup);
2386
2133
  if (snapIndex >= swiper.snapGrid.length) snapIndex = swiper.snapGrid.length - 1;
@@ -2406,7 +2153,8 @@ function loopFixDot(_temp) {
2406
2153
  }
2407
2154
  swiper.setTranslate(updateTranslate);
2408
2155
  }
2409
- // Remove slide clone ra khỏi slidesEl sau khi slideTo hoàn thành
2156
+
2157
+ // Remove clones
2410
2158
  const cloneSlides = slidesEl.querySelectorAll('[data-swiper-clone="true"]');
2411
2159
  cloneSlides.forEach(cloneSlide => {
2412
2160
  if (cloneSlide.parentNode) {
@@ -2436,7 +2184,7 @@ function loopDestroy() {
2436
2184
  params,
2437
2185
  slidesEl
2438
2186
  } = swiper;
2439
- if (!params.loop || !slidesEl || swiper.virtual && swiper.params.virtual.enabled) return;
2187
+ if (!params.loop || !slidesEl) return;
2440
2188
  swiper.recalcSlides();
2441
2189
  const newSlidesOrder = [];
2442
2190
  swiper.slides.forEach(slideEl => {
@@ -2497,7 +2245,6 @@ var grabCursor = {
2497
2245
  unsetGrabCursor
2498
2246
  };
2499
2247
 
2500
- // Modified from https://stackoverflow.com/questions/54520554/custom-element-getrootnode-closest-function-crossing-multiple-parent-shadowd
2501
2248
  function closestElement(selector, base) {
2502
2249
  if (base === void 0) {
2503
2250
  base = this;
@@ -2506,9 +2253,7 @@ function closestElement(selector, base) {
2506
2253
  if (!el || el === getDocument() || el === getWindow()) return null;
2507
2254
  if (el.assignedSlot) el = el.assignedSlot;
2508
2255
  const found = el.closest(selector);
2509
- if (!found && !el.getRootNode) {
2510
- return null;
2511
- }
2256
+ if (!found && !el.getRootNode) return null;
2512
2257
  return found || __closestFrom(el.getRootNode().host);
2513
2258
  }
2514
2259
  return __closestFrom(base);
@@ -2536,9 +2281,7 @@ function onTouchStart(event) {
2536
2281
  if (e.originalEvent) e = e.originalEvent;
2537
2282
  const data = swiper.touchEventsData;
2538
2283
  if (e.type === 'pointerdown') {
2539
- if (data.pointerId !== null && data.pointerId !== e.pointerId) {
2540
- return;
2541
- }
2284
+ if (data.pointerId !== null && data.pointerId !== e.pointerId) return;
2542
2285
  data.pointerId = e.pointerId;
2543
2286
  } else if (e.type === 'touchstart' && e.targetTouches.length === 1) {
2544
2287
  data.touchId = e.targetTouches[0].identifier;
@@ -2555,9 +2298,7 @@ function onTouchStart(event) {
2555
2298
  } = swiper;
2556
2299
  if (!enabled) return;
2557
2300
  if (!params.simulateTouch && e.pointerType === 'mouse') return;
2558
- if (swiper.animating && params.preventInteractionOnTransition) {
2559
- return;
2560
- }
2301
+ if (swiper.animating && params.preventInteractionOnTransition) return;
2561
2302
  if (!swiper.animating && params.cssMode && params.loop) {
2562
2303
  swiper.loopFix();
2563
2304
  }
@@ -2568,8 +2309,6 @@ function onTouchStart(event) {
2568
2309
  if ('which' in e && e.which === 3) return;
2569
2310
  if ('button' in e && e.button > 0) return;
2570
2311
  if (data.isTouched && data.isMoved) return;
2571
-
2572
- // change target el for shadow root component
2573
2312
  const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
2574
2313
  // eslint-disable-next-line
2575
2314
  const eventPath = e.composedPath ? e.composedPath() : e.path;
@@ -2578,8 +2317,6 @@ function onTouchStart(event) {
2578
2317
  }
2579
2318
  const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
2580
2319
  const isTargetShadow = !!(e.target && e.target.shadowRoot);
2581
-
2582
- // use closestElement for shadow root element to get the actual closest for nested shadow root element
2583
2320
  if (params.noSwiping && (isTargetShadow ? closestElement(noSwipingSelector, targetEl) : targetEl.closest(noSwipingSelector))) {
2584
2321
  swiper.allowClick = true;
2585
2322
  return;
@@ -2591,12 +2328,7 @@ function onTouchStart(event) {
2591
2328
  touches.currentY = e.pageY;
2592
2329
  const startX = touches.currentX;
2593
2330
  const startY = touches.currentY;
2594
-
2595
- // Do NOT start if iOS edge swipe is detected. Otherwise iOS app cannot swipe-to-go-back anymore
2596
-
2597
- if (!preventEdgeSwipe(swiper, e, startX)) {
2598
- return;
2599
- }
2331
+ if (!preventEdgeSwipe(swiper, e, startX)) return;
2600
2332
  Object.assign(data, {
2601
2333
  isTouched: true,
2602
2334
  isMoved: false,
@@ -2625,9 +2357,6 @@ function onTouchStart(event) {
2625
2357
  if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !targetEl.isContentEditable) {
2626
2358
  e.preventDefault();
2627
2359
  }
2628
- if (params.freeMode && params.freeMode.enabled && swiper.freeMode && swiper.animating && !params.cssMode) {
2629
- swiper.freeMode.onTouchStart();
2630
- }
2631
2360
  swiper.emit('touchStart', e);
2632
2361
  }
2633
2362
 
@@ -2646,7 +2375,7 @@ function onTouchMove(event) {
2646
2375
  let e = event;
2647
2376
  if (e.originalEvent) e = e.originalEvent;
2648
2377
  if (e.type === 'pointermove') {
2649
- if (data.touchId !== null) return; // return from pointer if we use touch
2378
+ if (data.touchId !== null) return;
2650
2379
  const id = e.pointerId;
2651
2380
  if (id !== data.pointerId) return;
2652
2381
  }
@@ -2687,7 +2416,6 @@ function onTouchMove(event) {
2687
2416
  }
2688
2417
  if (params.touchReleaseOnEdges && !params.loop) {
2689
2418
  if (swiper.isVertical()) {
2690
- // Vertical
2691
2419
  if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper.translate >= swiper.minTranslate()) {
2692
2420
  data.isTouched = false;
2693
2421
  data.isMoved = false;
@@ -2789,7 +2517,6 @@ function onTouchMove(event) {
2789
2517
  swiper.wrapperEl.dispatchEvent(evt);
2790
2518
  }
2791
2519
  data.allowMomentumBounce = false;
2792
- // Grab Cursor
2793
2520
  if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
2794
2521
  swiper.setGrabCursor(true);
2795
2522
  }
@@ -2860,8 +2587,6 @@ function onTouchMove(event) {
2860
2587
  if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
2861
2588
  data.currentTranslate = data.startTranslate;
2862
2589
  }
2863
-
2864
- // Threshold
2865
2590
  if (params.threshold > 0) {
2866
2591
  if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
2867
2592
  if (!data.allowThresholdMove) {
@@ -2879,17 +2604,12 @@ function onTouchMove(event) {
2879
2604
  }
2880
2605
  if (!params.followFinger || params.cssMode) return;
2881
2606
 
2882
- // Update active index in free mode
2883
- if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {
2607
+ // core-lite: no optional feature updates; only watchSlidesProgress
2608
+ if (params.watchSlidesProgress) {
2884
2609
  swiper.updateActiveIndex();
2885
2610
  swiper.updateSlidesClasses();
2886
2611
  }
2887
- if (params.freeMode && params.freeMode.enabled && swiper.freeMode) {
2888
- swiper.freeMode.onTouchMove();
2889
- }
2890
- // Update progress
2891
2612
  swiper.updateProgress(data.currentTranslate);
2892
- // Update translate
2893
2613
  swiper.setTranslate(data.currentTranslate);
2894
2614
  }
2895
2615
 
@@ -2901,7 +2621,7 @@ function onTouchEnd(event) {
2901
2621
  let targetTouch;
2902
2622
  const isTouchEvent = e.type === 'touchend' || e.type === 'touchcancel';
2903
2623
  if (!isTouchEvent) {
2904
- if (data.touchId !== null) return; // return from pointer if we use touch
2624
+ if (data.touchId !== null) return;
2905
2625
  if (e.pointerId !== data.pointerId) return;
2906
2626
  targetTouch = e;
2907
2627
  } else {
@@ -2910,9 +2630,7 @@ function onTouchEnd(event) {
2910
2630
  }
2911
2631
  if (['pointercancel', 'pointerout', 'pointerleave', 'contextmenu'].includes(e.type)) {
2912
2632
  const proceed = ['pointercancel', 'contextmenu'].includes(e.type) && (swiper.browser.isSafari || swiper.browser.isWebView);
2913
- if (!proceed) {
2914
- return;
2915
- }
2633
+ if (!proceed) return;
2916
2634
  }
2917
2635
  data.pointerId = null;
2918
2636
  data.touchId = null;
@@ -2930,9 +2648,7 @@ function onTouchEnd(event) {
2930
2648
  }
2931
2649
  data.allowTouchCallbacks = false;
2932
2650
  if (!data.isTouched) {
2933
- if (data.isMoved && params.grabCursor) {
2934
- swiper.setGrabCursor(false);
2935
- }
2651
+ if (data.isMoved && params.grabCursor) swiper.setGrabCursor(false);
2936
2652
  data.isMoved = false;
2937
2653
  data.startMoving = false;
2938
2654
  return;
@@ -2942,8 +2658,6 @@ function onTouchEnd(event) {
2942
2658
  if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
2943
2659
  swiper.setGrabCursor(false);
2944
2660
  }
2945
-
2946
- // Time diff
2947
2661
  const touchEndTime = now();
2948
2662
  const timeDiff = touchEndTime - data.touchStartTime;
2949
2663
 
@@ -2970,20 +2684,8 @@ function onTouchEnd(event) {
2970
2684
  data.isMoved = false;
2971
2685
  data.startMoving = false;
2972
2686
  let currentPos;
2973
- if (params.followFinger) {
2974
- currentPos = rtl ? swiper.translate : -swiper.translate;
2975
- } else {
2976
- currentPos = -data.currentTranslate;
2977
- }
2978
- if (params.cssMode) {
2979
- return;
2980
- }
2981
- if (params.freeMode && params.freeMode.enabled) {
2982
- swiper.freeMode.onTouchEnd({
2983
- currentPos
2984
- });
2985
- return;
2986
- }
2687
+ if (params.followFinger) currentPos = rtl ? swiper.translate : -swiper.translate;else currentPos = -data.currentTranslate;
2688
+ if (params.cssMode) return;
2987
2689
 
2988
2690
  // Find current slide
2989
2691
  const swipeToLast = currentPos >= -swiper.maxTranslate() && !swiper.params.loop;
@@ -3005,22 +2707,22 @@ function onTouchEnd(event) {
3005
2707
  let rewindLastIndex = null;
3006
2708
  if (params.rewind) {
3007
2709
  if (swiper.isBeginning) {
3008
- rewindLastIndex = params.virtual && params.virtual.enabled && swiper.virtual ? swiper.virtual.slides.length - 1 : swiper.slides.length - 1;
2710
+ rewindLastIndex = swiper.slides.length - 1;
3009
2711
  } else if (swiper.isEnd) {
3010
2712
  rewindFirstIndex = 0;
3011
2713
  }
3012
2714
  }
3013
- // Find current slide size
3014
2715
  const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
3015
2716
  const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
3016
2717
  if (timeDiff > params.longSwipesMs) {
3017
- // Long touches
3018
2718
  if (!params.longSwipes) {
3019
2719
  swiper.slideTo(swiper.activeIndex);
3020
2720
  return;
3021
2721
  }
3022
2722
  if (swiper.swipeDirection === 'next') {
3023
- if (ratio >= params.longSwipesRatio) swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);else swiper.slideTo(stopIndex);
2723
+ if (ratio >= params.longSwipesRatio) {
2724
+ swiper.slideTo(params.rewind && swiper.isEnd ? rewindFirstIndex : stopIndex + increment);
2725
+ } else swiper.slideTo(stopIndex);
3024
2726
  }
3025
2727
  if (swiper.swipeDirection === 'prev') {
3026
2728
  if (ratio > 1 - params.longSwipesRatio) {
@@ -3072,7 +2774,6 @@ function onResize() {
3072
2774
  allowSlidePrev,
3073
2775
  snapGrid
3074
2776
  } = swiper;
3075
- const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
3076
2777
 
3077
2778
  // Disable locks on resize
3078
2779
  swiper.allowSlideNext = true;
@@ -3080,15 +2781,12 @@ function onResize() {
3080
2781
  swiper.updateSize();
3081
2782
  swiper.updateSlides();
3082
2783
  swiper.updateSlidesClasses();
3083
- const isVirtualLoop = isVirtual && params.loop;
3084
- if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides && !isVirtualLoop) {
2784
+ if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides) {
3085
2785
  swiper.slideTo(swiper.slides.length - 1, 0, false, true);
2786
+ } else if (swiper.params.loop) {
2787
+ swiper.slideToLoop(swiper.realIndex, 0, false, true);
3086
2788
  } else {
3087
- if (swiper.params.loop && !isVirtual) {
3088
- swiper.slideToLoop(swiper.realIndex, 0, false, true);
3089
- } else {
3090
- swiper.slideTo(swiper.activeIndex, 0, false, true);
3091
- }
2789
+ swiper.slideTo(swiper.activeIndex, 0, false, true);
3092
2790
  }
3093
2791
  if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
3094
2792
  clearTimeout(swiper.autoplay.resizeTimeout);
@@ -3098,10 +2796,11 @@ function onResize() {
3098
2796
  }
3099
2797
  }, 500);
3100
2798
  }
2799
+
3101
2800
  // Return locks after resize
3102
2801
  swiper.allowSlidePrev = allowSlidePrev;
3103
2802
  swiper.allowSlideNext = allowSlideNext;
3104
- if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
2803
+ if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
3105
2804
  swiper.checkOverflow();
3106
2805
  }
3107
2806
  }
@@ -3155,6 +2854,10 @@ function onLoad(e) {
3155
2854
  if (swiper.params.cssMode || swiper.params.slidesPerView !== 'auto' && !swiper.params.autoHeight) {
3156
2855
  return;
3157
2856
  }
2857
+ const el = e?.target;
2858
+ // IMG, IFRAME, EMBED with width/height attributes don't change slide size — no need to call swiper.update()
2859
+ if (!el || !['IMG', 'IFRAME', 'EMBED'].includes(el.tagName)) return;
2860
+ if (el.hasAttribute('width') && el.hasAttribute('height')) return;
3158
2861
  swiper.update();
3159
2862
  }
3160
2863
 
@@ -3266,8 +2969,15 @@ var events$1 = {
3266
2969
  detachEvents
3267
2970
  };
3268
2971
 
3269
- const isGridEnabled = (swiper, params) => {
3270
- return swiper.grid && params.grid && params.grid.rows > 1;
2972
+ const toggleModule = (swiper, params, breakpointParams, prop) => {
2973
+ const wasModuleEnabled = params[prop] && params[prop].enabled;
2974
+ const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
2975
+ if (wasModuleEnabled && !isModuleEnabled) {
2976
+ swiper[prop].disable();
2977
+ }
2978
+ if (!wasModuleEnabled && isModuleEnabled) {
2979
+ swiper[prop].enable();
2980
+ }
3271
2981
  };
3272
2982
  function setBreakpoint() {
3273
2983
  const swiper = this;
@@ -3288,38 +2998,20 @@ function setBreakpoint() {
3288
2998
  if (!breakpoint || swiper.currentBreakpoint === breakpoint) return;
3289
2999
  const breakpointOnlyParams = breakpoint in breakpoints ? breakpoints[breakpoint] : undefined;
3290
3000
  const breakpointParams = breakpointOnlyParams || swiper.originalParams;
3291
- const wasMultiRow = isGridEnabled(swiper, params);
3292
- const isMultiRow = isGridEnabled(swiper, breakpointParams);
3293
3001
  const wasGrabCursor = swiper.params.grabCursor;
3294
3002
  const isGrabCursor = breakpointParams.grabCursor;
3295
3003
  const wasEnabled = params.enabled;
3296
- if (wasMultiRow && !isMultiRow) {
3297
- el.classList.remove(`${params.containerModifierClass}grid`, `${params.containerModifierClass}grid-column`);
3298
- swiper.emitContainerClasses();
3299
- } else if (!wasMultiRow && isMultiRow) {
3300
- el.classList.add(`${params.containerModifierClass}grid`);
3301
- if (breakpointParams.grid.fill && breakpointParams.grid.fill === 'column' || !breakpointParams.grid.fill && params.grid.fill === 'column') {
3302
- el.classList.add(`${params.containerModifierClass}grid-column`);
3303
- }
3304
- swiper.emitContainerClasses();
3305
- }
3306
3004
  if (wasGrabCursor && !isGrabCursor) {
3307
3005
  swiper.unsetGrabCursor();
3308
3006
  } else if (!wasGrabCursor && isGrabCursor) {
3309
3007
  swiper.setGrabCursor();
3310
3008
  }
3311
3009
 
3312
- // Toggle navigation, pagination, scrollbar
3313
- ['navigation', 'pagination', 'scrollbar'].forEach(prop => {
3010
+ // Core-lite: toggle navigation & pagination only.
3011
+ const modules = ['navigation', 'pagination'];
3012
+ modules.forEach(prop => {
3314
3013
  if (typeof breakpointParams[prop] === 'undefined') return;
3315
- const wasModuleEnabled = params[prop] && params[prop].enabled;
3316
- const isModuleEnabled = breakpointParams[prop] && breakpointParams[prop].enabled;
3317
- if (wasModuleEnabled && !isModuleEnabled) {
3318
- swiper[prop].disable();
3319
- }
3320
- if (!wasModuleEnabled && isModuleEnabled) {
3321
- swiper[prop].enable();
3322
- }
3014
+ toggleModule(swiper, params, breakpointParams, prop);
3323
3015
  });
3324
3016
  const directionChanged = breakpointParams.direction && breakpointParams.direction !== params.direction;
3325
3017
  const needsReLoop = params.loop && (breakpointParams.slidesPerView !== params.slidesPerView || directionChanged);
@@ -3401,7 +3093,7 @@ var breakpoints = {
3401
3093
  getBreakpoint
3402
3094
  };
3403
3095
 
3404
- function prepareClasses(entries, prefix) {
3096
+ const prepareClasses = (entries, prefix) => {
3405
3097
  const resultClasses = [];
3406
3098
  entries.forEach(item => {
3407
3099
  if (typeof item === 'object') {
@@ -3415,7 +3107,7 @@ function prepareClasses(entries, prefix) {
3415
3107
  }
3416
3108
  });
3417
3109
  return resultClasses;
3418
- }
3110
+ };
3419
3111
  function addClasses() {
3420
3112
  const swiper = this;
3421
3113
  const {
@@ -3425,17 +3117,12 @@ function addClasses() {
3425
3117
  el,
3426
3118
  device
3427
3119
  } = swiper;
3120
+ // core-lite: removed module-specific classes
3428
3121
  // prettier-ignore
3429
3122
  const suffixes = prepareClasses(['initialized', params.direction, {
3430
- 'free-mode': swiper.params.freeMode && params.freeMode.enabled
3431
- }, {
3432
3123
  'autoheight': params.autoHeight
3433
3124
  }, {
3434
3125
  'rtl': rtl
3435
- }, {
3436
- 'grid': params.grid && params.grid.rows > 1
3437
- }, {
3438
- 'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
3439
3126
  }, {
3440
3127
  'android': device.android
3441
3128
  }, {
@@ -3532,16 +3219,12 @@ var defaults = {
3532
3219
  autoHeight: false,
3533
3220
  // Set wrapper width
3534
3221
  setWrapperSize: false,
3535
- // Virtual Translate
3536
- virtualTranslate: false,
3537
- // Effects
3222
+ // Effects (core-lite only supports `slide`)
3538
3223
  effect: 'slide',
3539
- // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
3540
-
3541
3224
  // Breakpoints
3542
3225
  breakpoints: undefined,
3543
3226
  breakpointsBase: 'window',
3544
- // Slides grid
3227
+ // Slides
3545
3228
  spaceBetween: 0,
3546
3229
  slidesPerView: 1,
3547
3230
  slidesPerGroup: 1,
@@ -3644,7 +3327,9 @@ function moduleExtendParams(params, allModulesParams) {
3644
3327
  if (moduleParamName === 'navigation' && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].prevEl && !params[moduleParamName].nextEl) {
3645
3328
  params[moduleParamName].auto = true;
3646
3329
  }
3647
- if (['pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].el) {
3330
+
3331
+ // Core-lite: keep only pagination auto-init.
3332
+ if (moduleParamName === 'pagination' && params[moduleParamName] && params[moduleParamName].enabled && !params[moduleParamName].el) {
3648
3333
  params[moduleParamName].auto = true;
3649
3334
  }
3650
3335
  if (!(moduleParamName in params && 'enabled' in moduleParams)) {
@@ -3770,7 +3455,6 @@ class Swiper {
3770
3455
  // Indexes
3771
3456
  activeIndex: 0,
3772
3457
  realIndex: 0,
3773
- //
3774
3458
  isBeginning: true,
3775
3459
  isEnd: false,
3776
3460
  // Props
@@ -3797,12 +3481,9 @@ class Swiper {
3797
3481
  currentTranslate: undefined,
3798
3482
  startTranslate: undefined,
3799
3483
  allowThresholdMove: undefined,
3800
- // Form elements to match
3801
3484
  focusableElements: swiper.params.focusableElements,
3802
- // Last click time
3803
3485
  lastClickTime: 0,
3804
3486
  clickTimeout: undefined,
3805
- // Velocities
3806
3487
  velocities: [],
3807
3488
  allowMomentumBounce: undefined,
3808
3489
  startMoving: undefined,
@@ -3831,7 +3512,6 @@ class Swiper {
3831
3512
  swiper.init();
3832
3513
  }
3833
3514
 
3834
- // Return app instance
3835
3515
  // eslint-disable-next-line no-constructor-return
3836
3516
  return swiper;
3837
3517
  }
@@ -3863,16 +3543,6 @@ class Swiper {
3863
3543
  getSlideIndexByData(index) {
3864
3544
  return this.getSlideIndex(this.slides.find(slideEl => slideEl.getAttribute('data-swiper-slide-index') * 1 === index));
3865
3545
  }
3866
- getSlideIndexWhenGrid(index) {
3867
- if (this.grid && this.params.grid && this.params.grid.rows > 1) {
3868
- if (this.params.grid.fill === 'column') {
3869
- index = Math.floor(index / this.params.grid.rows);
3870
- } else if (this.params.grid.fill === 'row') {
3871
- index = index % Math.ceil(this.slides.length / this.params.grid.rows);
3872
- }
3873
- }
3874
- return index;
3875
- }
3876
3546
  recalcSlides() {
3877
3547
  const swiper = this;
3878
3548
  const {
@@ -3974,21 +3644,15 @@ class Swiper {
3974
3644
  }
3975
3645
  }
3976
3646
  } else {
3977
- // eslint-disable-next-line
3978
3647
  if (view === 'current') {
3979
3648
  for (let i = activeIndex + 1; i < slides.length; i += 1) {
3980
3649
  const slideInView = exact ? slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize : slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
3981
- if (slideInView) {
3982
- spv += 1;
3983
- }
3650
+ if (slideInView) spv += 1;
3984
3651
  }
3985
3652
  } else {
3986
- // previous
3987
3653
  for (let i = activeIndex - 1; i >= 0; i -= 1) {
3988
3654
  const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
3989
- if (slideInView) {
3990
- spv += 1;
3991
- }
3655
+ if (slideInView) spv += 1;
3992
3656
  }
3993
3657
  }
3994
3658
  }
@@ -4001,14 +3665,11 @@ class Swiper {
4001
3665
  snapGrid,
4002
3666
  params
4003
3667
  } = swiper;
4004
- // Breakpoints
4005
3668
  if (params.breakpoints) {
4006
3669
  swiper.setBreakpoint();
4007
3670
  }
4008
3671
  [...swiper.el.querySelectorAll('[loading="lazy"]')].forEach(imageEl => {
4009
- if (imageEl.complete) {
4010
- processLazyPreloader(swiper, imageEl);
4011
- }
3672
+ if (imageEl.complete) processLazyPreloader(swiper, imageEl);
4012
3673
  });
4013
3674
  swiper.updateSize();
4014
3675
  swiper.updateSlides();
@@ -4022,22 +3683,12 @@ class Swiper {
4022
3683
  swiper.updateSlidesClasses();
4023
3684
  }
4024
3685
  let translated;
4025
- if (params.freeMode && params.freeMode.enabled && !params.cssMode) {
4026
- setTranslate();
4027
- if (params.autoHeight) {
4028
- swiper.updateAutoHeight();
4029
- }
3686
+ if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
3687
+ translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);
4030
3688
  } else {
4031
- if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !params.centeredSlides) {
4032
- const slides = swiper.virtual && params.virtual.enabled ? swiper.virtual.slides : swiper.slides;
4033
- translated = swiper.slideTo(slides.length - 1, 0, false, true);
4034
- } else {
4035
- translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
4036
- }
4037
- if (!translated) {
4038
- setTranslate();
4039
- }
3689
+ translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
4040
3690
  }
3691
+ if (!translated) setTranslate();
4041
3692
  if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
4042
3693
  swiper.checkOverflow();
4043
3694
  }
@@ -4050,7 +3701,6 @@ class Swiper {
4050
3701
  const swiper = this;
4051
3702
  const currentDirection = swiper.params.direction;
4052
3703
  if (!newDirection) {
4053
- // eslint-disable-next-line
4054
3704
  newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
4055
3705
  }
4056
3706
  if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
@@ -4088,15 +3738,11 @@ class Swiper {
4088
3738
  mount(element) {
4089
3739
  const swiper = this;
4090
3740
  if (swiper.mounted) return true;
4091
-
4092
- // Find el
4093
3741
  let el = element || swiper.params.el;
4094
3742
  if (typeof el === 'string') {
4095
3743
  el = document.querySelector(el);
4096
3744
  }
4097
- if (!el) {
4098
- return false;
4099
- }
3745
+ if (!el) return false;
4100
3746
  el.swiper = swiper;
4101
3747
  if (el.parentNode && el.parentNode.host && el.parentNode.host.nodeName === swiper.params.swiperElementNodeName.toUpperCase()) {
4102
3748
  swiper.isElement = true;
@@ -4107,12 +3753,10 @@ class Swiper {
4107
3753
  const getWrapper = () => {
4108
3754
  if (el && el.shadowRoot && el.shadowRoot.querySelector) {
4109
3755
  const res = el.shadowRoot.querySelector(getWrapperSelector());
4110
- // Children needs to return slot items
4111
3756
  return res;
4112
3757
  }
4113
3758
  return elementChildren(el, getWrapperSelector())[0];
4114
3759
  };
4115
- // Find Wrapper
4116
3760
  let wrapperEl = getWrapper();
4117
3761
  if (!wrapperEl && swiper.params.createElements) {
4118
3762
  wrapperEl = createElement('div', swiper.params.wrapperClass);
@@ -4127,7 +3771,6 @@ class Swiper {
4127
3771
  slidesEl: swiper.isElement && !el.parentNode.host.slideSlots ? el.parentNode.host : wrapperEl,
4128
3772
  hostEl: swiper.isElement ? el.parentNode.host : el,
4129
3773
  mounted: true,
4130
- // RTL
4131
3774
  rtl: el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl',
4132
3775
  rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || elementStyle(el, 'direction') === 'rtl'),
4133
3776
  wrongRTL: elementStyle(wrapperEl, 'display') === '-webkit-box'
@@ -4147,7 +3790,6 @@ class Swiper {
4147
3790
  const gap = Math.abs(swiper.snapGrid[1] - swiper.snapGrid[0]);
4148
3791
  const swiperTranslate = structuredClone(swiper.snapGrid[1]);
4149
3792
  if (isFirstSlide) {
4150
- // Move last item to first position when at first slide
4151
3793
  const lastSlide = slides.at(-1);
4152
3794
  lastSlide.swiperLoopMoveDOM = true;
4153
3795
  swiper.slidesEl.prepend(lastSlide);
@@ -4159,7 +3801,6 @@ class Swiper {
4159
3801
  swiper.setTransition(speed);
4160
3802
  swiper.setTranslate(-swiperTranslate);
4161
3803
  } else if (isLastSlide) {
4162
- // Move first item to last position when at last slide
4163
3804
  const firstSlide = slides[0];
4164
3805
  firstSlide.swiperLoopMoveDOM = true;
4165
3806
  swiper.slidesEl.append(firstSlide);
@@ -4180,42 +3821,24 @@ class Swiper {
4180
3821
  const mounted = swiper.mount(el);
4181
3822
  if (mounted === false) return swiper;
4182
3823
  swiper.emit('beforeInit');
4183
-
4184
- // Set breakpoint
4185
3824
  if (swiper.params.breakpoints) {
4186
3825
  swiper.setBreakpoint();
4187
3826
  }
4188
-
4189
- // Add Classes
4190
3827
  swiper.addClasses();
4191
-
4192
- // Update size
4193
3828
  swiper.updateSize();
4194
-
4195
- // Update slides
4196
3829
  swiper.updateSlides();
4197
3830
  if (swiper.params.watchOverflow) {
4198
3831
  swiper.checkOverflow();
4199
3832
  }
4200
-
4201
- // Set Grab Cursor
4202
3833
  if (swiper.params.grabCursor && swiper.enabled) {
4203
3834
  swiper.setGrabCursor();
4204
3835
  }
4205
3836
 
4206
- // Slide To Initial Slide
4207
- if (swiper.params.loop && swiper.virtual && swiper.params.virtual.enabled) {
4208
- swiper.slideTo(swiper.params.initialSlide + swiper.virtual.slidesBefore, 0, swiper.params.runCallbacksOnInit, false, true);
4209
- } else {
4210
- swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
4211
- }
4212
-
4213
- // Create loop
3837
+ // Slide to initial slide (core-lite: no optional feature initial offsets)
3838
+ swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
4214
3839
  if (swiper.params.loop) {
4215
3840
  swiper.loopCreate(undefined, true);
4216
3841
  }
4217
-
4218
- // Attach events
4219
3842
  swiper.attachEvents();
4220
3843
  const lazyElements = [...swiper.el.querySelectorAll('[loading="lazy"]')];
4221
3844
  if (swiper.isElement) {
@@ -4225,18 +3848,12 @@ class Swiper {
4225
3848
  if (imageEl.complete) {
4226
3849
  processLazyPreloader(swiper, imageEl);
4227
3850
  } else {
4228
- imageEl.addEventListener('load', e => {
4229
- processLazyPreloader(swiper, e.target);
4230
- });
3851
+ imageEl.addEventListener('load', e => processLazyPreloader(swiper, e.target));
4231
3852
  }
4232
3853
  });
4233
3854
  preload(swiper);
4234
-
4235
- // Init Flag
4236
3855
  swiper.initialized = true;
4237
3856
  preload(swiper);
4238
-
4239
- // Emit
4240
3857
  swiper.emit('init');
4241
3858
  swiper.emit('afterInit');
4242
3859
  return swiper;
@@ -4259,27 +3876,15 @@ class Swiper {
4259
3876
  return null;
4260
3877
  }
4261
3878
  swiper.emit('beforeDestroy');
4262
-
4263
- // Init Flag
4264
3879
  swiper.initialized = false;
4265
-
4266
- // Detach events
4267
3880
  swiper.detachEvents();
4268
-
4269
- // Destroy loop
4270
3881
  if (params.loop) {
4271
3882
  swiper.loopDestroy();
4272
3883
  }
4273
-
4274
- // Cleanup styles
4275
3884
  if (cleanStyles) {
4276
3885
  swiper.removeClasses();
4277
- if (el && typeof el !== 'string') {
4278
- el.removeAttribute('style');
4279
- }
4280
- if (wrapperEl) {
4281
- wrapperEl.removeAttribute('style');
4282
- }
3886
+ if (el && typeof el !== 'string') el.removeAttribute('style');
3887
+ if (wrapperEl) wrapperEl.removeAttribute('style');
4283
3888
  if (slides && slides.length) {
4284
3889
  slides.forEach(slideEl => {
4285
3890
  slideEl.classList.remove(params.slideVisibleClass, params.slideFullyVisibleClass, params.slideActiveClass, params.slideNextClass, params.slidePrevClass);
@@ -4289,8 +3894,6 @@ class Swiper {
4289
3894
  }
4290
3895
  }
4291
3896
  swiper.emit('destroy');
4292
-
4293
- // Detach emitter events
4294
3897
  Object.keys(swiper.eventsListeners).forEach(eventName => {
4295
3898
  swiper.off(eventName);
4296
3899
  });