/* eslint no-param-reassign: "off" */
|
import $ from '../../utils/dom';
|
import Utils from '../../utils/utils';
|
import Support from '../../utils/support';
|
|
import SwiperClass from '../../utils/class';
|
|
import update from './update/index';
|
import translate from './translate/index';
|
import transition from './transition/index';
|
import slide from './slide/index';
|
import loop from './loop/index';
|
import grabCursor from './grab-cursor/index';
|
import manipulation from './manipulation/index';
|
import events from './events/index';
|
import breakpoints from './breakpoints/index';
|
import classes from './classes/index';
|
import images from './images/index';
|
import checkOverflow from './check-overflow/index';
|
|
import defaults from './defaults';
|
|
const prototypes = {
|
update,
|
translate,
|
transition,
|
slide,
|
loop,
|
grabCursor,
|
manipulation,
|
events,
|
breakpoints,
|
checkOverflow,
|
classes,
|
images,
|
};
|
|
const extendedDefaults = {};
|
|
class Swiper extends SwiperClass {
|
constructor(...args) {
|
let el;
|
let params;
|
if (args.length === 1 && args[0].constructor && args[0].constructor === Object) {
|
params = args[0];
|
} else {
|
[el, params] = args;
|
}
|
if (!params) params = {};
|
|
params = Utils.extend({}, params);
|
if (el && !params.el) params.el = el;
|
|
super(params);
|
|
Object.keys(prototypes).forEach((prototypeGroup) => {
|
Object.keys(prototypes[prototypeGroup]).forEach((protoMethod) => {
|
if (!Swiper.prototype[protoMethod]) {
|
Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
|
}
|
});
|
});
|
|
// Swiper Instance
|
const swiper = this;
|
if (typeof swiper.modules === 'undefined') {
|
swiper.modules = {};
|
}
|
Object.keys(swiper.modules).forEach((moduleName) => {
|
const module = swiper.modules[moduleName];
|
if (module.params) {
|
const moduleParamName = Object.keys(module.params)[0];
|
const moduleParams = module.params[moduleParamName];
|
if (typeof moduleParams !== 'object' || moduleParams === null) return;
|
if (!(moduleParamName in params && 'enabled' in moduleParams)) return;
|
if (params[moduleParamName] === true) {
|
params[moduleParamName] = { enabled: true };
|
}
|
if (
|
typeof params[moduleParamName] === 'object'
|
&& !('enabled' in params[moduleParamName])
|
) {
|
params[moduleParamName].enabled = true;
|
}
|
if (!params[moduleParamName]) params[moduleParamName] = { enabled: false };
|
}
|
});
|
|
// Extend defaults with modules params
|
const swiperParams = Utils.extend({}, defaults);
|
swiper.useModulesParams(swiperParams);
|
|
// Extend defaults with passed params
|
swiper.params = Utils.extend({}, swiperParams, extendedDefaults, params);
|
swiper.originalParams = Utils.extend({}, swiper.params);
|
swiper.passedParams = Utils.extend({}, params);
|
|
// Save Dom lib
|
swiper.$ = $;
|
|
// Find el
|
const $el = $(swiper.params.el);
|
el = $el[0];
|
|
if (!el) {
|
return undefined;
|
}
|
|
if ($el.length > 1) {
|
const swipers = [];
|
$el.each((index, containerEl) => {
|
const newParams = Utils.extend({}, params, { el: containerEl });
|
swipers.push(new Swiper(newParams));
|
});
|
return swipers;
|
}
|
|
el.swiper = swiper;
|
$el.data('swiper', swiper);
|
|
// Find Wrapper
|
let $wrapperEl;
|
if (el && el.shadowRoot && el.shadowRoot.querySelector) {
|
$wrapperEl = $(el.shadowRoot.querySelector(`.${swiper.params.wrapperClass}`));
|
// Children needs to return slot items
|
$wrapperEl.children = (options) => $el.children(options);
|
} else {
|
$wrapperEl = $el.children(`.${swiper.params.wrapperClass}`);
|
}
|
// Extend Swiper
|
Utils.extend(swiper, {
|
$el,
|
el,
|
$wrapperEl,
|
wrapperEl: $wrapperEl[0],
|
|
// Classes
|
classNames: [],
|
|
// Slides
|
slides: $(),
|
slidesGrid: [],
|
snapGrid: [],
|
slidesSizesGrid: [],
|
|
// isDirection
|
isHorizontal() {
|
return swiper.params.direction === 'horizontal';
|
},
|
isVertical() {
|
return swiper.params.direction === 'vertical';
|
},
|
// RTL
|
rtl: (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'),
|
rtlTranslate: swiper.params.direction === 'horizontal' && (el.dir.toLowerCase() === 'rtl' || $el.css('direction') === 'rtl'),
|
wrongRTL: $wrapperEl.css('display') === '-webkit-box',
|
|
// Indexes
|
activeIndex: 0,
|
realIndex: 0,
|
|
//
|
isBeginning: true,
|
isEnd: false,
|
|
// Props
|
translate: 0,
|
previousTranslate: 0,
|
progress: 0,
|
velocity: 0,
|
animating: false,
|
|
// Locks
|
allowSlideNext: swiper.params.allowSlideNext,
|
allowSlidePrev: swiper.params.allowSlidePrev,
|
|
// Touch Events
|
touchEvents: (function touchEvents() {
|
const touch = ['touchstart', 'touchmove', 'touchend', 'touchcancel'];
|
let desktop = ['mousedown', 'mousemove', 'mouseup'];
|
if (Support.pointerEvents) {
|
desktop = ['pointerdown', 'pointermove', 'pointerup'];
|
}
|
swiper.touchEventsTouch = {
|
start: touch[0],
|
move: touch[1],
|
end: touch[2],
|
cancel: touch[3],
|
};
|
swiper.touchEventsDesktop = {
|
start: desktop[0],
|
move: desktop[1],
|
end: desktop[2],
|
};
|
return Support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch : swiper.touchEventsDesktop;
|
}()),
|
touchEventsData: {
|
isTouched: undefined,
|
isMoved: undefined,
|
allowTouchCallbacks: undefined,
|
touchStartTime: undefined,
|
isScrolling: undefined,
|
currentTranslate: undefined,
|
startTranslate: undefined,
|
allowThresholdMove: undefined,
|
// Form elements to match
|
formElements: 'input, select, option, textarea, button, video, label',
|
// Last click time
|
lastClickTime: Utils.now(),
|
clickTimeout: undefined,
|
// Velocities
|
velocities: [],
|
allowMomentumBounce: undefined,
|
isTouchEvent: undefined,
|
startMoving: undefined,
|
},
|
|
// Clicks
|
allowClick: true,
|
|
// Touches
|
allowTouchMove: swiper.params.allowTouchMove,
|
|
touches: {
|
startX: 0,
|
startY: 0,
|
currentX: 0,
|
currentY: 0,
|
diff: 0,
|
},
|
|
// Images
|
imagesToLoad: [],
|
imagesLoaded: 0,
|
|
});
|
|
// Install Modules
|
swiper.useModules();
|
|
// Init
|
if (swiper.params.init) {
|
swiper.init();
|
}
|
|
// Return app instance
|
return swiper;
|
}
|
|
slidesPerViewDynamic() {
|
const swiper = this;
|
const {
|
params, slides, slidesGrid, size: swiperSize, activeIndex,
|
} = swiper;
|
let spv = 1;
|
if (params.centeredSlides) {
|
let slideSize = slides[activeIndex].swiperSlideSize;
|
let breakLoop;
|
for (let i = activeIndex + 1; i < slides.length; i += 1) {
|
if (slides[i] && !breakLoop) {
|
slideSize += slides[i].swiperSlideSize;
|
spv += 1;
|
if (slideSize > swiperSize) breakLoop = true;
|
}
|
}
|
for (let i = activeIndex - 1; i >= 0; i -= 1) {
|
if (slides[i] && !breakLoop) {
|
slideSize += slides[i].swiperSlideSize;
|
spv += 1;
|
if (slideSize > swiperSize) breakLoop = true;
|
}
|
}
|
} else {
|
for (let i = activeIndex + 1; i < slides.length; i += 1) {
|
if (slidesGrid[i] - slidesGrid[activeIndex] < swiperSize) {
|
spv += 1;
|
}
|
}
|
}
|
return spv;
|
}
|
|
update() {
|
const swiper = this;
|
if (!swiper || swiper.destroyed) return;
|
const { snapGrid, params } = swiper;
|
// Breakpoints
|
if (params.breakpoints) {
|
swiper.setBreakpoint();
|
}
|
swiper.updateSize();
|
swiper.updateSlides();
|
swiper.updateProgress();
|
swiper.updateSlidesClasses();
|
|
function setTranslate() {
|
const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
|
const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
|
swiper.setTranslate(newTranslate);
|
swiper.updateActiveIndex();
|
swiper.updateSlidesClasses();
|
}
|
let translated;
|
if (swiper.params.freeMode) {
|
setTranslate();
|
if (swiper.params.autoHeight) {
|
swiper.updateAutoHeight();
|
}
|
} else {
|
if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !swiper.params.centeredSlides) {
|
translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);
|
} else {
|
translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
|
}
|
if (!translated) {
|
setTranslate();
|
}
|
}
|
if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
|
swiper.checkOverflow();
|
}
|
swiper.emit('update');
|
}
|
|
changeDirection(newDirection, needUpdate = true) {
|
const swiper = this;
|
const currentDirection = swiper.params.direction;
|
if (!newDirection) {
|
// eslint-disable-next-line
|
newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
|
}
|
if ((newDirection === currentDirection) || (newDirection !== 'horizontal' && newDirection !== 'vertical')) {
|
return swiper;
|
}
|
|
swiper.$el
|
.removeClass(`${swiper.params.containerModifierClass}${currentDirection}`)
|
.addClass(`${swiper.params.containerModifierClass}${newDirection}`);
|
|
swiper.params.direction = newDirection;
|
|
swiper.slides.each((slideIndex, slideEl) => {
|
if (newDirection === 'vertical') {
|
slideEl.style.width = '';
|
} else {
|
slideEl.style.height = '';
|
}
|
});
|
|
swiper.emit('changeDirection');
|
if (needUpdate) swiper.update();
|
|
return swiper;
|
}
|
|
init() {
|
const swiper = this;
|
if (swiper.initialized) return;
|
|
swiper.emit('beforeInit');
|
|
// Set breakpoint
|
if (swiper.params.breakpoints) {
|
swiper.setBreakpoint();
|
}
|
|
// Add Classes
|
swiper.addClasses();
|
|
// Create loop
|
if (swiper.params.loop) {
|
swiper.loopCreate();
|
}
|
|
// Update size
|
swiper.updateSize();
|
|
// Update slides
|
swiper.updateSlides();
|
|
if (swiper.params.watchOverflow) {
|
swiper.checkOverflow();
|
}
|
|
// Set Grab Cursor
|
if (swiper.params.grabCursor) {
|
swiper.setGrabCursor();
|
}
|
|
if (swiper.params.preloadImages) {
|
swiper.preloadImages();
|
}
|
|
// Slide To Initial Slide
|
if (swiper.params.loop) {
|
swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params.runCallbacksOnInit);
|
} else {
|
swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit);
|
}
|
|
// Attach events
|
swiper.attachEvents();
|
|
// Init Flag
|
swiper.initialized = true;
|
|
// Emit
|
swiper.emit('init');
|
}
|
|
destroy(deleteInstance = true, cleanStyles = true) {
|
const swiper = this;
|
const {
|
params, $el, $wrapperEl, slides,
|
} = swiper;
|
|
if (typeof swiper.params === 'undefined' || swiper.destroyed) {
|
return null;
|
}
|
|
swiper.emit('beforeDestroy');
|
|
// Init Flag
|
swiper.initialized = false;
|
|
// Detach events
|
swiper.detachEvents();
|
|
// Destroy loop
|
if (params.loop) {
|
swiper.loopDestroy();
|
}
|
|
// Cleanup styles
|
if (cleanStyles) {
|
swiper.removeClasses();
|
$el.removeAttr('style');
|
$wrapperEl.removeAttr('style');
|
if (slides && slides.length) {
|
slides
|
.removeClass([
|
params.slideVisibleClass,
|
params.slideActiveClass,
|
params.slideNextClass,
|
params.slidePrevClass,
|
].join(' '))
|
.removeAttr('style')
|
.removeAttr('data-swiper-slide-index');
|
}
|
}
|
|
swiper.emit('destroy');
|
|
// Detach emitter events
|
Object.keys(swiper.eventsListeners).forEach((eventName) => {
|
swiper.off(eventName);
|
});
|
|
if (deleteInstance !== false) {
|
swiper.$el[0].swiper = null;
|
swiper.$el.data('swiper', null);
|
Utils.deleteProps(swiper);
|
}
|
swiper.destroyed = true;
|
|
return null;
|
}
|
|
static extendDefaults(newDefaults) {
|
Utils.extend(extendedDefaults, newDefaults);
|
}
|
|
static get extendedDefaults() {
|
return extendedDefaults;
|
}
|
|
static get defaults() {
|
return defaults;
|
}
|
|
static get Class() {
|
return SwiperClass;
|
}
|
|
static get $() {
|
return $;
|
}
|
}
|
|
export default Swiper;
|