/*! * Splide.js * Version : 2.0.1 * License : MIT * Copyright: 2019 Naotoshi Fujita */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["Splide"] = factory(); else root["Splide"] = factory(); })(window, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); var states_namespaceObject = {}; __webpack_require__.r(states_namespaceObject); __webpack_require__.d(states_namespaceObject, "CREATED", function() { return CREATED; }); __webpack_require__.d(states_namespaceObject, "MOUNTED", function() { return MOUNTED; }); __webpack_require__.d(states_namespaceObject, "IDLE", function() { return IDLE; }); __webpack_require__.d(states_namespaceObject, "MOVING", function() { return MOVING; }); __webpack_require__.d(states_namespaceObject, "DESTROYED", function() { return DESTROYED; }); // CONCATENATED MODULE: ./src/js/core/event.js /** * The function for providing an Event object simply managing events. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The function for providing an Event object simply managing events. */ /* harmony default export */ var core_event = (function () { /** * Store all event data. * * @type {Array} */ var data = []; var Event = { /** * Subscribe the given event(s). * * @param {string} events - An event name. Use space to separate multiple events. * Also, namespace is accepted by dot, such as 'resize.{namespace}'. * @param {function} handler - A callback function. * @param {Element} elm - Optional. Native event will be listened to when this arg is provided. * @param {Object} options - Optional. Options for addEventListener. */ on: function on(events, handler, elm, options) { if (elm === void 0) { elm = null; } if (options === void 0) { options = {}; } events.split(' ').forEach(function (event) { if (elm) { elm.addEventListener(event, handler, options); } data.push({ event: event, handler: handler, elm: elm, options: options }); }); }, /** * Unsubscribe the given event(s). * * @param {string} events - A event name or names split by space. * @param {Element} elm - Optional. removeEventListener() will be called when this arg is provided. */ off: function off(events, elm) { if (elm === void 0) { elm = null; } events.split(' ').forEach(function (event) { for (var i in data) { var item = data[i]; if (item && item.event === event && item.elm === elm) { unsubscribe(item); delete data[i]; break; } } }); }, /** * Emit an event. * This method is only for custom events. * * @param {string} event - An event name. * @param {*} args - Any number of arguments passed to handlers. */ emit: function emit(event) { for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } data.forEach(function (item) { if (!item.elm && item.event.split('.')[0] === event) { item.handler.apply(item, args); } }); }, /** * Clear event data. */ destroy: function destroy() { data.forEach(unsubscribe); data = []; } }; /** * Remove the registered event listener. * * @param {Object} item - An object containing event data. */ function unsubscribe(item) { if (item.elm) { item.elm.removeEventListener(item.event, item.handler, item.options); } } return Event; }); // CONCATENATED MODULE: ./src/js/core/state.js /** * The function providing a super simple state system. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The function providing a super simple state system. * * @param {string|number} initialState - Provide the initial state value. */ /* harmony default export */ var state = (function (initialState) { /** * Store the current state. * * @type {string|number} */ var curr = initialState; return { /** * Change state. * * @param {string|number} state - A new state. */ set: function set(state) { curr = state; }, /** * Verify if the current state is given one or not. * * @param {string|number} state - A state name to be verified. * * @return {boolean} - True if the current state is the given one. */ is: function is(state) { return state === curr; } }; }); // CONCATENATED MODULE: ./src/js/constants/classes.js /** * Export class names. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * A root class name. * * @type {string} */ var ROOT = 'splide'; /** * The definition table of all classes for elements. * They might be modified by options. * * @type {Object} */ var ELEMENT_CLASSES = { root: ROOT, slider: ROOT + "__slider", track: ROOT + "__track", list: ROOT + "__list", slide: ROOT + "__slide", container: ROOT + "__slide__container", arrows: ROOT + "__arrows", arrow: ROOT + "__arrow", prev: ROOT + "__arrow--prev", next: ROOT + "__arrow--next", pagination: ROOT + "__pagination", page: ROOT + "__pagination__page", clone: ROOT + "__slide--clone", progress: ROOT + "__progress", bar: ROOT + "__progress__bar", autoplay: ROOT + "__autoplay", play: ROOT + "__play", pause: ROOT + "__pause", spinner: ROOT + "__spinner", sr: ROOT + "__sr" }; /** * Definitions of status classes. * * @type {Object} */ var STATUS_CLASSES = { active: 'is-active', visible: 'is-visible', loading: 'is-loading' }; // CONCATENATED MODULE: ./src/js/constants/i18n.js /** * Export i18n texts as object. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Texts for i18n. * * @type {Object} */ var I18N = { prev: 'Previous slide', next: 'Next slide', first: 'Go to first slide', last: 'Go to last slide', slideX: 'Go to slide %s', pageX: 'Go to page %s', play: 'Start autoplay', pause: 'Pause autoplay' }; // CONCATENATED MODULE: ./src/js/constants/defaults.js /** * Export default options. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ var DEFAULTS = { /** * Determine a slider type. * - 'slide': Regular slider. * - 'loop' : Carousel slider. * - 'fade' : Change slides with fade transition. perPage, drag options are ignored. * * @type {string} */ type: 'slide', /** * Whether to rewind a slider before the first slide or after the last one. * In "loop" mode, this option is ignored. * * @type {boolean} */ rewind: false, /** * Transition speed in milliseconds. * * @type {number} */ speed: 400, /** * Define slider max width. * * @type {number} */ width: 0, /** * Define slider height. * * @type {number} */ height: 0, /** * Fix width of slides. CSS format is allowed such as 10em, 80% or 80vw. * perPage number will be ignored when this option is falsy. * * @type {number|string} */ fixedWidth: 0, /** * Fix height of slides. CSS format is allowed such as 10em, 80vh but % unit is not accepted. * heightRatio option will be ignored when this option is falsy. * * @type {number} */ fixedHeight: 0, /** * Determine height of slides by ratio to a slider width. * This will be ignored when the fixedHeight is provided. * * @type {number} */ heightRatio: 0, /** * If true, slide width will be determined by the element width itself. * - perPage/perMove should be 1. * - lazyLoad should be false. * * @type {boolean} */ autoWidth: false, /** * Determine how many slides should be displayed per page. * * @type {number} */ perPage: 1, /** * Determine how many slides should be moved when a slider goes to next or perv. * * @type {number} */ perMove: 0, /** * Start index. * * @type {number} */ start: 0, /** * Determine which slide should be focused if there are multiple slides in a page. * A string "center" is acceptable for centering slides. * * @type {boolean|number|string} */ focus: false, /** * Gap between slides. CSS format is allowed such as 1em. * * @type {number|string} */ gap: 0, /** * Set padding-left/right in horizontal mode or padding-top/bottom in vertical one. * Give a single value to set a same size for both sides or * do an object for different sizes. * Also, CSS format is allowed such as 1em. * * @example * - 10: Number * - '1em': CSS format. * - { left: 0, right: 20 }: Object for different sizes in horizontal mode. * - { top: 0, bottom: 20 }: Object for different sizes in vertical mode. * * @type {number|string|Object} */ padding: 0, /** * Whether to append arrows. * * @type {boolean} */ arrows: true, /** * Change the arrow SVG path like 'm7.61 0.807-2.12...'. * * @type {string} */ arrowPath: '', /** * Whether to append pagination(indicator dots) or not. * * @type {boolean} */ pagination: true, /** * Activate autoplay. * * @type {boolean} */ autoplay: false, /** * Autoplay interval in milliseconds. * * @type {number} */ interval: 5000, /** * Whether to stop autoplay when a slider is hovered. * * @type {boolean} */ pauseOnHover: true, /** * Whether to stop autoplay when a slider elements are focused. * True is recommended for accessibility. * * @type {boolean} */ pauseOnFocus: true, /** * Loading images lazily. * Image src must be provided by a data-splide-lazy attribute. * * - false: Do nothing. * - 'nearby': Only images around an active slide will be loaded. * - 'sequential': All images will be sequentially loaded. * * @type {boolean|string} */ lazyLoad: false, /** * This option works only when a lazyLoad option is "nearby". * Determine how many pages(not slides) around an active slide should be loaded beforehand. * * @type {number} */ preloadPages: 1, /** * Easing for CSS transition. For example, linear, ease or cubic-bezier(). * * @type {string} */ easing: 'cubic-bezier(.42,.65,.27,.99)', /** * Whether to control a slide via keyboard. * * @type {boolean} */ keyboard: true, /** * Whether to allow mouse drag and touch swipe. * * @type {boolean} */ drag: true, /** * Threshold for determining if the action is "flick" or "swipe". * Around 0.5 is recommended. * * @type {number} */ flickThreshold: .6, /** * Determine power of flick. The larger number this is, the farther a slider runs by flick. * Around 500 is recommended. * * @type {number} */ flickPower: 600, /** * Limit a number of pages to move by flick. * * @type {number} */ flickMaxPages: 1, /** * Slider direction. * - 'ltr': Left to right. * - 'rtl': Right to left. * - 'ttb': Top to bottom. * * @type {string} */ direction: 'ltr', /** * Set img src to background-image of its parent element. * Images with various sizes can be displayed as same dimension without cropping work. * fixedHeight or heightRatio is required. * * @type {boolean} */ cover: false, /** * Whether to enable accessibility(aria and screen reader texts) or not. * * @type {boolean} */ accessibility: true, /** * Determine if a slider is navigation for another. * Use "sync" API to synchronize two sliders. * * @type {boolean} */ isNavigation: false, /** * Whether to trim spaces before the fist slide or after the last one when "focus" is not 0. * * @type {boolean} */ trimSpace: true, /** * Slide status is updated after move as default. * If true, it will be updated before move. * * @type {boolean} */ updateOnMove: false, /** * Breakpoints definitions. * * @example * { * '1000': { * perPage: 3, * gap: 20 * }, * '600': { * perPage: 1, * gap: 5, * } * } * * @type {boolean|Object} */ breakpoints: false, /** * Collection of class names. * * @see ./classes.js * * @type {Object} */ classes: ELEMENT_CLASSES, /** * Collection of i18n texts. * * @see ./i18n.js * * @type {Object} */ i18n: I18N }; // CONCATENATED MODULE: ./src/js/utils/object.js function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /** * Some utility functions related with Object, supporting IE. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Iterate an object like Array.forEach. * IE doesn't support forEach of HTMLCollection. * * @param {Object} obj - An object. * @param {function} callback - A function handling each value. Arguments are value, property and index. */ function each(obj, callback) { Object.keys(obj).some(function (key, index) { return callback(obj[key], key, index); }); } /** * Return values of the given object as an array. * IE doesn't support Object.values. * * @param {Object} obj - An object. * * @return {Array} - An array containing all values of the given object. */ function values(obj) { return Object.keys(obj).map(function (key) { return obj[key]; }); } /** * Check if the given subject is object or not. * * @param {*} subject - A subject to be verified. * * @return {boolean} - True if object, false otherwise. */ function isObject(subject) { return typeof subject === 'object'; } /** * Merge two objects deeply. * * @param {Object} to - An object where "from" is merged. * @param {Object} from - An object merged to "to". * * @return {Object} - A merged object. */ function merge(_ref, from) { var to = _extends({}, _ref); each(from, function (value, key) { if (isObject(value)) { if (!isObject(to[key])) { to[key] = {}; } to[key] = merge(to[key], value); } else { to[key] = value; } }); return to; } /** * Assign all properties "from" to "to" object. * * @param {Object} to - An object where properties are assigned. * @param {Object} from - An object whose properties are assigned to "to". * * @return {Object} - An assigned object. */ function object_assign(to, from) { to._s = from; Object.keys(from).forEach(function (key) { if (!to[key]) { Object.defineProperty(to, key, Object.getOwnPropertyDescriptor(from, key)); } }); return to; } // CONCATENATED MODULE: ./src/js/utils/utils.js /** * A package of some miscellaneous utility functions. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Convert the given value to array. * * @param {*} value - Any value. * * @return {*[]} - Array containing the given value. */ function toArray(value) { return Array.isArray(value) ? value : [value]; } /** * Check if the given value is between min and max. * Min will be returned when the value is less than min or max will do when greater than max. * * @param {number} value - A number to be checked. * @param {number} m1 - Minimum or maximum number. * @param {number} m2 - Maximum or minimum number. * * @return {number} - A value itself, min or max. */ function between(value, m1, m2) { return Math.min(Math.max(value, m1 > m2 ? m2 : m1), m1 > m2 ? m1 : m2); } /** * The sprintf method with minimum functionality. * * @param {string} format - The string format. * @param {string|Array} replacements - Replacements accepting multiple arguments. * * @returns {string} - Converted string. */ function sprintf(format, replacements) { var i = 0; return format.replace(/%s/g, function () { return toArray(replacements)[i++]; }); } /** * Append px unit to the given subject if necessary. * * @param {number|string} value - A value that may not include an unit. * * @return {string} - If the value is string, return itself. * If number, do value + "px". An empty string, otherwise. */ function unit(value) { var type = typeof value; if (type === 'number' && value > 0) { return parseFloat(value) + 'px'; } return type === 'string' ? value : ''; } /** * Pad start with 0. * * @param {number} number - A number to be filled with 0. * * @return {string|number} - Padded number. */ function pad(number) { return number < 10 ? '0' + number : number; } /** * Convert the given value to pixel. * * @param {Element} root - Root element where a dummy div is appended. * @param {string|number} value - CSS value to be converted, such as 10rem. * * @return {number} - Pixel. */ function toPixel(root, value) { if (typeof value === 'string') { var div = create('div', {}); applyStyle(div, { position: 'absolute', width: value }); append(root, div); value = div.clientWidth; dom_remove(div); } return value; } // CONCATENATED MODULE: ./src/js/utils/dom.js /** * Some utility functions related with DOM. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Find the first element matching the given selector. * Be aware that all selectors after a space are ignored. * * @param {Element|Node} elm - An ancestor element. * @param {string} selector - DOMString. * * @return {Element|null} - A found element or null. */ function find(elm, selector) { return elm ? elm.querySelector(selector.split(' ')[0]) : null; } /** * Find a first child having the given tag or class name. * * @param {Element} parent - A parent element. * @param {string} tagOrClassName - A tag or class name. * * @return {Element|null} - A found element on success. Null on failure. */ function child(parent, tagOrClassName) { if (parent) { return values(parent.children).filter(function (child) { return hasClass(child, tagOrClassName.split(' ')[0]) || child.tagName.toLowerCase() === tagOrClassName; })[0] || null; } return null; } /** * Create an element with some optional attributes. * * @param {string} tag - A tag name. * @param {Object} attrs - An object any attribute pairs of name and value. * * @return {Element} - A created element. */ function create(tag, attrs) { var elm = document.createElement(tag); each(attrs, function (value, key) { return setAttribute(elm, key, value); }); return elm; } /** * Convert HTML string to DOM node. * * @param {string} html - HTML string. * * @return {Node} - A created node. */ function domify(html) { var div = create('div', {}); div.innerHTML = html; return div.firstChild; } /** * Remove a given element from a DOM tree. * * @param {Element|Element[]} elms - Element(s) to be removed. */ function dom_remove(elms) { toArray(elms).forEach(function (elm) { if (elm && elm.parentElement) { elm.parentElement.removeChild(elm); } }); } /** * Append a child to a given element. * * @param {Element} parent - A parent element. * @param {Element} child - An element to be appended. */ function append(parent, child) { if (parent) { parent.appendChild(child); } } /** * Insert an element before the reference element. * * @param {Element|Node} ref - A reference element. * @param {Element} elm - An element to be inserted. */ function before(elm, ref) { if (elm && ref && ref.parentElement) { ref.parentElement.insertBefore(elm, ref); } } /** * Apply styles to the given element. * * @param {Element} elm - An element where styles are applied. * @param {Object} styles - Object containing styles. */ function applyStyle(elm, styles) { if (elm) { each(styles, function (value, prop) { if (value !== null) { elm.style[prop] = value; } }); } } /** * Add or remove classes to/from the element. * This function is for internal usage. * * @param {Element} elm - An element where classes are added. * @param {string|string[]} classes - Class names being added. * @param {boolean} remove - Whether to remove or add classes. */ function addOrRemoveClasses(elm, classes, remove) { if (elm) { toArray(classes).forEach(function (name) { if (name) { elm.classList[remove ? 'remove' : 'add'](name); } }); } } /** * Add classes to the element. * * @param {Element} elm - An element where classes are added. * @param {string|string[]} classes - Class names being added. */ function addClass(elm, classes) { addOrRemoveClasses(elm, classes, false); } /** * Remove a class from the element. * * @param {Element} elm - An element where classes are removed. * @param {string|string[]} classes - A class name being removed. */ function removeClass(elm, classes) { addOrRemoveClasses(elm, classes, true); } /** * Verify if the provided element has the class or not. * * @param {Element} elm - An element. * @param {string} className - A class name. * * @return {boolean} - True if the element has the class or false if not. */ function hasClass(elm, className) { return !!elm && elm.classList.contains(className); } /** * Set attribute to the given element. * * @param {Element} elm - An element where an attribute is assigned. * @param {string} name - Attribute name. * @param {string|number|boolean} value - Attribute value. */ function setAttribute(elm, name, value) { if (elm) { elm.setAttribute(name, value); } } /** * Get attribute from the given element. * * @param {Element} elm - An element where an attribute is assigned. * @param {string} name - Attribute name. * * @return {string} - The value of the given attribute if available. An empty string if not. */ function getAttribute(elm, name) { return elm ? elm.getAttribute(name) : ''; } /** * Remove attribute from the given element. * * @param {Element|Element[]} elms - An element where an attribute is removed. * @param {string|string[]} names - Attribute name. */ function removeAttribute(elms, names) { toArray(names).forEach(function (name) { toArray(elms).forEach(function (elm) { return elm && elm.removeAttribute(name); }); }); } /** * Trigger the given callback after all images contained by the element are loaded. * * @param {Element} elm - Element that may contain images. * @param {Function} callback - Callback function fired right after all images are loaded. */ function dom_loaded(elm, callback) { var images = elm.querySelectorAll('img'); var length = images.length; if (length) { var count = 0; each(images, function (img) { img.onload = img.onerror = function () { if (++count === length) { callback(); } }; }); } else { // Trigger the callback immediately if there is no image. callback(); } } // CONCATENATED MODULE: ./src/js/transitions/slide/index.js /** * The component for general slide effect transition. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The component for general slide effect transition. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The component object. */ /* harmony default export */ var transitions_slide = (function (Splide, Components) { /** * Hold the list element. * * @type {Element} */ var list; /** * Hold the onEnd callback function. * * @type {function} */ var endCallback; return { /** * Called when the component is mounted. */ mount: function mount() { list = Components.Elements.list; Splide.on('transitionend', function (e) { if (e.target === list && endCallback) { endCallback(); } }, list); }, /** * Start transition. * * @param {number} destIndex - Destination slide index that might be clone's. * @param {number} newIndex - New index. * @param {Object} coord - Destination coordinates. * @param {function} done - Callback function must be invoked when transition is completed. */ start: function start(destIndex, newIndex, coord, done) { var options = Splide.options; endCallback = done; applyStyle(list, { transition: "transform " + options.speed + "ms " + options.easing, transform: "translate(" + coord.x + "px," + coord.y + "px)" }); } }; }); // CONCATENATED MODULE: ./src/js/transitions/fade/index.js /** * The component for fade transition. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The component for fade transition. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The component object. */ /* harmony default export */ var fade = (function (Splide, Components) { if (Components.Drag) { Components.Drag.required = false; } var Fade = { /** * Called when the component is mounted. * Apply transition style to the first slide. */ mount: function mount() { apply(Splide.index); }, /** * Start transition. * * @param {number} destIndex - Destination slide index that might be clone's. * @param {number} newIndex - New index. * @param {Object} coord - Destination coordinates. * @param {function} done - Callback function must be invoked when transition is completed. */ start: function start(destIndex, newIndex, coord, done) { apply(newIndex); done(); } }; /** * Apply transition style to the slide specified by the given index. * * @param {number} index - A slide index. */ function apply(index) { var options = Splide.options; applyStyle(Components.Elements.slides[index], { transition: "opacity " + options.speed + "ms " + options.easing }); } return Fade; }); // CONCATENATED MODULE: ./src/js/transitions/index.js /** * Export transition components. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ // CONCATENATED MODULE: ./src/js/constants/types.js /** * Export slider types. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Normal slider. * * @type {string} */ var SLIDE = 'slide'; /** * Loop after the last slide and before the first one. * * @type {string} */ var LOOP = 'loop'; /** * The track doesn't move. * * @type {string} */ var FADE = 'fade'; // CONCATENATED MODULE: ./src/js/core/composer.js /** * Provide a function for composing components. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Compose components. * * @param {Splide} Splide - Splide instance. * @param {Object} Components - Additional components. * @param {function} Transition - Change component for transition. * * @return {Object} - An object containing all components. */ function compose(Splide, Components, Transition) { var components = {}; each(Components, function (Component, name) { components[name] = Component(Splide, components, name.toLowerCase()); }); Transition = Transition || Splide.is(FADE) ? fade : transitions_slide; components.Transition = Transition(Splide, components); return components; } // CONCATENATED MODULE: ./src/js/utils/error.js /** * Utility functions for outputting logs. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Prefix of an error massage. * * @type {string} */ var MESSAGE_PREFIX = '[SPLIDE]'; /** * Display an error message on the browser console. * * @param {string} message - An error message. */ function error_error(message) { console.error(MESSAGE_PREFIX + " " + message); } /** * Check existence of the given object and throw an error if it doesn't. * * @throws {Error} * * @param {*} subject - A subject to be confirmed. * @param {string} message - An error message. */ function exist(subject, message) { if (!subject) { throw new Error(message); } } // CONCATENATED MODULE: ./src/js/constants/states.js /** * Export state constants. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Splide has been just created. * * @type {number} */ var CREATED = 1; /** * All components have been mounted and initialized. * * @type {number} */ var MOUNTED = 2; /** * Splide is ready for transition. * * @type {number} */ var IDLE = 3; /** * Splide is moving. * * @type {number} */ var MOVING = 4; /** * Splide is moving. * * @type {number} */ var DESTROYED = 5; // CONCATENATED MODULE: ./src/js/splide.js function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /** * The main class for applying Splide to an element. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The main class for applying Splide to an element, * providing some APIs to control the behavior. */ var splide_Splide = /*#__PURE__*/ function () { /** * Splide constructor. * * @throws {Error} When the given root element or selector is invalid. * * @param {Element|string} root - A selector for a root element or an element itself. * @param {Object} options - Optional. Options to change default behaviour. * @param {Object} Components - Optional. Components. */ function Splide(root, options, Components) { var _this = this; if (options === void 0) { options = {}; } if (Components === void 0) { Components = {}; } this.root = root instanceof Element ? root : find(document, root); exist(this.root, 'An invalid element/selector was given.'); this.Components = null; this.Event = core_event(); this.State = state(CREATED); this.STATES = states_namespaceObject; this._o = merge(DEFAULTS, options); this._i = 0; this._c = Components; this.on('move drag', function () { return _this.State.set(MOVING); }).on('moved dragged', function () { return _this.State.set(IDLE); }); } /** * Compose and mount components. * * @param {Object} Extensions - Optional. Additional components. * @param {function} Transition - Optional. Set a custom transition component. * * @return {Splide|null} - This instance or null if an exception occurred. */ var _proto = Splide.prototype; _proto.mount = function mount(Extensions, Transition) { var _this2 = this; if (Extensions === void 0) { Extensions = {}; } if (Transition === void 0) { Transition = null; } this.Components = this.Components || compose(this, merge(this._c, Extensions), Transition); try { each(this.Components, function (component, key) { var required = component.required; if (required === undefined || required) { component.mount && component.mount(); } else { delete _this2.Components[key]; } }); } catch (e) { error_error(e.message); return null; } this.State.set(MOUNTED); each(this.Components, function (component) { component.mounted && component.mounted(); }); // Breakpoints can destroy the Splide. if (!this.State.is(DESTROYED)) { this.emit('mounted'); this.State.set(IDLE); this.emit('ready'); } applyStyle(this.root, { visibility: 'visible' }); return this; } /** * Set sync target. * * @param {Splide} splide - A Splide instance. * * @return {Splide} - This instance. */ ; _proto.sync = function sync(splide) { this.sibling = splide; return this; } /** * Register callback fired on the given event(s). * * @param {string} events - An event name. Use space to separate multiple events. * Also, namespace is accepted by dot, such as 'resize.{namespace}'. * @param {function} handler - A callback function. * @param {Element} elm - Optional. Native event will be listened to when this arg is provided. * @param {Object} options - Optional. Options for addEventListener. * * @return {Splide} - This instance. */ ; _proto.on = function on(events, handler, elm, options) { if (elm === void 0) { elm = null; } if (options === void 0) { options = {}; } this.Event.on(events, handler, elm, options); return this; } /** * Unsubscribe the given event. * * @param {string} events - A event name. * @param {Element} elm - Optional. removeEventListener() will be called when this arg is provided. * * @return {Splide} - This instance. */ ; _proto.off = function off(events, elm) { if (elm === void 0) { elm = null; } this.Event.off(events, elm); return this; } /** * Emit an event. * * @param {string} event - An event name. * @param {*} args - Any number of arguments passed to handlers. */ ; _proto.emit = function emit(event) { var _this$Event; for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } (_this$Event = this.Event).emit.apply(_this$Event, [event].concat(args)); return this; } /** * Go to the slide specified by the given control. * * @param {string|number} control - A control pattern. * @param {boolean} wait - Optional. Whether to wait for transition. */ ; _proto.go = function go(control, wait) { if (wait === void 0) { wait = true; } if (this.State.is(IDLE) || this.State.is(MOVING) && !wait) { this.Components.Controller.go(control, false); } return this; } /** * Verify whether the slider type is the given one or not. * * @param {string} type - A slider type. * * @return {boolean} - True if the slider type is the provided type or false if not. */ ; _proto.is = function is(type) { return type === this._o.type; } /** * Insert a slide. * * @param {Element|string} slide - A slide element to be added. * @param {number} index - A slide will be added at the position. */ ; _proto.add = function add(slide, index) { if (index === void 0) { index = -1; } this.Components.Elements.add(slide, index, this.refresh.bind(this)); return this; } /** * Remove the slide designated by the index. * * @param {number} index - A slide index. */ ; _proto.remove = function remove(index) { this.Components.Elements.remove(index); this.refresh(); return this; } /** * Destroy all Slide objects and clones and recreate them again. * And then call "updated" event. */ ; _proto.refresh = function refresh() { this.emit('refresh').emit('updated', this._o); return this; } /** * Destroy the Splide. * "Completely" boolean is mainly for breakpoints. * * @param {boolean} completely - Destroy completely. */ ; _proto.destroy = function destroy(completely) { if (completely === void 0) { completely = true; } values(this.Components).reverse().forEach(function (component) { component.destroy && component.destroy(completely); }); this.emit('destroy', completely); // Destroy all event handlers, including ones for native events. this.Event.destroy(); this.State.set(DESTROYED); return this; } /** * Return the current slide index. * * @return {number} - The current slide index. // */ ; _createClass(Splide, [{ key: "index", get: function get() { return this._i; } /** * Set the current slide index. * * @param {number|string} index - A new index. */ , set: function set(index) { this._i = parseInt(index); } /** * Return length of slides. * This is an alias of Elements.length. * * @return {number} - A number of slides. */ }, { key: "length", get: function get() { return this.Components.Elements.length; } /** * Return options. * * @return {Object} - Options object. */ }, { key: "options", get: function get() { return this._o; } /** * Set options with merging the given object to the current one. * * @param {Object} options - New options. */ , set: function set(options) { var created = this.State.is(CREATED); if (!created) { this.emit('update'); } this._o = merge(this._o, options); if (!created) { this.emit('updated', this._o); } } /** * Return the class list. * This is an alias of Splide.options.classList. * * @return {Object} - An object containing all class list. */ }, { key: "classes", get: function get() { return this._o.classes; } /** * Return the i18n strings. * This is an alias of Splide.options.i18n. * * @return {Object} - An object containing all i18n strings. */ }, { key: "i18n", get: function get() { return this._o.i18n; } }]); return Splide; }(); // CONCATENATED MODULE: ./src/js/components/options/index.js /** * The component for initializing options. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The component for initializing options. * * @param {Splide} Splide - A Splide instance. * * @return {Object} - The component object. */ /* harmony default export */ var components_options = (function (Splide) { /** * Retrieve options from the data attribute. * Note that IE10 doesn't support dataset property. * * @type {string} */ var options = getAttribute(Splide.root, 'data-splide'); if (options) { try { Splide.options = JSON.parse(options); } catch (e) { error_error(e.message); } } return { /** * Called when the component is mounted. */ mount: function mount() { if (Splide.State.is(CREATED)) { Splide.index = Splide.options.start; } }, /** * Fix some options that must be never changed by breakpoints. * * @param {Object} fixedOptions - Options to be fixed. */ fix: function fix(fixedOptions) { var options = merge(Splide.options, fixedOptions); var breakpoints = options.breakpoints; if (breakpoints) { each(breakpoints, function (value, key) { options.breakpoints[key] = merge(breakpoints[key], fixedOptions); }); } Splide.options = options; } }; }); // CONCATENATED MODULE: ./src/js/constants/directions.js /** * Export layout modes. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Enumerate slides from left to right. * * @type {string} */ var LTR = 'ltr'; /** * Enumerate slides from right to left. * * @type {string} */ var RTL = 'rtl'; /** * Enumerate slides in a col. * * @type {string} */ var TTB = 'ttb'; // CONCATENATED MODULE: ./src/js/components/elements/slide.js /** * The sub component for handling each slide. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Events for restoring original styles. * * @type {string} */ var STYLE_RESTORE_EVENTS = 'update.slide'; /** * The sub component for handling each slide. * * @param {Splide} Splide - A Splide instance. * @param {number} index - An unique slide index. * @param {number} realIndex - Clones should pass a real slide index. * @param {Element} slide - A slide element. * * @return {Object} - The sub component object. */ /* harmony default export */ var elements_slide = (function (Splide, index, realIndex, slide) { /** * Events when the slide status is updated. * Append a namespace to remove listeners later. * * @type {string} */ var STATUS_UPDATE_EVENTS = 'ready.slide updated.slide resize.slide ' + (Splide.options.updateOnMove ? 'move.slide' : 'moved.slide'); /** * Slide sub component object. * * @type {Object} */ var Slide = { /** * Slide element. * * @type {Element} */ slide: slide, /** * Slide index. * * @type {number} */ index: index, /** * Real index for clones. * * @type {number} */ realIndex: realIndex, /** * Container element if available. * * @type {Element|null} */ container: find(slide, "." + Splide.classes.container), /** * Whether this is a cloned slide or not. * * @type {boolean} */ isClone: realIndex > -1, /** * Hold the original styles. * * @type {string} */ styles: getAttribute(slide, 'style') || '', /** * Called when the component is mounted. */ mount: function mount() { var _this = this; if (!this.isClone) { slide.id = Splide.root.id + "-slide" + pad(index + 1); } Splide.on(STATUS_UPDATE_EVENTS, function () { return _this.update(); }).on(STYLE_RESTORE_EVENTS, restoreStyles); }, /** * Destroy. */ destroy: function destroy() { Splide.off(STATUS_UPDATE_EVENTS).off(STYLE_RESTORE_EVENTS); removeClass(slide, values(STATUS_CLASSES)); restoreStyles(); }, /** * Update active and visible status. */ update: function update() { _update(this.isActive(), false); _update(this.isVisible(), true); }, /** * Check whether this slide is active or not. * * @return {boolean} - True if the slide is active or false if not. */ isActive: function isActive() { return Splide.index === index; }, /** * Check whether this slide is visible in the viewport or not. * * @return {boolean} - True if the slide is visible or false if not. */ isVisible: function isVisible() { var floor = Math.floor; var Components = Splide.Components; var Track = Components.Track; var prop = Splide.options.direction === TTB ? 'clientHeight' : 'clientWidth'; var position = floor((Track.toPosition(index) + Track.offset(index) - Track.position) * Track.sign); var edge = floor(position + slide[prop]); var size = Components.Elements.track[prop]; return 0 <= position && position <= size && 0 <= edge && edge <= size || this.isActive(); }, /** * Calculate how far this slide is from another slide and * return true if the distance is within the given number. * * @param {number} from - Index of a target slide. * @param {number} within - True if the slide is within this number. * * @return {boolean} - True if the slide is within the number or false otherwise. */ isWithin: function isWithin(from, within) { var diff = Math.abs(from - index); if (!Splide.is(SLIDE) && !this.isClone) { diff = Math.min(diff, Splide.length - diff); } return diff < within; } }; /** * Update classes for activity or visibility. * * @param {boolean} active - Is active/visible or not. * @param {boolean} forVisibility - Toggle classes for activity or visibility. */ function _update(active, forVisibility) { var type = forVisibility ? 'visible' : 'active'; var className = STATUS_CLASSES[type]; if (active) { addClass(slide, className); Splide.emit("" + type, Slide); } else { if (hasClass(slide, className)) { removeClass(slide, className); Splide.emit("" + (forVisibility ? 'hidden' : 'inactive'), Slide); } } } /** * Restore the original styles. */ function restoreStyles() { setAttribute(slide, 'style', Slide.styles); } return Slide; }); // CONCATENATED MODULE: ./src/js/components/elements/index.js /** * The component for main elements. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The property name for UID stored in a window object. * * @type {string} */ var UID_NAME = 'uid'; /** * The component for main elements. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The component object. */ /* harmony default export */ var components_elements = (function (Splide, Components) { /** * Hold the root element. * * @type {Element} */ var root = Splide.root; /** * Hold the class list. * * @type {Object} */ var classes = Splide.classes; /** * Store Slide objects. * * @type {Array} */ var Slides = []; /* * Assign unique ID to the root element if it doesn't have the one. * Note that IE doesn't support padStart() to fill the uid by 0. */ if (!root.id) { window.splide = window.splide || {}; var uid = window.splide[UID_NAME] || 0; window.splide[UID_NAME] = ++uid; root.id = "splide" + pad(uid); } /** * Elements component object. * * @type {Object} */ var Elements = { /** * Called when the component is mounted. * Collect main elements and store them as member properties. */ mount: function mount() { var _this = this; this.slider = child(root, classes.slider); this.track = find(root, "." + classes.track); this.list = child(this.track, classes.list); exist(this.track && this.list, 'Track or list was not found.'); this.slides = values(this.list.children); var arrows = findParts(classes.arrows); this.arrows = { prev: find(arrows, "." + classes.prev), next: find(arrows, "." + classes.next) }; var autoplay = findParts(classes.autoplay); this.bar = find(findParts(classes.progress), "." + classes.bar); this.play = find(autoplay, "." + classes.play); this.pause = find(autoplay, "." + classes.pause); this.track.id = this.track.id || root.id + "-track"; this.list.id = this.list.id || root.id + "-list"; init(); Splide.on('refresh', function () { _this.destroy(); init(); }); }, /** * Destroy. */ destroy: function destroy() { Slides.forEach(function (Slide) { Slide.destroy(); }); Slides = []; removeClass(root, getClasses()); }, /** * Register a slide to create a Slide object and handle its behavior. * * @param {Element} slide - A slide element. * @param {number} index - A unique index. This can be negative. * @param {number} realIndex - A real index for clones. Set -1 for real slides. */ register: function register(slide, index, realIndex) { var SlideObject = elements_slide(Splide, index, realIndex, slide); SlideObject.mount(); Slides.push(SlideObject); }, /** * Return the Slide object designated by the index. * Note that "find" is not supported by IE. * * @return {Object|undefined} - A Slide object if available. Undefined if not. */ getSlide: function getSlide(index) { return Slides.filter(function (Slide) { return Slide.index === index; })[0]; }, /** * Return all Slide objects. * * @param {boolean} includeClones - Whether to include cloned slides or not. * * @return {Object[]} - Slide objects. */ getSlides: function getSlides(includeClones) { return includeClones ? Slides : Slides.filter(function (Slide) { return !Slide.isClone; }); }, /** * Return Slide objects belonging to the given page. * * @param {number} page - A page number. * * @return {Object[]} - An array containing Slide objects. */ getSlidesByPage: function getSlidesByPage(page) { var idx = Components.Controller.toIndex(page); var options = Splide.options; var max = options.focus !== false ? 1 : options.perPage; return Slides.filter(function (_ref) { var index = _ref.index; return idx <= index && index < idx + max; }); }, /** * Insert a slide to a slider. * Need to refresh Splide after adding a slide. * * @param {Node|string} slide - A slide element to be added. * @param {number} index - A slide will be added at the position. * @param {Function} callback - Called right after the slide is added to the DOM tree. */ add: function add(slide, index, callback) { if (typeof slide === 'string') { slide = domify(slide); } if (slide instanceof Element) { var ref = this.slides[index]; applyStyle(slide, { display: 'none' }); if (ref) { before(slide, ref); this.slides.splice(index, 0, slide); } else { append(this.list, slide); this.slides.push(slide); } dom_loaded(slide, function () { applyStyle(slide, { display: '' }); callback && callback(slide); }); } }, /** * Remove a slide from a slider. * Need to refresh Splide after removing a slide. * * @param index - Slide index. */ remove: function remove(index) { dom_remove(this.slides.splice(index, 1)[0]); }, /** * Trigger the provided callback for each Slide object. * * @param {Function} callback - A callback function. The first argument will be the Slide object. */ each: function each(callback) { Slides.forEach(callback); }, /** * Return slides length without clones. * * @return {number} - Slide length. */ get length() { return this.slides.length; }, /** * Return "SlideObjects" length including clones. * * @return {number} - Slide length including clones. */ get total() { return Slides.length; } }; /** * Initialization. */ function init() { addClass(root, getClasses()); Elements.slides.forEach(function (slide, index) { Elements.register(slide, index, -1); }); } /** * Return class names for the root element. */ function getClasses() { var rootClass = classes.root; var options = Splide.options; return [rootClass + "--" + options.type, rootClass + "--" + options.direction, options.drag ? rootClass + "--draggable" : '', options.isNavigation ? rootClass + "--nav" : '']; } /** * Find parts only from children of the root or track. * * @return {Element|null} - A found element or null. */ function findParts(className) { return child(root, className) || child(Elements.slider, className); } return Elements; }); // CONCATENATED MODULE: ./src/js/components/controller/index.js /** * The component for controlling the track. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ var controller_floor = Math.floor; /** * The component for controlling the track. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The component object. */ /* harmony default export */ var controller = (function (Splide, Components) { /** * Store current options. * * @type {Object} */ var options; /** * True if the slide is LOOP mode. * * @type {boolean} */ var isLoop; /** * Controller component object. * * @type {Object} */ var Controller = { /** * Called when the component is mounted. */ mount: function mount() { options = Splide.options; isLoop = Splide.is(LOOP); bind(); }, /** * Make track run by the given control. * - "+{i}" : Increment the slide index by i. * - "-{i}" : Decrement the slide index by i. * - "{i}" : Go to the slide whose index is i. * - ">" : Go to next page. * - "<" : Go to prev page. * - ">{i}" : Go to page i. * * @param {string|number} control - A control pattern. * @param {boolean} silently - Go to the destination without event emission. */ go: function go(control, silently) { var destIndex = this.trim(this.parse(control)); Components.Track.go(destIndex, this.rewind(destIndex), silently); }, /** * Parse the given control and return the destination index for the track. * * @param {string} control - A control target pattern. * * @return {string|number} - A parsed target. */ parse: function parse(control) { var index = Splide.index; var matches = String(control).match(/([+\-<>])(\d+)?/); var indicator = matches ? matches[1] : ''; var number = matches ? parseInt(matches[2]) : 0; switch (indicator) { case '+': index += number || 1; break; case '-': index -= number || 1; break; case '>': index = this.toIndex(number > -1 ? number : this.toPage(index) + 1); break; case '<': index = this.toIndex(number > -1 ? number : this.toPage(index) - 1); break; default: index = parseInt(control); } return index; }, /** * Compute index from the given page number. * * @param {number} page - Page number. * * @return {number} - A computed page number. */ toIndex: function toIndex(page) { if (hasFocus()) { return page; } var length = Splide.length; var perPage = options.perPage; var index = page * perPage; index = index - (this.pageLength * perPage - length) * controller_floor(index / length); // Adjustment for the last page. if (length - perPage <= index && index < length) { index = length - perPage; } return index; }, /** * Compute page number from the given slide index. * * @param index - Slide index. * * @return {number} - A computed page number. */ toPage: function toPage(index) { if (hasFocus()) { return index; } var length = Splide.length; var perPage = options.perPage; // Make the last "perPage" number of slides belong to the last page. if (length - perPage <= index && index < length) { return controller_floor((length - 1) / perPage); } return controller_floor(index / perPage); }, /** * Trim the given index according to the current mode. * Index being returned could be less than 0 or greater than the length in Loop mode. * * @param {number} index - An index being trimmed. * * @return {number} - A trimmed index. */ trim: function trim(index) { if (!isLoop) { index = options.rewind ? this.rewind(index) : between(index, 0, this.edgeIndex); } return index; }, /** * Rewind the given index if it's out of range. * * @param {number} index - An index. * * @return {number} - A rewound index. */ rewind: function rewind(index) { var edge = this.edgeIndex; if (isLoop) { while (index > edge) { index -= edge + 1; } while (index < 0) { index += edge + 1; } } else { if (index > edge) { index = 0; } else if (index < 0) { index = edge; } } return index; }, /** * Check if the direction is "rtl" or not. * * @return {boolean} - True if "rtl" or false if not. */ isRtl: function isRtl() { return options.direction === RTL; }, /** * Return the page length. * * @return {number} - Max page number. */ get pageLength() { var length = Splide.length; return hasFocus() ? length : Math.ceil(length / options.perPage); }, /** * Return the edge index. * * @return {number} - Edge index. */ get edgeIndex() { var length = Splide.length; if (!length) { return 0; } if (hasFocus() || options.isNavigation || isLoop) { return length - 1; } return length - options.perPage; }, /** * Return the index of the previous slide. * * @return {number} - The index of the previous slide if available. -1 otherwise. */ get prevIndex() { var prev = Splide.index - 1; if (isLoop || options.rewind) { prev = this.rewind(prev); } return prev > -1 ? prev : -1; }, /** * Return the index of the next slide. * * @return {number} - The index of the next slide if available. -1 otherwise. */ get nextIndex() { var next = Splide.index + 1; if (isLoop || options.rewind) { next = this.rewind(next); } return Splide.index < next && next <= this.edgeIndex || next === 0 ? next : -1; } }; /** * Listen some events. */ function bind() { Splide.on('move', function (newIndex) { Splide.index = newIndex; }).on('updated', function (newOptions) { options = newOptions; var index = between(Splide.index, 0, Controller.edgeIndex); Splide.index = Controller.rewind(Controller.trim(index)); }); } /** * Verify if the focus option is available or not. * * @return {boolean} - True if a slider has the focus option. */ function hasFocus() { return options.focus !== false; } return Controller; }); // CONCATENATED MODULE: ./src/js/components/track/directions/vertical.js /** * The resolver component for vertical move. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The resolver component for vertical move. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The resolver object. */ /* harmony default export */ var vertical = (function (Splide, Components) { /** * Hold the Layout object. * * @type {Object} */ var Layout; return { /** * Axis of translate. * * @type {string} */ axis: 'Y', /** * Sign for the direction. * * @return {number} */ sign: -1, /** * Initialization. */ init: function init() { Layout = Components.Layout; }, /** * Calculate position by index. * * @param {number} index - Slide index. * * @return {Object} - Calculated position. */ toPosition: function toPosition(index) { return -((index + Components.Clones.length / 2) * (Layout.slideHeight() + Layout.gap) + this.offset()); }, /** * Calculate the closest slide index from the given position. * * @return {number} - The closest slide index. */ toIndex: function toIndex(position) { var slideHeight = Layout.slideHeight(); var cloneOffset = (slideHeight + Layout.gap) * Components.Clones.length / 2; return Math.round(-(position + cloneOffset + this.offset()) / (slideHeight + Layout.gap)); }, /** * Trim redundant spaces on the left or right edge if necessary. * * @param {number} position - Position value to be trimmed. * * @return {number} - Trimmed position. */ trim: function trim(position) { var edge = -(Layout.listHeight - (Layout.height + Layout.gap)); return between(position, edge, 0); }, /** * Return current offset value, considering direction. * * @return {number} - Offset amount. */ offset: function offset() { var focus = Splide.options.focus; var slideHeight = Layout.slideHeight(); if (focus === 'center') { return -(Layout.height - slideHeight) / 2; } return -(parseInt(focus) || 0) * (slideHeight + Layout.gap); } }; }); // CONCATENATED MODULE: ./src/js/components/track/directions/horizontal.js /** * The resolver component for horizontal move. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The resolver component for horizontal move. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The resolver object. */ /* harmony default export */ var horizontal = (function (Splide, Components) { /** * Hold the Layout component. * * @type {Object} */ var Layout; /** * Hold the Elements component. * * @type {Object} */ var Elements; return { /** * Axis of translate. * * @type {string} */ axis: 'X', /** * Sign for the direction. * * @type {number} */ sign: Splide.options.direction === RTL ? 1 : -1, /** * Initialization. */ init: function init() { Layout = Components.Layout; Elements = Components.Elements; }, /** * Calculate position by index. * * @param {number} index - Slide index. * * @return {Object} - Calculated position. */ toPosition: function toPosition(index) { return this.sign * (Layout.totalWidth(index - 1) + this.offset(index)); }, /** * Calculate the closest slide index from the given position. * * @return {number} - The closest slide position. */ toIndex: function toIndex(position) { position *= this.sign; if (Splide.is(SLIDE)) { position = between(position, Layout.totalWidth(Elements.total), 0); } var Slides = Elements.getSlides(true); for (var i in Slides) { var Slide = Slides[i]; var slideIndex = Slide.index; var slidePosition = this.sign * this.toPosition(slideIndex); if (slidePosition < position && position <= slidePosition + Layout.slideWidth(slideIndex) + Layout.gap) { return slideIndex; } } return 0; }, /** * Trim redundant spaces on the left or right edge if necessary. * * @param {number} position - Position value to be trimmed. * * @return {number} - Trimmed position. */ trim: function trim(position) { var edge = this.sign * (Layout.totalWidth(Elements.total) - (Layout.width + Layout.gap)); return between(position, edge, 0); }, /** * Return current offset value, considering direction. * * @return {number} - Offset amount. */ offset: function offset(index) { var focus = Splide.options.focus; var slideWidth = Layout.slideWidth(index); if (focus === 'center') { return -(Layout.width - slideWidth) / 2; } return -(parseInt(focus) || 0) * (slideWidth + Layout.gap); } }; }); // CONCATENATED MODULE: ./src/js/components/track/index.js /** * The component for moving list in the track. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The component for moving list in the track. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The component object. */ /* harmony default export */ var components_track = (function (Splide, Components) { /** * Store the list element. * * @type {Element} */ var list; /** * Store the current position. * * @type {number} */ var currPosition = 0; /** * Whether the current direction is vertical or not. * * @type {boolean} */ var isVertical = Splide.options.direction === TTB; /** * Whether the slider type is FADE or not. * * @type {boolean} */ var isFade = Splide.is(FADE); /** * Track component object. * * @type {Object} */ var Track = object_assign({ /** * Called when the component is mounted. */ mount: function mount() { list = Components.Elements.list; this.init(); }, /** * Called after the component is mounted. * The resize event must be registered after the Layout's one is done. */ mounted: function mounted() { var _this = this; if (!isFade) { Splide.on('mounted resize updated', function () { _this.jump(Splide.index); }); } }, /** * Go to the given destination index. * After arriving there, the track is jump to the new index without animation, mainly for loop mode. * * @param {number} destIndex - A destination index. * This can be negative or greater than slides length for reaching clones. * @param {number} newIndex - An actual new index. They are always same in Slide and Rewind mode. * @param {boolean} silently - If true, suppress emitting events. */ go: function go(destIndex, newIndex, silently) { var _this2 = this; var newPosition = getTrimmedPosition(destIndex); var prevIndex = Splide.index; if (!silently) { Splide.emit('move', newIndex, prevIndex, destIndex); } if (Math.abs(newPosition - currPosition) >= 1 || isFade) { Components.Transition.start(destIndex, newIndex, this.toCoord(newPosition), function () { _this2.end(destIndex, newIndex, prevIndex, silently); }); } else { if (destIndex !== prevIndex && Splide.options.trimSpace === 'move') { Components.Controller.go(destIndex + destIndex - prevIndex, silently); } else { this.end(destIndex, newIndex, prevIndex, silently); } } }, /** * Called whenever slides arrive at a destination. * * @param {number} destIndex - A destination index. * @param {number} newIndex - A new index. * @param {number} prevIndex - A previous index. * @param {boolean} silently - If true, suppress emitting events. */ end: function end(destIndex, newIndex, prevIndex, silently) { applyStyle(list, { transition: '' }); if (!isFade) { this.jump(newIndex); } if (!silently) { Splide.emit('moved', newIndex, prevIndex, destIndex); } }, /** * Move the track to the specified index. * * @param {number} index - A destination index where the track jumps. */ jump: function jump(index) { this.translate(getTrimmedPosition(index)); }, /** * Set position. * * @param {number} position - A new position value. */ translate: function translate(position) { currPosition = position; applyStyle(list, { transform: "translate" + this.axis + "(" + position + "px)" }); }, /** * Trim redundant spaces on the left or right edge if necessary. * * @param {number} position - Position value to be trimmed. * * @return {number} - Trimmed position. */ trim: function trim(position) { if (!Splide.options.trimSpace || Splide.is(LOOP)) { return position; } return this._s.trim(position); }, /** * Return coordinates object by the given position. * * @param {number} position - A position value. * * @return {Object} - A coordinates object. */ toCoord: function toCoord(position) { return { x: isVertical ? 0 : position, y: isVertical ? position : 0 }; }, /** * Return current position. * * @return {number} - Current position. */ get position() { return currPosition; } }, isVertical ? vertical(Splide, Components) : horizontal(Splide, Components)); /** * Convert index to the trimmed position. * * @return {number} - Trimmed position. */ function getTrimmedPosition(index) { return Track.trim(Track.toPosition(index)); } return Track; }); // CONCATENATED MODULE: ./src/js/components/clones/index.js /** * The component for cloning some slides for "loop" mode of the track. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The component for cloning some slides for "loop" mode of the track. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The component object. */ /* harmony default export */ var components_clones = (function (Splide, Components) { /** * Store information of all clones. * * @type {Array} */ var clones = []; /** * Keep Elements component. * * @type {Object} */ var Elements = Components.Elements; /** * Clones component object. * * @type {Object} */ var Clones = { /** * Called when the component is mounted. */ mount: function mount() { var _this = this; if (Splide.is(LOOP)) { generateClones(); Splide.on('refresh', function () { _this.destroy(); generateClones(); }); } }, /** * Destroy. */ destroy: function destroy() { dom_remove(clones); clones = []; }, /** * Return all clones. * * @return {Element[]} - Cloned elements. */ get clones() { return clones; }, /** * Return clone length. * * @return {number} - A length of clones. */ get length() { return clones.length; } }; /** * Generate and append clones. */ function generateClones() { var length = Elements.length; if (!length) { return; } var count = getCloneCount(); var slides = Elements.slides; while (slides.length < count) { slides = slides.concat(slides); } slides.slice(0, count).forEach(function (elm, index) { var clone = cloneDeeply(elm); append(Elements.list, clone); clones.push(clone); Elements.register(clone, index + length, index); }); slides.slice(-count).forEach(function (elm, index) { var clone = cloneDeeply(elm); before(clone, slides[0]); clones.push(clone); Elements.register(clone, index - count, index); }); } /** * Return half count of clones to be generated. * Clone count is determined by: * - Max pages a flick action can move. * - Whether the slide length is enough for perPage. * * @return {number} - Count for clones. */ function getCloneCount() { var options = Splide.options; if (options.autoWidth) { return Elements.length; } return options.perPage * (options.drag ? options.flickMaxPages + 1 : 1); } /** * Clone deeply the given element. * * @param {Element} elm - An element being duplicated. * * @return {Node} - A cloned node(element). */ function cloneDeeply(elm) { var clone = elm.cloneNode(true); addClass(clone, Splide.classes.clone); // ID should not be duplicated. removeAttribute(clone, 'id'); return clone; } return Clones; }); // CONCATENATED MODULE: ./src/js/components/layout/directions/horizontal.js /** * The resolver component for horizontal layout. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Max width of a slide. * * @type {number} */ var SLIDE_MAX_WIDTH = 5000; /** * The resolver component for horizontal layout. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The resolver object. */ /* harmony default export */ var directions_horizontal = (function (Splide, Components) { /** * Keep the Elements component. * * @type {string} */ var Elements = Components.Elements; /** * Keep the root element. * * @type {Element} */ var root = Splide.root; /** * Keep the track element. * * @type {Element} */ var track; /** * Keep the latest options. * * @type {Element} */ var options = Splide.options; return { /** * Margin property name. * * @type {string} */ margin: 'margin' + (options.direction === RTL ? 'Left' : 'Right'), /** * Always 0 because the height will be determined by inner contents. * * @type {number} */ height: 0, /** * Always 0 because the height will be determined by inner contents. * * @type {number} */ listHeight: 0, /** * Initialization. */ init: function init() { options = Splide.options; track = Elements.track; this.gap = toPixel(root, options.gap); var padding = options.padding; var _padding$left = padding.left, left = _padding$left === void 0 ? padding : _padding$left, _padding$right = padding.right, right = _padding$right === void 0 ? padding : _padding$right; this.padding = { left: toPixel(root, left), right: toPixel(root, right) }; applyStyle(track, { paddingLeft: unit(left), paddingRight: unit(right) }); }, /** * Accumulate slide width including the gap to the designated index. * * @param {number|undefined} index - If undefined, width of all slides will be accumulated. * * @return {number} - Accumulated width. */ totalWidth: function totalWidth(index) { var _this = this; return Elements.getSlides(true).filter(function (Slide) { return Slide.index <= index; }).reduce(function (accumulator, Slide) { return accumulator + _this.slideWidth(Slide.index) + _this.gap; }, 0); }, /** * Return the slide width in px. * * @param {number} index - Slide index. * * @return {number} - The slide width. */ slideWidth: function slideWidth(index) { if (options.autoWidth) { var Slide = Elements.getSlide(index); return Slide ? Slide.slide.offsetWidth : 0; } var width = options.fixedWidth || (this.width + this.gap) / options.perPage - this.gap; return toPixel(root, width); }, /** * Return the slide height in px. * * @return {number} - The slide height. */ slideHeight: function slideHeight() { var height = options.height || options.fixedHeight || this.width * options.heightRatio; return toPixel(root, height); }, /** * Return slider width without padding. * * @return {number} - Current slider width. */ get width() { return track.clientWidth - this.padding.left - this.padding.right; }, /** * Return list width. * * @return {number} - Current list width. */ get listWidth() { var total = Elements.total; return options.autoWidth ? total * SLIDE_MAX_WIDTH : this.totalWidth(total); } }; }); // CONCATENATED MODULE: ./src/js/components/layout/directions/vertical.js /** * The resolver component for vertical layout. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The resolver component for vertical layout. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The resolver object. */ /* harmony default export */ var directions_vertical = (function (Splide, Components) { /** * Keep the Elements component. * * @type {string} */ var Elements = Components.Elements; /** * Keep the root element. * * @type {Element} */ var root = Splide.root; /** * Keep the track element. * * @type {Element} */ var track; /** * Keep the latest options. * * @type {Element} */ var options; return { /** * Margin property name. * * @type {string} */ margin: 'marginBottom', /** * Init slider styles according to options. */ init: function init() { options = Splide.options; track = Elements.track; this.gap = toPixel(root, options.gap); var padding = options.padding; var _padding$top = padding.top, top = _padding$top === void 0 ? padding : _padding$top, _padding$bottom = padding.bottom, bottom = _padding$bottom === void 0 ? padding : _padding$bottom; this.padding = { top: toPixel(root, top), bottom: toPixel(root, bottom) }; applyStyle(track, { paddingTop: unit(top), paddingBottom: unit(bottom) }); }, /** * Return the slide width in px. * * @return {number} - The slide width. */ slideWidth: function slideWidth() { return toPixel(root, options.fixedWidth || this.width); }, /** * Return the slide height in px. * * @return {number} - The slide height. */ slideHeight: function slideHeight() { var height = options.fixedHeight || (this.height + this.gap) / options.perPage - this.gap; return toPixel(root, height); }, /** * Return slider width without padding. * * @return {number} - Current slider width. */ get width() { return track.clientWidth; }, /** * Return slide height without padding. * * @return {number} - Slider height. */ get height() { var height = options.height || this.width * options.heightRatio; exist(height, '"height" or "heightRatio" is missing.'); return toPixel(root, height) - this.padding.top - this.padding.bottom; }, /** * Return list width. * * @return {number} - Current list width. */ get listWidth() { return this.width; }, /** * Return list height. * * @return {number} - Current list height. */ get listHeight() { return (this.slideHeight() + this.gap) * Elements.total; } }; }); // CONCATENATED MODULE: ./src/js/utils/time.js /** * A package of utility functions related with time. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Simple throttle function that controls how often the given function is executed. * * @param {function} func - A function to be throttled. * @param {number} wait - Time in millisecond for interval of execution. * * @return {Function} - A debounced function. */ function throttle(func, wait) { var timeout; // Declare function by the "function" keyword to prevent "this" from being inherited. return function () { if (!timeout) { timeout = setTimeout(function () { func(); timeout = null; }, wait); } }; } /** * Custom setInterval function that provides progress rate as callback. * * @param {function} callback - A callback function fired every time the interval time passes. * @param {number} interval - Interval duration in milliseconds. * @param {function} progress - A callback function fired whenever the progress goes. * * @return {Object} - An object containing play() and pause() functions. */ function createInterval(callback, interval, progress) { var _window = window, requestAnimationFrame = _window.requestAnimationFrame; var start, elapse, rate, _pause = true; var step = function step(timestamp) { if (!_pause) { if (!start) { start = timestamp; } elapse = timestamp - start; rate = elapse / interval; if (elapse >= interval) { start = 0; rate = 1; callback(); } if (progress) { progress(rate); } requestAnimationFrame(step); } }; return { pause: function pause() { _pause = true; start = 0; }, play: function play() { start = 0; if (_pause) { _pause = false; requestAnimationFrame(step); } } }; } // CONCATENATED MODULE: ./src/js/components/layout/index.js /** * The component for handing slide layouts and their sizes. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Interval time for throttle. * * @type {number} */ var THROTTLE = 100; /** * The component for handing slide layouts and their sizes. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The component object. */ /* harmony default export */ var layout = (function (Splide, Components) { /** * Keep the Elements component. * * @type {string} */ var Elements = Components.Elements; /** * Layout component object. * * @type {Object} */ var Layout = object_assign({ /** * Called when the component is mounted. */ mount: function mount() { bind(); init(); }, /** * Destroy. */ destroy: function destroy() { removeAttribute([Elements.list, Elements.track], 'style'); } }, Splide.options.direction === TTB ? directions_vertical(Splide, Components) : directions_horizontal(Splide, Components)); /** * Init slider styles according to options. */ function init() { Layout.init(); applyStyle(Splide.root, { maxWidth: unit(Splide.options.width) }); Elements.each(function (Slide) { Slide.slide.style[Layout.margin] = unit(Layout.gap); }); resize(); } /** * Listen the resize native event with throttle. * Initialize when the component is mounted or options are updated. */ function bind() { Splide.on('resize load', throttle(function () { Splide.emit('resize'); }, THROTTLE), window).on('resize', resize).on('updated', init); } /** * Resize the list and slides including clones. */ function resize() { applyStyle(Elements.list, { width: unit(Layout.listWidth), height: unit(Layout.listHeight) }); applyStyle(Elements.track, { height: unit(Layout.height) }); var slideHeight = unit(Layout.slideHeight()); Elements.each(function (Slide) { applyStyle(Slide.container, { height: slideHeight }); applyStyle(Slide.slide, { width: Splide.options.autoWidth ? null : unit(Layout.slideWidth(Slide.index)), height: Slide.container ? null : slideHeight }); }); } return Layout; }); // CONCATENATED MODULE: ./src/js/components/drag/index.js /** * The component for supporting mouse drag and swipe. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ var abs = Math.abs; /** * Adjust how much the track can be pulled on the first or last page. * The larger number this is, the farther the track moves. * This should be around 5 - 9. * * @type {number} */ var FRICTION_REDUCER = 7; /** * To start dragging the track, the drag angle must be less than this threshold. * * @type {number} */ var ANGLE_THRESHOLD = 30; /** * When a drag distance is over this value, the action will be treated as "swipe", not "flick". * * @type {number} */ var SWIPE_THRESHOLD = 150; /** * The component supporting mouse drag and swipe. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The component object. */ /* harmony default export */ var drag = (function (Splide, Components) { /** * Store the Move component. * * @type {Object} */ var Track = Components.Track; /** * Store the Controller component. * * @type {Object} */ var Controller = Components.Controller; /** * Coordinate of the track on starting drag. * * @type {Object} */ var startCoord; /** * Analyzed info on starting drag. * * @type {Object|null} */ var startInfo; /** * Analyzed info being updated while dragging/swiping. * * @type {Object} */ var currentInfo; /** * Determine whether slides are being dragged or not. * * @type {boolean} */ var isDragging; /** * Whether the slider direction is vertical or not. * * @type {boolean} */ var isVertical = Splide.options.direction === TTB; /** * Axis for the direction. * * @type {string} */ var axis = isVertical ? 'y' : 'x'; /** * Drag component object. * * @type {Object} */ var Drag = { /** * Mount only when the drag option is true. * * @type {boolean} */ required: Splide.options.drag, /** * Whether dragging is disabled or not. * * @type {boolean} */ disabled: false, /** * Called when the component is mounted. */ mount: function mount() { var list = Components.Elements.list; Splide.on('touchstart mousedown', start, list).on('touchmove mousemove', move, list, { passive: false }).on('touchend touchcancel mouseleave mouseup dragend', end, list).on('mounted refresh', function () { // Prevent dragging an image or anchor itself. each(list.querySelectorAll('img, a'), function (elm) { Splide.off('dragstart', elm).on('dragstart', function (e) { e.preventDefault(); }, elm, { passive: false }); }); }); } }; /** * Called when the track starts to be dragged. * * @param {TouchEvent|MouseEvent} e - TouchEvent or MouseEvent object. */ function start(e) { if (!Drag.disabled && !isDragging && Splide.State.is(IDLE)) { startCoord = Track.toCoord(Track.position); startInfo = analyze(e, {}); currentInfo = startInfo; } } /** * Called while the track being dragged. * * @param {TouchEvent|MouseEvent} e - TouchEvent or MouseEvent object. */ function move(e) { if (startInfo) { currentInfo = analyze(e, startInfo); if (isDragging) { if (e.cancelable) { e.preventDefault(); } var position = startCoord[axis] + currentInfo.offset[axis]; Track.translate(resist(position)); } else { if (shouldMove(currentInfo)) { Splide.emit('drag', startInfo); isDragging = true; } } } } /** * Determine whether to start moving the track or not by drag angle. * * @param {Object} info - An information object. * * @return {boolean} - True if the track should be moved or false if not. */ function shouldMove(_ref) { var offset = _ref.offset; if (Splide.State.is(IDLE)) { var angle = Math.atan(abs(offset.y) / abs(offset.x)) * 180 / Math.PI; if (isVertical) { angle = 90 - angle; } return angle < ANGLE_THRESHOLD; } return false; } /** * Resist dragging the track on the first/last page because there is no more. * * @param {number} position - A position being applied to the track. * * @return {Object} - Adjusted position. */ function resist(position) { if (!Splide.is(LOOP)) { var sign = Track.sign; var _start = sign * Track.trim(Track.toPosition(0)); var _end = sign * Track.trim(Track.toPosition(Controller.edgeIndex)); position *= sign; if (position < _start) { position = _start - FRICTION_REDUCER * Math.log(_start - position); } else if (position > _end) { position = _end + FRICTION_REDUCER * Math.log(position - _end); } position *= sign; } return position; } /** * Called when dragging ends. */ function end() { startInfo = null; if (isDragging) { Splide.emit('dragged', currentInfo); go(currentInfo); isDragging = false; } } /** * Go to the slide determined by the analyzed data. * * @param {Object} info - An info object. */ function go(info) { var velocity = info.velocity[axis]; var absV = abs(velocity); if (absV > 0) { var Layout = Components.Layout; var options = Splide.options; var sign = velocity < 0 ? -1 : 1; var destination = Track.position; if (absV > options.flickThreshold && abs(info.offset[axis]) < SWIPE_THRESHOLD) { destination += sign * Math.min(absV * options.flickPower, Layout.width * (options.flickMaxPages || 1)); } var index = Track.toIndex(destination); // Do not allow the track to go to a previous position. if (index === Splide.index) { index += sign * Track.sign; } if (!Splide.is(LOOP)) { index = between(index, 0, Controller.edgeIndex); } Controller.go(index, options.isNavigation); } } /** * Analyze the given event object and return important information for handling swipe behavior. * * @param {Event} e - Touch or Mouse event object. * @param {Object} startInfo - Information analyzed on start for calculating difference from the current one. * * @return {Object} - An object containing analyzed information, such as offset, velocity, etc. */ function analyze(e, startInfo) { var timeStamp = e.timeStamp, touches = e.touches; var _ref2 = touches ? touches[0] : e, clientX = _ref2.clientX, clientY = _ref2.clientY; var _ref3 = startInfo.to || {}, _ref3$x = _ref3.x, fromX = _ref3$x === void 0 ? clientX : _ref3$x, _ref3$y = _ref3.y, fromY = _ref3$y === void 0 ? clientY : _ref3$y; var startTime = startInfo.time || 0; var offset = { x: clientX - fromX, y: clientY - fromY }; var duration = timeStamp - startTime; var velocity = { x: offset.x / duration, y: offset.y / duration }; return { to: { x: clientX, y: clientY }, offset: offset, time: timeStamp, velocity: velocity }; } return Drag; }); // CONCATENATED MODULE: ./src/js/components/click/index.js /** * The component for handling a click event. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The component for handling a click event. * Click should be disabled during drag/swipe. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The component object. */ /* harmony default export */ var click = (function (Splide, Components) { /** * Whether click is disabled or not. * * @type {boolean} */ var disabled = false; /** * Click component object. * * @type {Object} */ var Click = { /** * Mount only when the drag is activated and the slide type is not "fade". * * @type {boolean} */ required: Splide.options.drag && !Splide.is(FADE), /** * Called when the component is mounted. */ mount: function mount() { Splide.on('click', onClick, Components.Elements.track, { capture: true }).on('drag', function () { disabled = true; }).on('moved', function () { disabled = false; }); } }; /** * Called when a track element is clicked. * * @param {Event} e - A click event. */ function onClick(e) { if (disabled) { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); } } return Click; }); // CONCATENATED MODULE: ./src/js/components/autoplay/index.js /** * The component for playing slides automatically. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Set of pause flags. */ var PAUSE_FLAGS = { HOVER: 1, FOCUS: 2, MANUAL: 3 }; /** * The component for playing slides automatically. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * @param {string} name - A component name as a lowercase string. * * @return {Object} - The component object. */ /* harmony default export */ var components_autoplay = (function (Splide, Components, name) { /** * Store pause flags. * * @type {Array} */ var flags = []; /** * Store an interval object. * * @type {Object}; */ var interval; /** * Keep the Elements component. * * @type {string} */ var Elements = Components.Elements; /** * Autoplay component object. * * @type {Object} */ var Autoplay = { /** * Required only when the autoplay option is true. * * @type {boolean} */ required: Splide.options.autoplay, /** * Called when the component is mounted. * Note that autoplay starts only if there are slides over perPage number. */ mount: function mount() { var options = Splide.options; if (Elements.slides.length > options.perPage) { interval = createInterval(function () { Splide.go('>'); }, options.interval, function (rate) { Splide.emit(name + ":playing", rate); if (Elements.bar) { applyStyle(Elements.bar, { width: rate * 100 + "%" }); } }); bind(); this.play(); } }, /** * Start autoplay. * * @param {number} flag - A pause flag to be removed. */ play: function play(flag) { if (flag === void 0) { flag = 0; } flags = flags.filter(function (f) { return f !== flag; }); if (!flags.length) { Splide.emit(name + ":play"); interval.play(); } }, /** * Pause autoplay. * Note that Array.includes is not supported by IE. * * @param {number} flag - A pause flag to be added. */ pause: function pause(flag) { if (flag === void 0) { flag = 0; } interval.pause(); if (flags.indexOf(flag) === -1) { flags.push(flag); } if (flags.length === 1) { Splide.emit(name + ":pause"); } } }; /** * Listen some events. */ function bind() { var options = Splide.options; var sibling = Splide.sibling; var elms = [Splide.root, sibling ? sibling.root : null]; if (options.pauseOnHover) { switchOn(elms, 'mouseleave', PAUSE_FLAGS.HOVER, true); switchOn(elms, 'mouseenter', PAUSE_FLAGS.HOVER, false); } if (options.pauseOnFocus) { switchOn(elms, 'focusout', PAUSE_FLAGS.FOCUS, true); switchOn(elms, 'focusin', PAUSE_FLAGS.FOCUS, false); } Splide.on('click', function () { // Need to be removed a focus flag at first. Autoplay.play(PAUSE_FLAGS.FOCUS); Autoplay.play(PAUSE_FLAGS.MANUAL); }, Elements.play).on('move refresh', function () { Autoplay.play(); }) // Rewind the timer. .on('destroy', function () { Autoplay.pause(); }); switchOn([Elements.pause], 'click', PAUSE_FLAGS.MANUAL, false); } /** * Play or pause on the given event. * * @param {Element[]} elms - Elements. * @param {string} event - An event name or names. * @param {number} flag - A pause flag defined on the top. * @param {boolean} play - Determine whether to play or pause. */ function switchOn(elms, event, flag, play) { for (var i in elms) { Splide.on(event, function () { Autoplay[play ? 'play' : 'pause'](flag); }, elms[i]); } } return Autoplay; }); // CONCATENATED MODULE: ./src/js/components/cover/index.js /** * The component for change an img element to background image of its wrapper. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The component for change an img element to background image of its wrapper. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * * @return {Object} - The component object. */ /* harmony default export */ var components_cover = (function (Splide, Components) { /** * Hold options. * * @type {Object} */ var options = Splide.options; /** * Cover component object. * * @type {Object} */ var Cover = { /** * Required only when "cover" option is true. * * @type {boolean} */ required: options.cover, /** * Called when the component is mounted. */ mount: function mount() { apply(false); Splide.on('lazyload:loaded', function (img) { cover(img, false); }); Splide.on('updated', function () { return apply(false); }); }, /** * Destroy. */ destroy: function destroy() { apply(true); } }; /** * Apply "cover" to all slides. * * @param {boolean} uncover - If true, "cover" will be clear. */ function apply(uncover) { Components.Elements.each(function (Slide) { var img = child(Slide.slide, 'img') || child(Slide.container, 'img'); if (img && img.src) { cover(img, uncover); } }); } /** * Set background image of the parent element, using source of the given image element. * * @param {Element} img - An image element. * @param {boolean} uncover - Reset "cover". */ function cover(img, uncover) { applyStyle(img.parentElement, { background: uncover ? '' : "center/cover no-repeat url(\"" + img.src + "\")" }); applyStyle(img, { display: uncover ? '' : 'none' }); } return Cover; }); // CONCATENATED MODULE: ./src/js/components/arrows/path.js /** * Export vector path for an arrow. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * Namespace definition for SVG element. * * @type {string} */ var XML_NAME_SPACE = 'http://www.w3.org/2000/svg'; /** * The arrow vector path. * * @type {number} */ var PATH = 'm15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z'; /** * SVG width and height. * * @type {number} */ var SIZE = 40; // CONCATENATED MODULE: ./src/js/components/arrows/index.js /** * The component for appending prev/next arrows. * * @author Naotoshi Fujita * @copyright Naotoshi Fujita. All rights reserved. */ /** * The component for appending prev/next arrows. * * @param {Splide} Splide - A Splide instance. * @param {Object} Components - An object containing components. * @param {string} name - A component name as a lowercase string. * * @return {Object} - The component object. */ /* harmony default export */ var components_arrows = (function (Splide, Components, name) { /** * Previous arrow element. * * @type {Element|undefined} */ var prev; /** * Next arrow element. * * @type {Element|undefined} */ var next; /** * Store the class list. * * @type {Object} */ var classes = Splide.classes; /** * Hold the root element. * * @type {Element} */ var root = Splide.root; /** * Whether arrows are created programmatically or not. * * @type {boolean} */ var created; /** * Hold the Elements component. * * @type {Object} */ var Elements = Components.Elements; /** * Arrows component object. * * @type {Object} */ var Arrows = { /** * Required when the arrows option is true. * * @type {boolean} */ required: Splide.options.arrows, /** * Called when the component is mounted. */ mount: function mount() { // Attempt to get arrows from HTML source. prev = Elements.arrows.prev; next = Elements.arrows.next; // If arrows were not found in HTML, let's generate them. if ((!prev || !next) && Splide.options.arrows) { prev = createArrow(true); next = createArrow(false); created = true; appendArrows(); } if (prev && next) { bind(); } this.arrows = { prev: prev, next: next }; }, /** * Called after all components are mounted. */ mounted: function mounted() { Splide.emit(name + ":mounted", prev, next); }, /** * Destroy. */ destroy: function destroy() { removeAttribute([prev, next], 'disabled'); if (created) { dom_remove(prev.parentElement); } } }; /** * Listen native and custom events. */ function bind() { Splide.on('click', function () { return onClick(true); }, prev).on('click', function () { return onClick(false); }, next).on('mounted move updated', updateDisabled); } /** * Called when an arrow is clicked. * * @param {boolean} prev - If true, the previous arrow is clicked. */ function onClick(prev) { var perMove = Splide.options.perMove; Splide.go(perMove ? "" + (prev ? '-' : '+') + perMove : prev ? '<' : '>'); } /** * Update a disabled attribute. */ function updateDisabled() { var _Components$Controlle = Components.Controller, prevIndex = _Components$Controlle.prevIndex, nextIndex = _Components$Controlle.nextIndex; var isEnough = Splide.length > Splide.options.perPage || Splide.is(LOOP); prev.disabled = prevIndex < 0 || !isEnough; next.disabled = nextIndex < 0 || !isEnough; Splide.emit(name + ":updated", prev, next, prevIndex, nextIndex); } /** * Create a wrapper element and append arrows. */ function appendArrows() { var wrapper = create('div', { "class": classes.arrows }); append(wrapper, prev); append(wrapper, next); var slider = Elements.slider; var parent = Splide.options.arrows === 'slider' && slider ? slider : root; before(wrapper, parent.firstElementChild); } /** * Create an arrow element. * * @param {boolean} prev - Determine to create a prev arrow or next arrow. * * @return {Element} - A created arrow element. */ function createArrow(prev) { var arrow = "