10093 lines
282 KiB
JavaScript
Executable file
10093 lines
282 KiB
JavaScript
Executable file
/*!
|
|
* Name : Just Another Parallax [Jarallax]
|
|
* Version : 1.12.4
|
|
* Author : nK <https://nkdev.info>
|
|
* GitHub : https://github.com/nk-o/jarallax
|
|
*/
|
|
/******/ (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 = 10);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */,
|
|
/* 1 */,
|
|
/* 2 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = function (callback) {
|
|
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
|
// Already ready or interactive, execute callback
|
|
callback.call();
|
|
} else if (document.attachEvent) {
|
|
// Old browsers
|
|
document.attachEvent('onreadystatechange', function () {
|
|
if (document.readyState === 'interactive') callback.call();
|
|
});
|
|
} else if (document.addEventListener) {
|
|
// Modern browsers
|
|
document.addEventListener('DOMContentLoaded', callback);
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 3 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
/* WEBPACK VAR INJECTION */(function(global) {var win;
|
|
|
|
if (typeof window !== "undefined") {
|
|
win = window;
|
|
} else if (typeof global !== "undefined") {
|
|
win = global;
|
|
} else if (typeof self !== "undefined") {
|
|
win = self;
|
|
} else {
|
|
win = {};
|
|
}
|
|
|
|
module.exports = win;
|
|
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(4)))
|
|
|
|
/***/ }),
|
|
/* 4 */
|
|
/***/ (function(module, exports) {
|
|
|
|
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
|
|
var g; // This works in non-strict mode
|
|
|
|
g = function () {
|
|
return this;
|
|
}();
|
|
|
|
try {
|
|
// This works if eval is allowed (see CSP)
|
|
g = g || new Function("return this")();
|
|
} catch (e) {
|
|
// This works if the window reference is available
|
|
if ((typeof window === "undefined" ? "undefined" : _typeof(window)) === "object") g = window;
|
|
} // g can still be undefined, but nothing to do about it...
|
|
// We return undefined, instead of nothing here, so it's
|
|
// easier to handle this case. if(!global) { ...}
|
|
|
|
|
|
module.exports = g;
|
|
|
|
/***/ }),
|
|
/* 5 */,
|
|
/* 6 */,
|
|
/* 7 */,
|
|
/* 8 */,
|
|
/* 9 */,
|
|
/* 10 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
module.exports = __webpack_require__(11);
|
|
|
|
|
|
/***/ }),
|
|
/* 11 */
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony import */ var lite_ready__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
|
|
/* harmony import */ var lite_ready__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lite_ready__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ var global__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
|
/* harmony import */ var global__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(global__WEBPACK_IMPORTED_MODULE_1__);
|
|
/* harmony import */ var _jarallax_esm__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(12);
|
|
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
|
|
|
|
|
|
// no conflict
|
|
|
|
var oldPlugin = global__WEBPACK_IMPORTED_MODULE_1__["window"].jarallax;
|
|
global__WEBPACK_IMPORTED_MODULE_1__["window"].jarallax = _jarallax_esm__WEBPACK_IMPORTED_MODULE_2__["default"];
|
|
|
|
global__WEBPACK_IMPORTED_MODULE_1__["window"].jarallax.noConflict = function () {
|
|
global__WEBPACK_IMPORTED_MODULE_1__["window"].jarallax = oldPlugin;
|
|
return this;
|
|
}; // jQuery support
|
|
|
|
|
|
if ('undefined' !== typeof global__WEBPACK_IMPORTED_MODULE_1__["jQuery"]) {
|
|
var jQueryPlugin = function jQueryPlugin() {
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
|
|
Array.prototype.unshift.call(args, this);
|
|
var res = _jarallax_esm__WEBPACK_IMPORTED_MODULE_2__["default"].apply(global__WEBPACK_IMPORTED_MODULE_1__["window"], args);
|
|
return 'object' !== _typeof(res) ? res : this;
|
|
};
|
|
|
|
jQueryPlugin.constructor = _jarallax_esm__WEBPACK_IMPORTED_MODULE_2__["default"].constructor; // no conflict
|
|
|
|
var oldJqPlugin = global__WEBPACK_IMPORTED_MODULE_1__["jQuery"].fn.jarallax;
|
|
global__WEBPACK_IMPORTED_MODULE_1__["jQuery"].fn.jarallax = jQueryPlugin;
|
|
|
|
global__WEBPACK_IMPORTED_MODULE_1__["jQuery"].fn.jarallax.noConflict = function () {
|
|
global__WEBPACK_IMPORTED_MODULE_1__["jQuery"].fn.jarallax = oldJqPlugin;
|
|
return this;
|
|
};
|
|
} // data-jarallax initialization
|
|
|
|
|
|
lite_ready__WEBPACK_IMPORTED_MODULE_0___default()(function () {
|
|
Object(_jarallax_esm__WEBPACK_IMPORTED_MODULE_2__["default"])(document.querySelectorAll('[data-jarallax]'));
|
|
});
|
|
|
|
/***/ }),
|
|
/* 12 */
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
"use strict";
|
|
__webpack_require__.r(__webpack_exports__);
|
|
/* harmony import */ var lite_ready__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
|
|
/* harmony import */ var lite_ready__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lite_ready__WEBPACK_IMPORTED_MODULE_0__);
|
|
/* harmony import */ var global__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
|
|
/* harmony import */ var global__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(global__WEBPACK_IMPORTED_MODULE_1__);
|
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
|
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
|
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
|
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
|
|
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
|
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
|
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
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; }
|
|
|
|
|
|
|
|
var navigator = global__WEBPACK_IMPORTED_MODULE_1__["window"].navigator;
|
|
var isIE = -1 < navigator.userAgent.indexOf('MSIE ') || -1 < navigator.userAgent.indexOf('Trident/') || -1 < navigator.userAgent.indexOf('Edge/');
|
|
var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
|
|
|
var supportTransform = function () {
|
|
var prefixes = 'transform WebkitTransform MozTransform'.split(' ');
|
|
var div = document.createElement('div');
|
|
|
|
for (var i = 0; i < prefixes.length; i += 1) {
|
|
if (div && div.style[prefixes[i]] !== undefined) {
|
|
return prefixes[i];
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}();
|
|
|
|
var $deviceHelper;
|
|
/**
|
|
* The most popular mobile browsers changes height after page scroll and this generates image jumping.
|
|
* We can fix it using this workaround with vh units.
|
|
*/
|
|
|
|
function getDeviceHeight() {
|
|
if (!$deviceHelper && document.body) {
|
|
$deviceHelper = document.createElement('div');
|
|
$deviceHelper.style.cssText = 'position: fixed; top: -9999px; left: 0; height: 100vh; width: 0;';
|
|
document.body.appendChild($deviceHelper);
|
|
}
|
|
|
|
return ($deviceHelper ? $deviceHelper.clientHeight : 0) || global__WEBPACK_IMPORTED_MODULE_1__["window"].innerHeight || document.documentElement.clientHeight;
|
|
} // Window height data
|
|
|
|
|
|
var wndH;
|
|
|
|
function updateWndVars() {
|
|
if (isMobile) {
|
|
wndH = getDeviceHeight();
|
|
} else {
|
|
wndH = global__WEBPACK_IMPORTED_MODULE_1__["window"].innerHeight || document.documentElement.clientHeight;
|
|
}
|
|
}
|
|
|
|
updateWndVars();
|
|
global__WEBPACK_IMPORTED_MODULE_1__["window"].addEventListener('resize', updateWndVars);
|
|
global__WEBPACK_IMPORTED_MODULE_1__["window"].addEventListener('orientationchange', updateWndVars);
|
|
global__WEBPACK_IMPORTED_MODULE_1__["window"].addEventListener('load', updateWndVars);
|
|
lite_ready__WEBPACK_IMPORTED_MODULE_0___default()(function () {
|
|
updateWndVars({
|
|
type: 'dom-loaded'
|
|
});
|
|
}); // list with all jarallax instances
|
|
// need to render all in one scroll/resize event
|
|
|
|
var jarallaxList = []; // get all parents of the element.
|
|
|
|
function getParents(elem) {
|
|
var parents = [];
|
|
|
|
while (null !== elem.parentElement) {
|
|
elem = elem.parentElement;
|
|
|
|
if (1 === elem.nodeType) {
|
|
parents.push(elem);
|
|
}
|
|
}
|
|
|
|
return parents;
|
|
}
|
|
|
|
function updateParallax() {
|
|
if (!jarallaxList.length) {
|
|
return;
|
|
}
|
|
|
|
jarallaxList.forEach(function (data, k) {
|
|
var instance = data.instance,
|
|
oldData = data.oldData;
|
|
var clientRect = instance.$item.getBoundingClientRect();
|
|
var newData = {
|
|
width: clientRect.width,
|
|
height: clientRect.height,
|
|
top: clientRect.top,
|
|
bottom: clientRect.bottom,
|
|
wndW: global__WEBPACK_IMPORTED_MODULE_1__["window"].innerWidth,
|
|
wndH: wndH
|
|
};
|
|
var isResized = !oldData || oldData.wndW !== newData.wndW || oldData.wndH !== newData.wndH || oldData.width !== newData.width || oldData.height !== newData.height;
|
|
var isScrolled = isResized || !oldData || oldData.top !== newData.top || oldData.bottom !== newData.bottom;
|
|
jarallaxList[k].oldData = newData;
|
|
|
|
if (isResized) {
|
|
instance.onResize();
|
|
}
|
|
|
|
if (isScrolled) {
|
|
instance.onScroll();
|
|
}
|
|
});
|
|
global__WEBPACK_IMPORTED_MODULE_1__["window"].requestAnimationFrame(updateParallax);
|
|
}
|
|
|
|
var instanceID = 0; // Jarallax class
|
|
|
|
var Jarallax = /*#__PURE__*/function () {
|
|
function Jarallax(item, userOptions) {
|
|
_classCallCheck(this, Jarallax);
|
|
|
|
var self = this;
|
|
self.instanceID = instanceID;
|
|
instanceID += 1;
|
|
self.$item = item;
|
|
self.defaults = {
|
|
type: 'scroll',
|
|
// type of parallax: scroll, scale, opacity, scale-opacity, scroll-opacity
|
|
speed: 0.5,
|
|
// supported value from -1 to 2
|
|
imgSrc: null,
|
|
imgElement: '.jarallax-img',
|
|
imgSize: 'cover',
|
|
imgPosition: '50% 50%',
|
|
imgRepeat: 'no-repeat',
|
|
// supported only for background, not for <img> tag
|
|
keepImg: false,
|
|
// keep <img> tag in it's default place
|
|
elementInViewport: null,
|
|
zIndex: -100,
|
|
disableParallax: false,
|
|
disableVideo: false,
|
|
// video
|
|
videoSrc: null,
|
|
videoStartTime: 0,
|
|
videoEndTime: 0,
|
|
videoVolume: 0,
|
|
videoLoop: true,
|
|
videoPlayOnlyVisible: true,
|
|
videoLazyLoading: true,
|
|
// events
|
|
onScroll: null,
|
|
// function(calculations) {}
|
|
onInit: null,
|
|
// function() {}
|
|
onDestroy: null,
|
|
// function() {}
|
|
onCoverImage: null // function() {}
|
|
|
|
}; // prepare data-options
|
|
|
|
var dataOptions = self.$item.dataset || {};
|
|
var pureDataOptions = {};
|
|
Object.keys(dataOptions).forEach(function (key) {
|
|
var loweCaseOption = key.substr(0, 1).toLowerCase() + key.substr(1);
|
|
|
|
if (loweCaseOption && 'undefined' !== typeof self.defaults[loweCaseOption]) {
|
|
pureDataOptions[loweCaseOption] = dataOptions[key];
|
|
}
|
|
});
|
|
self.options = self.extend({}, self.defaults, pureDataOptions, userOptions);
|
|
self.pureOptions = self.extend({}, self.options); // prepare 'true' and 'false' strings to boolean
|
|
|
|
Object.keys(self.options).forEach(function (key) {
|
|
if ('true' === self.options[key]) {
|
|
self.options[key] = true;
|
|
} else if ('false' === self.options[key]) {
|
|
self.options[key] = false;
|
|
}
|
|
}); // fix speed option [-1.0, 2.0]
|
|
|
|
self.options.speed = Math.min(2, Math.max(-1, parseFloat(self.options.speed))); // prepare disableParallax callback
|
|
|
|
if ('string' === typeof self.options.disableParallax) {
|
|
self.options.disableParallax = new RegExp(self.options.disableParallax);
|
|
}
|
|
|
|
if (self.options.disableParallax instanceof RegExp) {
|
|
var disableParallaxRegexp = self.options.disableParallax;
|
|
|
|
self.options.disableParallax = function () {
|
|
return disableParallaxRegexp.test(navigator.userAgent);
|
|
};
|
|
}
|
|
|
|
if ('function' !== typeof self.options.disableParallax) {
|
|
self.options.disableParallax = function () {
|
|
return false;
|
|
};
|
|
} // prepare disableVideo callback
|
|
|
|
|
|
if ('string' === typeof self.options.disableVideo) {
|
|
self.options.disableVideo = new RegExp(self.options.disableVideo);
|
|
}
|
|
|
|
if (self.options.disableVideo instanceof RegExp) {
|
|
var disableVideoRegexp = self.options.disableVideo;
|
|
|
|
self.options.disableVideo = function () {
|
|
return disableVideoRegexp.test(navigator.userAgent);
|
|
};
|
|
}
|
|
|
|
if ('function' !== typeof self.options.disableVideo) {
|
|
self.options.disableVideo = function () {
|
|
return false;
|
|
};
|
|
} // custom element to check if parallax in viewport
|
|
|
|
|
|
var elementInVP = self.options.elementInViewport; // get first item from array
|
|
|
|
if (elementInVP && 'object' === _typeof(elementInVP) && 'undefined' !== typeof elementInVP.length) {
|
|
var _elementInVP = elementInVP;
|
|
|
|
var _elementInVP2 = _slicedToArray(_elementInVP, 1);
|
|
|
|
elementInVP = _elementInVP2[0];
|
|
} // check if dom element
|
|
|
|
|
|
if (!(elementInVP instanceof Element)) {
|
|
elementInVP = null;
|
|
}
|
|
|
|
self.options.elementInViewport = elementInVP;
|
|
self.image = {
|
|
src: self.options.imgSrc || null,
|
|
$container: null,
|
|
useImgTag: false,
|
|
// position fixed is needed for the most of browsers because absolute position have glitches
|
|
// on MacOS with smooth scroll there is a huge lags with absolute position - https://github.com/nk-o/jarallax/issues/75
|
|
// on mobile devices better scrolled with absolute position
|
|
position: /iPad|iPhone|iPod|Android/.test(navigator.userAgent) ? 'absolute' : 'fixed'
|
|
};
|
|
|
|
if (self.initImg() && self.canInitParallax()) {
|
|
self.init();
|
|
}
|
|
} // add styles to element
|
|
// eslint-disable-next-line class-methods-use-this
|
|
|
|
|
|
_createClass(Jarallax, [{
|
|
key: "css",
|
|
value: function css(el, styles) {
|
|
if ('string' === typeof styles) {
|
|
return global__WEBPACK_IMPORTED_MODULE_1__["window"].getComputedStyle(el).getPropertyValue(styles);
|
|
} // add transform property with vendor prefix
|
|
|
|
|
|
if (styles.transform && supportTransform) {
|
|
styles[supportTransform] = styles.transform;
|
|
}
|
|
|
|
Object.keys(styles).forEach(function (key) {
|
|
el.style[key] = styles[key];
|
|
});
|
|
return el;
|
|
} // Extend like jQuery.extend
|
|
// eslint-disable-next-line class-methods-use-this
|
|
|
|
}, {
|
|
key: "extend",
|
|
value: function extend(out) {
|
|
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
args[_key - 1] = arguments[_key];
|
|
}
|
|
|
|
out = out || {};
|
|
Object.keys(args).forEach(function (i) {
|
|
if (!args[i]) {
|
|
return;
|
|
}
|
|
|
|
Object.keys(args[i]).forEach(function (key) {
|
|
out[key] = args[i][key];
|
|
});
|
|
});
|
|
return out;
|
|
} // get window size and scroll position. Useful for extensions
|
|
// eslint-disable-next-line class-methods-use-this
|
|
|
|
}, {
|
|
key: "getWindowData",
|
|
value: function getWindowData() {
|
|
return {
|
|
width: global__WEBPACK_IMPORTED_MODULE_1__["window"].innerWidth || document.documentElement.clientWidth,
|
|
height: wndH,
|
|
y: document.documentElement.scrollTop
|
|
};
|
|
} // Jarallax functions
|
|
|
|
}, {
|
|
key: "initImg",
|
|
value: function initImg() {
|
|
var self = this; // find image element
|
|
|
|
var $imgElement = self.options.imgElement;
|
|
|
|
if ($imgElement && 'string' === typeof $imgElement) {
|
|
$imgElement = self.$item.querySelector($imgElement);
|
|
} // check if dom element
|
|
|
|
|
|
if (!($imgElement instanceof Element)) {
|
|
if (self.options.imgSrc) {
|
|
$imgElement = new Image();
|
|
$imgElement.src = self.options.imgSrc;
|
|
} else {
|
|
$imgElement = null;
|
|
}
|
|
}
|
|
|
|
if ($imgElement) {
|
|
if (self.options.keepImg) {
|
|
self.image.$item = $imgElement.cloneNode(true);
|
|
} else {
|
|
self.image.$item = $imgElement;
|
|
self.image.$itemParent = $imgElement.parentNode;
|
|
}
|
|
|
|
self.image.useImgTag = true;
|
|
} // true if there is img tag
|
|
|
|
|
|
if (self.image.$item) {
|
|
return true;
|
|
} // get image src
|
|
|
|
|
|
if (null === self.image.src) {
|
|
self.image.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
|
self.image.bgImage = self.css(self.$item, 'background-image');
|
|
}
|
|
|
|
return !(!self.image.bgImage || 'none' === self.image.bgImage);
|
|
}
|
|
}, {
|
|
key: "canInitParallax",
|
|
value: function canInitParallax() {
|
|
return supportTransform && !this.options.disableParallax();
|
|
}
|
|
}, {
|
|
key: "init",
|
|
value: function init() {
|
|
var self = this;
|
|
var containerStyles = {
|
|
position: 'absolute',
|
|
top: 0,
|
|
left: 0,
|
|
width: '100%',
|
|
height: '100%',
|
|
overflow: 'hidden'
|
|
};
|
|
var imageStyles = {
|
|
pointerEvents: 'none',
|
|
transformStyle: 'preserve-3d',
|
|
backfaceVisibility: 'hidden',
|
|
willChange: 'transform,opacity'
|
|
};
|
|
|
|
if (!self.options.keepImg) {
|
|
// save default user styles
|
|
var curStyle = self.$item.getAttribute('style');
|
|
|
|
if (curStyle) {
|
|
self.$item.setAttribute('data-jarallax-original-styles', curStyle);
|
|
}
|
|
|
|
if (self.image.useImgTag) {
|
|
var curImgStyle = self.image.$item.getAttribute('style');
|
|
|
|
if (curImgStyle) {
|
|
self.image.$item.setAttribute('data-jarallax-original-styles', curImgStyle);
|
|
}
|
|
}
|
|
} // set relative position and z-index to the parent
|
|
|
|
|
|
if ('static' === self.css(self.$item, 'position')) {
|
|
self.css(self.$item, {
|
|
position: 'relative'
|
|
});
|
|
}
|
|
|
|
if ('auto' === self.css(self.$item, 'z-index')) {
|
|
self.css(self.$item, {
|
|
zIndex: 0
|
|
});
|
|
} // container for parallax image
|
|
|
|
|
|
self.image.$container = document.createElement('div');
|
|
self.css(self.image.$container, containerStyles);
|
|
self.css(self.image.$container, {
|
|
'z-index': self.options.zIndex
|
|
}); // fix for IE https://github.com/nk-o/jarallax/issues/110
|
|
|
|
if (isIE) {
|
|
self.css(self.image.$container, {
|
|
opacity: 0.9999
|
|
});
|
|
}
|
|
|
|
self.image.$container.setAttribute('id', "jarallax-container-".concat(self.instanceID));
|
|
self.$item.appendChild(self.image.$container); // use img tag
|
|
|
|
if (self.image.useImgTag) {
|
|
imageStyles = self.extend({
|
|
'object-fit': self.options.imgSize,
|
|
'object-position': self.options.imgPosition,
|
|
// support for plugin https://github.com/bfred-it/object-fit-images
|
|
'font-family': "object-fit: ".concat(self.options.imgSize, "; object-position: ").concat(self.options.imgPosition, ";"),
|
|
'max-width': 'none'
|
|
}, containerStyles, imageStyles); // use div with background image
|
|
} else {
|
|
self.image.$item = document.createElement('div');
|
|
|
|
if (self.image.src) {
|
|
imageStyles = self.extend({
|
|
'background-position': self.options.imgPosition,
|
|
'background-size': self.options.imgSize,
|
|
'background-repeat': self.options.imgRepeat,
|
|
'background-image': self.image.bgImage || "url(\"".concat(self.image.src, "\")")
|
|
}, containerStyles, imageStyles);
|
|
}
|
|
}
|
|
|
|
if ('opacity' === self.options.type || 'scale' === self.options.type || 'scale-opacity' === self.options.type || 1 === self.options.speed) {
|
|
self.image.position = 'absolute';
|
|
} // 1. Check if one of parents have transform style (without this check, scroll transform will be inverted if used parallax with position fixed)
|
|
// discussion - https://github.com/nk-o/jarallax/issues/9
|
|
// 2. Check if parents have overflow scroll
|
|
|
|
|
|
if ('fixed' === self.image.position) {
|
|
var $parents = getParents(self.$item).filter(function (el) {
|
|
var styles = global__WEBPACK_IMPORTED_MODULE_1__["window"].getComputedStyle(el);
|
|
var parentTransform = styles['-webkit-transform'] || styles['-moz-transform'] || styles.transform;
|
|
var overflowRegex = /(auto|scroll)/;
|
|
return parentTransform && 'none' !== parentTransform || overflowRegex.test(styles.overflow + styles['overflow-y'] + styles['overflow-x']);
|
|
});
|
|
self.image.position = $parents.length ? 'absolute' : 'fixed';
|
|
} // add position to parallax block
|
|
|
|
|
|
imageStyles.position = self.image.position; // insert parallax image
|
|
|
|
self.css(self.image.$item, imageStyles);
|
|
self.image.$container.appendChild(self.image.$item); // set initial position and size
|
|
|
|
self.onResize();
|
|
self.onScroll(true); // call onInit event
|
|
|
|
if (self.options.onInit) {
|
|
self.options.onInit.call(self);
|
|
} // remove default user background
|
|
|
|
|
|
if ('none' !== self.css(self.$item, 'background-image')) {
|
|
self.css(self.$item, {
|
|
'background-image': 'none'
|
|
});
|
|
}
|
|
|
|
self.addToParallaxList();
|
|
} // add to parallax instances list
|
|
|
|
}, {
|
|
key: "addToParallaxList",
|
|
value: function addToParallaxList() {
|
|
jarallaxList.push({
|
|
instance: this
|
|
});
|
|
|
|
if (1 === jarallaxList.length) {
|
|
global__WEBPACK_IMPORTED_MODULE_1__["window"].requestAnimationFrame(updateParallax);
|
|
}
|
|
} // remove from parallax instances list
|
|
|
|
}, {
|
|
key: "removeFromParallaxList",
|
|
value: function removeFromParallaxList() {
|
|
var self = this;
|
|
jarallaxList.forEach(function (data, key) {
|
|
if (data.instance.instanceID === self.instanceID) {
|
|
jarallaxList.splice(key, 1);
|
|
}
|
|
});
|
|
}
|
|
}, {
|
|
key: "destroy",
|
|
value: function destroy() {
|
|
var self = this;
|
|
self.removeFromParallaxList(); // return styles on container as before jarallax init
|
|
|
|
var originalStylesTag = self.$item.getAttribute('data-jarallax-original-styles');
|
|
self.$item.removeAttribute('data-jarallax-original-styles'); // null occurs if there is no style tag before jarallax init
|
|
|
|
if (!originalStylesTag) {
|
|
self.$item.removeAttribute('style');
|
|
} else {
|
|
self.$item.setAttribute('style', originalStylesTag);
|
|
}
|
|
|
|
if (self.image.useImgTag) {
|
|
// return styles on img tag as before jarallax init
|
|
var originalStylesImgTag = self.image.$item.getAttribute('data-jarallax-original-styles');
|
|
self.image.$item.removeAttribute('data-jarallax-original-styles'); // null occurs if there is no style tag before jarallax init
|
|
|
|
if (!originalStylesImgTag) {
|
|
self.image.$item.removeAttribute('style');
|
|
} else {
|
|
self.image.$item.setAttribute('style', originalStylesTag);
|
|
} // move img tag to its default position
|
|
|
|
|
|
if (self.image.$itemParent) {
|
|
self.image.$itemParent.appendChild(self.image.$item);
|
|
}
|
|
} // remove additional dom elements
|
|
|
|
|
|
if (self.$clipStyles) {
|
|
self.$clipStyles.parentNode.removeChild(self.$clipStyles);
|
|
}
|
|
|
|
if (self.image.$container) {
|
|
self.image.$container.parentNode.removeChild(self.image.$container);
|
|
} // call onDestroy event
|
|
|
|
|
|
if (self.options.onDestroy) {
|
|
self.options.onDestroy.call(self);
|
|
} // delete jarallax from item
|
|
|
|
|
|
delete self.$item.jarallax;
|
|
} // it will remove some image overlapping
|
|
// overlapping occur due to an image position fixed inside absolute position element
|
|
|
|
}, {
|
|
key: "clipContainer",
|
|
value: function clipContainer() {
|
|
// needed only when background in fixed position
|
|
if ('fixed' !== this.image.position) {
|
|
return;
|
|
}
|
|
|
|
var self = this;
|
|
var rect = self.image.$container.getBoundingClientRect();
|
|
var width = rect.width,
|
|
height = rect.height;
|
|
|
|
if (!self.$clipStyles) {
|
|
self.$clipStyles = document.createElement('style');
|
|
self.$clipStyles.setAttribute('type', 'text/css');
|
|
self.$clipStyles.setAttribute('id', "jarallax-clip-".concat(self.instanceID));
|
|
var head = document.head || document.getElementsByTagName('head')[0];
|
|
head.appendChild(self.$clipStyles);
|
|
} // clip is used for old browsers.
|
|
// clip-path for modern browsers (also fixes Safari v14 bug https://github.com/nk-o/jarallax/issues/181 ).
|
|
|
|
|
|
var styles = "#jarallax-container-".concat(self.instanceID, " {\n clip: rect(0 ").concat(width, "px ").concat(height, "px 0);\n clip: rect(0, ").concat(width, "px, ").concat(height, "px, 0);\n -webkit-clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);\n clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);\n }"); // add clip styles inline (this method need for support IE8 and less browsers)
|
|
|
|
if (self.$clipStyles.styleSheet) {
|
|
self.$clipStyles.styleSheet.cssText = styles;
|
|
} else {
|
|
self.$clipStyles.innerHTML = styles;
|
|
}
|
|
}
|
|
}, {
|
|
key: "coverImage",
|
|
value: function coverImage() {
|
|
var self = this;
|
|
var rect = self.image.$container.getBoundingClientRect();
|
|
var contH = rect.height;
|
|
var speed = self.options.speed;
|
|
var isScroll = 'scroll' === self.options.type || 'scroll-opacity' === self.options.type;
|
|
var scrollDist = 0;
|
|
var resultH = contH;
|
|
var resultMT = 0; // scroll parallax
|
|
|
|
if (isScroll) {
|
|
// scroll distance and height for image
|
|
if (0 > speed) {
|
|
scrollDist = speed * Math.max(contH, wndH);
|
|
|
|
if (wndH < contH) {
|
|
scrollDist -= speed * (contH - wndH);
|
|
}
|
|
} else {
|
|
scrollDist = speed * (contH + wndH);
|
|
} // size for scroll parallax
|
|
|
|
|
|
if (1 < speed) {
|
|
resultH = Math.abs(scrollDist - wndH);
|
|
} else if (0 > speed) {
|
|
resultH = scrollDist / speed + Math.abs(scrollDist);
|
|
} else {
|
|
resultH += (wndH - contH) * (1 - speed);
|
|
}
|
|
|
|
scrollDist /= 2;
|
|
} // store scroll distance
|
|
|
|
|
|
self.parallaxScrollDistance = scrollDist; // vertical center
|
|
|
|
if (isScroll) {
|
|
resultMT = (wndH - resultH) / 2;
|
|
} else {
|
|
resultMT = (contH - resultH) / 2;
|
|
} // apply result to item
|
|
|
|
|
|
self.css(self.image.$item, {
|
|
height: "".concat(resultH, "px"),
|
|
marginTop: "".concat(resultMT, "px"),
|
|
left: 'fixed' === self.image.position ? "".concat(rect.left, "px") : '0',
|
|
width: "".concat(rect.width, "px")
|
|
}); // call onCoverImage event
|
|
|
|
if (self.options.onCoverImage) {
|
|
self.options.onCoverImage.call(self);
|
|
} // return some useful data. Used in the video cover function
|
|
|
|
|
|
return {
|
|
image: {
|
|
height: resultH,
|
|
marginTop: resultMT
|
|
},
|
|
container: rect
|
|
};
|
|
}
|
|
}, {
|
|
key: "isVisible",
|
|
value: function isVisible() {
|
|
return this.isElementInViewport || false;
|
|
}
|
|
}, {
|
|
key: "onScroll",
|
|
value: function onScroll(force) {
|
|
var self = this;
|
|
var rect = self.$item.getBoundingClientRect();
|
|
var contT = rect.top;
|
|
var contH = rect.height;
|
|
var styles = {}; // check if in viewport
|
|
|
|
var viewportRect = rect;
|
|
|
|
if (self.options.elementInViewport) {
|
|
viewportRect = self.options.elementInViewport.getBoundingClientRect();
|
|
}
|
|
|
|
self.isElementInViewport = 0 <= viewportRect.bottom && 0 <= viewportRect.right && viewportRect.top <= wndH && viewportRect.left <= global__WEBPACK_IMPORTED_MODULE_1__["window"].innerWidth; // stop calculations if item is not in viewport
|
|
|
|
if (force ? false : !self.isElementInViewport) {
|
|
return;
|
|
} // calculate parallax helping variables
|
|
|
|
|
|
var beforeTop = Math.max(0, contT);
|
|
var beforeTopEnd = Math.max(0, contH + contT);
|
|
var afterTop = Math.max(0, -contT);
|
|
var beforeBottom = Math.max(0, contT + contH - wndH);
|
|
var beforeBottomEnd = Math.max(0, contH - (contT + contH - wndH));
|
|
var afterBottom = Math.max(0, -contT + wndH - contH);
|
|
var fromViewportCenter = 1 - 2 * ((wndH - contT) / (wndH + contH)); // calculate on how percent of section is visible
|
|
|
|
var visiblePercent = 1;
|
|
|
|
if (contH < wndH) {
|
|
visiblePercent = 1 - (afterTop || beforeBottom) / contH;
|
|
} else if (beforeTopEnd <= wndH) {
|
|
visiblePercent = beforeTopEnd / wndH;
|
|
} else if (beforeBottomEnd <= wndH) {
|
|
visiblePercent = beforeBottomEnd / wndH;
|
|
} // opacity
|
|
|
|
|
|
if ('opacity' === self.options.type || 'scale-opacity' === self.options.type || 'scroll-opacity' === self.options.type) {
|
|
styles.transform = 'translate3d(0,0,0)';
|
|
styles.opacity = visiblePercent;
|
|
} // scale
|
|
|
|
|
|
if ('scale' === self.options.type || 'scale-opacity' === self.options.type) {
|
|
var scale = 1;
|
|
|
|
if (0 > self.options.speed) {
|
|
scale -= self.options.speed * visiblePercent;
|
|
} else {
|
|
scale += self.options.speed * (1 - visiblePercent);
|
|
}
|
|
|
|
styles.transform = "scale(".concat(scale, ") translate3d(0,0,0)");
|
|
} // scroll
|
|
|
|
|
|
if ('scroll' === self.options.type || 'scroll-opacity' === self.options.type) {
|
|
var positionY = self.parallaxScrollDistance * fromViewportCenter; // fix if parallax block in absolute position
|
|
|
|
if ('absolute' === self.image.position) {
|
|
positionY -= contT;
|
|
}
|
|
|
|
styles.transform = "translate3d(0,".concat(positionY, "px,0)");
|
|
}
|
|
|
|
self.css(self.image.$item, styles); // call onScroll event
|
|
|
|
if (self.options.onScroll) {
|
|
self.options.onScroll.call(self, {
|
|
section: rect,
|
|
beforeTop: beforeTop,
|
|
beforeTopEnd: beforeTopEnd,
|
|
afterTop: afterTop,
|
|
beforeBottom: beforeBottom,
|
|
beforeBottomEnd: beforeBottomEnd,
|
|
afterBottom: afterBottom,
|
|
visiblePercent: visiblePercent,
|
|
fromViewportCenter: fromViewportCenter
|
|
});
|
|
}
|
|
}
|
|
}, {
|
|
key: "onResize",
|
|
value: function onResize() {
|
|
this.coverImage();
|
|
this.clipContainer();
|
|
}
|
|
}]);
|
|
|
|
return Jarallax;
|
|
}(); // global definition
|
|
|
|
|
|
var plugin = function plugin(items, options) {
|
|
// check for dom element
|
|
// thanks: http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object
|
|
if ('object' === (typeof HTMLElement === "undefined" ? "undefined" : _typeof(HTMLElement)) ? items instanceof HTMLElement : items && 'object' === _typeof(items) && null !== items && 1 === items.nodeType && 'string' === typeof items.nodeName) {
|
|
items = [items];
|
|
}
|
|
|
|
var len = items.length;
|
|
var k = 0;
|
|
var ret;
|
|
|
|
for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
|
|
args[_key2 - 2] = arguments[_key2];
|
|
}
|
|
|
|
for (k; k < len; k += 1) {
|
|
if ('object' === _typeof(options) || 'undefined' === typeof options) {
|
|
if (!items[k].jarallax) {
|
|
items[k].jarallax = new Jarallax(items[k], options);
|
|
}
|
|
} else if (items[k].jarallax) {
|
|
// eslint-disable-next-line prefer-spread
|
|
ret = items[k].jarallax[options].apply(items[k].jarallax, args);
|
|
}
|
|
|
|
if ('undefined' !== typeof ret) {
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
return items;
|
|
};
|
|
|
|
plugin.constructor = Jarallax;
|
|
/* harmony default export */ __webpack_exports__["default"] = (plugin);
|
|
|
|
/***/ })
|
|
/******/ ]);
|
|
/*!
|
|
* jPinning v0.1
|
|
* Pin and unpin your headers while you are scrolling
|
|
* MIT License
|
|
*/
|
|
(function( $ ) {
|
|
$.fn.jPinning = function( options ) {
|
|
// Default settings
|
|
var defaults = {
|
|
offset: false, //offset for header to hide or show in pixels
|
|
onPin: function(){}, //Fires when the header shows up
|
|
onUnpin: function(){} //Fires when the header hides out
|
|
};
|
|
// Merge default settings with user settings
|
|
var settings = $.extend( {}, defaults, options );
|
|
|
|
var elements = {
|
|
lastScrollTop: 0,
|
|
document: $(document),
|
|
window: $(window),
|
|
status: 'pinned'
|
|
};
|
|
|
|
var classes = {
|
|
nav: 'pinning-nav',
|
|
pinned: 'pinned',
|
|
unpinned: 'unpinned',
|
|
top: 'pinning-top'
|
|
};
|
|
|
|
var methods = {
|
|
|
|
isUnpinned: function(){
|
|
/**
|
|
* Check if header is unpinned
|
|
* @return boolean
|
|
*/
|
|
if( elements.status == 'unpinned' )
|
|
return true;
|
|
return false;
|
|
},
|
|
|
|
isPinned: function(){
|
|
/**
|
|
* Check if header is pinned
|
|
* @return boolean
|
|
*/
|
|
if( elements.status == 'pinned' )
|
|
return true;
|
|
return false;
|
|
},
|
|
|
|
prepare: function(){
|
|
/*
|
|
* This will add the needed classes for the header to work properly
|
|
*/
|
|
elements.target.addClass(classes.nav);
|
|
elements.target.css('position', 'fixed');
|
|
},
|
|
|
|
pin: function(){
|
|
/*
|
|
* If the header is unpinned this function will update the status to "pinned",
|
|
* update header classes and execute the callback function.
|
|
*/
|
|
if( methods.isUnpinned() ){
|
|
elements.status = 'pinned';
|
|
elements.target.removeClass(classes.unpinned).addClass(classes.pinned);
|
|
settings.onPin.call( elements.target );
|
|
}
|
|
},
|
|
|
|
unpin: function(){
|
|
/*
|
|
* If the header is pinned this function will update the status to "unpinned",
|
|
* update header classes and execute the callback function.
|
|
*/
|
|
|
|
if( methods.isPinned() ){
|
|
elements.status = 'unpinned';
|
|
elements.target
|
|
.removeClass(classes.pinned)
|
|
.removeClass(classes.top)
|
|
.addClass(classes.unpinned);
|
|
settings.onUnpin.call( elements.target );
|
|
}
|
|
},
|
|
|
|
calcOffset: function(st){
|
|
/**
|
|
* Check if offset is setted and if so calculate it
|
|
* @return boolean
|
|
*/
|
|
|
|
if( settings.offset == 'auto' ){
|
|
settings.offset = elements.target.outerHeight();
|
|
}
|
|
|
|
if( settings.offset ){
|
|
if( st > settings.offset ){
|
|
return true;
|
|
}else {
|
|
return false;
|
|
}
|
|
}else {
|
|
return true;
|
|
}
|
|
},
|
|
|
|
pinHandler: function(){
|
|
/*
|
|
* This function will add "top" class to the header when it reachs the top of the page.
|
|
* Also it will call pin() or unpin() functions depending if the user is scrolling up or down.
|
|
*/
|
|
var st = elements.window.scrollTop(),
|
|
maxScroll = elements.document.height() - elements.window.height();
|
|
|
|
if( st < 0 ) {
|
|
st = 0;
|
|
}
|
|
|
|
if( st >= maxScroll ) {
|
|
st = maxScroll;
|
|
elements.lastScrollTop = st - 1;
|
|
}
|
|
|
|
if ( st == 0 ){
|
|
elements.target.addClass(classes.top);
|
|
}
|
|
|
|
if ( st <= elements.lastScrollTop ){
|
|
/* Scrolling up */
|
|
methods.pin();
|
|
} else {
|
|
/* Scrolling down */
|
|
var offset = methods.calcOffset(st);
|
|
if( offset ){
|
|
methods.unpin();
|
|
}
|
|
}
|
|
|
|
elements.lastScrollTop = st;
|
|
}
|
|
};
|
|
|
|
// jPinning init
|
|
return this.each(function() {
|
|
elements.target = $(this); //Get initialized element
|
|
methods.prepare(); //Prepare element
|
|
$(window).on( 'scroll', methods.pinHandler ); //Call handler on scroll
|
|
});
|
|
|
|
};
|
|
}( jQuery ));
|
|
/*!
|
|
* imagesLoaded PACKAGED v4.1.1
|
|
* JavaScript is all like "You images are done yet or what?"
|
|
* MIT License
|
|
*/
|
|
|
|
/**
|
|
* EvEmitter v1.0.3
|
|
* Lil' event emitter
|
|
* MIT License
|
|
*/
|
|
|
|
/* jshint unused: true, undef: true, strict: true */
|
|
|
|
( function( global, factory ) {
|
|
// universal module definition
|
|
/* jshint strict: false */ /* globals define, module, window */
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD - RequireJS
|
|
define( 'ev-emitter/ev-emitter',factory );
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS - Browserify, Webpack
|
|
module.exports = factory();
|
|
} else {
|
|
// Browser globals
|
|
global.EvEmitter = factory();
|
|
}
|
|
|
|
}( typeof window != 'undefined' ? window : this, function() {
|
|
|
|
|
|
|
|
function EvEmitter() {}
|
|
|
|
var proto = EvEmitter.prototype;
|
|
|
|
proto.on = function( eventName, listener ) {
|
|
if ( !eventName || !listener ) {
|
|
return;
|
|
}
|
|
// set events hash
|
|
var events = this._events = this._events || {};
|
|
// set listeners array
|
|
var listeners = events[ eventName ] = events[ eventName ] || [];
|
|
// only add once
|
|
if ( listeners.indexOf( listener ) == -1 ) {
|
|
listeners.push( listener );
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
proto.once = function( eventName, listener ) {
|
|
if ( !eventName || !listener ) {
|
|
return;
|
|
}
|
|
// add event
|
|
this.on( eventName, listener );
|
|
// set once flag
|
|
// set onceEvents hash
|
|
var onceEvents = this._onceEvents = this._onceEvents || {};
|
|
// set onceListeners object
|
|
var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
|
|
// set flag
|
|
onceListeners[ listener ] = true;
|
|
|
|
return this;
|
|
};
|
|
|
|
proto.off = function( eventName, listener ) {
|
|
var listeners = this._events && this._events[ eventName ];
|
|
if ( !listeners || !listeners.length ) {
|
|
return;
|
|
}
|
|
var index = listeners.indexOf( listener );
|
|
if ( index != -1 ) {
|
|
listeners.splice( index, 1 );
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
proto.emitEvent = function( eventName, args ) {
|
|
var listeners = this._events && this._events[ eventName ];
|
|
if ( !listeners || !listeners.length ) {
|
|
return;
|
|
}
|
|
var i = 0;
|
|
var listener = listeners[i];
|
|
args = args || [];
|
|
// once stuff
|
|
var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
|
|
|
|
while ( listener ) {
|
|
var isOnce = onceListeners && onceListeners[ listener ];
|
|
if ( isOnce ) {
|
|
// remove listener
|
|
// remove before trigger to prevent recursion
|
|
this.off( eventName, listener );
|
|
// unset once flag
|
|
delete onceListeners[ listener ];
|
|
}
|
|
// trigger listener
|
|
listener.apply( this, args );
|
|
// get next listener
|
|
i += isOnce ? 0 : 1;
|
|
listener = listeners[i];
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
return EvEmitter;
|
|
|
|
}));
|
|
|
|
/*!
|
|
* imagesLoaded v4.1.1
|
|
* JavaScript is all like "You images are done yet or what?"
|
|
* MIT License
|
|
*/
|
|
|
|
( function( window, factory ) { 'use strict';
|
|
// universal module definition
|
|
|
|
/*global define: false, module: false, require: false */
|
|
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( [
|
|
'ev-emitter/ev-emitter'
|
|
], function( EvEmitter ) {
|
|
return factory( window, EvEmitter );
|
|
});
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory(
|
|
window,
|
|
require('ev-emitter')
|
|
);
|
|
} else {
|
|
// browser global
|
|
window.imagesLoaded = factory(
|
|
window,
|
|
window.EvEmitter
|
|
);
|
|
}
|
|
|
|
})( window,
|
|
|
|
// -------------------------- factory -------------------------- //
|
|
|
|
function factory( window, EvEmitter ) {
|
|
|
|
|
|
|
|
var $ = window.jQuery;
|
|
var console = window.console;
|
|
|
|
// -------------------------- helpers -------------------------- //
|
|
|
|
// extend objects
|
|
function extend( a, b ) {
|
|
for ( var prop in b ) {
|
|
a[ prop ] = b[ prop ];
|
|
}
|
|
return a;
|
|
}
|
|
|
|
// turn element or nodeList into an array
|
|
function makeArray( obj ) {
|
|
var ary = [];
|
|
if ( Array.isArray( obj ) ) {
|
|
// use object if already an array
|
|
ary = obj;
|
|
} else if ( typeof obj.length == 'number' ) {
|
|
// convert nodeList to array
|
|
for ( var i=0; i < obj.length; i++ ) {
|
|
ary.push( obj[i] );
|
|
}
|
|
} else {
|
|
// array of single index
|
|
ary.push( obj );
|
|
}
|
|
return ary;
|
|
}
|
|
|
|
// -------------------------- imagesLoaded -------------------------- //
|
|
|
|
/**
|
|
* @param {Array, Element, NodeList, String} elem
|
|
* @param {Object or Function} options - if function, use as callback
|
|
* @param {Function} onAlways - callback function
|
|
*/
|
|
function ImagesLoaded( elem, options, onAlways ) {
|
|
// coerce ImagesLoaded() without new, to be new ImagesLoaded()
|
|
if ( !( this instanceof ImagesLoaded ) ) {
|
|
return new ImagesLoaded( elem, options, onAlways );
|
|
}
|
|
// use elem as selector string
|
|
if ( typeof elem == 'string' ) {
|
|
elem = document.querySelectorAll( elem );
|
|
}
|
|
|
|
this.elements = makeArray( elem );
|
|
this.options = extend( {}, this.options );
|
|
|
|
if ( typeof options == 'function' ) {
|
|
onAlways = options;
|
|
} else {
|
|
extend( this.options, options );
|
|
}
|
|
|
|
if ( onAlways ) {
|
|
this.on( 'always', onAlways );
|
|
}
|
|
|
|
this.getImages();
|
|
|
|
if ( $ ) {
|
|
// add jQuery Deferred object
|
|
this.jqDeferred = new $.Deferred();
|
|
}
|
|
|
|
// HACK check async to allow time to bind listeners
|
|
setTimeout( function() {
|
|
this.check();
|
|
}.bind( this ));
|
|
}
|
|
|
|
ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
|
|
|
|
ImagesLoaded.prototype.options = {};
|
|
|
|
ImagesLoaded.prototype.getImages = function() {
|
|
this.images = [];
|
|
|
|
// filter & find items if we have an item selector
|
|
this.elements.forEach( this.addElementImages, this );
|
|
};
|
|
|
|
/**
|
|
* @param {Node} element
|
|
*/
|
|
ImagesLoaded.prototype.addElementImages = function( elem ) {
|
|
// filter siblings
|
|
if ( elem.nodeName == 'IMG' ) {
|
|
this.addImage( elem );
|
|
}
|
|
// get background image on element
|
|
if ( this.options.background === true ) {
|
|
this.addElementBackgroundImages( elem );
|
|
}
|
|
|
|
// find children
|
|
// no non-element nodes, #143
|
|
var nodeType = elem.nodeType;
|
|
if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
|
|
return;
|
|
}
|
|
var childImgs = elem.querySelectorAll('img');
|
|
// concat childElems to filterFound array
|
|
for ( var i=0; i < childImgs.length; i++ ) {
|
|
var img = childImgs[i];
|
|
this.addImage( img );
|
|
}
|
|
|
|
// get child background images
|
|
if ( typeof this.options.background == 'string' ) {
|
|
var children = elem.querySelectorAll( this.options.background );
|
|
for ( i=0; i < children.length; i++ ) {
|
|
var child = children[i];
|
|
this.addElementBackgroundImages( child );
|
|
}
|
|
}
|
|
};
|
|
|
|
var elementNodeTypes = {
|
|
1: true,
|
|
9: true,
|
|
11: true
|
|
};
|
|
|
|
ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
|
|
var style = getComputedStyle( elem );
|
|
if ( !style ) {
|
|
// Firefox returns null if in a hidden iframe https://bugzil.la/548397
|
|
return;
|
|
}
|
|
// get url inside url("...")
|
|
var reURL = /url\((['"])?(.*?)\1\)/gi;
|
|
var matches = reURL.exec( style.backgroundImage );
|
|
while ( matches !== null ) {
|
|
var url = matches && matches[2];
|
|
if ( url ) {
|
|
this.addBackground( url, elem );
|
|
}
|
|
matches = reURL.exec( style.backgroundImage );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @param {Image} img
|
|
*/
|
|
ImagesLoaded.prototype.addImage = function( img ) {
|
|
var loadingImage = new LoadingImage( img );
|
|
this.images.push( loadingImage );
|
|
};
|
|
|
|
ImagesLoaded.prototype.addBackground = function( url, elem ) {
|
|
var background = new Background( url, elem );
|
|
this.images.push( background );
|
|
};
|
|
|
|
ImagesLoaded.prototype.check = function() {
|
|
var _this = this;
|
|
this.progressedCount = 0;
|
|
this.hasAnyBroken = false;
|
|
// complete if no images
|
|
if ( !this.images.length ) {
|
|
this.complete();
|
|
return;
|
|
}
|
|
|
|
function onProgress( image, elem, message ) {
|
|
// HACK - Chrome triggers event before object properties have changed. #83
|
|
setTimeout( function() {
|
|
_this.progress( image, elem, message );
|
|
});
|
|
}
|
|
|
|
this.images.forEach( function( loadingImage ) {
|
|
loadingImage.once( 'progress', onProgress );
|
|
loadingImage.check();
|
|
});
|
|
};
|
|
|
|
ImagesLoaded.prototype.progress = function( image, elem, message ) {
|
|
this.progressedCount++;
|
|
this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
|
|
// progress event
|
|
this.emitEvent( 'progress', [ this, image, elem ] );
|
|
if ( this.jqDeferred && this.jqDeferred.notify ) {
|
|
this.jqDeferred.notify( this, image );
|
|
}
|
|
// check if completed
|
|
if ( this.progressedCount == this.images.length ) {
|
|
this.complete();
|
|
}
|
|
|
|
if ( this.options.debug && console ) {
|
|
console.log( 'progress: ' + message, image, elem );
|
|
}
|
|
};
|
|
|
|
ImagesLoaded.prototype.complete = function() {
|
|
var eventName = this.hasAnyBroken ? 'fail' : 'done';
|
|
this.isComplete = true;
|
|
this.emitEvent( eventName, [ this ] );
|
|
this.emitEvent( 'always', [ this ] );
|
|
if ( this.jqDeferred ) {
|
|
var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
|
|
this.jqDeferred[ jqMethod ]( this );
|
|
}
|
|
};
|
|
|
|
// -------------------------- -------------------------- //
|
|
|
|
function LoadingImage( img ) {
|
|
this.img = img;
|
|
}
|
|
|
|
LoadingImage.prototype = Object.create( EvEmitter.prototype );
|
|
|
|
LoadingImage.prototype.check = function() {
|
|
// If complete is true and browser supports natural sizes,
|
|
// try to check for image status manually.
|
|
var isComplete = this.getIsImageComplete();
|
|
if ( isComplete ) {
|
|
// report based on naturalWidth
|
|
this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
|
|
return;
|
|
}
|
|
|
|
// If none of the checks above matched, simulate loading on detached element.
|
|
this.proxyImage = new Image();
|
|
this.proxyImage.addEventListener( 'load', this );
|
|
this.proxyImage.addEventListener( 'error', this );
|
|
// bind to image as well for Firefox. #191
|
|
this.img.addEventListener( 'load', this );
|
|
this.img.addEventListener( 'error', this );
|
|
this.proxyImage.src = this.img.src;
|
|
};
|
|
|
|
LoadingImage.prototype.getIsImageComplete = function() {
|
|
return this.img.complete && this.img.naturalWidth !== undefined;
|
|
};
|
|
|
|
LoadingImage.prototype.confirm = function( isLoaded, message ) {
|
|
this.isLoaded = isLoaded;
|
|
this.emitEvent( 'progress', [ this, this.img, message ] );
|
|
};
|
|
|
|
// ----- events ----- //
|
|
|
|
// trigger specified handler for event type
|
|
LoadingImage.prototype.handleEvent = function( event ) {
|
|
var method = 'on' + event.type;
|
|
if ( this[ method ] ) {
|
|
this[ method ]( event );
|
|
}
|
|
};
|
|
|
|
LoadingImage.prototype.onload = function() {
|
|
this.confirm( true, 'onload' );
|
|
this.unbindEvents();
|
|
};
|
|
|
|
LoadingImage.prototype.onerror = function() {
|
|
this.confirm( false, 'onerror' );
|
|
this.unbindEvents();
|
|
};
|
|
|
|
LoadingImage.prototype.unbindEvents = function() {
|
|
this.proxyImage.removeEventListener( 'load', this );
|
|
this.proxyImage.removeEventListener( 'error', this );
|
|
this.img.removeEventListener( 'load', this );
|
|
this.img.removeEventListener( 'error', this );
|
|
};
|
|
|
|
// -------------------------- Background -------------------------- //
|
|
|
|
function Background( url, element ) {
|
|
this.url = url;
|
|
this.element = element;
|
|
this.img = new Image();
|
|
}
|
|
|
|
// inherit LoadingImage prototype
|
|
Background.prototype = Object.create( LoadingImage.prototype );
|
|
|
|
Background.prototype.check = function() {
|
|
this.img.addEventListener( 'load', this );
|
|
this.img.addEventListener( 'error', this );
|
|
this.img.src = this.url;
|
|
// check if image is already complete
|
|
var isComplete = this.getIsImageComplete();
|
|
if ( isComplete ) {
|
|
this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
|
|
this.unbindEvents();
|
|
}
|
|
};
|
|
|
|
Background.prototype.unbindEvents = function() {
|
|
this.img.removeEventListener( 'load', this );
|
|
this.img.removeEventListener( 'error', this );
|
|
};
|
|
|
|
Background.prototype.confirm = function( isLoaded, message ) {
|
|
this.isLoaded = isLoaded;
|
|
this.emitEvent( 'progress', [ this, this.element, message ] );
|
|
};
|
|
|
|
// -------------------------- jQuery -------------------------- //
|
|
|
|
ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
|
|
jQuery = jQuery || window.jQuery;
|
|
if ( !jQuery ) {
|
|
return;
|
|
}
|
|
// set local variable
|
|
$ = jQuery;
|
|
// $().imagesLoaded()
|
|
$.fn.imagesLoaded = function( options, callback ) {
|
|
var instance = new ImagesLoaded( this, options, callback );
|
|
return instance.jqDeferred.promise( $(this) );
|
|
};
|
|
};
|
|
// try making plugin
|
|
ImagesLoaded.makeJQueryPlugin();
|
|
|
|
// -------------------------- -------------------------- //
|
|
|
|
return ImagesLoaded;
|
|
|
|
});
|
|
|
|
|
|
/*!
|
|
* Isotope PACKAGED v3.0.1
|
|
*
|
|
* Licensed GPLv3 for open source use
|
|
* or Isotope Commercial License for commercial use
|
|
*
|
|
* http://isotope.metafizzy.co
|
|
* Copyright 2016 Metafizzy
|
|
*/
|
|
|
|
/**
|
|
* Bridget makes jQuery widgets
|
|
* v2.0.0
|
|
* MIT license
|
|
*/
|
|
|
|
/* jshint browser: true, strict: true, undef: true, unused: true */
|
|
|
|
( function( window, factory ) {
|
|
'use strict';
|
|
/* globals define: false, module: false, require: false */
|
|
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
|
|
factory( window, jQuery );
|
|
});
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory(
|
|
window,
|
|
require('jquery')
|
|
);
|
|
} else {
|
|
// browser global
|
|
window.jQueryBridget = factory(
|
|
window,
|
|
window.jQuery
|
|
);
|
|
}
|
|
|
|
}( window, function factory( window, jQuery ) {
|
|
'use strict';
|
|
|
|
// ----- utils ----- //
|
|
|
|
var arraySlice = Array.prototype.slice;
|
|
|
|
// helper function for logging errors
|
|
// $.error breaks jQuery chaining
|
|
var console = window.console;
|
|
var logError = typeof console == 'undefined' ? function() {} :
|
|
function( message ) {
|
|
console.error( message );
|
|
};
|
|
|
|
// ----- jQueryBridget ----- //
|
|
|
|
function jQueryBridget( namespace, PluginClass, $ ) {
|
|
$ = $ || jQuery || window.jQuery;
|
|
if ( !$ ) {
|
|
return;
|
|
}
|
|
|
|
// add option method -> $().plugin('option', {...})
|
|
if ( !PluginClass.prototype.option ) {
|
|
// option setter
|
|
PluginClass.prototype.option = function( opts ) {
|
|
// bail out if not an object
|
|
if ( !$.isPlainObject( opts ) ){
|
|
return;
|
|
}
|
|
this.options = $.extend( true, this.options, opts );
|
|
};
|
|
}
|
|
|
|
// make jQuery plugin
|
|
$.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
|
|
if ( typeof arg0 == 'string' ) {
|
|
// method call $().plugin( 'methodName', { options } )
|
|
// shift arguments by 1
|
|
var args = arraySlice.call( arguments, 1 );
|
|
return methodCall( this, arg0, args );
|
|
}
|
|
// just $().plugin({ options })
|
|
plainCall( this, arg0 );
|
|
return this;
|
|
};
|
|
|
|
// $().plugin('methodName')
|
|
function methodCall( $elems, methodName, args ) {
|
|
var returnValue;
|
|
var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
|
|
|
|
$elems.each( function( i, elem ) {
|
|
// get instance
|
|
var instance = $.data( elem, namespace );
|
|
if ( !instance ) {
|
|
logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
|
|
pluginMethodStr );
|
|
return;
|
|
}
|
|
|
|
var method = instance[ methodName ];
|
|
if ( !method || methodName.charAt(0) == '_' ) {
|
|
logError( pluginMethodStr + ' is not a valid method' );
|
|
return;
|
|
}
|
|
|
|
// apply method, get return value
|
|
var value = method.apply( instance, args );
|
|
// set return value if value is returned, use only first value
|
|
returnValue = returnValue === undefined ? value : returnValue;
|
|
});
|
|
|
|
return returnValue !== undefined ? returnValue : $elems;
|
|
}
|
|
|
|
function plainCall( $elems, options ) {
|
|
$elems.each( function( i, elem ) {
|
|
var instance = $.data( elem, namespace );
|
|
if ( instance ) {
|
|
// set options & init
|
|
instance.option( options );
|
|
instance._init();
|
|
} else {
|
|
// initialize new instance
|
|
instance = new PluginClass( elem, options );
|
|
$.data( elem, namespace, instance );
|
|
}
|
|
});
|
|
}
|
|
|
|
updateJQuery( $ );
|
|
|
|
}
|
|
|
|
// ----- updateJQuery ----- //
|
|
|
|
// set $.bridget for v1 backwards compatibility
|
|
function updateJQuery( $ ) {
|
|
if ( !$ || ( $ && $.bridget ) ) {
|
|
return;
|
|
}
|
|
$.bridget = jQueryBridget;
|
|
}
|
|
|
|
updateJQuery( jQuery || window.jQuery );
|
|
|
|
// ----- ----- //
|
|
|
|
return jQueryBridget;
|
|
|
|
}));
|
|
|
|
/**
|
|
* EvEmitter v1.0.3
|
|
* Lil' event emitter
|
|
* MIT License
|
|
*/
|
|
|
|
/* jshint unused: true, undef: true, strict: true */
|
|
|
|
( function( global, factory ) {
|
|
// universal module definition
|
|
/* jshint strict: false */ /* globals define, module, window */
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD - RequireJS
|
|
define( 'ev-emitter/ev-emitter',factory );
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS - Browserify, Webpack
|
|
module.exports = factory();
|
|
} else {
|
|
// Browser globals
|
|
global.EvEmitter = factory();
|
|
}
|
|
|
|
}( typeof window != 'undefined' ? window : this, function() {
|
|
|
|
|
|
|
|
function EvEmitter() {}
|
|
|
|
var proto = EvEmitter.prototype;
|
|
|
|
proto.on = function( eventName, listener ) {
|
|
if ( !eventName || !listener ) {
|
|
return;
|
|
}
|
|
// set events hash
|
|
var events = this._events = this._events || {};
|
|
// set listeners array
|
|
var listeners = events[ eventName ] = events[ eventName ] || [];
|
|
// only add once
|
|
if ( listeners.indexOf( listener ) == -1 ) {
|
|
listeners.push( listener );
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
proto.once = function( eventName, listener ) {
|
|
if ( !eventName || !listener ) {
|
|
return;
|
|
}
|
|
// add event
|
|
this.on( eventName, listener );
|
|
// set once flag
|
|
// set onceEvents hash
|
|
var onceEvents = this._onceEvents = this._onceEvents || {};
|
|
// set onceListeners object
|
|
var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
|
|
// set flag
|
|
onceListeners[ listener ] = true;
|
|
|
|
return this;
|
|
};
|
|
|
|
proto.off = function( eventName, listener ) {
|
|
var listeners = this._events && this._events[ eventName ];
|
|
if ( !listeners || !listeners.length ) {
|
|
return;
|
|
}
|
|
var index = listeners.indexOf( listener );
|
|
if ( index != -1 ) {
|
|
listeners.splice( index, 1 );
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
proto.emitEvent = function( eventName, args ) {
|
|
var listeners = this._events && this._events[ eventName ];
|
|
if ( !listeners || !listeners.length ) {
|
|
return;
|
|
}
|
|
var i = 0;
|
|
var listener = listeners[i];
|
|
args = args || [];
|
|
// once stuff
|
|
var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
|
|
|
|
while ( listener ) {
|
|
var isOnce = onceListeners && onceListeners[ listener ];
|
|
if ( isOnce ) {
|
|
// remove listener
|
|
// remove before trigger to prevent recursion
|
|
this.off( eventName, listener );
|
|
// unset once flag
|
|
delete onceListeners[ listener ];
|
|
}
|
|
// trigger listener
|
|
listener.apply( this, args );
|
|
// get next listener
|
|
i += isOnce ? 0 : 1;
|
|
listener = listeners[i];
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
return EvEmitter;
|
|
|
|
}));
|
|
|
|
/*!
|
|
* getSize v2.0.2
|
|
* measure size of elements
|
|
* MIT license
|
|
*/
|
|
|
|
/*jshint browser: true, strict: true, undef: true, unused: true */
|
|
/*global define: false, module: false, console: false */
|
|
|
|
( function( window, factory ) {
|
|
'use strict';
|
|
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( 'get-size/get-size',[],function() {
|
|
return factory();
|
|
});
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory();
|
|
} else {
|
|
// browser global
|
|
window.getSize = factory();
|
|
}
|
|
|
|
})( window, function factory() {
|
|
'use strict';
|
|
|
|
// -------------------------- helpers -------------------------- //
|
|
|
|
// get a number from a string, not a percentage
|
|
function getStyleSize( value ) {
|
|
var num = parseFloat( value );
|
|
// not a percent like '100%', and a number
|
|
var isValid = value.indexOf('%') == -1 && !isNaN( num );
|
|
return isValid && num;
|
|
}
|
|
|
|
function noop() {}
|
|
|
|
var logError = typeof console == 'undefined' ? noop :
|
|
function( message ) {
|
|
console.error( message );
|
|
};
|
|
|
|
// -------------------------- measurements -------------------------- //
|
|
|
|
var measurements = [
|
|
'paddingLeft',
|
|
'paddingRight',
|
|
'paddingTop',
|
|
'paddingBottom',
|
|
'marginLeft',
|
|
'marginRight',
|
|
'marginTop',
|
|
'marginBottom',
|
|
'borderLeftWidth',
|
|
'borderRightWidth',
|
|
'borderTopWidth',
|
|
'borderBottomWidth'
|
|
];
|
|
|
|
var measurementsLength = measurements.length;
|
|
|
|
function getZeroSize() {
|
|
var size = {
|
|
width: 0,
|
|
height: 0,
|
|
innerWidth: 0,
|
|
innerHeight: 0,
|
|
outerWidth: 0,
|
|
outerHeight: 0
|
|
};
|
|
for ( var i=0; i < measurementsLength; i++ ) {
|
|
var measurement = measurements[i];
|
|
size[ measurement ] = 0;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
// -------------------------- getStyle -------------------------- //
|
|
|
|
/**
|
|
* getStyle, get style of element, check for Firefox bug
|
|
* https://bugzilla.mozilla.org/show_bug.cgi?id=548397
|
|
*/
|
|
function getStyle( elem ) {
|
|
var style = getComputedStyle( elem );
|
|
if ( !style ) {
|
|
logError( 'Style returned ' + style +
|
|
'. Are you running this code in a hidden iframe on Firefox? ' +
|
|
'See http://bit.ly/getsizebug1' );
|
|
}
|
|
return style;
|
|
}
|
|
|
|
// -------------------------- setup -------------------------- //
|
|
|
|
var isSetup = false;
|
|
|
|
var isBoxSizeOuter;
|
|
|
|
/**
|
|
* setup
|
|
* check isBoxSizerOuter
|
|
* do on first getSize() rather than on page load for Firefox bug
|
|
*/
|
|
function setup() {
|
|
// setup once
|
|
if ( isSetup ) {
|
|
return;
|
|
}
|
|
isSetup = true;
|
|
|
|
// -------------------------- box sizing -------------------------- //
|
|
|
|
/**
|
|
* WebKit measures the outer-width on style.width on border-box elems
|
|
* IE & Firefox<29 measures the inner-width
|
|
*/
|
|
var div = document.createElement('div');
|
|
div.style.width = '200px';
|
|
div.style.padding = '1px 2px 3px 4px';
|
|
div.style.borderStyle = 'solid';
|
|
div.style.borderWidth = '1px 2px 3px 4px';
|
|
div.style.boxSizing = 'border-box';
|
|
|
|
var body = document.body || document.documentElement;
|
|
body.appendChild( div );
|
|
var style = getStyle( div );
|
|
|
|
getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200;
|
|
body.removeChild( div );
|
|
|
|
}
|
|
|
|
// -------------------------- getSize -------------------------- //
|
|
|
|
function getSize( elem ) {
|
|
setup();
|
|
|
|
// use querySeletor if elem is string
|
|
if ( typeof elem == 'string' ) {
|
|
elem = document.querySelector( elem );
|
|
}
|
|
|
|
// do not proceed on non-objects
|
|
if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
|
|
return;
|
|
}
|
|
|
|
var style = getStyle( elem );
|
|
|
|
// if hidden, everything is 0
|
|
if ( style.display == 'none' ) {
|
|
return getZeroSize();
|
|
}
|
|
|
|
var size = {};
|
|
size.width = elem.offsetWidth;
|
|
size.height = elem.offsetHeight;
|
|
|
|
var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
|
|
|
|
// get all measurements
|
|
for ( var i=0; i < measurementsLength; i++ ) {
|
|
var measurement = measurements[i];
|
|
var value = style[ measurement ];
|
|
var num = parseFloat( value );
|
|
// any 'auto', 'medium' value will be 0
|
|
size[ measurement ] = !isNaN( num ) ? num : 0;
|
|
}
|
|
|
|
var paddingWidth = size.paddingLeft + size.paddingRight;
|
|
var paddingHeight = size.paddingTop + size.paddingBottom;
|
|
var marginWidth = size.marginLeft + size.marginRight;
|
|
var marginHeight = size.marginTop + size.marginBottom;
|
|
var borderWidth = size.borderLeftWidth + size.borderRightWidth;
|
|
var borderHeight = size.borderTopWidth + size.borderBottomWidth;
|
|
|
|
var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
|
|
|
|
// overwrite width and height if we can get it from style
|
|
var styleWidth = getStyleSize( style.width );
|
|
if ( styleWidth !== false ) {
|
|
size.width = styleWidth +
|
|
// add padding and border unless it's already including it
|
|
( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
|
|
}
|
|
|
|
var styleHeight = getStyleSize( style.height );
|
|
if ( styleHeight !== false ) {
|
|
size.height = styleHeight +
|
|
// add padding and border unless it's already including it
|
|
( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
|
|
}
|
|
|
|
size.innerWidth = size.width - ( paddingWidth + borderWidth );
|
|
size.innerHeight = size.height - ( paddingHeight + borderHeight );
|
|
|
|
size.outerWidth = size.width + marginWidth;
|
|
size.outerHeight = size.height + marginHeight;
|
|
|
|
return size;
|
|
}
|
|
|
|
return getSize;
|
|
|
|
});
|
|
|
|
/**
|
|
* matchesSelector v2.0.1
|
|
* matchesSelector( element, '.selector' )
|
|
* MIT license
|
|
*/
|
|
|
|
/*jshint browser: true, strict: true, undef: true, unused: true */
|
|
|
|
( function( window, factory ) {
|
|
/*global define: false, module: false */
|
|
'use strict';
|
|
// universal module definition
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( 'desandro-matches-selector/matches-selector',factory );
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory();
|
|
} else {
|
|
// browser global
|
|
window.matchesSelector = factory();
|
|
}
|
|
|
|
}( window, function factory() {
|
|
'use strict';
|
|
|
|
var matchesMethod = ( function() {
|
|
var ElemProto = Element.prototype;
|
|
// check for the standard method name first
|
|
if ( ElemProto.matches ) {
|
|
return 'matches';
|
|
}
|
|
// check un-prefixed
|
|
if ( ElemProto.matchesSelector ) {
|
|
return 'matchesSelector';
|
|
}
|
|
// check vendor prefixes
|
|
var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
|
|
|
|
for ( var i=0; i < prefixes.length; i++ ) {
|
|
var prefix = prefixes[i];
|
|
var method = prefix + 'MatchesSelector';
|
|
if ( ElemProto[ method ] ) {
|
|
return method;
|
|
}
|
|
}
|
|
})();
|
|
|
|
return function matchesSelector( elem, selector ) {
|
|
return elem[ matchesMethod ]( selector );
|
|
};
|
|
|
|
}));
|
|
|
|
/**
|
|
* Fizzy UI utils v2.0.2
|
|
* MIT license
|
|
*/
|
|
|
|
/*jshint browser: true, undef: true, unused: true, strict: true */
|
|
|
|
( function( window, factory ) {
|
|
// universal module definition
|
|
/*jshint strict: false */ /*globals define, module, require */
|
|
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( 'fizzy-ui-utils/utils',[
|
|
'desandro-matches-selector/matches-selector'
|
|
], function( matchesSelector ) {
|
|
return factory( window, matchesSelector );
|
|
});
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory(
|
|
window,
|
|
require('desandro-matches-selector')
|
|
);
|
|
} else {
|
|
// browser global
|
|
window.fizzyUIUtils = factory(
|
|
window,
|
|
window.matchesSelector
|
|
);
|
|
}
|
|
|
|
}( window, function factory( window, matchesSelector ) {
|
|
|
|
|
|
|
|
var utils = {};
|
|
|
|
// ----- extend ----- //
|
|
|
|
// extends objects
|
|
utils.extend = function( a, b ) {
|
|
for ( var prop in b ) {
|
|
a[ prop ] = b[ prop ];
|
|
}
|
|
return a;
|
|
};
|
|
|
|
// ----- modulo ----- //
|
|
|
|
utils.modulo = function( num, div ) {
|
|
return ( ( num % div ) + div ) % div;
|
|
};
|
|
|
|
// ----- makeArray ----- //
|
|
|
|
// turn element or nodeList into an array
|
|
utils.makeArray = function( obj ) {
|
|
var ary = [];
|
|
if ( Array.isArray( obj ) ) {
|
|
// use object if already an array
|
|
ary = obj;
|
|
} else if ( obj && typeof obj.length == 'number' ) {
|
|
// convert nodeList to array
|
|
for ( var i=0; i < obj.length; i++ ) {
|
|
ary.push( obj[i] );
|
|
}
|
|
} else {
|
|
// array of single index
|
|
ary.push( obj );
|
|
}
|
|
return ary;
|
|
};
|
|
|
|
// ----- removeFrom ----- //
|
|
|
|
utils.removeFrom = function( ary, obj ) {
|
|
var index = ary.indexOf( obj );
|
|
if ( index != -1 ) {
|
|
ary.splice( index, 1 );
|
|
}
|
|
};
|
|
|
|
// ----- getParent ----- //
|
|
|
|
utils.getParent = function( elem, selector ) {
|
|
while ( elem != document.body ) {
|
|
elem = elem.parentNode;
|
|
if ( matchesSelector( elem, selector ) ) {
|
|
return elem;
|
|
}
|
|
}
|
|
};
|
|
|
|
// ----- getQueryElement ----- //
|
|
|
|
// use element as selector string
|
|
utils.getQueryElement = function( elem ) {
|
|
if ( typeof elem == 'string' ) {
|
|
return document.querySelector( elem );
|
|
}
|
|
return elem;
|
|
};
|
|
|
|
// ----- handleEvent ----- //
|
|
|
|
// enable .ontype to trigger from .addEventListener( elem, 'type' )
|
|
utils.handleEvent = function( event ) {
|
|
var method = 'on' + event.type;
|
|
if ( this[ method ] ) {
|
|
this[ method ]( event );
|
|
}
|
|
};
|
|
|
|
// ----- filterFindElements ----- //
|
|
|
|
utils.filterFindElements = function( elems, selector ) {
|
|
// make array of elems
|
|
elems = utils.makeArray( elems );
|
|
var ffElems = [];
|
|
|
|
elems.forEach( function( elem ) {
|
|
// check that elem is an actual element
|
|
if ( !( elem instanceof HTMLElement ) ) {
|
|
return;
|
|
}
|
|
// add elem if no selector
|
|
if ( !selector ) {
|
|
ffElems.push( elem );
|
|
return;
|
|
}
|
|
// filter & find items if we have a selector
|
|
// filter
|
|
if ( matchesSelector( elem, selector ) ) {
|
|
ffElems.push( elem );
|
|
}
|
|
// find children
|
|
var childElems = elem.querySelectorAll( selector );
|
|
// concat childElems to filterFound array
|
|
for ( var i=0; i < childElems.length; i++ ) {
|
|
ffElems.push( childElems[i] );
|
|
}
|
|
});
|
|
|
|
return ffElems;
|
|
};
|
|
|
|
// ----- debounceMethod ----- //
|
|
|
|
utils.debounceMethod = function( _class, methodName, threshold ) {
|
|
// original method
|
|
var method = _class.prototype[ methodName ];
|
|
var timeoutName = methodName + 'Timeout';
|
|
|
|
_class.prototype[ methodName ] = function() {
|
|
var timeout = this[ timeoutName ];
|
|
if ( timeout ) {
|
|
clearTimeout( timeout );
|
|
}
|
|
var args = arguments;
|
|
|
|
var _this = this;
|
|
this[ timeoutName ] = setTimeout( function() {
|
|
method.apply( _this, args );
|
|
delete _this[ timeoutName ];
|
|
}, threshold || 100 );
|
|
};
|
|
};
|
|
|
|
// ----- docReady ----- //
|
|
|
|
utils.docReady = function( callback ) {
|
|
var readyState = document.readyState;
|
|
if ( readyState == 'complete' || readyState == 'interactive' ) {
|
|
callback();
|
|
} else {
|
|
document.addEventListener( 'DOMContentLoaded', callback );
|
|
}
|
|
};
|
|
|
|
// ----- htmlInit ----- //
|
|
|
|
// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
|
|
utils.toDashed = function( str ) {
|
|
return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
|
|
return $1 + '-' + $2;
|
|
}).toLowerCase();
|
|
};
|
|
|
|
var console = window.console;
|
|
/**
|
|
* allow user to initialize classes via [data-namespace] or .js-namespace class
|
|
* htmlInit( Widget, 'widgetName' )
|
|
* options are parsed from data-namespace-options
|
|
*/
|
|
utils.htmlInit = function( WidgetClass, namespace ) {
|
|
utils.docReady( function() {
|
|
var dashedNamespace = utils.toDashed( namespace );
|
|
var dataAttr = 'data-' + dashedNamespace;
|
|
var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
|
|
var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
|
|
var elems = utils.makeArray( dataAttrElems )
|
|
.concat( utils.makeArray( jsDashElems ) );
|
|
var dataOptionsAttr = dataAttr + '-options';
|
|
var jQuery = window.jQuery;
|
|
|
|
elems.forEach( function( elem ) {
|
|
var attr = elem.getAttribute( dataAttr ) ||
|
|
elem.getAttribute( dataOptionsAttr );
|
|
var options;
|
|
try {
|
|
options = attr && JSON.parse( attr );
|
|
} catch ( error ) {
|
|
// log error, do not initialize
|
|
if ( console ) {
|
|
console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
|
|
': ' + error );
|
|
}
|
|
return;
|
|
}
|
|
// initialize
|
|
var instance = new WidgetClass( elem, options );
|
|
// make available via $().data('layoutname')
|
|
if ( jQuery ) {
|
|
jQuery.data( elem, namespace, instance );
|
|
}
|
|
});
|
|
|
|
});
|
|
};
|
|
|
|
// ----- ----- //
|
|
|
|
return utils;
|
|
|
|
}));
|
|
|
|
/**
|
|
* Outlayer Item
|
|
*/
|
|
|
|
( function( window, factory ) {
|
|
// universal module definition
|
|
/* jshint strict: false */ /* globals define, module, require */
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD - RequireJS
|
|
define( 'outlayer/item',[
|
|
'ev-emitter/ev-emitter',
|
|
'get-size/get-size'
|
|
],
|
|
factory
|
|
);
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS - Browserify, Webpack
|
|
module.exports = factory(
|
|
require('ev-emitter'),
|
|
require('get-size')
|
|
);
|
|
} else {
|
|
// browser global
|
|
window.Outlayer = {};
|
|
window.Outlayer.Item = factory(
|
|
window.EvEmitter,
|
|
window.getSize
|
|
);
|
|
}
|
|
|
|
}( window, function factory( EvEmitter, getSize ) {
|
|
'use strict';
|
|
|
|
// ----- helpers ----- //
|
|
|
|
function isEmptyObj( obj ) {
|
|
for ( var prop in obj ) {
|
|
return false;
|
|
}
|
|
prop = null;
|
|
return true;
|
|
}
|
|
|
|
// -------------------------- CSS3 support -------------------------- //
|
|
|
|
|
|
var docElemStyle = document.documentElement.style;
|
|
|
|
var transitionProperty = typeof docElemStyle.transition == 'string' ?
|
|
'transition' : 'WebkitTransition';
|
|
var transformProperty = typeof docElemStyle.transform == 'string' ?
|
|
'transform' : 'WebkitTransform';
|
|
|
|
var transitionEndEvent = {
|
|
WebkitTransition: 'webkitTransitionEnd',
|
|
transition: 'transitionend'
|
|
}[ transitionProperty ];
|
|
|
|
// cache all vendor properties that could have vendor prefix
|
|
var vendorProperties = {
|
|
transform: transformProperty,
|
|
transition: transitionProperty,
|
|
transitionDuration: transitionProperty + 'Duration',
|
|
transitionProperty: transitionProperty + 'Property',
|
|
transitionDelay: transitionProperty + 'Delay'
|
|
};
|
|
|
|
// -------------------------- Item -------------------------- //
|
|
|
|
function Item( element, layout ) {
|
|
if ( !element ) {
|
|
return;
|
|
}
|
|
|
|
this.element = element;
|
|
// parent layout class, i.e. Masonry, Isotope, or Packery
|
|
this.layout = layout;
|
|
this.position = {
|
|
x: 0,
|
|
y: 0
|
|
};
|
|
|
|
this._create();
|
|
}
|
|
|
|
// inherit EvEmitter
|
|
var proto = Item.prototype = Object.create( EvEmitter.prototype );
|
|
proto.constructor = Item;
|
|
|
|
proto._create = function() {
|
|
// transition objects
|
|
this._transn = {
|
|
ingProperties: {},
|
|
clean: {},
|
|
onEnd: {}
|
|
};
|
|
|
|
this.css({
|
|
position: 'absolute'
|
|
});
|
|
};
|
|
|
|
// trigger specified handler for event type
|
|
proto.handleEvent = function( event ) {
|
|
var method = 'on' + event.type;
|
|
if ( this[ method ] ) {
|
|
this[ method ]( event );
|
|
}
|
|
};
|
|
|
|
proto.getSize = function() {
|
|
this.size = getSize( this.element );
|
|
};
|
|
|
|
/**
|
|
* apply CSS styles to element
|
|
* @param {Object} style
|
|
*/
|
|
proto.css = function( style ) {
|
|
var elemStyle = this.element.style;
|
|
|
|
for ( var prop in style ) {
|
|
// use vendor property if available
|
|
var supportedProp = vendorProperties[ prop ] || prop;
|
|
elemStyle[ supportedProp ] = style[ prop ];
|
|
}
|
|
};
|
|
|
|
// measure position, and sets it
|
|
proto.getPosition = function() {
|
|
var style = getComputedStyle( this.element );
|
|
var isOriginLeft = this.layout._getOption('originLeft');
|
|
var isOriginTop = this.layout._getOption('originTop');
|
|
var xValue = style[ isOriginLeft ? 'left' : 'right' ];
|
|
var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
|
|
// convert percent to pixels
|
|
var layoutSize = this.layout.size;
|
|
var x = xValue.indexOf('%') != -1 ?
|
|
( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 );
|
|
var y = yValue.indexOf('%') != -1 ?
|
|
( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 );
|
|
|
|
// clean up 'auto' or other non-integer values
|
|
x = isNaN( x ) ? 0 : x;
|
|
y = isNaN( y ) ? 0 : y;
|
|
// remove padding from measurement
|
|
x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
|
|
y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
|
|
|
|
this.position.x = x;
|
|
this.position.y = y;
|
|
};
|
|
|
|
// set settled position, apply padding
|
|
proto.layoutPosition = function() {
|
|
var layoutSize = this.layout.size;
|
|
var style = {};
|
|
var isOriginLeft = this.layout._getOption('originLeft');
|
|
var isOriginTop = this.layout._getOption('originTop');
|
|
|
|
// x
|
|
var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
|
|
var xProperty = isOriginLeft ? 'left' : 'right';
|
|
var xResetProperty = isOriginLeft ? 'right' : 'left';
|
|
|
|
var x = this.position.x + layoutSize[ xPadding ];
|
|
// set in percentage or pixels
|
|
style[ xProperty ] = this.getXValue( x );
|
|
// reset other property
|
|
style[ xResetProperty ] = '';
|
|
|
|
// y
|
|
var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
|
|
var yProperty = isOriginTop ? 'top' : 'bottom';
|
|
var yResetProperty = isOriginTop ? 'bottom' : 'top';
|
|
|
|
var y = this.position.y + layoutSize[ yPadding ];
|
|
// set in percentage or pixels
|
|
style[ yProperty ] = this.getYValue( y );
|
|
// reset other property
|
|
style[ yResetProperty ] = '';
|
|
|
|
this.css( style );
|
|
this.emitEvent( 'layout', [ this ] );
|
|
};
|
|
|
|
proto.getXValue = function( x ) {
|
|
var isHorizontal = this.layout._getOption('horizontal');
|
|
return this.layout.options.percentPosition && !isHorizontal ?
|
|
( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
|
|
};
|
|
|
|
proto.getYValue = function( y ) {
|
|
var isHorizontal = this.layout._getOption('horizontal');
|
|
return this.layout.options.percentPosition && isHorizontal ?
|
|
( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
|
|
};
|
|
|
|
proto._transitionTo = function( x, y ) {
|
|
this.getPosition();
|
|
// get current x & y from top/left
|
|
var curX = this.position.x;
|
|
var curY = this.position.y;
|
|
|
|
var compareX = parseInt( x, 10 );
|
|
var compareY = parseInt( y, 10 );
|
|
var didNotMove = compareX === this.position.x && compareY === this.position.y;
|
|
|
|
// save end position
|
|
this.setPosition( x, y );
|
|
|
|
// if did not move and not transitioning, just go to layout
|
|
if ( didNotMove && !this.isTransitioning ) {
|
|
this.layoutPosition();
|
|
return;
|
|
}
|
|
|
|
var transX = x - curX;
|
|
var transY = y - curY;
|
|
var transitionStyle = {};
|
|
transitionStyle.transform = this.getTranslate( transX, transY );
|
|
|
|
this.transition({
|
|
to: transitionStyle,
|
|
onTransitionEnd: {
|
|
transform: this.layoutPosition
|
|
},
|
|
isCleaning: true
|
|
});
|
|
};
|
|
|
|
proto.getTranslate = function( x, y ) {
|
|
// flip cooridinates if origin on right or bottom
|
|
var isOriginLeft = this.layout._getOption('originLeft');
|
|
var isOriginTop = this.layout._getOption('originTop');
|
|
x = isOriginLeft ? x : -x;
|
|
y = isOriginTop ? y : -y;
|
|
return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
|
|
};
|
|
|
|
// non transition + transform support
|
|
proto.goTo = function( x, y ) {
|
|
this.setPosition( x, y );
|
|
this.layoutPosition();
|
|
};
|
|
|
|
proto.moveTo = proto._transitionTo;
|
|
|
|
proto.setPosition = function( x, y ) {
|
|
this.position.x = parseInt( x, 10 );
|
|
this.position.y = parseInt( y, 10 );
|
|
};
|
|
|
|
// ----- transition ----- //
|
|
|
|
/**
|
|
* @param {Object} style - CSS
|
|
* @param {Function} onTransitionEnd
|
|
*/
|
|
|
|
// non transition, just trigger callback
|
|
proto._nonTransition = function( args ) {
|
|
this.css( args.to );
|
|
if ( args.isCleaning ) {
|
|
this._removeStyles( args.to );
|
|
}
|
|
for ( var prop in args.onTransitionEnd ) {
|
|
args.onTransitionEnd[ prop ].call( this );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* proper transition
|
|
* @param {Object} args - arguments
|
|
* @param {Object} to - style to transition to
|
|
* @param {Object} from - style to start transition from
|
|
* @param {Boolean} isCleaning - removes transition styles after transition
|
|
* @param {Function} onTransitionEnd - callback
|
|
*/
|
|
proto.transition = function( args ) {
|
|
// redirect to nonTransition if no transition duration
|
|
if ( !parseFloat( this.layout.options.transitionDuration ) ) {
|
|
this._nonTransition( args );
|
|
return;
|
|
}
|
|
|
|
var _transition = this._transn;
|
|
// keep track of onTransitionEnd callback by css property
|
|
for ( var prop in args.onTransitionEnd ) {
|
|
_transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
|
|
}
|
|
// keep track of properties that are transitioning
|
|
for ( prop in args.to ) {
|
|
_transition.ingProperties[ prop ] = true;
|
|
// keep track of properties to clean up when transition is done
|
|
if ( args.isCleaning ) {
|
|
_transition.clean[ prop ] = true;
|
|
}
|
|
}
|
|
|
|
// set from styles
|
|
if ( args.from ) {
|
|
this.css( args.from );
|
|
// force redraw. http://blog.alexmaccaw.com/css-transitions
|
|
var h = this.element.offsetHeight;
|
|
// hack for JSHint to hush about unused var
|
|
h = null;
|
|
}
|
|
// enable transition
|
|
this.enableTransition( args.to );
|
|
// set styles that are transitioning
|
|
this.css( args.to );
|
|
|
|
this.isTransitioning = true;
|
|
|
|
};
|
|
|
|
// dash before all cap letters, including first for
|
|
// WebkitTransform => -webkit-transform
|
|
function toDashedAll( str ) {
|
|
return str.replace( /([A-Z])/g, function( $1 ) {
|
|
return '-' + $1.toLowerCase();
|
|
});
|
|
}
|
|
|
|
var transitionProps = 'opacity,' + toDashedAll( transformProperty );
|
|
|
|
proto.enableTransition = function(/* style */) {
|
|
// HACK changing transitionProperty during a transition
|
|
// will cause transition to jump
|
|
if ( this.isTransitioning ) {
|
|
return;
|
|
}
|
|
|
|
// make `transition: foo, bar, baz` from style object
|
|
// HACK un-comment this when enableTransition can work
|
|
// while a transition is happening
|
|
// var transitionValues = [];
|
|
// for ( var prop in style ) {
|
|
// // dash-ify camelCased properties like WebkitTransition
|
|
// prop = vendorProperties[ prop ] || prop;
|
|
// transitionValues.push( toDashedAll( prop ) );
|
|
// }
|
|
// munge number to millisecond, to match stagger
|
|
var duration = this.layout.options.transitionDuration;
|
|
duration = typeof duration == 'number' ? duration + 'ms' : duration;
|
|
// enable transition styles
|
|
this.css({
|
|
transitionProperty: transitionProps,
|
|
transitionDuration: duration,
|
|
transitionDelay: this.staggerDelay || 0
|
|
});
|
|
// listen for transition end event
|
|
this.element.addEventListener( transitionEndEvent, this, false );
|
|
};
|
|
|
|
// ----- events ----- //
|
|
|
|
proto.onwebkitTransitionEnd = function( event ) {
|
|
this.ontransitionend( event );
|
|
};
|
|
|
|
proto.onotransitionend = function( event ) {
|
|
this.ontransitionend( event );
|
|
};
|
|
|
|
// properties that I munge to make my life easier
|
|
var dashedVendorProperties = {
|
|
'-webkit-transform': 'transform'
|
|
};
|
|
|
|
proto.ontransitionend = function( event ) {
|
|
// disregard bubbled events from children
|
|
if ( event.target !== this.element ) {
|
|
return;
|
|
}
|
|
var _transition = this._transn;
|
|
// get property name of transitioned property, convert to prefix-free
|
|
var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
|
|
|
|
// remove property that has completed transitioning
|
|
delete _transition.ingProperties[ propertyName ];
|
|
// check if any properties are still transitioning
|
|
if ( isEmptyObj( _transition.ingProperties ) ) {
|
|
// all properties have completed transitioning
|
|
this.disableTransition();
|
|
}
|
|
// clean style
|
|
if ( propertyName in _transition.clean ) {
|
|
// clean up style
|
|
this.element.style[ event.propertyName ] = '';
|
|
delete _transition.clean[ propertyName ];
|
|
}
|
|
// trigger onTransitionEnd callback
|
|
if ( propertyName in _transition.onEnd ) {
|
|
var onTransitionEnd = _transition.onEnd[ propertyName ];
|
|
onTransitionEnd.call( this );
|
|
delete _transition.onEnd[ propertyName ];
|
|
}
|
|
|
|
this.emitEvent( 'transitionEnd', [ this ] );
|
|
};
|
|
|
|
proto.disableTransition = function() {
|
|
this.removeTransitionStyles();
|
|
this.element.removeEventListener( transitionEndEvent, this, false );
|
|
this.isTransitioning = false;
|
|
};
|
|
|
|
/**
|
|
* removes style property from element
|
|
* @param {Object} style
|
|
**/
|
|
proto._removeStyles = function( style ) {
|
|
// clean up transition styles
|
|
var cleanStyle = {};
|
|
for ( var prop in style ) {
|
|
cleanStyle[ prop ] = '';
|
|
}
|
|
this.css( cleanStyle );
|
|
};
|
|
|
|
var cleanTransitionStyle = {
|
|
transitionProperty: '',
|
|
transitionDuration: '',
|
|
transitionDelay: ''
|
|
};
|
|
|
|
proto.removeTransitionStyles = function() {
|
|
// remove transition
|
|
this.css( cleanTransitionStyle );
|
|
};
|
|
|
|
// ----- stagger ----- //
|
|
|
|
proto.stagger = function( delay ) {
|
|
delay = isNaN( delay ) ? 0 : delay;
|
|
this.staggerDelay = delay + 'ms';
|
|
};
|
|
|
|
// ----- show/hide/remove ----- //
|
|
|
|
// remove element from DOM
|
|
proto.removeElem = function() {
|
|
this.element.parentNode.removeChild( this.element );
|
|
// remove display: none
|
|
this.css({ display: '' });
|
|
this.emitEvent( 'remove', [ this ] );
|
|
};
|
|
|
|
proto.remove = function() {
|
|
// just remove element if no transition support or no transition
|
|
if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
|
|
this.removeElem();
|
|
return;
|
|
}
|
|
|
|
// start transition
|
|
this.once( 'transitionEnd', function() {
|
|
this.removeElem();
|
|
});
|
|
this.hide();
|
|
};
|
|
|
|
proto.reveal = function() {
|
|
delete this.isHidden;
|
|
// remove display: none
|
|
this.css({ display: '' });
|
|
|
|
var options = this.layout.options;
|
|
|
|
var onTransitionEnd = {};
|
|
var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
|
|
onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
|
|
|
|
this.transition({
|
|
from: options.hiddenStyle,
|
|
to: options.visibleStyle,
|
|
isCleaning: true,
|
|
onTransitionEnd: onTransitionEnd
|
|
});
|
|
};
|
|
|
|
proto.onRevealTransitionEnd = function() {
|
|
// check if still visible
|
|
// during transition, item may have been hidden
|
|
if ( !this.isHidden ) {
|
|
this.emitEvent('reveal');
|
|
}
|
|
};
|
|
|
|
/**
|
|
* get style property use for hide/reveal transition end
|
|
* @param {String} styleProperty - hiddenStyle/visibleStyle
|
|
* @returns {String}
|
|
*/
|
|
proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
|
|
var optionStyle = this.layout.options[ styleProperty ];
|
|
// use opacity
|
|
if ( optionStyle.opacity ) {
|
|
return 'opacity';
|
|
}
|
|
// get first property
|
|
for ( var prop in optionStyle ) {
|
|
return prop;
|
|
}
|
|
};
|
|
|
|
proto.hide = function() {
|
|
// set flag
|
|
this.isHidden = true;
|
|
// remove display: none
|
|
this.css({ display: '' });
|
|
|
|
var options = this.layout.options;
|
|
|
|
var onTransitionEnd = {};
|
|
var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
|
|
onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
|
|
|
|
this.transition({
|
|
from: options.visibleStyle,
|
|
to: options.hiddenStyle,
|
|
// keep hidden stuff hidden
|
|
isCleaning: true,
|
|
onTransitionEnd: onTransitionEnd
|
|
});
|
|
};
|
|
|
|
proto.onHideTransitionEnd = function() {
|
|
// check if still hidden
|
|
// during transition, item may have been un-hidden
|
|
if ( this.isHidden ) {
|
|
this.css({ display: 'none' });
|
|
this.emitEvent('hide');
|
|
}
|
|
};
|
|
|
|
proto.destroy = function() {
|
|
this.css({
|
|
position: '',
|
|
left: '',
|
|
right: '',
|
|
top: '',
|
|
bottom: '',
|
|
transition: '',
|
|
transform: ''
|
|
});
|
|
};
|
|
|
|
return Item;
|
|
|
|
}));
|
|
|
|
/*!
|
|
* Outlayer v2.1.0
|
|
* the brains and guts of a layout library
|
|
* MIT license
|
|
*/
|
|
|
|
( function( window, factory ) {
|
|
'use strict';
|
|
// universal module definition
|
|
/* jshint strict: false */ /* globals define, module, require */
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD - RequireJS
|
|
define( 'outlayer/outlayer',[
|
|
'ev-emitter/ev-emitter',
|
|
'get-size/get-size',
|
|
'fizzy-ui-utils/utils',
|
|
'./item'
|
|
],
|
|
function( EvEmitter, getSize, utils, Item ) {
|
|
return factory( window, EvEmitter, getSize, utils, Item);
|
|
}
|
|
);
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS - Browserify, Webpack
|
|
module.exports = factory(
|
|
window,
|
|
require('ev-emitter'),
|
|
require('get-size'),
|
|
require('fizzy-ui-utils'),
|
|
require('./item')
|
|
);
|
|
} else {
|
|
// browser global
|
|
window.Outlayer = factory(
|
|
window,
|
|
window.EvEmitter,
|
|
window.getSize,
|
|
window.fizzyUIUtils,
|
|
window.Outlayer.Item
|
|
);
|
|
}
|
|
|
|
}( window, function factory( window, EvEmitter, getSize, utils, Item ) {
|
|
'use strict';
|
|
|
|
// ----- vars ----- //
|
|
|
|
var console = window.console;
|
|
var jQuery = window.jQuery;
|
|
var noop = function() {};
|
|
|
|
// -------------------------- Outlayer -------------------------- //
|
|
|
|
// globally unique identifiers
|
|
var GUID = 0;
|
|
// internal store of all Outlayer intances
|
|
var instances = {};
|
|
|
|
|
|
/**
|
|
* @param {Element, String} element
|
|
* @param {Object} options
|
|
* @constructor
|
|
*/
|
|
function Outlayer( element, options ) {
|
|
var queryElement = utils.getQueryElement( element );
|
|
if ( !queryElement ) {
|
|
if ( console ) {
|
|
console.error( 'Bad element for ' + this.constructor.namespace +
|
|
': ' + ( queryElement || element ) );
|
|
}
|
|
return;
|
|
}
|
|
this.element = queryElement;
|
|
// add jQuery
|
|
if ( jQuery ) {
|
|
this.$element = jQuery( this.element );
|
|
}
|
|
|
|
// options
|
|
this.options = utils.extend( {}, this.constructor.defaults );
|
|
this.option( options );
|
|
|
|
// add id for Outlayer.getFromElement
|
|
var id = ++GUID;
|
|
this.element.outlayerGUID = id; // expando
|
|
instances[ id ] = this; // associate via id
|
|
|
|
// kick it off
|
|
this._create();
|
|
|
|
var isInitLayout = this._getOption('initLayout');
|
|
if ( isInitLayout ) {
|
|
this.layout();
|
|
}
|
|
}
|
|
|
|
// settings are for internal use only
|
|
Outlayer.namespace = 'outlayer';
|
|
Outlayer.Item = Item;
|
|
|
|
// default options
|
|
Outlayer.defaults = {
|
|
containerStyle: {
|
|
position: 'relative'
|
|
},
|
|
initLayout: true,
|
|
originLeft: true,
|
|
originTop: true,
|
|
resize: true,
|
|
resizeContainer: true,
|
|
// item options
|
|
transitionDuration: '0.4s',
|
|
hiddenStyle: {
|
|
opacity: 0,
|
|
transform: 'scale(0.001)'
|
|
},
|
|
visibleStyle: {
|
|
opacity: 1,
|
|
transform: 'scale(1)'
|
|
}
|
|
};
|
|
|
|
var proto = Outlayer.prototype;
|
|
// inherit EvEmitter
|
|
utils.extend( proto, EvEmitter.prototype );
|
|
|
|
/**
|
|
* set options
|
|
* @param {Object} opts
|
|
*/
|
|
proto.option = function( opts ) {
|
|
utils.extend( this.options, opts );
|
|
};
|
|
|
|
/**
|
|
* get backwards compatible option value, check old name
|
|
*/
|
|
proto._getOption = function( option ) {
|
|
var oldOption = this.constructor.compatOptions[ option ];
|
|
return oldOption && this.options[ oldOption ] !== undefined ?
|
|
this.options[ oldOption ] : this.options[ option ];
|
|
};
|
|
|
|
Outlayer.compatOptions = {
|
|
// currentName: oldName
|
|
initLayout: 'isInitLayout',
|
|
horizontal: 'isHorizontal',
|
|
layoutInstant: 'isLayoutInstant',
|
|
originLeft: 'isOriginLeft',
|
|
originTop: 'isOriginTop',
|
|
resize: 'isResizeBound',
|
|
resizeContainer: 'isResizingContainer'
|
|
};
|
|
|
|
proto._create = function() {
|
|
// get items from children
|
|
this.reloadItems();
|
|
// elements that affect layout, but are not laid out
|
|
this.stamps = [];
|
|
this.stamp( this.options.stamp );
|
|
// set container style
|
|
utils.extend( this.element.style, this.options.containerStyle );
|
|
|
|
// bind resize method
|
|
var canBindResize = this._getOption('resize');
|
|
if ( canBindResize ) {
|
|
this.bindResize();
|
|
}
|
|
};
|
|
|
|
// goes through all children again and gets bricks in proper order
|
|
proto.reloadItems = function() {
|
|
// collection of item elements
|
|
this.items = this._itemize( this.element.children );
|
|
};
|
|
|
|
|
|
/**
|
|
* turn elements into Outlayer.Items to be used in layout
|
|
* @param {Array or NodeList or HTMLElement} elems
|
|
* @returns {Array} items - collection of new Outlayer Items
|
|
*/
|
|
proto._itemize = function( elems ) {
|
|
|
|
var itemElems = this._filterFindItemElements( elems );
|
|
var Item = this.constructor.Item;
|
|
|
|
// create new Outlayer Items for collection
|
|
var items = [];
|
|
for ( var i=0; i < itemElems.length; i++ ) {
|
|
var elem = itemElems[i];
|
|
var item = new Item( elem, this );
|
|
items.push( item );
|
|
}
|
|
|
|
return items;
|
|
};
|
|
|
|
/**
|
|
* get item elements to be used in layout
|
|
* @param {Array or NodeList or HTMLElement} elems
|
|
* @returns {Array} items - item elements
|
|
*/
|
|
proto._filterFindItemElements = function( elems ) {
|
|
return utils.filterFindElements( elems, this.options.itemSelector );
|
|
};
|
|
|
|
/**
|
|
* getter method for getting item elements
|
|
* @returns {Array} elems - collection of item elements
|
|
*/
|
|
proto.getItemElements = function() {
|
|
return this.items.map( function( item ) {
|
|
return item.element;
|
|
});
|
|
};
|
|
|
|
// ----- init & layout ----- //
|
|
|
|
/**
|
|
* lays out all items
|
|
*/
|
|
proto.layout = function() {
|
|
this._resetLayout();
|
|
this._manageStamps();
|
|
|
|
// don't animate first layout
|
|
var layoutInstant = this._getOption('layoutInstant');
|
|
var isInstant = layoutInstant !== undefined ?
|
|
layoutInstant : !this._isLayoutInited;
|
|
this.layoutItems( this.items, isInstant );
|
|
|
|
// flag for initalized
|
|
this._isLayoutInited = true;
|
|
};
|
|
|
|
// _init is alias for layout
|
|
proto._init = proto.layout;
|
|
|
|
/**
|
|
* logic before any new layout
|
|
*/
|
|
proto._resetLayout = function() {
|
|
this.getSize();
|
|
};
|
|
|
|
|
|
proto.getSize = function() {
|
|
this.size = getSize( this.element );
|
|
};
|
|
|
|
/**
|
|
* get measurement from option, for columnWidth, rowHeight, gutter
|
|
* if option is String -> get element from selector string, & get size of element
|
|
* if option is Element -> get size of element
|
|
* else use option as a number
|
|
*
|
|
* @param {String} measurement
|
|
* @param {String} size - width or height
|
|
* @private
|
|
*/
|
|
proto._getMeasurement = function( measurement, size ) {
|
|
var option = this.options[ measurement ];
|
|
var elem;
|
|
if ( !option ) {
|
|
// default to 0
|
|
this[ measurement ] = 0;
|
|
} else {
|
|
// use option as an element
|
|
if ( typeof option == 'string' ) {
|
|
elem = this.element.querySelector( option );
|
|
} else if ( option instanceof HTMLElement ) {
|
|
elem = option;
|
|
}
|
|
// use size of element, if element
|
|
this[ measurement ] = elem ? getSize( elem )[ size ] : option;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* layout a collection of item elements
|
|
* @api public
|
|
*/
|
|
proto.layoutItems = function( items, isInstant ) {
|
|
items = this._getItemsForLayout( items );
|
|
|
|
this._layoutItems( items, isInstant );
|
|
|
|
this._postLayout();
|
|
};
|
|
|
|
/**
|
|
* get the items to be laid out
|
|
* you may want to skip over some items
|
|
* @param {Array} items
|
|
* @returns {Array} items
|
|
*/
|
|
proto._getItemsForLayout = function( items ) {
|
|
return items.filter( function( item ) {
|
|
return !item.isIgnored;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* layout items
|
|
* @param {Array} items
|
|
* @param {Boolean} isInstant
|
|
*/
|
|
proto._layoutItems = function( items, isInstant ) {
|
|
this._emitCompleteOnItems( 'layout', items );
|
|
|
|
if ( !items || !items.length ) {
|
|
// no items, emit event with empty array
|
|
return;
|
|
}
|
|
|
|
var queue = [];
|
|
|
|
items.forEach( function( item ) {
|
|
// get x/y object from method
|
|
var position = this._getItemLayoutPosition( item );
|
|
// enqueue
|
|
position.item = item;
|
|
position.isInstant = isInstant || item.isLayoutInstant;
|
|
queue.push( position );
|
|
}, this );
|
|
|
|
this._processLayoutQueue( queue );
|
|
};
|
|
|
|
/**
|
|
* get item layout position
|
|
* @param {Outlayer.Item} item
|
|
* @returns {Object} x and y position
|
|
*/
|
|
proto._getItemLayoutPosition = function( /* item */ ) {
|
|
return {
|
|
x: 0,
|
|
y: 0
|
|
};
|
|
};
|
|
|
|
/**
|
|
* iterate over array and position each item
|
|
* Reason being - separating this logic prevents 'layout invalidation'
|
|
* thx @paul_irish
|
|
* @param {Array} queue
|
|
*/
|
|
proto._processLayoutQueue = function( queue ) {
|
|
this.updateStagger();
|
|
queue.forEach( function( obj, i ) {
|
|
this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
|
|
}, this );
|
|
};
|
|
|
|
// set stagger from option in milliseconds number
|
|
proto.updateStagger = function() {
|
|
var stagger = this.options.stagger;
|
|
if ( stagger === null || stagger === undefined ) {
|
|
this.stagger = 0;
|
|
return;
|
|
}
|
|
this.stagger = getMilliseconds( stagger );
|
|
return this.stagger;
|
|
};
|
|
|
|
/**
|
|
* Sets position of item in DOM
|
|
* @param {Outlayer.Item} item
|
|
* @param {Number} x - horizontal position
|
|
* @param {Number} y - vertical position
|
|
* @param {Boolean} isInstant - disables transitions
|
|
*/
|
|
proto._positionItem = function( item, x, y, isInstant, i ) {
|
|
if ( isInstant ) {
|
|
// if not transition, just set CSS
|
|
item.goTo( x, y );
|
|
} else {
|
|
item.stagger( i * this.stagger );
|
|
item.moveTo( x, y );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Any logic you want to do after each layout,
|
|
* i.e. size the container
|
|
*/
|
|
proto._postLayout = function() {
|
|
this.resizeContainer();
|
|
};
|
|
|
|
proto.resizeContainer = function() {
|
|
var isResizingContainer = this._getOption('resizeContainer');
|
|
if ( !isResizingContainer ) {
|
|
return;
|
|
}
|
|
var size = this._getContainerSize();
|
|
if ( size ) {
|
|
this._setContainerMeasure( size.width, true );
|
|
this._setContainerMeasure( size.height, false );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Sets width or height of container if returned
|
|
* @returns {Object} size
|
|
* @param {Number} width
|
|
* @param {Number} height
|
|
*/
|
|
proto._getContainerSize = noop;
|
|
|
|
/**
|
|
* @param {Number} measure - size of width or height
|
|
* @param {Boolean} isWidth
|
|
*/
|
|
proto._setContainerMeasure = function( measure, isWidth ) {
|
|
if ( measure === undefined ) {
|
|
return;
|
|
}
|
|
|
|
var elemSize = this.size;
|
|
// add padding and border width if border box
|
|
if ( elemSize.isBorderBox ) {
|
|
measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
|
|
elemSize.borderLeftWidth + elemSize.borderRightWidth :
|
|
elemSize.paddingBottom + elemSize.paddingTop +
|
|
elemSize.borderTopWidth + elemSize.borderBottomWidth;
|
|
}
|
|
|
|
measure = Math.max( measure, 0 );
|
|
this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
|
|
};
|
|
|
|
/**
|
|
* emit eventComplete on a collection of items events
|
|
* @param {String} eventName
|
|
* @param {Array} items - Outlayer.Items
|
|
*/
|
|
proto._emitCompleteOnItems = function( eventName, items ) {
|
|
var _this = this;
|
|
function onComplete() {
|
|
_this.dispatchEvent( eventName + 'Complete', null, [ items ] );
|
|
}
|
|
|
|
var count = items.length;
|
|
if ( !items || !count ) {
|
|
onComplete();
|
|
return;
|
|
}
|
|
|
|
var doneCount = 0;
|
|
function tick() {
|
|
doneCount++;
|
|
if ( doneCount == count ) {
|
|
onComplete();
|
|
}
|
|
}
|
|
|
|
// bind callback
|
|
items.forEach( function( item ) {
|
|
item.once( eventName, tick );
|
|
});
|
|
};
|
|
|
|
/**
|
|
* emits events via EvEmitter and jQuery events
|
|
* @param {String} type - name of event
|
|
* @param {Event} event - original event
|
|
* @param {Array} args - extra arguments
|
|
*/
|
|
proto.dispatchEvent = function( type, event, args ) {
|
|
// add original event to arguments
|
|
var emitArgs = event ? [ event ].concat( args ) : args;
|
|
this.emitEvent( type, emitArgs );
|
|
|
|
if ( jQuery ) {
|
|
// set this.$element
|
|
this.$element = this.$element || jQuery( this.element );
|
|
if ( event ) {
|
|
// create jQuery event
|
|
var $event = jQuery.Event( event );
|
|
$event.type = type;
|
|
this.$element.trigger( $event, args );
|
|
} else {
|
|
// just trigger with type if no event available
|
|
this.$element.trigger( type, args );
|
|
}
|
|
}
|
|
};
|
|
|
|
// -------------------------- ignore & stamps -------------------------- //
|
|
|
|
|
|
/**
|
|
* keep item in collection, but do not lay it out
|
|
* ignored items do not get skipped in layout
|
|
* @param {Element} elem
|
|
*/
|
|
proto.ignore = function( elem ) {
|
|
var item = this.getItem( elem );
|
|
if ( item ) {
|
|
item.isIgnored = true;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* return item to layout collection
|
|
* @param {Element} elem
|
|
*/
|
|
proto.unignore = function( elem ) {
|
|
var item = this.getItem( elem );
|
|
if ( item ) {
|
|
delete item.isIgnored;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* adds elements to stamps
|
|
* @param {NodeList, Array, Element, or String} elems
|
|
*/
|
|
proto.stamp = function( elems ) {
|
|
elems = this._find( elems );
|
|
if ( !elems ) {
|
|
return;
|
|
}
|
|
|
|
this.stamps = this.stamps.concat( elems );
|
|
// ignore
|
|
elems.forEach( this.ignore, this );
|
|
};
|
|
|
|
/**
|
|
* removes elements to stamps
|
|
* @param {NodeList, Array, or Element} elems
|
|
*/
|
|
proto.unstamp = function( elems ) {
|
|
elems = this._find( elems );
|
|
if ( !elems ){
|
|
return;
|
|
}
|
|
|
|
elems.forEach( function( elem ) {
|
|
// filter out removed stamp elements
|
|
utils.removeFrom( this.stamps, elem );
|
|
this.unignore( elem );
|
|
}, this );
|
|
};
|
|
|
|
/**
|
|
* finds child elements
|
|
* @param {NodeList, Array, Element, or String} elems
|
|
* @returns {Array} elems
|
|
*/
|
|
proto._find = function( elems ) {
|
|
if ( !elems ) {
|
|
return;
|
|
}
|
|
// if string, use argument as selector string
|
|
if ( typeof elems == 'string' ) {
|
|
elems = this.element.querySelectorAll( elems );
|
|
}
|
|
elems = utils.makeArray( elems );
|
|
return elems;
|
|
};
|
|
|
|
proto._manageStamps = function() {
|
|
if ( !this.stamps || !this.stamps.length ) {
|
|
return;
|
|
}
|
|
|
|
this._getBoundingRect();
|
|
|
|
this.stamps.forEach( this._manageStamp, this );
|
|
};
|
|
|
|
// update boundingLeft / Top
|
|
proto._getBoundingRect = function() {
|
|
// get bounding rect for container element
|
|
var boundingRect = this.element.getBoundingClientRect();
|
|
var size = this.size;
|
|
this._boundingRect = {
|
|
left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
|
|
top: boundingRect.top + size.paddingTop + size.borderTopWidth,
|
|
right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
|
|
bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
|
|
};
|
|
};
|
|
|
|
/**
|
|
* @param {Element} stamp
|
|
**/
|
|
proto._manageStamp = noop;
|
|
|
|
/**
|
|
* get x/y position of element relative to container element
|
|
* @param {Element} elem
|
|
* @returns {Object} offset - has left, top, right, bottom
|
|
*/
|
|
proto._getElementOffset = function( elem ) {
|
|
var boundingRect = elem.getBoundingClientRect();
|
|
var thisRect = this._boundingRect;
|
|
var size = getSize( elem );
|
|
var offset = {
|
|
left: boundingRect.left - thisRect.left - size.marginLeft,
|
|
top: boundingRect.top - thisRect.top - size.marginTop,
|
|
right: thisRect.right - boundingRect.right - size.marginRight,
|
|
bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
|
|
};
|
|
return offset;
|
|
};
|
|
|
|
// -------------------------- resize -------------------------- //
|
|
|
|
// enable event handlers for listeners
|
|
// i.e. resize -> onresize
|
|
proto.handleEvent = utils.handleEvent;
|
|
|
|
/**
|
|
* Bind layout to window resizing
|
|
*/
|
|
proto.bindResize = function() {
|
|
window.addEventListener( 'resize', this );
|
|
this.isResizeBound = true;
|
|
};
|
|
|
|
/**
|
|
* Unbind layout to window resizing
|
|
*/
|
|
proto.unbindResize = function() {
|
|
window.removeEventListener( 'resize', this );
|
|
this.isResizeBound = false;
|
|
};
|
|
|
|
proto.onresize = function() {
|
|
this.resize();
|
|
};
|
|
|
|
utils.debounceMethod( Outlayer, 'onresize', 100 );
|
|
|
|
proto.resize = function() {
|
|
// don't trigger if size did not change
|
|
// or if resize was unbound. See #9
|
|
if ( !this.isResizeBound || !this.needsResizeLayout() ) {
|
|
return;
|
|
}
|
|
|
|
this.layout();
|
|
};
|
|
|
|
/**
|
|
* check if layout is needed post layout
|
|
* @returns Boolean
|
|
*/
|
|
proto.needsResizeLayout = function() {
|
|
var size = getSize( this.element );
|
|
// check that this.size and size are there
|
|
// IE8 triggers resize on body size change, so they might not be
|
|
var hasSizes = this.size && size;
|
|
return hasSizes && size.innerWidth !== this.size.innerWidth;
|
|
};
|
|
|
|
// -------------------------- methods -------------------------- //
|
|
|
|
/**
|
|
* add items to Outlayer instance
|
|
* @param {Array or NodeList or Element} elems
|
|
* @returns {Array} items - Outlayer.Items
|
|
**/
|
|
proto.addItems = function( elems ) {
|
|
var items = this._itemize( elems );
|
|
// add items to collection
|
|
if ( items.length ) {
|
|
this.items = this.items.concat( items );
|
|
}
|
|
return items;
|
|
};
|
|
|
|
/**
|
|
* Layout newly-appended item elements
|
|
* @param {Array or NodeList or Element} elems
|
|
*/
|
|
proto.appended = function( elems ) {
|
|
var items = this.addItems( elems );
|
|
if ( !items.length ) {
|
|
return;
|
|
}
|
|
// layout and reveal just the new items
|
|
this.layoutItems( items, true );
|
|
this.reveal( items );
|
|
};
|
|
|
|
/**
|
|
* Layout prepended elements
|
|
* @param {Array or NodeList or Element} elems
|
|
*/
|
|
proto.prepended = function( elems ) {
|
|
var items = this._itemize( elems );
|
|
if ( !items.length ) {
|
|
return;
|
|
}
|
|
// add items to beginning of collection
|
|
var previousItems = this.items.slice(0);
|
|
this.items = items.concat( previousItems );
|
|
// start new layout
|
|
this._resetLayout();
|
|
this._manageStamps();
|
|
// layout new stuff without transition
|
|
this.layoutItems( items, true );
|
|
this.reveal( items );
|
|
// layout previous items
|
|
this.layoutItems( previousItems );
|
|
};
|
|
|
|
/**
|
|
* reveal a collection of items
|
|
* @param {Array of Outlayer.Items} items
|
|
*/
|
|
proto.reveal = function( items ) {
|
|
this._emitCompleteOnItems( 'reveal', items );
|
|
if ( !items || !items.length ) {
|
|
return;
|
|
}
|
|
var stagger = this.updateStagger();
|
|
items.forEach( function( item, i ) {
|
|
item.stagger( i * stagger );
|
|
item.reveal();
|
|
});
|
|
};
|
|
|
|
/**
|
|
* hide a collection of items
|
|
* @param {Array of Outlayer.Items} items
|
|
*/
|
|
proto.hide = function( items ) {
|
|
this._emitCompleteOnItems( 'hide', items );
|
|
if ( !items || !items.length ) {
|
|
return;
|
|
}
|
|
var stagger = this.updateStagger();
|
|
items.forEach( function( item, i ) {
|
|
item.stagger( i * stagger );
|
|
item.hide();
|
|
});
|
|
};
|
|
|
|
/**
|
|
* reveal item elements
|
|
* @param {Array}, {Element}, {NodeList} items
|
|
*/
|
|
proto.revealItemElements = function( elems ) {
|
|
var items = this.getItems( elems );
|
|
this.reveal( items );
|
|
};
|
|
|
|
/**
|
|
* hide item elements
|
|
* @param {Array}, {Element}, {NodeList} items
|
|
*/
|
|
proto.hideItemElements = function( elems ) {
|
|
var items = this.getItems( elems );
|
|
this.hide( items );
|
|
};
|
|
|
|
/**
|
|
* get Outlayer.Item, given an Element
|
|
* @param {Element} elem
|
|
* @param {Function} callback
|
|
* @returns {Outlayer.Item} item
|
|
*/
|
|
proto.getItem = function( elem ) {
|
|
// loop through items to get the one that matches
|
|
for ( var i=0; i < this.items.length; i++ ) {
|
|
var item = this.items[i];
|
|
if ( item.element == elem ) {
|
|
// return item
|
|
return item;
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* get collection of Outlayer.Items, given Elements
|
|
* @param {Array} elems
|
|
* @returns {Array} items - Outlayer.Items
|
|
*/
|
|
proto.getItems = function( elems ) {
|
|
elems = utils.makeArray( elems );
|
|
var items = [];
|
|
elems.forEach( function( elem ) {
|
|
var item = this.getItem( elem );
|
|
if ( item ) {
|
|
items.push( item );
|
|
}
|
|
}, this );
|
|
|
|
return items;
|
|
};
|
|
|
|
/**
|
|
* remove element(s) from instance and DOM
|
|
* @param {Array or NodeList or Element} elems
|
|
*/
|
|
proto.remove = function( elems ) {
|
|
var removeItems = this.getItems( elems );
|
|
|
|
this._emitCompleteOnItems( 'remove', removeItems );
|
|
|
|
// bail if no items to remove
|
|
if ( !removeItems || !removeItems.length ) {
|
|
return;
|
|
}
|
|
|
|
removeItems.forEach( function( item ) {
|
|
item.remove();
|
|
// remove item from collection
|
|
utils.removeFrom( this.items, item );
|
|
}, this );
|
|
};
|
|
|
|
// ----- destroy ----- //
|
|
|
|
// remove and disable Outlayer instance
|
|
proto.destroy = function() {
|
|
// clean up dynamic styles
|
|
var style = this.element.style;
|
|
style.height = '';
|
|
style.position = '';
|
|
style.width = '';
|
|
// destroy items
|
|
this.items.forEach( function( item ) {
|
|
item.destroy();
|
|
});
|
|
|
|
this.unbindResize();
|
|
|
|
var id = this.element.outlayerGUID;
|
|
delete instances[ id ]; // remove reference to instance by id
|
|
delete this.element.outlayerGUID;
|
|
// remove data for jQuery
|
|
if ( jQuery ) {
|
|
jQuery.removeData( this.element, this.constructor.namespace );
|
|
}
|
|
|
|
};
|
|
|
|
// -------------------------- data -------------------------- //
|
|
|
|
/**
|
|
* get Outlayer instance from element
|
|
* @param {Element} elem
|
|
* @returns {Outlayer}
|
|
*/
|
|
Outlayer.data = function( elem ) {
|
|
elem = utils.getQueryElement( elem );
|
|
var id = elem && elem.outlayerGUID;
|
|
return id && instances[ id ];
|
|
};
|
|
|
|
|
|
// -------------------------- create Outlayer class -------------------------- //
|
|
|
|
/**
|
|
* create a layout class
|
|
* @param {String} namespace
|
|
*/
|
|
Outlayer.create = function( namespace, options ) {
|
|
// sub-class Outlayer
|
|
var Layout = subclass( Outlayer );
|
|
// apply new options and compatOptions
|
|
Layout.defaults = utils.extend( {}, Outlayer.defaults );
|
|
utils.extend( Layout.defaults, options );
|
|
Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions );
|
|
|
|
Layout.namespace = namespace;
|
|
|
|
Layout.data = Outlayer.data;
|
|
|
|
// sub-class Item
|
|
Layout.Item = subclass( Item );
|
|
|
|
// -------------------------- declarative -------------------------- //
|
|
|
|
utils.htmlInit( Layout, namespace );
|
|
|
|
// -------------------------- jQuery bridge -------------------------- //
|
|
|
|
// make into jQuery plugin
|
|
if ( jQuery && jQuery.bridget ) {
|
|
jQuery.bridget( namespace, Layout );
|
|
}
|
|
|
|
return Layout;
|
|
};
|
|
|
|
function subclass( Parent ) {
|
|
function SubClass() {
|
|
Parent.apply( this, arguments );
|
|
}
|
|
|
|
SubClass.prototype = Object.create( Parent.prototype );
|
|
SubClass.prototype.constructor = SubClass;
|
|
|
|
return SubClass;
|
|
}
|
|
|
|
// ----- helpers ----- //
|
|
|
|
// how many milliseconds are in each unit
|
|
var msUnits = {
|
|
ms: 1,
|
|
s: 1000
|
|
};
|
|
|
|
// munge time-like parameter into millisecond number
|
|
// '0.4s' -> 40
|
|
function getMilliseconds( time ) {
|
|
if ( typeof time == 'number' ) {
|
|
return time;
|
|
}
|
|
var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
|
|
var num = matches && matches[1];
|
|
var unit = matches && matches[2];
|
|
if ( !num.length ) {
|
|
return 0;
|
|
}
|
|
num = parseFloat( num );
|
|
var mult = msUnits[ unit ] || 1;
|
|
return num * mult;
|
|
}
|
|
|
|
// ----- fin ----- //
|
|
|
|
// back in global
|
|
Outlayer.Item = Item;
|
|
|
|
return Outlayer;
|
|
|
|
}));
|
|
|
|
/**
|
|
* Isotope Item
|
|
**/
|
|
|
|
( function( window, factory ) {
|
|
// universal module definition
|
|
/* jshint strict: false */ /*globals define, module, require */
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( 'isotope/js/item',[
|
|
'outlayer/outlayer'
|
|
],
|
|
factory );
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory(
|
|
require('outlayer')
|
|
);
|
|
} else {
|
|
// browser global
|
|
window.Isotope = window.Isotope || {};
|
|
window.Isotope.Item = factory(
|
|
window.Outlayer
|
|
);
|
|
}
|
|
|
|
}( window, function factory( Outlayer ) {
|
|
'use strict';
|
|
|
|
// -------------------------- Item -------------------------- //
|
|
|
|
// sub-class Outlayer Item
|
|
function Item() {
|
|
Outlayer.Item.apply( this, arguments );
|
|
}
|
|
|
|
var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
|
|
|
|
var _create = proto._create;
|
|
proto._create = function() {
|
|
// assign id, used for original-order sorting
|
|
this.id = this.layout.itemGUID++;
|
|
_create.call( this );
|
|
this.sortData = {};
|
|
};
|
|
|
|
proto.updateSortData = function() {
|
|
if ( this.isIgnored ) {
|
|
return;
|
|
}
|
|
// default sorters
|
|
this.sortData.id = this.id;
|
|
// for backward compatibility
|
|
this.sortData['original-order'] = this.id;
|
|
this.sortData.random = Math.random();
|
|
// go thru getSortData obj and apply the sorters
|
|
var getSortData = this.layout.options.getSortData;
|
|
var sorters = this.layout._sorters;
|
|
for ( var key in getSortData ) {
|
|
var sorter = sorters[ key ];
|
|
this.sortData[ key ] = sorter( this.element, this );
|
|
}
|
|
};
|
|
|
|
var _destroy = proto.destroy;
|
|
proto.destroy = function() {
|
|
// call super
|
|
_destroy.apply( this, arguments );
|
|
// reset display, #741
|
|
this.css({
|
|
display: ''
|
|
});
|
|
};
|
|
|
|
return Item;
|
|
|
|
}));
|
|
|
|
/**
|
|
* Isotope LayoutMode
|
|
*/
|
|
|
|
( function( window, factory ) {
|
|
// universal module definition
|
|
/* jshint strict: false */ /*globals define, module, require */
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( 'isotope/js/layout-mode',[
|
|
'get-size/get-size',
|
|
'outlayer/outlayer'
|
|
],
|
|
factory );
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory(
|
|
require('get-size'),
|
|
require('outlayer')
|
|
);
|
|
} else {
|
|
// browser global
|
|
window.Isotope = window.Isotope || {};
|
|
window.Isotope.LayoutMode = factory(
|
|
window.getSize,
|
|
window.Outlayer
|
|
);
|
|
}
|
|
|
|
}( window, function factory( getSize, Outlayer ) {
|
|
'use strict';
|
|
|
|
// layout mode class
|
|
function LayoutMode( isotope ) {
|
|
this.isotope = isotope;
|
|
// link properties
|
|
if ( isotope ) {
|
|
this.options = isotope.options[ this.namespace ];
|
|
this.element = isotope.element;
|
|
this.items = isotope.filteredItems;
|
|
this.size = isotope.size;
|
|
}
|
|
}
|
|
|
|
var proto = LayoutMode.prototype;
|
|
|
|
/**
|
|
* some methods should just defer to default Outlayer method
|
|
* and reference the Isotope instance as `this`
|
|
**/
|
|
var facadeMethods = [
|
|
'_resetLayout',
|
|
'_getItemLayoutPosition',
|
|
'_manageStamp',
|
|
'_getContainerSize',
|
|
'_getElementOffset',
|
|
'needsResizeLayout',
|
|
'_getOption'
|
|
];
|
|
|
|
facadeMethods.forEach( function( methodName ) {
|
|
proto[ methodName ] = function() {
|
|
return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
|
|
};
|
|
});
|
|
|
|
// ----- ----- //
|
|
|
|
// for horizontal layout modes, check vertical size
|
|
proto.needsVerticalResizeLayout = function() {
|
|
// don't trigger if size did not change
|
|
var size = getSize( this.isotope.element );
|
|
// check that this.size and size are there
|
|
// IE8 triggers resize on body size change, so they might not be
|
|
var hasSizes = this.isotope.size && size;
|
|
return hasSizes && size.innerHeight != this.isotope.size.innerHeight;
|
|
};
|
|
|
|
// ----- measurements ----- //
|
|
|
|
proto._getMeasurement = function() {
|
|
this.isotope._getMeasurement.apply( this, arguments );
|
|
};
|
|
|
|
proto.getColumnWidth = function() {
|
|
this.getSegmentSize( 'column', 'Width' );
|
|
};
|
|
|
|
proto.getRowHeight = function() {
|
|
this.getSegmentSize( 'row', 'Height' );
|
|
};
|
|
|
|
/**
|
|
* get columnWidth or rowHeight
|
|
* segment: 'column' or 'row'
|
|
* size 'Width' or 'Height'
|
|
**/
|
|
proto.getSegmentSize = function( segment, size ) {
|
|
var segmentName = segment + size;
|
|
var outerSize = 'outer' + size;
|
|
// columnWidth / outerWidth // rowHeight / outerHeight
|
|
this._getMeasurement( segmentName, outerSize );
|
|
// got rowHeight or columnWidth, we can chill
|
|
if ( this[ segmentName ] ) {
|
|
return;
|
|
}
|
|
// fall back to item of first element
|
|
var firstItemSize = this.getFirstItemSize();
|
|
this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
|
|
// or size of container
|
|
this.isotope.size[ 'inner' + size ];
|
|
};
|
|
|
|
proto.getFirstItemSize = function() {
|
|
var firstItem = this.isotope.filteredItems[0];
|
|
return firstItem && firstItem.element && getSize( firstItem.element );
|
|
};
|
|
|
|
// ----- methods that should reference isotope ----- //
|
|
|
|
proto.layout = function() {
|
|
this.isotope.layout.apply( this.isotope, arguments );
|
|
};
|
|
|
|
proto.getSize = function() {
|
|
this.isotope.getSize();
|
|
this.size = this.isotope.size;
|
|
};
|
|
|
|
// -------------------------- create -------------------------- //
|
|
|
|
LayoutMode.modes = {};
|
|
|
|
LayoutMode.create = function( namespace, options ) {
|
|
|
|
function Mode() {
|
|
LayoutMode.apply( this, arguments );
|
|
}
|
|
|
|
Mode.prototype = Object.create( proto );
|
|
Mode.prototype.constructor = Mode;
|
|
|
|
// default options
|
|
if ( options ) {
|
|
Mode.options = options;
|
|
}
|
|
|
|
Mode.prototype.namespace = namespace;
|
|
// register in Isotope
|
|
LayoutMode.modes[ namespace ] = Mode;
|
|
|
|
return Mode;
|
|
};
|
|
|
|
return LayoutMode;
|
|
|
|
}));
|
|
|
|
/*!
|
|
* Masonry v4.1.0
|
|
* Cascading grid layout library
|
|
* http://masonry.desandro.com
|
|
* MIT License
|
|
* by David DeSandro
|
|
*/
|
|
|
|
( function( window, factory ) {
|
|
// universal module definition
|
|
/* jshint strict: false */ /*globals define, module, require */
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( 'masonry/masonry',[
|
|
'outlayer/outlayer',
|
|
'get-size/get-size'
|
|
],
|
|
factory );
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory(
|
|
require('outlayer'),
|
|
require('get-size')
|
|
);
|
|
} else {
|
|
// browser global
|
|
window.Masonry = factory(
|
|
window.Outlayer,
|
|
window.getSize
|
|
);
|
|
}
|
|
|
|
}( window, function factory( Outlayer, getSize ) {
|
|
|
|
|
|
|
|
// -------------------------- masonryDefinition -------------------------- //
|
|
|
|
// create an Outlayer layout class
|
|
var Masonry = Outlayer.create('masonry');
|
|
// isFitWidth -> fitWidth
|
|
Masonry.compatOptions.fitWidth = 'isFitWidth';
|
|
|
|
Masonry.prototype._resetLayout = function() {
|
|
this.getSize();
|
|
this._getMeasurement( 'columnWidth', 'outerWidth' );
|
|
this._getMeasurement( 'gutter', 'outerWidth' );
|
|
this.measureColumns();
|
|
|
|
// reset column Y
|
|
this.colYs = [];
|
|
for ( var i=0; i < this.cols; i++ ) {
|
|
this.colYs.push( 0 );
|
|
}
|
|
|
|
this.maxY = 0;
|
|
};
|
|
|
|
Masonry.prototype.measureColumns = function() {
|
|
this.getContainerWidth();
|
|
// if columnWidth is 0, default to outerWidth of first item
|
|
if ( !this.columnWidth ) {
|
|
var firstItem = this.items[0];
|
|
var firstItemElem = firstItem && firstItem.element;
|
|
// columnWidth fall back to item of first element
|
|
this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
|
|
// if first elem has no width, default to size of container
|
|
this.containerWidth;
|
|
}
|
|
|
|
var columnWidth = this.columnWidth += this.gutter;
|
|
|
|
// calculate columns
|
|
var containerWidth = this.containerWidth + this.gutter;
|
|
var cols = containerWidth / columnWidth;
|
|
// fix rounding errors, typically with gutters
|
|
var excess = columnWidth - containerWidth % columnWidth;
|
|
// if overshoot is less than a pixel, round up, otherwise floor it
|
|
var mathMethod = excess && excess < 1 ? 'round' : 'floor';
|
|
cols = Math[ mathMethod ]( cols );
|
|
this.cols = Math.max( cols, 1 );
|
|
};
|
|
|
|
Masonry.prototype.getContainerWidth = function() {
|
|
// container is parent if fit width
|
|
var isFitWidth = this._getOption('fitWidth');
|
|
var container = isFitWidth ? this.element.parentNode : this.element;
|
|
// check that this.size and size are there
|
|
// IE8 triggers resize on body size change, so they might not be
|
|
var size = getSize( container );
|
|
this.containerWidth = size && size.innerWidth;
|
|
};
|
|
|
|
Masonry.prototype._getItemLayoutPosition = function( item ) {
|
|
item.getSize();
|
|
// how many columns does this brick span
|
|
var remainder = item.size.outerWidth % this.columnWidth;
|
|
var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
|
|
// round if off by 1 pixel, otherwise use ceil
|
|
var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
|
|
colSpan = Math.min( colSpan, this.cols );
|
|
|
|
var colGroup = this._getColGroup( colSpan );
|
|
// get the minimum Y value from the columns
|
|
var minimumY = Math.min.apply( Math, colGroup );
|
|
var shortColIndex = colGroup.indexOf( minimumY );
|
|
|
|
// position the brick
|
|
var position = {
|
|
x: this.columnWidth * shortColIndex,
|
|
y: minimumY
|
|
};
|
|
|
|
// apply setHeight to necessary columns
|
|
var setHeight = minimumY + item.size.outerHeight;
|
|
var setSpan = this.cols + 1 - colGroup.length;
|
|
for ( var i = 0; i < setSpan; i++ ) {
|
|
this.colYs[ shortColIndex + i ] = setHeight;
|
|
}
|
|
|
|
return position;
|
|
};
|
|
|
|
/**
|
|
* @param {Number} colSpan - number of columns the element spans
|
|
* @returns {Array} colGroup
|
|
*/
|
|
Masonry.prototype._getColGroup = function( colSpan ) {
|
|
if ( colSpan < 2 ) {
|
|
// if brick spans only one column, use all the column Ys
|
|
return this.colYs;
|
|
}
|
|
|
|
var colGroup = [];
|
|
// how many different places could this brick fit horizontally
|
|
var groupCount = this.cols + 1 - colSpan;
|
|
// for each group potential horizontal position
|
|
for ( var i = 0; i < groupCount; i++ ) {
|
|
// make an array of colY values for that one group
|
|
var groupColYs = this.colYs.slice( i, i + colSpan );
|
|
// and get the max value of the array
|
|
colGroup[i] = Math.max.apply( Math, groupColYs );
|
|
}
|
|
return colGroup;
|
|
};
|
|
|
|
Masonry.prototype._manageStamp = function( stamp ) {
|
|
var stampSize = getSize( stamp );
|
|
var offset = this._getElementOffset( stamp );
|
|
// get the columns that this stamp affects
|
|
var isOriginLeft = this._getOption('originLeft');
|
|
var firstX = isOriginLeft ? offset.left : offset.right;
|
|
var lastX = firstX + stampSize.outerWidth;
|
|
var firstCol = Math.floor( firstX / this.columnWidth );
|
|
firstCol = Math.max( 0, firstCol );
|
|
var lastCol = Math.floor( lastX / this.columnWidth );
|
|
// lastCol should not go over if multiple of columnWidth #425
|
|
lastCol -= lastX % this.columnWidth ? 0 : 1;
|
|
lastCol = Math.min( this.cols - 1, lastCol );
|
|
// set colYs to bottom of the stamp
|
|
|
|
var isOriginTop = this._getOption('originTop');
|
|
var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +
|
|
stampSize.outerHeight;
|
|
for ( var i = firstCol; i <= lastCol; i++ ) {
|
|
this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
|
|
}
|
|
};
|
|
|
|
Masonry.prototype._getContainerSize = function() {
|
|
this.maxY = Math.max.apply( Math, this.colYs );
|
|
var size = {
|
|
height: this.maxY
|
|
};
|
|
|
|
if ( this._getOption('fitWidth') ) {
|
|
size.width = this._getContainerFitWidth();
|
|
}
|
|
|
|
return size;
|
|
};
|
|
|
|
Masonry.prototype._getContainerFitWidth = function() {
|
|
var unusedCols = 0;
|
|
// count unused columns
|
|
var i = this.cols;
|
|
while ( --i ) {
|
|
if ( this.colYs[i] !== 0 ) {
|
|
break;
|
|
}
|
|
unusedCols++;
|
|
}
|
|
// fit container to columns that have been used
|
|
return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
|
|
};
|
|
|
|
Masonry.prototype.needsResizeLayout = function() {
|
|
var previousWidth = this.containerWidth;
|
|
this.getContainerWidth();
|
|
return previousWidth != this.containerWidth;
|
|
};
|
|
|
|
return Masonry;
|
|
|
|
}));
|
|
|
|
/*!
|
|
* Masonry layout mode
|
|
* sub-classes Masonry
|
|
* http://masonry.desandro.com
|
|
*/
|
|
|
|
( function( window, factory ) {
|
|
// universal module definition
|
|
/* jshint strict: false */ /*globals define, module, require */
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( 'isotope/js/layout-modes/masonry',[
|
|
'../layout-mode',
|
|
'masonry/masonry'
|
|
],
|
|
factory );
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory(
|
|
require('../layout-mode'),
|
|
require('masonry-layout')
|
|
);
|
|
} else {
|
|
// browser global
|
|
factory(
|
|
window.Isotope.LayoutMode,
|
|
window.Masonry
|
|
);
|
|
}
|
|
|
|
}( window, function factory( LayoutMode, Masonry ) {
|
|
'use strict';
|
|
|
|
// -------------------------- masonryDefinition -------------------------- //
|
|
|
|
// create an Outlayer layout class
|
|
var MasonryMode = LayoutMode.create('masonry');
|
|
|
|
var proto = MasonryMode.prototype;
|
|
|
|
var keepModeMethods = {
|
|
_getElementOffset: true,
|
|
layout: true,
|
|
_getMeasurement: true
|
|
};
|
|
|
|
// inherit Masonry prototype
|
|
for ( var method in Masonry.prototype ) {
|
|
// do not inherit mode methods
|
|
if ( !keepModeMethods[ method ] ) {
|
|
proto[ method ] = Masonry.prototype[ method ];
|
|
}
|
|
}
|
|
|
|
var measureColumns = proto.measureColumns;
|
|
proto.measureColumns = function() {
|
|
// set items, used if measuring first item
|
|
this.items = this.isotope.filteredItems;
|
|
measureColumns.call( this );
|
|
};
|
|
|
|
// point to mode options for fitWidth
|
|
var _getOption = proto._getOption;
|
|
proto._getOption = function( option ) {
|
|
if ( option == 'fitWidth' ) {
|
|
return this.options.isFitWidth !== undefined ?
|
|
this.options.isFitWidth : this.options.fitWidth;
|
|
}
|
|
return _getOption.apply( this.isotope, arguments );
|
|
};
|
|
|
|
return MasonryMode;
|
|
|
|
}));
|
|
|
|
/**
|
|
* fitRows layout mode
|
|
*/
|
|
|
|
( function( window, factory ) {
|
|
// universal module definition
|
|
/* jshint strict: false */ /*globals define, module, require */
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( 'isotope/js/layout-modes/fit-rows',[
|
|
'../layout-mode'
|
|
],
|
|
factory );
|
|
} else if ( typeof exports == 'object' ) {
|
|
// CommonJS
|
|
module.exports = factory(
|
|
require('../layout-mode')
|
|
);
|
|
} else {
|
|
// browser global
|
|
factory(
|
|
window.Isotope.LayoutMode
|
|
);
|
|
}
|
|
|
|
}( window, function factory( LayoutMode ) {
|
|
'use strict';
|
|
|
|
var FitRows = LayoutMode.create('fitRows');
|
|
|
|
var proto = FitRows.prototype;
|
|
|
|
proto._resetLayout = function() {
|
|
this.x = 0;
|
|
this.y = 0;
|
|
this.maxY = 0;
|
|
this._getMeasurement( 'gutter', 'outerWidth' );
|
|
};
|
|
|
|
proto._getItemLayoutPosition = function( item ) {
|
|
item.getSize();
|
|
|
|
var itemWidth = item.size.outerWidth + this.gutter;
|
|
// if this element cannot fit in the current row
|
|
var containerWidth = this.isotope.size.innerWidth + this.gutter;
|
|
if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
|
|
this.x = 0;
|
|
this.y = this.maxY;
|
|
}
|
|
|
|
var position = {
|
|
x: this.x,
|
|
y: this.y
|
|
};
|
|
|
|
this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
|
|
this.x += itemWidth;
|
|
|
|
return position;
|
|
};
|
|
|
|
proto._getContainerSize = function() {
|
|
return { height: this.maxY };
|
|
};
|
|
|
|
return FitRows;
|
|
|
|
}));
|
|
|
|
/**
|
|
* vertical layout mode
|
|
*/
|
|
|
|
( function( window, factory ) {
|
|
// universal module definition
|
|
/* jshint strict: false */ /*globals define, module, require */
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( 'isotope/js/layout-modes/vertical',[
|
|
'../layout-mode'
|
|
],
|
|
factory );
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory(
|
|
require('../layout-mode')
|
|
);
|
|
} else {
|
|
// browser global
|
|
factory(
|
|
window.Isotope.LayoutMode
|
|
);
|
|
}
|
|
|
|
}( window, function factory( LayoutMode ) {
|
|
'use strict';
|
|
|
|
var Vertical = LayoutMode.create( 'vertical', {
|
|
horizontalAlignment: 0
|
|
});
|
|
|
|
var proto = Vertical.prototype;
|
|
|
|
proto._resetLayout = function() {
|
|
this.y = 0;
|
|
};
|
|
|
|
proto._getItemLayoutPosition = function( item ) {
|
|
item.getSize();
|
|
var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
|
|
this.options.horizontalAlignment;
|
|
var y = this.y;
|
|
this.y += item.size.outerHeight;
|
|
return { x: x, y: y };
|
|
};
|
|
|
|
proto._getContainerSize = function() {
|
|
return { height: this.y };
|
|
};
|
|
|
|
return Vertical;
|
|
|
|
}));
|
|
|
|
/*!
|
|
* Isotope v3.0.1
|
|
*
|
|
* Licensed GPLv3 for open source use
|
|
* or Isotope Commercial License for commercial use
|
|
*
|
|
* http://isotope.metafizzy.co
|
|
* Copyright 2016 Metafizzy
|
|
*/
|
|
|
|
( function( window, factory ) {
|
|
// universal module definition
|
|
/* jshint strict: false */ /*globals define, module, require */
|
|
if ( typeof define == 'function' && define.amd ) {
|
|
// AMD
|
|
define( [
|
|
'outlayer/outlayer',
|
|
'get-size/get-size',
|
|
'desandro-matches-selector/matches-selector',
|
|
'fizzy-ui-utils/utils',
|
|
'isotope/js/item',
|
|
'isotope/js/layout-mode',
|
|
// include default layout modes
|
|
'isotope/js/layout-modes/masonry',
|
|
'isotope/js/layout-modes/fit-rows',
|
|
'isotope/js/layout-modes/vertical'
|
|
],
|
|
function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
|
|
return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
|
|
});
|
|
} else if ( typeof module == 'object' && module.exports ) {
|
|
// CommonJS
|
|
module.exports = factory(
|
|
window,
|
|
require('outlayer'),
|
|
require('get-size'),
|
|
require('desandro-matches-selector'),
|
|
require('fizzy-ui-utils'),
|
|
require('isotope/js/item'),
|
|
require('isotope/js/layout-mode'),
|
|
// include default layout modes
|
|
require('isotope/js/layout-modes/masonry'),
|
|
require('isotope/js/layout-modes/fit-rows'),
|
|
require('isotope/js/layout-modes/vertical')
|
|
);
|
|
} else {
|
|
// browser global
|
|
window.Isotope = factory(
|
|
window,
|
|
window.Outlayer,
|
|
window.getSize,
|
|
window.matchesSelector,
|
|
window.fizzyUIUtils,
|
|
window.Isotope.Item,
|
|
window.Isotope.LayoutMode
|
|
);
|
|
}
|
|
|
|
}( window, function factory( window, Outlayer, getSize, matchesSelector, utils,
|
|
Item, LayoutMode ) {
|
|
|
|
|
|
|
|
// -------------------------- vars -------------------------- //
|
|
|
|
var jQuery = window.jQuery;
|
|
|
|
// -------------------------- helpers -------------------------- //
|
|
|
|
var trim = String.prototype.trim ?
|
|
function( str ) {
|
|
return str.trim();
|
|
} :
|
|
function( str ) {
|
|
return str.replace( /^\s+|\s+$/g, '' );
|
|
};
|
|
|
|
// -------------------------- isotopeDefinition -------------------------- //
|
|
|
|
// create an Outlayer layout class
|
|
var Isotope = Outlayer.create( 'isotope', {
|
|
layoutMode: 'masonry',
|
|
isJQueryFiltering: true,
|
|
sortAscending: true
|
|
});
|
|
|
|
Isotope.Item = Item;
|
|
Isotope.LayoutMode = LayoutMode;
|
|
|
|
var proto = Isotope.prototype;
|
|
|
|
proto._create = function() {
|
|
this.itemGUID = 0;
|
|
// functions that sort items
|
|
this._sorters = {};
|
|
this._getSorters();
|
|
// call super
|
|
Outlayer.prototype._create.call( this );
|
|
|
|
// create layout modes
|
|
this.modes = {};
|
|
// start filteredItems with all items
|
|
this.filteredItems = this.items;
|
|
// keep of track of sortBys
|
|
this.sortHistory = [ 'original-order' ];
|
|
// create from registered layout modes
|
|
for ( var name in LayoutMode.modes ) {
|
|
this._initLayoutMode( name );
|
|
}
|
|
};
|
|
|
|
proto.reloadItems = function() {
|
|
// reset item ID counter
|
|
this.itemGUID = 0;
|
|
// call super
|
|
Outlayer.prototype.reloadItems.call( this );
|
|
};
|
|
|
|
proto._itemize = function() {
|
|
var items = Outlayer.prototype._itemize.apply( this, arguments );
|
|
// assign ID for original-order
|
|
for ( var i=0; i < items.length; i++ ) {
|
|
var item = items[i];
|
|
item.id = this.itemGUID++;
|
|
}
|
|
this._updateItemsSortData( items );
|
|
return items;
|
|
};
|
|
|
|
|
|
// -------------------------- layout -------------------------- //
|
|
|
|
proto._initLayoutMode = function( name ) {
|
|
var Mode = LayoutMode.modes[ name ];
|
|
// set mode options
|
|
// HACK extend initial options, back-fill in default options
|
|
var initialOpts = this.options[ name ] || {};
|
|
this.options[ name ] = Mode.options ?
|
|
utils.extend( Mode.options, initialOpts ) : initialOpts;
|
|
// init layout mode instance
|
|
this.modes[ name ] = new Mode( this );
|
|
};
|
|
|
|
|
|
proto.layout = function() {
|
|
// if first time doing layout, do all magic
|
|
if ( !this._isLayoutInited && this._getOption('initLayout') ) {
|
|
this.arrange();
|
|
return;
|
|
}
|
|
this._layout();
|
|
};
|
|
|
|
// private method to be used in layout() & magic()
|
|
proto._layout = function() {
|
|
// don't animate first layout
|
|
var isInstant = this._getIsInstant();
|
|
// layout flow
|
|
this._resetLayout();
|
|
this._manageStamps();
|
|
this.layoutItems( this.filteredItems, isInstant );
|
|
|
|
// flag for initalized
|
|
this._isLayoutInited = true;
|
|
};
|
|
|
|
// filter + sort + layout
|
|
proto.arrange = function( opts ) {
|
|
// set any options pass
|
|
this.option( opts );
|
|
this._getIsInstant();
|
|
// filter, sort, and layout
|
|
|
|
// filter
|
|
var filtered = this._filter( this.items );
|
|
this.filteredItems = filtered.matches;
|
|
|
|
this._bindArrangeComplete();
|
|
|
|
if ( this._isInstant ) {
|
|
this._noTransition( this._hideReveal, [ filtered ] );
|
|
} else {
|
|
this._hideReveal( filtered );
|
|
}
|
|
|
|
this._sort();
|
|
this._layout();
|
|
};
|
|
// alias to _init for main plugin method
|
|
proto._init = proto.arrange;
|
|
|
|
proto._hideReveal = function( filtered ) {
|
|
this.reveal( filtered.needReveal );
|
|
this.hide( filtered.needHide );
|
|
};
|
|
|
|
// HACK
|
|
// Don't animate/transition first layout
|
|
// Or don't animate/transition other layouts
|
|
proto._getIsInstant = function() {
|
|
var isLayoutInstant = this._getOption('layoutInstant');
|
|
var isInstant = isLayoutInstant !== undefined ? isLayoutInstant :
|
|
!this._isLayoutInited;
|
|
this._isInstant = isInstant;
|
|
return isInstant;
|
|
};
|
|
|
|
// listen for layoutComplete, hideComplete and revealComplete
|
|
// to trigger arrangeComplete
|
|
proto._bindArrangeComplete = function() {
|
|
// listen for 3 events to trigger arrangeComplete
|
|
var isLayoutComplete, isHideComplete, isRevealComplete;
|
|
var _this = this;
|
|
function arrangeParallelCallback() {
|
|
if ( isLayoutComplete && isHideComplete && isRevealComplete ) {
|
|
_this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );
|
|
}
|
|
}
|
|
this.once( 'layoutComplete', function() {
|
|
isLayoutComplete = true;
|
|
arrangeParallelCallback();
|
|
});
|
|
this.once( 'hideComplete', function() {
|
|
isHideComplete = true;
|
|
arrangeParallelCallback();
|
|
});
|
|
this.once( 'revealComplete', function() {
|
|
isRevealComplete = true;
|
|
arrangeParallelCallback();
|
|
});
|
|
};
|
|
|
|
// -------------------------- filter -------------------------- //
|
|
|
|
proto._filter = function( items ) {
|
|
var filter = this.options.filter;
|
|
filter = filter || '*';
|
|
var matches = [];
|
|
var hiddenMatched = [];
|
|
var visibleUnmatched = [];
|
|
|
|
var test = this._getFilterTest( filter );
|
|
|
|
// test each item
|
|
for ( var i=0; i < items.length; i++ ) {
|
|
var item = items[i];
|
|
if ( item.isIgnored ) {
|
|
continue;
|
|
}
|
|
// add item to either matched or unmatched group
|
|
var isMatched = test( item );
|
|
// item.isFilterMatched = isMatched;
|
|
// add to matches if its a match
|
|
if ( isMatched ) {
|
|
matches.push( item );
|
|
}
|
|
// add to additional group if item needs to be hidden or revealed
|
|
if ( isMatched && item.isHidden ) {
|
|
hiddenMatched.push( item );
|
|
} else if ( !isMatched && !item.isHidden ) {
|
|
visibleUnmatched.push( item );
|
|
}
|
|
}
|
|
|
|
// return collections of items to be manipulated
|
|
return {
|
|
matches: matches,
|
|
needReveal: hiddenMatched,
|
|
needHide: visibleUnmatched
|
|
};
|
|
};
|
|
|
|
// get a jQuery, function, or a matchesSelector test given the filter
|
|
proto._getFilterTest = function( filter ) {
|
|
if ( jQuery && this.options.isJQueryFiltering ) {
|
|
// use jQuery
|
|
return function( item ) {
|
|
return jQuery( item.element ).is( filter );
|
|
};
|
|
}
|
|
if ( typeof filter == 'function' ) {
|
|
// use filter as function
|
|
return function( item ) {
|
|
return filter( item.element );
|
|
};
|
|
}
|
|
// default, use filter as selector string
|
|
return function( item ) {
|
|
return matchesSelector( item.element, filter );
|
|
};
|
|
};
|
|
|
|
// -------------------------- sorting -------------------------- //
|
|
|
|
/**
|
|
* @params {Array} elems
|
|
* @public
|
|
*/
|
|
proto.updateSortData = function( elems ) {
|
|
// get items
|
|
var items;
|
|
if ( elems ) {
|
|
elems = utils.makeArray( elems );
|
|
items = this.getItems( elems );
|
|
} else {
|
|
// update all items if no elems provided
|
|
items = this.items;
|
|
}
|
|
|
|
this._getSorters();
|
|
this._updateItemsSortData( items );
|
|
};
|
|
|
|
proto._getSorters = function() {
|
|
var getSortData = this.options.getSortData;
|
|
for ( var key in getSortData ) {
|
|
var sorter = getSortData[ key ];
|
|
this._sorters[ key ] = mungeSorter( sorter );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @params {Array} items - of Isotope.Items
|
|
* @private
|
|
*/
|
|
proto._updateItemsSortData = function( items ) {
|
|
// do not update if no items
|
|
var len = items && items.length;
|
|
|
|
for ( var i=0; len && i < len; i++ ) {
|
|
var item = items[i];
|
|
item.updateSortData();
|
|
}
|
|
};
|
|
|
|
// ----- munge sorter ----- //
|
|
|
|
// encapsulate this, as we just need mungeSorter
|
|
// other functions in here are just for munging
|
|
var mungeSorter = ( function() {
|
|
// add a magic layer to sorters for convienent shorthands
|
|
// `.foo-bar` will use the text of .foo-bar querySelector
|
|
// `[foo-bar]` will use attribute
|
|
// you can also add parser
|
|
// `.foo-bar parseInt` will parse that as a number
|
|
function mungeSorter( sorter ) {
|
|
// if not a string, return function or whatever it is
|
|
if ( typeof sorter != 'string' ) {
|
|
return sorter;
|
|
}
|
|
// parse the sorter string
|
|
var args = trim( sorter ).split(' ');
|
|
var query = args[0];
|
|
// check if query looks like [an-attribute]
|
|
var attrMatch = query.match( /^\[(.+)\]$/ );
|
|
var attr = attrMatch && attrMatch[1];
|
|
var getValue = getValueGetter( attr, query );
|
|
// use second argument as a parser
|
|
var parser = Isotope.sortDataParsers[ args[1] ];
|
|
// parse the value, if there was a parser
|
|
sorter = parser ? function( elem ) {
|
|
return elem && parser( getValue( elem ) );
|
|
} :
|
|
// otherwise just return value
|
|
function( elem ) {
|
|
return elem && getValue( elem );
|
|
};
|
|
|
|
return sorter;
|
|
}
|
|
|
|
// get an attribute getter, or get text of the querySelector
|
|
function getValueGetter( attr, query ) {
|
|
// if query looks like [foo-bar], get attribute
|
|
if ( attr ) {
|
|
return function getAttribute( elem ) {
|
|
return elem.getAttribute( attr );
|
|
};
|
|
}
|
|
|
|
// otherwise, assume its a querySelector, and get its text
|
|
return function getChildText( elem ) {
|
|
var child = elem.querySelector( query );
|
|
return child && child.textContent;
|
|
};
|
|
}
|
|
|
|
return mungeSorter;
|
|
})();
|
|
|
|
// parsers used in getSortData shortcut strings
|
|
Isotope.sortDataParsers = {
|
|
'parseInt': function( val ) {
|
|
return parseInt( val, 10 );
|
|
},
|
|
'parseFloat': function( val ) {
|
|
return parseFloat( val );
|
|
}
|
|
};
|
|
|
|
// ----- sort method ----- //
|
|
|
|
// sort filteredItem order
|
|
proto._sort = function() {
|
|
var sortByOpt = this.options.sortBy;
|
|
if ( !sortByOpt ) {
|
|
return;
|
|
}
|
|
// concat all sortBy and sortHistory
|
|
var sortBys = [].concat.apply( sortByOpt, this.sortHistory );
|
|
// sort magic
|
|
var itemSorter = getItemSorter( sortBys, this.options.sortAscending );
|
|
this.filteredItems.sort( itemSorter );
|
|
// keep track of sortBy History
|
|
if ( sortByOpt != this.sortHistory[0] ) {
|
|
// add to front, oldest goes in last
|
|
this.sortHistory.unshift( sortByOpt );
|
|
}
|
|
};
|
|
|
|
// returns a function used for sorting
|
|
function getItemSorter( sortBys, sortAsc ) {
|
|
return function sorter( itemA, itemB ) {
|
|
// cycle through all sortKeys
|
|
for ( var i = 0; i < sortBys.length; i++ ) {
|
|
var sortBy = sortBys[i];
|
|
var a = itemA.sortData[ sortBy ];
|
|
var b = itemB.sortData[ sortBy ];
|
|
if ( a > b || a < b ) {
|
|
// if sortAsc is an object, use the value given the sortBy key
|
|
var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
|
|
var direction = isAscending ? 1 : -1;
|
|
return ( a > b ? 1 : -1 ) * direction;
|
|
}
|
|
}
|
|
return 0;
|
|
};
|
|
}
|
|
|
|
// -------------------------- methods -------------------------- //
|
|
|
|
// get layout mode
|
|
proto._mode = function() {
|
|
var layoutMode = this.options.layoutMode;
|
|
var mode = this.modes[ layoutMode ];
|
|
if ( !mode ) {
|
|
// TODO console.error
|
|
throw new Error( 'No layout mode: ' + layoutMode );
|
|
}
|
|
// HACK sync mode's options
|
|
// any options set after init for layout mode need to be synced
|
|
mode.options = this.options[ layoutMode ];
|
|
return mode;
|
|
};
|
|
|
|
proto._resetLayout = function() {
|
|
// trigger original reset layout
|
|
Outlayer.prototype._resetLayout.call( this );
|
|
this._mode()._resetLayout();
|
|
};
|
|
|
|
proto._getItemLayoutPosition = function( item ) {
|
|
return this._mode()._getItemLayoutPosition( item );
|
|
};
|
|
|
|
proto._manageStamp = function( stamp ) {
|
|
this._mode()._manageStamp( stamp );
|
|
};
|
|
|
|
proto._getContainerSize = function() {
|
|
return this._mode()._getContainerSize();
|
|
};
|
|
|
|
proto.needsResizeLayout = function() {
|
|
return this._mode().needsResizeLayout();
|
|
};
|
|
|
|
// -------------------------- adding & removing -------------------------- //
|
|
|
|
// HEADS UP overwrites default Outlayer appended
|
|
proto.appended = function( elems ) {
|
|
var items = this.addItems( elems );
|
|
if ( !items.length ) {
|
|
return;
|
|
}
|
|
// filter, layout, reveal new items
|
|
var filteredItems = this._filterRevealAdded( items );
|
|
// add to filteredItems
|
|
this.filteredItems = this.filteredItems.concat( filteredItems );
|
|
};
|
|
|
|
// HEADS UP overwrites default Outlayer prepended
|
|
proto.prepended = function( elems ) {
|
|
var items = this._itemize( elems );
|
|
if ( !items.length ) {
|
|
return;
|
|
}
|
|
// start new layout
|
|
this._resetLayout();
|
|
this._manageStamps();
|
|
// filter, layout, reveal new items
|
|
var filteredItems = this._filterRevealAdded( items );
|
|
// layout previous items
|
|
this.layoutItems( this.filteredItems );
|
|
// add to items and filteredItems
|
|
this.filteredItems = filteredItems.concat( this.filteredItems );
|
|
this.items = items.concat( this.items );
|
|
};
|
|
|
|
proto._filterRevealAdded = function( items ) {
|
|
var filtered = this._filter( items );
|
|
this.hide( filtered.needHide );
|
|
// reveal all new items
|
|
this.reveal( filtered.matches );
|
|
// layout new items, no transition
|
|
this.layoutItems( filtered.matches, true );
|
|
return filtered.matches;
|
|
};
|
|
|
|
/**
|
|
* Filter, sort, and layout newly-appended item elements
|
|
* @param {Array or NodeList or Element} elems
|
|
*/
|
|
proto.insert = function( elems ) {
|
|
var items = this.addItems( elems );
|
|
if ( !items.length ) {
|
|
return;
|
|
}
|
|
// append item elements
|
|
var i, item;
|
|
var len = items.length;
|
|
for ( i=0; i < len; i++ ) {
|
|
item = items[i];
|
|
this.element.appendChild( item.element );
|
|
}
|
|
// filter new stuff
|
|
var filteredInsertItems = this._filter( items ).matches;
|
|
// set flag
|
|
for ( i=0; i < len; i++ ) {
|
|
items[i].isLayoutInstant = true;
|
|
}
|
|
this.arrange();
|
|
// reset flag
|
|
for ( i=0; i < len; i++ ) {
|
|
delete items[i].isLayoutInstant;
|
|
}
|
|
this.reveal( filteredInsertItems );
|
|
};
|
|
|
|
var _remove = proto.remove;
|
|
proto.remove = function( elems ) {
|
|
elems = utils.makeArray( elems );
|
|
var removeItems = this.getItems( elems );
|
|
// do regular thing
|
|
_remove.call( this, elems );
|
|
// bail if no items to remove
|
|
var len = removeItems && removeItems.length;
|
|
// remove elems from filteredItems
|
|
for ( var i=0; len && i < len; i++ ) {
|
|
var item = removeItems[i];
|
|
// remove item from collection
|
|
utils.removeFrom( this.filteredItems, item );
|
|
}
|
|
};
|
|
|
|
proto.shuffle = function() {
|
|
// update random sortData
|
|
for ( var i=0; i < this.items.length; i++ ) {
|
|
var item = this.items[i];
|
|
item.sortData.random = Math.random();
|
|
}
|
|
this.options.sortBy = 'random';
|
|
this._sort();
|
|
this._layout();
|
|
};
|
|
|
|
/**
|
|
* trigger fn without transition
|
|
* kind of hacky to have this in the first place
|
|
* @param {Function} fn
|
|
* @param {Array} args
|
|
* @returns ret
|
|
* @private
|
|
*/
|
|
proto._noTransition = function( fn, args ) {
|
|
// save transitionDuration before disabling
|
|
var transitionDuration = this.options.transitionDuration;
|
|
// disable transition
|
|
this.options.transitionDuration = 0;
|
|
// do it
|
|
var returnValue = fn.apply( this, args );
|
|
// re-enable transition for reveal
|
|
this.options.transitionDuration = transitionDuration;
|
|
return returnValue;
|
|
};
|
|
|
|
// ----- helper methods ----- //
|
|
|
|
/**
|
|
* getter method for getting filtered item elements
|
|
* @returns {Array} elems - collection of item elements
|
|
*/
|
|
proto.getFilteredItemElements = function() {
|
|
return this.filteredItems.map( function( item ) {
|
|
return item.element;
|
|
});
|
|
};
|
|
|
|
// ----- ----- //
|
|
|
|
return Isotope;
|
|
|
|
}));
|
|
|
|
|
|
/*
|
|
_ _ _ _
|
|
___| (_) ___| | __ (_)___
|
|
/ __| | |/ __| |/ / | / __|
|
|
\__ \ | | (__| < _ | \__ \
|
|
|___/_|_|\___|_|\_(_)/ |___/
|
|
|__/
|
|
|
|
Version: 1.9.0
|
|
Author: Ken Wheeler
|
|
Website: http://kenwheeler.github.io
|
|
Docs: http://kenwheeler.github.io/slick
|
|
Repo: http://github.com/kenwheeler/slick
|
|
Issues: http://github.com/kenwheeler/slick/issues
|
|
|
|
*/
|
|
/* global window, document, define, jQuery, setInterval, clearInterval */
|
|
;(function(factory) {
|
|
'use strict';
|
|
if (typeof define === 'function' && define.amd) {
|
|
define(['jquery'], factory);
|
|
} else if (typeof exports !== 'undefined') {
|
|
module.exports = factory(require('jquery'));
|
|
} else {
|
|
factory(jQuery);
|
|
}
|
|
|
|
}(function($) {
|
|
'use strict';
|
|
var Slick = window.Slick || {};
|
|
|
|
Slick = (function() {
|
|
|
|
var instanceUid = 0;
|
|
|
|
function Slick(element, settings) {
|
|
|
|
var _ = this, dataSettings;
|
|
|
|
_.defaults = {
|
|
accessibility: true,
|
|
adaptiveHeight: false,
|
|
appendArrows: $(element),
|
|
appendDots: $(element),
|
|
arrows: true,
|
|
asNavFor: null,
|
|
prevArrow: '<button class="slick-prev" aria-label="Previous" type="button">Previous</button>',
|
|
nextArrow: '<button class="slick-next" aria-label="Next" type="button">Next</button>',
|
|
autoplay: false,
|
|
autoplaySpeed: 3000,
|
|
centerMode: false,
|
|
centerPadding: '50px',
|
|
cssEase: 'ease',
|
|
customPaging: function(slider, i) {
|
|
return $('<button type="button" />').text(i + 1);
|
|
},
|
|
dots: false,
|
|
dotsClass: 'slick-dots',
|
|
draggable: true,
|
|
easing: 'linear',
|
|
edgeFriction: 0.35,
|
|
fade: false,
|
|
focusOnSelect: false,
|
|
focusOnChange: false,
|
|
infinite: true,
|
|
initialSlide: 0,
|
|
lazyLoad: 'ondemand',
|
|
mobileFirst: false,
|
|
pauseOnHover: true,
|
|
pauseOnFocus: true,
|
|
pauseOnDotsHover: false,
|
|
respondTo: 'window',
|
|
responsive: null,
|
|
rows: 1,
|
|
rtl: false,
|
|
slide: '',
|
|
slidesPerRow: 1,
|
|
slidesToShow: 1,
|
|
slidesToScroll: 1,
|
|
speed: 500,
|
|
swipe: true,
|
|
swipeToSlide: false,
|
|
touchMove: true,
|
|
touchThreshold: 5,
|
|
useCSS: true,
|
|
useTransform: true,
|
|
variableWidth: false,
|
|
vertical: false,
|
|
verticalSwiping: false,
|
|
waitForAnimate: true,
|
|
zIndex: 1000
|
|
};
|
|
|
|
_.initials = {
|
|
animating: false,
|
|
dragging: false,
|
|
autoPlayTimer: null,
|
|
currentDirection: 0,
|
|
currentLeft: null,
|
|
currentSlide: 0,
|
|
direction: 1,
|
|
$dots: null,
|
|
listWidth: null,
|
|
listHeight: null,
|
|
loadIndex: 0,
|
|
$nextArrow: null,
|
|
$prevArrow: null,
|
|
scrolling: false,
|
|
slideCount: null,
|
|
slideWidth: null,
|
|
$slideTrack: null,
|
|
$slides: null,
|
|
sliding: false,
|
|
slideOffset: 0,
|
|
swipeLeft: null,
|
|
swiping: false,
|
|
$list: null,
|
|
touchObject: {},
|
|
transformsEnabled: false,
|
|
unslicked: false
|
|
};
|
|
|
|
$.extend(_, _.initials);
|
|
|
|
_.activeBreakpoint = null;
|
|
_.animType = null;
|
|
_.animProp = null;
|
|
_.breakpoints = [];
|
|
_.breakpointSettings = [];
|
|
_.cssTransitions = false;
|
|
_.focussed = false;
|
|
_.interrupted = false;
|
|
_.hidden = 'hidden';
|
|
_.paused = true;
|
|
_.positionProp = null;
|
|
_.respondTo = null;
|
|
_.rowCount = 1;
|
|
_.shouldClick = true;
|
|
_.$slider = $(element);
|
|
_.$slidesCache = null;
|
|
_.transformType = null;
|
|
_.transitionType = null;
|
|
_.visibilityChange = 'visibilitychange';
|
|
_.windowWidth = 0;
|
|
_.windowTimer = null;
|
|
|
|
dataSettings = $(element).data('slick') || {};
|
|
|
|
_.options = $.extend({}, _.defaults, settings, dataSettings);
|
|
|
|
_.currentSlide = _.options.initialSlide;
|
|
|
|
_.originalSettings = _.options;
|
|
|
|
if (typeof document.mozHidden !== 'undefined') {
|
|
_.hidden = 'mozHidden';
|
|
_.visibilityChange = 'mozvisibilitychange';
|
|
} else if (typeof document.webkitHidden !== 'undefined') {
|
|
_.hidden = 'webkitHidden';
|
|
_.visibilityChange = 'webkitvisibilitychange';
|
|
}
|
|
|
|
_.autoPlay = $.proxy(_.autoPlay, _);
|
|
_.autoPlayClear = $.proxy(_.autoPlayClear, _);
|
|
_.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
|
|
_.changeSlide = $.proxy(_.changeSlide, _);
|
|
_.clickHandler = $.proxy(_.clickHandler, _);
|
|
_.selectHandler = $.proxy(_.selectHandler, _);
|
|
_.setPosition = $.proxy(_.setPosition, _);
|
|
_.swipeHandler = $.proxy(_.swipeHandler, _);
|
|
_.dragHandler = $.proxy(_.dragHandler, _);
|
|
_.keyHandler = $.proxy(_.keyHandler, _);
|
|
|
|
_.instanceUid = instanceUid++;
|
|
|
|
// A simple way to check for HTML strings
|
|
// Strict HTML recognition (must start with <)
|
|
// Extracted from jQuery v1.11 source
|
|
_.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;
|
|
|
|
|
|
_.registerBreakpoints();
|
|
_.init(true);
|
|
|
|
}
|
|
|
|
return Slick;
|
|
|
|
}());
|
|
|
|
Slick.prototype.activateADA = function() {
|
|
var _ = this;
|
|
|
|
_.$slideTrack.find('.slick-active').attr({
|
|
'aria-hidden': 'false'
|
|
}).find('a, input, button, select').attr({
|
|
'tabindex': '0'
|
|
});
|
|
|
|
};
|
|
|
|
Slick.prototype.addSlide = Slick.prototype.slickAdd = function(markup, index, addBefore) {
|
|
|
|
var _ = this;
|
|
|
|
if (typeof(index) === 'boolean') {
|
|
addBefore = index;
|
|
index = null;
|
|
} else if (index < 0 || (index >= _.slideCount)) {
|
|
return false;
|
|
}
|
|
|
|
_.unload();
|
|
|
|
if (typeof(index) === 'number') {
|
|
if (index === 0 && _.$slides.length === 0) {
|
|
$(markup).appendTo(_.$slideTrack);
|
|
} else if (addBefore) {
|
|
$(markup).insertBefore(_.$slides.eq(index));
|
|
} else {
|
|
$(markup).insertAfter(_.$slides.eq(index));
|
|
}
|
|
} else {
|
|
if (addBefore === true) {
|
|
$(markup).prependTo(_.$slideTrack);
|
|
} else {
|
|
$(markup).appendTo(_.$slideTrack);
|
|
}
|
|
}
|
|
|
|
_.$slides = _.$slideTrack.children(this.options.slide);
|
|
|
|
_.$slideTrack.children(this.options.slide).detach();
|
|
|
|
_.$slideTrack.append(_.$slides);
|
|
|
|
_.$slides.each(function(index, element) {
|
|
$(element).attr('data-slick-index', index);
|
|
});
|
|
|
|
_.$slidesCache = _.$slides;
|
|
|
|
_.reinit();
|
|
|
|
};
|
|
|
|
Slick.prototype.animateHeight = function() {
|
|
var _ = this;
|
|
if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
|
|
var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
|
|
_.$list.animate({
|
|
height: targetHeight
|
|
}, _.options.speed);
|
|
}
|
|
};
|
|
|
|
Slick.prototype.animateSlide = function(targetLeft, callback) {
|
|
|
|
var animProps = {},
|
|
_ = this;
|
|
|
|
_.animateHeight();
|
|
|
|
if (_.options.rtl === true && _.options.vertical === false) {
|
|
targetLeft = -targetLeft;
|
|
}
|
|
if (_.transformsEnabled === false) {
|
|
if (_.options.vertical === false) {
|
|
_.$slideTrack.animate({
|
|
left: targetLeft
|
|
}, _.options.speed, _.options.easing, callback);
|
|
} else {
|
|
_.$slideTrack.animate({
|
|
top: targetLeft
|
|
}, _.options.speed, _.options.easing, callback);
|
|
}
|
|
|
|
} else {
|
|
|
|
if (_.cssTransitions === false) {
|
|
if (_.options.rtl === true) {
|
|
_.currentLeft = -(_.currentLeft);
|
|
}
|
|
$({
|
|
animStart: _.currentLeft
|
|
}).animate({
|
|
animStart: targetLeft
|
|
}, {
|
|
duration: _.options.speed,
|
|
easing: _.options.easing,
|
|
step: function(now) {
|
|
now = Math.ceil(now);
|
|
if (_.options.vertical === false) {
|
|
animProps[_.animType] = 'translate(' +
|
|
now + 'px, 0px)';
|
|
_.$slideTrack.css(animProps);
|
|
} else {
|
|
animProps[_.animType] = 'translate(0px,' +
|
|
now + 'px)';
|
|
_.$slideTrack.css(animProps);
|
|
}
|
|
},
|
|
complete: function() {
|
|
if (callback) {
|
|
callback.call();
|
|
}
|
|
}
|
|
});
|
|
|
|
} else {
|
|
|
|
_.applyTransition();
|
|
targetLeft = Math.ceil(targetLeft);
|
|
|
|
if (_.options.vertical === false) {
|
|
animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
|
|
} else {
|
|
animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
|
|
}
|
|
_.$slideTrack.css(animProps);
|
|
|
|
if (callback) {
|
|
setTimeout(function() {
|
|
|
|
_.disableTransition();
|
|
|
|
callback.call();
|
|
}, _.options.speed);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.getNavTarget = function() {
|
|
|
|
var _ = this,
|
|
asNavFor = _.options.asNavFor;
|
|
|
|
if ( asNavFor && asNavFor !== null ) {
|
|
asNavFor = $(asNavFor).not(_.$slider);
|
|
}
|
|
|
|
return asNavFor;
|
|
|
|
};
|
|
|
|
Slick.prototype.asNavFor = function(index) {
|
|
|
|
var _ = this,
|
|
asNavFor = _.getNavTarget();
|
|
|
|
if ( asNavFor !== null && typeof asNavFor === 'object' ) {
|
|
asNavFor.each(function() {
|
|
var target = $(this).slick('getSlick');
|
|
if(!target.unslicked) {
|
|
target.slideHandler(index, true);
|
|
}
|
|
});
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.applyTransition = function(slide) {
|
|
|
|
var _ = this,
|
|
transition = {};
|
|
|
|
if (_.options.fade === false) {
|
|
transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
|
|
} else {
|
|
transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
|
|
}
|
|
|
|
if (_.options.fade === false) {
|
|
_.$slideTrack.css(transition);
|
|
} else {
|
|
_.$slides.eq(slide).css(transition);
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.autoPlay = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.autoPlayClear();
|
|
|
|
if ( _.slideCount > _.options.slidesToShow ) {
|
|
_.autoPlayTimer = setInterval( _.autoPlayIterator, _.options.autoplaySpeed );
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.autoPlayClear = function() {
|
|
|
|
var _ = this;
|
|
|
|
if (_.autoPlayTimer) {
|
|
clearInterval(_.autoPlayTimer);
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.autoPlayIterator = function() {
|
|
|
|
var _ = this,
|
|
slideTo = _.currentSlide + _.options.slidesToScroll;
|
|
|
|
if ( !_.paused && !_.interrupted && !_.focussed ) {
|
|
|
|
if ( _.options.infinite === false ) {
|
|
|
|
if ( _.direction === 1 && ( _.currentSlide + 1 ) === ( _.slideCount - 1 )) {
|
|
_.direction = 0;
|
|
}
|
|
|
|
else if ( _.direction === 0 ) {
|
|
|
|
slideTo = _.currentSlide - _.options.slidesToScroll;
|
|
|
|
if ( _.currentSlide - 1 === 0 ) {
|
|
_.direction = 1;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_.slideHandler( slideTo );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.buildArrows = function() {
|
|
|
|
var _ = this;
|
|
|
|
if (_.options.arrows === true ) {
|
|
|
|
_.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow');
|
|
_.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow');
|
|
|
|
if( _.slideCount > _.options.slidesToShow ) {
|
|
|
|
_.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
|
|
_.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
|
|
|
|
if (_.htmlExpr.test(_.options.prevArrow)) {
|
|
_.$prevArrow.prependTo(_.options.appendArrows);
|
|
}
|
|
|
|
if (_.htmlExpr.test(_.options.nextArrow)) {
|
|
_.$nextArrow.appendTo(_.options.appendArrows);
|
|
}
|
|
|
|
if (_.options.infinite !== true) {
|
|
_.$prevArrow
|
|
.addClass('slick-disabled')
|
|
.attr('aria-disabled', 'true');
|
|
}
|
|
|
|
} else {
|
|
|
|
_.$prevArrow.add( _.$nextArrow )
|
|
|
|
.addClass('slick-hidden')
|
|
.attr({
|
|
'aria-disabled': 'true',
|
|
'tabindex': '-1'
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.buildDots = function() {
|
|
|
|
var _ = this,
|
|
i, dot;
|
|
|
|
if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
|
|
|
|
_.$slider.addClass('slick-dotted');
|
|
|
|
dot = $('<ul />').addClass(_.options.dotsClass);
|
|
|
|
for (i = 0; i <= _.getDotCount(); i += 1) {
|
|
dot.append($('<li />').append(_.options.customPaging.call(this, _, i)));
|
|
}
|
|
|
|
_.$dots = dot.appendTo(_.options.appendDots);
|
|
|
|
_.$dots.find('li').first().addClass('slick-active');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.buildOut = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.$slides =
|
|
_.$slider
|
|
.children( _.options.slide + ':not(.slick-cloned)')
|
|
.addClass('slick-slide');
|
|
|
|
_.slideCount = _.$slides.length;
|
|
|
|
_.$slides.each(function(index, element) {
|
|
$(element)
|
|
.attr('data-slick-index', index)
|
|
.data('originalStyling', $(element).attr('style') || '');
|
|
});
|
|
|
|
_.$slider.addClass('slick-slider');
|
|
|
|
_.$slideTrack = (_.slideCount === 0) ?
|
|
$('<div class="slick-track"/>').appendTo(_.$slider) :
|
|
_.$slides.wrapAll('<div class="slick-track"/>').parent();
|
|
|
|
_.$list = _.$slideTrack.wrap(
|
|
'<div class="slick-list"/>').parent();
|
|
_.$slideTrack.css('opacity', 0);
|
|
|
|
if (_.options.centerMode === true || _.options.swipeToSlide === true) {
|
|
_.options.slidesToScroll = 1;
|
|
}
|
|
|
|
$('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');
|
|
|
|
_.setupInfinite();
|
|
|
|
_.buildArrows();
|
|
|
|
_.buildDots();
|
|
|
|
_.updateDots();
|
|
|
|
|
|
_.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
|
|
|
|
if (_.options.draggable === true) {
|
|
_.$list.addClass('draggable');
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.buildRows = function() {
|
|
|
|
var _ = this, a, b, c, newSlides, numOfSlides, originalSlides,slidesPerSection;
|
|
|
|
newSlides = document.createDocumentFragment();
|
|
originalSlides = _.$slider.children();
|
|
|
|
if(_.options.rows > 0) {
|
|
|
|
slidesPerSection = _.options.slidesPerRow * _.options.rows;
|
|
numOfSlides = Math.ceil(
|
|
originalSlides.length / slidesPerSection
|
|
);
|
|
|
|
for(a = 0; a < numOfSlides; a++){
|
|
var slide = document.createElement('div');
|
|
for(b = 0; b < _.options.rows; b++) {
|
|
var row = document.createElement('div');
|
|
for(c = 0; c < _.options.slidesPerRow; c++) {
|
|
var target = (a * slidesPerSection + ((b * _.options.slidesPerRow) + c));
|
|
if (originalSlides.get(target)) {
|
|
row.appendChild(originalSlides.get(target));
|
|
}
|
|
}
|
|
slide.appendChild(row);
|
|
}
|
|
newSlides.appendChild(slide);
|
|
}
|
|
|
|
_.$slider.empty().append(newSlides);
|
|
_.$slider.children().children().children()
|
|
.css({
|
|
'width':(100 / _.options.slidesPerRow) + '%',
|
|
'display': 'inline-block'
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.checkResponsive = function(initial, forceUpdate) {
|
|
|
|
var _ = this,
|
|
breakpoint, targetBreakpoint, respondToWidth, triggerBreakpoint = false;
|
|
var sliderWidth = _.$slider.width();
|
|
var windowWidth = window.innerWidth || $(window).width();
|
|
|
|
if (_.respondTo === 'window') {
|
|
respondToWidth = windowWidth;
|
|
} else if (_.respondTo === 'slider') {
|
|
respondToWidth = sliderWidth;
|
|
} else if (_.respondTo === 'min') {
|
|
respondToWidth = Math.min(windowWidth, sliderWidth);
|
|
}
|
|
|
|
if ( _.options.responsive &&
|
|
_.options.responsive.length &&
|
|
_.options.responsive !== null) {
|
|
|
|
targetBreakpoint = null;
|
|
|
|
for (breakpoint in _.breakpoints) {
|
|
if (_.breakpoints.hasOwnProperty(breakpoint)) {
|
|
if (_.originalSettings.mobileFirst === false) {
|
|
if (respondToWidth < _.breakpoints[breakpoint]) {
|
|
targetBreakpoint = _.breakpoints[breakpoint];
|
|
}
|
|
} else {
|
|
if (respondToWidth > _.breakpoints[breakpoint]) {
|
|
targetBreakpoint = _.breakpoints[breakpoint];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (targetBreakpoint !== null) {
|
|
if (_.activeBreakpoint !== null) {
|
|
if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) {
|
|
_.activeBreakpoint =
|
|
targetBreakpoint;
|
|
if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
|
|
_.unslick(targetBreakpoint);
|
|
} else {
|
|
_.options = $.extend({}, _.originalSettings,
|
|
_.breakpointSettings[
|
|
targetBreakpoint]);
|
|
if (initial === true) {
|
|
_.currentSlide = _.options.initialSlide;
|
|
}
|
|
_.refresh(initial);
|
|
}
|
|
triggerBreakpoint = targetBreakpoint;
|
|
}
|
|
} else {
|
|
_.activeBreakpoint = targetBreakpoint;
|
|
if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
|
|
_.unslick(targetBreakpoint);
|
|
} else {
|
|
_.options = $.extend({}, _.originalSettings,
|
|
_.breakpointSettings[
|
|
targetBreakpoint]);
|
|
if (initial === true) {
|
|
_.currentSlide = _.options.initialSlide;
|
|
}
|
|
_.refresh(initial);
|
|
}
|
|
triggerBreakpoint = targetBreakpoint;
|
|
}
|
|
} else {
|
|
if (_.activeBreakpoint !== null) {
|
|
_.activeBreakpoint = null;
|
|
_.options = _.originalSettings;
|
|
if (initial === true) {
|
|
_.currentSlide = _.options.initialSlide;
|
|
}
|
|
_.refresh(initial);
|
|
triggerBreakpoint = targetBreakpoint;
|
|
}
|
|
}
|
|
|
|
// only trigger breakpoints during an actual break. not on initialize.
|
|
if( !initial && triggerBreakpoint !== false ) {
|
|
_.$slider.trigger('breakpoint', [_, triggerBreakpoint]);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.changeSlide = function(event, dontAnimate) {
|
|
|
|
var _ = this,
|
|
$target = $(event.currentTarget),
|
|
indexOffset, slideOffset, unevenOffset;
|
|
|
|
// If target is a link, prevent default action.
|
|
if($target.is('a')) {
|
|
event.preventDefault();
|
|
}
|
|
|
|
// If target is not the <li> element (ie: a child), find the <li>.
|
|
if(!$target.is('li')) {
|
|
$target = $target.closest('li');
|
|
}
|
|
|
|
unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0);
|
|
indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;
|
|
|
|
switch (event.data.message) {
|
|
|
|
case 'previous':
|
|
slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
|
|
if (_.slideCount > _.options.slidesToShow) {
|
|
_.slideHandler(_.currentSlide - slideOffset, false, dontAnimate);
|
|
}
|
|
break;
|
|
|
|
case 'next':
|
|
slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
|
|
if (_.slideCount > _.options.slidesToShow) {
|
|
_.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
|
|
}
|
|
break;
|
|
|
|
case 'index':
|
|
var index = event.data.index === 0 ? 0 :
|
|
event.data.index || $target.index() * _.options.slidesToScroll;
|
|
|
|
_.slideHandler(_.checkNavigable(index), false, dontAnimate);
|
|
$target.children().trigger('focus');
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.checkNavigable = function(index) {
|
|
|
|
var _ = this,
|
|
navigables, prevNavigable;
|
|
|
|
navigables = _.getNavigableIndexes();
|
|
prevNavigable = 0;
|
|
if (index > navigables[navigables.length - 1]) {
|
|
index = navigables[navigables.length - 1];
|
|
} else {
|
|
for (var n in navigables) {
|
|
if (index < navigables[n]) {
|
|
index = prevNavigable;
|
|
break;
|
|
}
|
|
prevNavigable = navigables[n];
|
|
}
|
|
}
|
|
|
|
return index;
|
|
};
|
|
|
|
Slick.prototype.cleanUpEvents = function() {
|
|
|
|
var _ = this;
|
|
|
|
if (_.options.dots && _.$dots !== null) {
|
|
|
|
$('li', _.$dots)
|
|
.off('click.slick', _.changeSlide)
|
|
.off('mouseenter.slick', $.proxy(_.interrupt, _, true))
|
|
.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
|
|
|
|
if (_.options.accessibility === true) {
|
|
_.$dots.off('keydown.slick', _.keyHandler);
|
|
}
|
|
}
|
|
|
|
_.$slider.off('focus.slick blur.slick');
|
|
|
|
if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
|
|
_.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide);
|
|
_.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide);
|
|
|
|
if (_.options.accessibility === true) {
|
|
_.$prevArrow && _.$prevArrow.off('keydown.slick', _.keyHandler);
|
|
_.$nextArrow && _.$nextArrow.off('keydown.slick', _.keyHandler);
|
|
}
|
|
}
|
|
|
|
_.$list.off('touchstart.slick mousedown.slick', _.swipeHandler);
|
|
_.$list.off('touchmove.slick mousemove.slick', _.swipeHandler);
|
|
_.$list.off('touchend.slick mouseup.slick', _.swipeHandler);
|
|
_.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler);
|
|
|
|
_.$list.off('click.slick', _.clickHandler);
|
|
|
|
$(document).off(_.visibilityChange, _.visibility);
|
|
|
|
_.cleanUpSlideEvents();
|
|
|
|
if (_.options.accessibility === true) {
|
|
_.$list.off('keydown.slick', _.keyHandler);
|
|
}
|
|
|
|
if (_.options.focusOnSelect === true) {
|
|
$(_.$slideTrack).children().off('click.slick', _.selectHandler);
|
|
}
|
|
|
|
$(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange);
|
|
|
|
$(window).off('resize.slick.slick-' + _.instanceUid, _.resize);
|
|
|
|
$('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault);
|
|
|
|
$(window).off('load.slick.slick-' + _.instanceUid, _.setPosition);
|
|
|
|
};
|
|
|
|
Slick.prototype.cleanUpSlideEvents = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true));
|
|
_.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
|
|
|
|
};
|
|
|
|
Slick.prototype.cleanUpRows = function() {
|
|
|
|
var _ = this, originalSlides;
|
|
|
|
if(_.options.rows > 0) {
|
|
originalSlides = _.$slides.children().children();
|
|
originalSlides.removeAttr('style');
|
|
_.$slider.empty().append(originalSlides);
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.clickHandler = function(event) {
|
|
|
|
var _ = this;
|
|
|
|
if (_.shouldClick === false) {
|
|
event.stopImmediatePropagation();
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.destroy = function(refresh) {
|
|
|
|
var _ = this;
|
|
|
|
_.autoPlayClear();
|
|
|
|
_.touchObject = {};
|
|
|
|
_.cleanUpEvents();
|
|
|
|
$('.slick-cloned', _.$slider).detach();
|
|
|
|
if (_.$dots) {
|
|
_.$dots.remove();
|
|
}
|
|
|
|
if ( _.$prevArrow && _.$prevArrow.length ) {
|
|
|
|
_.$prevArrow
|
|
.removeClass('slick-disabled slick-arrow slick-hidden')
|
|
.removeAttr('aria-hidden aria-disabled tabindex')
|
|
.css('display','');
|
|
|
|
if ( _.htmlExpr.test( _.options.prevArrow )) {
|
|
_.$prevArrow.remove();
|
|
}
|
|
}
|
|
|
|
if ( _.$nextArrow && _.$nextArrow.length ) {
|
|
|
|
_.$nextArrow
|
|
.removeClass('slick-disabled slick-arrow slick-hidden')
|
|
.removeAttr('aria-hidden aria-disabled tabindex')
|
|
.css('display','');
|
|
|
|
if ( _.htmlExpr.test( _.options.nextArrow )) {
|
|
_.$nextArrow.remove();
|
|
}
|
|
}
|
|
|
|
|
|
if (_.$slides) {
|
|
|
|
_.$slides
|
|
.removeClass('slick-slide slick-active slick-center slick-visible slick-current')
|
|
.removeAttr('aria-hidden')
|
|
.removeAttr('data-slick-index')
|
|
.each(function(){
|
|
$(this).attr('style', $(this).data('originalStyling'));
|
|
});
|
|
|
|
_.$slideTrack.children(this.options.slide).detach();
|
|
|
|
_.$slideTrack.detach();
|
|
|
|
_.$list.detach();
|
|
|
|
_.$slider.append(_.$slides);
|
|
}
|
|
|
|
_.cleanUpRows();
|
|
|
|
_.$slider.removeClass('slick-slider');
|
|
_.$slider.removeClass('slick-initialized');
|
|
_.$slider.removeClass('slick-dotted');
|
|
|
|
_.unslicked = true;
|
|
|
|
if(!refresh) {
|
|
_.$slider.trigger('destroy', [_]);
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.disableTransition = function(slide) {
|
|
|
|
var _ = this,
|
|
transition = {};
|
|
|
|
transition[_.transitionType] = '';
|
|
|
|
if (_.options.fade === false) {
|
|
_.$slideTrack.css(transition);
|
|
} else {
|
|
_.$slides.eq(slide).css(transition);
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.fadeSlide = function(slideIndex, callback) {
|
|
|
|
var _ = this;
|
|
|
|
if (_.cssTransitions === false) {
|
|
|
|
_.$slides.eq(slideIndex).css({
|
|
zIndex: _.options.zIndex
|
|
});
|
|
|
|
_.$slides.eq(slideIndex).animate({
|
|
opacity: 1
|
|
}, _.options.speed, _.options.easing, callback);
|
|
|
|
} else {
|
|
|
|
_.applyTransition(slideIndex);
|
|
|
|
_.$slides.eq(slideIndex).css({
|
|
opacity: 1,
|
|
zIndex: _.options.zIndex
|
|
});
|
|
|
|
if (callback) {
|
|
setTimeout(function() {
|
|
|
|
_.disableTransition(slideIndex);
|
|
|
|
callback.call();
|
|
}, _.options.speed);
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.fadeSlideOut = function(slideIndex) {
|
|
|
|
var _ = this;
|
|
|
|
if (_.cssTransitions === false) {
|
|
|
|
_.$slides.eq(slideIndex).animate({
|
|
opacity: 0,
|
|
zIndex: _.options.zIndex - 2
|
|
}, _.options.speed, _.options.easing);
|
|
|
|
} else {
|
|
|
|
_.applyTransition(slideIndex);
|
|
|
|
_.$slides.eq(slideIndex).css({
|
|
opacity: 0,
|
|
zIndex: _.options.zIndex - 2
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.filterSlides = Slick.prototype.slickFilter = function(filter) {
|
|
|
|
var _ = this;
|
|
|
|
if (filter !== null) {
|
|
|
|
_.$slidesCache = _.$slides;
|
|
|
|
_.unload();
|
|
|
|
_.$slideTrack.children(this.options.slide).detach();
|
|
|
|
_.$slidesCache.filter(filter).appendTo(_.$slideTrack);
|
|
|
|
_.reinit();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.focusHandler = function() {
|
|
|
|
var _ = this;
|
|
|
|
// If any child element receives focus within the slider we need to pause the autoplay
|
|
_.$slider
|
|
.off('focus.slick blur.slick')
|
|
.on(
|
|
'focus.slick',
|
|
'*',
|
|
function(event) {
|
|
var $sf = $(this);
|
|
|
|
setTimeout(function() {
|
|
if( _.options.pauseOnFocus ) {
|
|
if ($sf.is(':focus')) {
|
|
_.focussed = true;
|
|
_.autoPlay();
|
|
}
|
|
}
|
|
}, 0);
|
|
}
|
|
).on(
|
|
'blur.slick',
|
|
'*',
|
|
function(event) {
|
|
var $sf = $(this);
|
|
|
|
// When a blur occurs on any elements within the slider we become unfocused
|
|
if( _.options.pauseOnFocus ) {
|
|
_.focussed = false;
|
|
_.autoPlay();
|
|
}
|
|
}
|
|
);
|
|
};
|
|
|
|
Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function() {
|
|
|
|
var _ = this;
|
|
return _.currentSlide;
|
|
|
|
};
|
|
|
|
Slick.prototype.getDotCount = function() {
|
|
|
|
var _ = this;
|
|
|
|
var breakPoint = 0;
|
|
var counter = 0;
|
|
var pagerQty = 0;
|
|
|
|
if (_.options.infinite === true) {
|
|
if (_.slideCount <= _.options.slidesToShow) {
|
|
++pagerQty;
|
|
} else {
|
|
while (breakPoint < _.slideCount) {
|
|
++pagerQty;
|
|
breakPoint = counter + _.options.slidesToScroll;
|
|
counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
|
|
}
|
|
}
|
|
} else if (_.options.centerMode === true) {
|
|
pagerQty = _.slideCount;
|
|
} else if(!_.options.asNavFor) {
|
|
pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll);
|
|
}else {
|
|
while (breakPoint < _.slideCount) {
|
|
++pagerQty;
|
|
breakPoint = counter + _.options.slidesToScroll;
|
|
counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
|
|
}
|
|
}
|
|
|
|
return pagerQty - 1;
|
|
|
|
};
|
|
|
|
Slick.prototype.getLeft = function(slideIndex) {
|
|
|
|
var _ = this,
|
|
targetLeft,
|
|
verticalHeight,
|
|
verticalOffset = 0,
|
|
targetSlide,
|
|
coef;
|
|
|
|
_.slideOffset = 0;
|
|
verticalHeight = _.$slides.first().outerHeight(true);
|
|
|
|
if (_.options.infinite === true) {
|
|
if (_.slideCount > _.options.slidesToShow) {
|
|
_.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1;
|
|
coef = -1
|
|
|
|
if (_.options.vertical === true && _.options.centerMode === true) {
|
|
if (_.options.slidesToShow === 2) {
|
|
coef = -1.5;
|
|
} else if (_.options.slidesToShow === 1) {
|
|
coef = -2
|
|
}
|
|
}
|
|
verticalOffset = (verticalHeight * _.options.slidesToShow) * coef;
|
|
}
|
|
if (_.slideCount % _.options.slidesToScroll !== 0) {
|
|
if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
|
|
if (slideIndex > _.slideCount) {
|
|
_.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1;
|
|
verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1;
|
|
} else {
|
|
_.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1;
|
|
verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (slideIndex + _.options.slidesToShow > _.slideCount) {
|
|
_.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth;
|
|
verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight;
|
|
}
|
|
}
|
|
|
|
if (_.slideCount <= _.options.slidesToShow) {
|
|
_.slideOffset = 0;
|
|
verticalOffset = 0;
|
|
}
|
|
|
|
if (_.options.centerMode === true && _.slideCount <= _.options.slidesToShow) {
|
|
_.slideOffset = ((_.slideWidth * Math.floor(_.options.slidesToShow)) / 2) - ((_.slideWidth * _.slideCount) / 2);
|
|
} else if (_.options.centerMode === true && _.options.infinite === true) {
|
|
_.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
|
|
} else if (_.options.centerMode === true) {
|
|
_.slideOffset = 0;
|
|
_.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
|
|
}
|
|
|
|
if (_.options.vertical === false) {
|
|
targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset;
|
|
} else {
|
|
targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset;
|
|
}
|
|
|
|
if (_.options.variableWidth === true) {
|
|
|
|
if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
|
|
targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
|
|
} else {
|
|
targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
|
|
}
|
|
|
|
if (_.options.rtl === true) {
|
|
if (targetSlide[0]) {
|
|
targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
|
|
} else {
|
|
targetLeft = 0;
|
|
}
|
|
} else {
|
|
targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
|
|
}
|
|
|
|
if (_.options.centerMode === true) {
|
|
if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
|
|
targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
|
|
} else {
|
|
targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
|
|
}
|
|
|
|
if (_.options.rtl === true) {
|
|
if (targetSlide[0]) {
|
|
targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
|
|
} else {
|
|
targetLeft = 0;
|
|
}
|
|
} else {
|
|
targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
|
|
}
|
|
|
|
targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2;
|
|
}
|
|
}
|
|
|
|
return targetLeft;
|
|
|
|
};
|
|
|
|
Slick.prototype.getOption = Slick.prototype.slickGetOption = function(option) {
|
|
|
|
var _ = this;
|
|
|
|
return _.options[option];
|
|
|
|
};
|
|
|
|
Slick.prototype.getNavigableIndexes = function() {
|
|
|
|
var _ = this,
|
|
breakPoint = 0,
|
|
counter = 0,
|
|
indexes = [],
|
|
max;
|
|
|
|
if (_.options.infinite === false) {
|
|
max = _.slideCount;
|
|
} else {
|
|
breakPoint = _.options.slidesToScroll * -1;
|
|
counter = _.options.slidesToScroll * -1;
|
|
max = _.slideCount * 2;
|
|
}
|
|
|
|
while (breakPoint < max) {
|
|
indexes.push(breakPoint);
|
|
breakPoint = counter + _.options.slidesToScroll;
|
|
counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
|
|
}
|
|
|
|
return indexes;
|
|
|
|
};
|
|
|
|
Slick.prototype.getSlick = function() {
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
Slick.prototype.getSlideCount = function() {
|
|
|
|
var _ = this,
|
|
slidesTraversed, swipedSlide, swipeTarget, centerOffset;
|
|
|
|
centerOffset = _.options.centerMode === true ? Math.floor(_.$list.width() / 2) : 0;
|
|
swipeTarget = (_.swipeLeft * -1) + centerOffset;
|
|
|
|
if (_.options.swipeToSlide === true) {
|
|
|
|
_.$slideTrack.find('.slick-slide').each(function(index, slide) {
|
|
|
|
var slideOuterWidth, slideOffset, slideRightBoundary;
|
|
slideOuterWidth = $(slide).outerWidth();
|
|
slideOffset = slide.offsetLeft;
|
|
if (_.options.centerMode !== true) {
|
|
slideOffset += (slideOuterWidth / 2);
|
|
}
|
|
|
|
slideRightBoundary = slideOffset + (slideOuterWidth);
|
|
|
|
if (swipeTarget < slideRightBoundary) {
|
|
swipedSlide = slide;
|
|
return false;
|
|
}
|
|
});
|
|
|
|
slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1;
|
|
|
|
return slidesTraversed;
|
|
|
|
} else {
|
|
return _.options.slidesToScroll;
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.goTo = Slick.prototype.slickGoTo = function(slide, dontAnimate) {
|
|
|
|
var _ = this;
|
|
|
|
_.changeSlide({
|
|
data: {
|
|
message: 'index',
|
|
index: parseInt(slide)
|
|
}
|
|
}, dontAnimate);
|
|
|
|
};
|
|
|
|
Slick.prototype.init = function(creation) {
|
|
|
|
var _ = this;
|
|
|
|
if (!$(_.$slider).hasClass('slick-initialized')) {
|
|
|
|
$(_.$slider).addClass('slick-initialized');
|
|
|
|
_.buildRows();
|
|
_.buildOut();
|
|
_.setProps();
|
|
_.startLoad();
|
|
_.loadSlider();
|
|
_.initializeEvents();
|
|
_.updateArrows();
|
|
_.updateDots();
|
|
_.checkResponsive(true);
|
|
_.focusHandler();
|
|
|
|
}
|
|
|
|
if (creation) {
|
|
_.$slider.trigger('init', [_]);
|
|
}
|
|
|
|
if (_.options.accessibility === true) {
|
|
_.initADA();
|
|
}
|
|
|
|
if ( _.options.autoplay ) {
|
|
|
|
_.paused = false;
|
|
_.autoPlay();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.initADA = function() {
|
|
var _ = this,
|
|
numDotGroups = Math.ceil(_.slideCount / _.options.slidesToShow),
|
|
tabControlIndexes = _.getNavigableIndexes().filter(function(val) {
|
|
return (val >= 0) && (val < _.slideCount);
|
|
});
|
|
|
|
_.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({
|
|
'aria-hidden': 'true',
|
|
'tabindex': '-1'
|
|
}).find('a, input, button, select').attr({
|
|
'tabindex': '-1'
|
|
});
|
|
|
|
if (_.$dots !== null) {
|
|
_.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) {
|
|
var slideControlIndex = tabControlIndexes.indexOf(i);
|
|
|
|
$(this).attr({
|
|
'role': 'tabpanel',
|
|
'id': 'slick-slide' + _.instanceUid + i,
|
|
'tabindex': -1
|
|
});
|
|
|
|
if (slideControlIndex !== -1) {
|
|
var ariaButtonControl = 'slick-slide-control' + _.instanceUid + slideControlIndex
|
|
if ($('#' + ariaButtonControl).length) {
|
|
$(this).attr({
|
|
'aria-describedby': ariaButtonControl
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
_.$dots.attr('role', 'tablist').find('li').each(function(i) {
|
|
var mappedSlideIndex = tabControlIndexes[i];
|
|
|
|
$(this).attr({
|
|
'role': 'presentation'
|
|
});
|
|
|
|
$(this).find('button').first().attr({
|
|
'role': 'tab',
|
|
'id': 'slick-slide-control' + _.instanceUid + i,
|
|
'aria-controls': 'slick-slide' + _.instanceUid + mappedSlideIndex,
|
|
'aria-label': (i + 1) + ' of ' + numDotGroups,
|
|
'aria-selected': null,
|
|
'tabindex': '-1'
|
|
});
|
|
|
|
}).eq(_.currentSlide).find('button').attr({
|
|
'aria-selected': 'true',
|
|
'tabindex': '0'
|
|
}).end();
|
|
}
|
|
|
|
for (var i=_.currentSlide, max=i+_.options.slidesToShow; i < max; i++) {
|
|
if (_.options.focusOnChange) {
|
|
_.$slides.eq(i).attr({'tabindex': '0'});
|
|
} else {
|
|
_.$slides.eq(i).removeAttr('tabindex');
|
|
}
|
|
}
|
|
|
|
_.activateADA();
|
|
|
|
};
|
|
|
|
Slick.prototype.initArrowEvents = function() {
|
|
|
|
var _ = this;
|
|
|
|
if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
|
|
_.$prevArrow
|
|
.off('click.slick')
|
|
.on('click.slick', {
|
|
message: 'previous'
|
|
}, _.changeSlide);
|
|
_.$nextArrow
|
|
.off('click.slick')
|
|
.on('click.slick', {
|
|
message: 'next'
|
|
}, _.changeSlide);
|
|
|
|
if (_.options.accessibility === true) {
|
|
_.$prevArrow.on('keydown.slick', _.keyHandler);
|
|
_.$nextArrow.on('keydown.slick', _.keyHandler);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.initDotEvents = function() {
|
|
|
|
var _ = this;
|
|
|
|
if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
|
|
$('li', _.$dots).on('click.slick', {
|
|
message: 'index'
|
|
}, _.changeSlide);
|
|
|
|
if (_.options.accessibility === true) {
|
|
_.$dots.on('keydown.slick', _.keyHandler);
|
|
}
|
|
}
|
|
|
|
if (_.options.dots === true && _.options.pauseOnDotsHover === true && _.slideCount > _.options.slidesToShow) {
|
|
|
|
$('li', _.$dots)
|
|
.on('mouseenter.slick', $.proxy(_.interrupt, _, true))
|
|
.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.initSlideEvents = function() {
|
|
|
|
var _ = this;
|
|
|
|
if ( _.options.pauseOnHover ) {
|
|
|
|
_.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true));
|
|
_.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.initializeEvents = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.initArrowEvents();
|
|
|
|
_.initDotEvents();
|
|
_.initSlideEvents();
|
|
|
|
_.$list.on('touchstart.slick mousedown.slick', {
|
|
action: 'start'
|
|
}, _.swipeHandler);
|
|
_.$list.on('touchmove.slick mousemove.slick', {
|
|
action: 'move'
|
|
}, _.swipeHandler);
|
|
_.$list.on('touchend.slick mouseup.slick', {
|
|
action: 'end'
|
|
}, _.swipeHandler);
|
|
_.$list.on('touchcancel.slick mouseleave.slick', {
|
|
action: 'end'
|
|
}, _.swipeHandler);
|
|
|
|
_.$list.on('click.slick', _.clickHandler);
|
|
|
|
$(document).on(_.visibilityChange, $.proxy(_.visibility, _));
|
|
|
|
if (_.options.accessibility === true) {
|
|
_.$list.on('keydown.slick', _.keyHandler);
|
|
}
|
|
|
|
if (_.options.focusOnSelect === true) {
|
|
$(_.$slideTrack).children().on('click.slick', _.selectHandler);
|
|
}
|
|
|
|
$(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _));
|
|
|
|
$(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _));
|
|
|
|
$('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault);
|
|
|
|
$(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
|
|
$(_.setPosition);
|
|
|
|
};
|
|
|
|
Slick.prototype.initUI = function() {
|
|
|
|
var _ = this;
|
|
|
|
if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
|
|
|
|
_.$prevArrow.show();
|
|
_.$nextArrow.show();
|
|
|
|
}
|
|
|
|
if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
|
|
|
|
_.$dots.show();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.keyHandler = function(event) {
|
|
|
|
var _ = this;
|
|
//Dont slide if the cursor is inside the form fields and arrow keys are pressed
|
|
if(!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
|
|
if (event.keyCode === 37 && _.options.accessibility === true) {
|
|
_.changeSlide({
|
|
data: {
|
|
message: _.options.rtl === true ? 'next' : 'previous'
|
|
}
|
|
});
|
|
} else if (event.keyCode === 39 && _.options.accessibility === true) {
|
|
_.changeSlide({
|
|
data: {
|
|
message: _.options.rtl === true ? 'previous' : 'next'
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.lazyLoad = function() {
|
|
|
|
var _ = this,
|
|
loadRange, cloneRange, rangeStart, rangeEnd;
|
|
|
|
function loadImages(imagesScope) {
|
|
|
|
$('img[data-lazy]', imagesScope).each(function() {
|
|
|
|
var image = $(this),
|
|
imageSource = $(this).attr('data-lazy'),
|
|
imageSrcSet = $(this).attr('data-srcset'),
|
|
imageSizes = $(this).attr('data-sizes') || _.$slider.attr('data-sizes'),
|
|
imageToLoad = document.createElement('img');
|
|
|
|
imageToLoad.onload = function() {
|
|
|
|
image
|
|
.animate({ opacity: 0 }, 100, function() {
|
|
|
|
if (imageSrcSet) {
|
|
image
|
|
.attr('srcset', imageSrcSet );
|
|
|
|
if (imageSizes) {
|
|
image
|
|
.attr('sizes', imageSizes );
|
|
}
|
|
}
|
|
|
|
image
|
|
.attr('src', imageSource)
|
|
.animate({ opacity: 1 }, 200, function() {
|
|
image
|
|
.removeAttr('data-lazy data-srcset data-sizes')
|
|
.removeClass('slick-loading');
|
|
});
|
|
_.$slider.trigger('lazyLoaded', [_, image, imageSource]);
|
|
});
|
|
|
|
};
|
|
|
|
imageToLoad.onerror = function() {
|
|
|
|
image
|
|
.removeAttr( 'data-lazy' )
|
|
.removeClass( 'slick-loading' )
|
|
.addClass( 'slick-lazyload-error' );
|
|
|
|
_.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
|
|
|
|
};
|
|
|
|
imageToLoad.src = imageSource;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (_.options.centerMode === true) {
|
|
if (_.options.infinite === true) {
|
|
rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1);
|
|
rangeEnd = rangeStart + _.options.slidesToShow + 2;
|
|
} else {
|
|
rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1));
|
|
rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide;
|
|
}
|
|
} else {
|
|
rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
|
|
rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow);
|
|
if (_.options.fade === true) {
|
|
if (rangeStart > 0) rangeStart--;
|
|
if (rangeEnd <= _.slideCount) rangeEnd++;
|
|
}
|
|
}
|
|
|
|
loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
|
|
|
|
if (_.options.lazyLoad === 'anticipated') {
|
|
var prevSlide = rangeStart - 1,
|
|
nextSlide = rangeEnd,
|
|
$slides = _.$slider.find('.slick-slide');
|
|
|
|
for (var i = 0; i < _.options.slidesToScroll; i++) {
|
|
if (prevSlide < 0) prevSlide = _.slideCount - 1;
|
|
loadRange = loadRange.add($slides.eq(prevSlide));
|
|
loadRange = loadRange.add($slides.eq(nextSlide));
|
|
prevSlide--;
|
|
nextSlide++;
|
|
}
|
|
}
|
|
|
|
loadImages(loadRange);
|
|
|
|
if (_.slideCount <= _.options.slidesToShow) {
|
|
cloneRange = _.$slider.find('.slick-slide');
|
|
loadImages(cloneRange);
|
|
} else
|
|
if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
|
|
cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
|
|
loadImages(cloneRange);
|
|
} else if (_.currentSlide === 0) {
|
|
cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
|
|
loadImages(cloneRange);
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.loadSlider = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.setPosition();
|
|
|
|
_.$slideTrack.css({
|
|
opacity: 1
|
|
});
|
|
|
|
_.$slider.removeClass('slick-loading');
|
|
|
|
_.initUI();
|
|
|
|
if (_.options.lazyLoad === 'progressive') {
|
|
_.progressiveLazyLoad();
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.next = Slick.prototype.slickNext = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.changeSlide({
|
|
data: {
|
|
message: 'next'
|
|
}
|
|
});
|
|
|
|
};
|
|
|
|
Slick.prototype.orientationChange = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.checkResponsive();
|
|
_.setPosition();
|
|
|
|
};
|
|
|
|
Slick.prototype.pause = Slick.prototype.slickPause = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.autoPlayClear();
|
|
_.paused = true;
|
|
|
|
};
|
|
|
|
Slick.prototype.play = Slick.prototype.slickPlay = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.autoPlay();
|
|
_.options.autoplay = true;
|
|
_.paused = false;
|
|
_.focussed = false;
|
|
_.interrupted = false;
|
|
|
|
};
|
|
|
|
Slick.prototype.postSlide = function(index) {
|
|
|
|
var _ = this;
|
|
|
|
if( !_.unslicked ) {
|
|
|
|
_.$slider.trigger('afterChange', [_, index]);
|
|
|
|
_.animating = false;
|
|
|
|
if (_.slideCount > _.options.slidesToShow) {
|
|
_.setPosition();
|
|
}
|
|
|
|
_.swipeLeft = null;
|
|
|
|
if ( _.options.autoplay ) {
|
|
_.autoPlay();
|
|
}
|
|
|
|
if (_.options.accessibility === true) {
|
|
_.initADA();
|
|
|
|
if (_.options.focusOnChange) {
|
|
var $currentSlide = $(_.$slides.get(_.currentSlide));
|
|
$currentSlide.attr('tabindex', 0).focus();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.prev = Slick.prototype.slickPrev = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.changeSlide({
|
|
data: {
|
|
message: 'previous'
|
|
}
|
|
});
|
|
|
|
};
|
|
|
|
Slick.prototype.preventDefault = function(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
};
|
|
|
|
Slick.prototype.progressiveLazyLoad = function( tryCount ) {
|
|
|
|
tryCount = tryCount || 1;
|
|
|
|
var _ = this,
|
|
$imgsToLoad = $( 'img[data-lazy]', _.$slider ),
|
|
image,
|
|
imageSource,
|
|
imageSrcSet,
|
|
imageSizes,
|
|
imageToLoad;
|
|
|
|
if ( $imgsToLoad.length ) {
|
|
|
|
image = $imgsToLoad.first();
|
|
imageSource = image.attr('data-lazy');
|
|
imageSrcSet = image.attr('data-srcset');
|
|
imageSizes = image.attr('data-sizes') || _.$slider.attr('data-sizes');
|
|
imageToLoad = document.createElement('img');
|
|
|
|
imageToLoad.onload = function() {
|
|
|
|
if (imageSrcSet) {
|
|
image
|
|
.attr('srcset', imageSrcSet );
|
|
|
|
if (imageSizes) {
|
|
image
|
|
.attr('sizes', imageSizes );
|
|
}
|
|
}
|
|
|
|
image
|
|
.attr( 'src', imageSource )
|
|
.removeAttr('data-lazy data-srcset data-sizes')
|
|
.removeClass('slick-loading');
|
|
|
|
if ( _.options.adaptiveHeight === true ) {
|
|
_.setPosition();
|
|
}
|
|
|
|
_.$slider.trigger('lazyLoaded', [ _, image, imageSource ]);
|
|
_.progressiveLazyLoad();
|
|
|
|
};
|
|
|
|
imageToLoad.onerror = function() {
|
|
|
|
if ( tryCount < 3 ) {
|
|
|
|
/**
|
|
* try to load the image 3 times,
|
|
* leave a slight delay so we don't get
|
|
* servers blocking the request.
|
|
*/
|
|
setTimeout( function() {
|
|
_.progressiveLazyLoad( tryCount + 1 );
|
|
}, 500 );
|
|
|
|
} else {
|
|
|
|
image
|
|
.removeAttr( 'data-lazy' )
|
|
.removeClass( 'slick-loading' )
|
|
.addClass( 'slick-lazyload-error' );
|
|
|
|
_.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
|
|
|
|
_.progressiveLazyLoad();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
imageToLoad.src = imageSource;
|
|
|
|
} else {
|
|
|
|
_.$slider.trigger('allImagesLoaded', [ _ ]);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.refresh = function( initializing ) {
|
|
|
|
var _ = this, currentSlide, lastVisibleIndex;
|
|
|
|
lastVisibleIndex = _.slideCount - _.options.slidesToShow;
|
|
|
|
// in non-infinite sliders, we don't want to go past the
|
|
// last visible index.
|
|
if( !_.options.infinite && ( _.currentSlide > lastVisibleIndex )) {
|
|
_.currentSlide = lastVisibleIndex;
|
|
}
|
|
|
|
// if less slides than to show, go to start.
|
|
if ( _.slideCount <= _.options.slidesToShow ) {
|
|
_.currentSlide = 0;
|
|
|
|
}
|
|
|
|
currentSlide = _.currentSlide;
|
|
|
|
_.destroy(true);
|
|
|
|
$.extend(_, _.initials, { currentSlide: currentSlide });
|
|
|
|
_.init();
|
|
|
|
if( !initializing ) {
|
|
|
|
_.changeSlide({
|
|
data: {
|
|
message: 'index',
|
|
index: currentSlide
|
|
}
|
|
}, false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.registerBreakpoints = function() {
|
|
|
|
var _ = this, breakpoint, currentBreakpoint, l,
|
|
responsiveSettings = _.options.responsive || null;
|
|
|
|
if ( $.type(responsiveSettings) === 'array' && responsiveSettings.length ) {
|
|
|
|
_.respondTo = _.options.respondTo || 'window';
|
|
|
|
for ( breakpoint in responsiveSettings ) {
|
|
|
|
l = _.breakpoints.length-1;
|
|
|
|
if (responsiveSettings.hasOwnProperty(breakpoint)) {
|
|
currentBreakpoint = responsiveSettings[breakpoint].breakpoint;
|
|
|
|
// loop through the breakpoints and cut out any existing
|
|
// ones with the same breakpoint number, we don't want dupes.
|
|
while( l >= 0 ) {
|
|
if( _.breakpoints[l] && _.breakpoints[l] === currentBreakpoint ) {
|
|
_.breakpoints.splice(l,1);
|
|
}
|
|
l--;
|
|
}
|
|
|
|
_.breakpoints.push(currentBreakpoint);
|
|
_.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_.breakpoints.sort(function(a, b) {
|
|
return ( _.options.mobileFirst ) ? a-b : b-a;
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.reinit = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.$slides =
|
|
_.$slideTrack
|
|
.children(_.options.slide)
|
|
.addClass('slick-slide');
|
|
|
|
_.slideCount = _.$slides.length;
|
|
|
|
if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
|
|
_.currentSlide = _.currentSlide - _.options.slidesToScroll;
|
|
}
|
|
|
|
if (_.slideCount <= _.options.slidesToShow) {
|
|
_.currentSlide = 0;
|
|
}
|
|
|
|
_.registerBreakpoints();
|
|
|
|
_.setProps();
|
|
_.setupInfinite();
|
|
_.buildArrows();
|
|
_.updateArrows();
|
|
_.initArrowEvents();
|
|
_.buildDots();
|
|
_.updateDots();
|
|
_.initDotEvents();
|
|
_.cleanUpSlideEvents();
|
|
_.initSlideEvents();
|
|
|
|
_.checkResponsive(false, true);
|
|
|
|
if (_.options.focusOnSelect === true) {
|
|
$(_.$slideTrack).children().on('click.slick', _.selectHandler);
|
|
}
|
|
|
|
_.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
|
|
|
|
_.setPosition();
|
|
_.focusHandler();
|
|
|
|
_.paused = !_.options.autoplay;
|
|
_.autoPlay();
|
|
|
|
_.$slider.trigger('reInit', [_]);
|
|
|
|
};
|
|
|
|
Slick.prototype.resize = function() {
|
|
|
|
var _ = this;
|
|
|
|
if ($(window).width() !== _.windowWidth) {
|
|
clearTimeout(_.windowDelay);
|
|
_.windowDelay = window.setTimeout(function() {
|
|
_.windowWidth = $(window).width();
|
|
_.checkResponsive();
|
|
if( !_.unslicked ) { _.setPosition(); }
|
|
}, 50);
|
|
}
|
|
};
|
|
|
|
Slick.prototype.removeSlide = Slick.prototype.slickRemove = function(index, removeBefore, removeAll) {
|
|
|
|
var _ = this;
|
|
|
|
if (typeof(index) === 'boolean') {
|
|
removeBefore = index;
|
|
index = removeBefore === true ? 0 : _.slideCount - 1;
|
|
} else {
|
|
index = removeBefore === true ? --index : index;
|
|
}
|
|
|
|
if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
|
|
return false;
|
|
}
|
|
|
|
_.unload();
|
|
|
|
if (removeAll === true) {
|
|
_.$slideTrack.children().remove();
|
|
} else {
|
|
_.$slideTrack.children(this.options.slide).eq(index).remove();
|
|
}
|
|
|
|
_.$slides = _.$slideTrack.children(this.options.slide);
|
|
|
|
_.$slideTrack.children(this.options.slide).detach();
|
|
|
|
_.$slideTrack.append(_.$slides);
|
|
|
|
_.$slidesCache = _.$slides;
|
|
|
|
_.reinit();
|
|
|
|
};
|
|
|
|
Slick.prototype.setCSS = function(position) {
|
|
|
|
var _ = this,
|
|
positionProps = {},
|
|
x, y;
|
|
|
|
if (_.options.rtl === true) {
|
|
position = -position;
|
|
}
|
|
x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px';
|
|
y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px';
|
|
|
|
positionProps[_.positionProp] = position;
|
|
|
|
if (_.transformsEnabled === false) {
|
|
_.$slideTrack.css(positionProps);
|
|
} else {
|
|
positionProps = {};
|
|
if (_.cssTransitions === false) {
|
|
positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
|
|
_.$slideTrack.css(positionProps);
|
|
} else {
|
|
positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
|
|
_.$slideTrack.css(positionProps);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.setDimensions = function() {
|
|
|
|
var _ = this;
|
|
|
|
if (_.options.vertical === false) {
|
|
if (_.options.centerMode === true) {
|
|
_.$list.css({
|
|
padding: ('0px ' + _.options.centerPadding)
|
|
});
|
|
}
|
|
} else {
|
|
_.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
|
|
if (_.options.centerMode === true) {
|
|
_.$list.css({
|
|
padding: (_.options.centerPadding + ' 0px')
|
|
});
|
|
}
|
|
}
|
|
|
|
_.listWidth = _.$list.width();
|
|
_.listHeight = _.$list.height();
|
|
|
|
|
|
if (_.options.vertical === false && _.options.variableWidth === false) {
|
|
_.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
|
|
_.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
|
|
|
|
} else if (_.options.variableWidth === true) {
|
|
_.$slideTrack.width(5000 * _.slideCount);
|
|
} else {
|
|
_.slideWidth = Math.ceil(_.listWidth);
|
|
_.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length)));
|
|
}
|
|
|
|
var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
|
|
if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
|
|
|
|
};
|
|
|
|
Slick.prototype.setFade = function() {
|
|
|
|
var _ = this,
|
|
targetLeft;
|
|
|
|
_.$slides.each(function(index, element) {
|
|
targetLeft = (_.slideWidth * index) * -1;
|
|
if (_.options.rtl === true) {
|
|
$(element).css({
|
|
position: 'relative',
|
|
right: targetLeft,
|
|
top: 0,
|
|
zIndex: _.options.zIndex - 2,
|
|
opacity: 0
|
|
});
|
|
} else {
|
|
$(element).css({
|
|
position: 'relative',
|
|
left: targetLeft,
|
|
top: 0,
|
|
zIndex: _.options.zIndex - 2,
|
|
opacity: 0
|
|
});
|
|
}
|
|
});
|
|
|
|
_.$slides.eq(_.currentSlide).css({
|
|
zIndex: _.options.zIndex - 1,
|
|
opacity: 1
|
|
});
|
|
|
|
};
|
|
|
|
Slick.prototype.setHeight = function() {
|
|
|
|
var _ = this;
|
|
|
|
if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
|
|
var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
|
|
_.$list.css('height', targetHeight);
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.setOption =
|
|
Slick.prototype.slickSetOption = function() {
|
|
|
|
/**
|
|
* accepts arguments in format of:
|
|
*
|
|
* - for changing a single option's value:
|
|
* .slick("setOption", option, value, refresh )
|
|
*
|
|
* - for changing a set of responsive options:
|
|
* .slick("setOption", 'responsive', [{}, ...], refresh )
|
|
*
|
|
* - for updating multiple values at once (not responsive)
|
|
* .slick("setOption", { 'option': value, ... }, refresh )
|
|
*/
|
|
|
|
var _ = this, l, item, option, value, refresh = false, type;
|
|
|
|
if( $.type( arguments[0] ) === 'object' ) {
|
|
|
|
option = arguments[0];
|
|
refresh = arguments[1];
|
|
type = 'multiple';
|
|
|
|
} else if ( $.type( arguments[0] ) === 'string' ) {
|
|
|
|
option = arguments[0];
|
|
value = arguments[1];
|
|
refresh = arguments[2];
|
|
|
|
if ( arguments[0] === 'responsive' && $.type( arguments[1] ) === 'array' ) {
|
|
|
|
type = 'responsive';
|
|
|
|
} else if ( typeof arguments[1] !== 'undefined' ) {
|
|
|
|
type = 'single';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( type === 'single' ) {
|
|
|
|
_.options[option] = value;
|
|
|
|
|
|
} else if ( type === 'multiple' ) {
|
|
|
|
$.each( option , function( opt, val ) {
|
|
|
|
_.options[opt] = val;
|
|
|
|
});
|
|
|
|
|
|
} else if ( type === 'responsive' ) {
|
|
|
|
for ( item in value ) {
|
|
|
|
if( $.type( _.options.responsive ) !== 'array' ) {
|
|
|
|
_.options.responsive = [ value[item] ];
|
|
|
|
} else {
|
|
|
|
l = _.options.responsive.length-1;
|
|
|
|
// loop through the responsive object and splice out duplicates.
|
|
while( l >= 0 ) {
|
|
|
|
if( _.options.responsive[l].breakpoint === value[item].breakpoint ) {
|
|
|
|
_.options.responsive.splice(l,1);
|
|
|
|
}
|
|
|
|
l--;
|
|
|
|
}
|
|
|
|
_.options.responsive.push( value[item] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( refresh ) {
|
|
|
|
_.unload();
|
|
_.reinit();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.setPosition = function() {
|
|
|
|
var _ = this;
|
|
|
|
_.setDimensions();
|
|
|
|
_.setHeight();
|
|
|
|
if (_.options.fade === false) {
|
|
_.setCSS(_.getLeft(_.currentSlide));
|
|
} else {
|
|
_.setFade();
|
|
}
|
|
|
|
_.$slider.trigger('setPosition', [_]);
|
|
|
|
};
|
|
|
|
Slick.prototype.setProps = function() {
|
|
|
|
var _ = this,
|
|
bodyStyle = document.body.style;
|
|
|
|
_.positionProp = _.options.vertical === true ? 'top' : 'left';
|
|
|
|
if (_.positionProp === 'top') {
|
|
_.$slider.addClass('slick-vertical');
|
|
} else {
|
|
_.$slider.removeClass('slick-vertical');
|
|
}
|
|
|
|
if (bodyStyle.WebkitTransition !== undefined ||
|
|
bodyStyle.MozTransition !== undefined ||
|
|
bodyStyle.msTransition !== undefined) {
|
|
if (_.options.useCSS === true) {
|
|
_.cssTransitions = true;
|
|
}
|
|
}
|
|
|
|
if ( _.options.fade ) {
|
|
if ( typeof _.options.zIndex === 'number' ) {
|
|
if( _.options.zIndex < 3 ) {
|
|
_.options.zIndex = 3;
|
|
}
|
|
} else {
|
|
_.options.zIndex = _.defaults.zIndex;
|
|
}
|
|
}
|
|
|
|
if (bodyStyle.OTransform !== undefined) {
|
|
_.animType = 'OTransform';
|
|
_.transformType = '-o-transform';
|
|
_.transitionType = 'OTransition';
|
|
if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
|
|
}
|
|
if (bodyStyle.MozTransform !== undefined) {
|
|
_.animType = 'MozTransform';
|
|
_.transformType = '-moz-transform';
|
|
_.transitionType = 'MozTransition';
|
|
if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
|
|
}
|
|
if (bodyStyle.webkitTransform !== undefined) {
|
|
_.animType = 'webkitTransform';
|
|
_.transformType = '-webkit-transform';
|
|
_.transitionType = 'webkitTransition';
|
|
if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
|
|
}
|
|
if (bodyStyle.msTransform !== undefined) {
|
|
_.animType = 'msTransform';
|
|
_.transformType = '-ms-transform';
|
|
_.transitionType = 'msTransition';
|
|
if (bodyStyle.msTransform === undefined) _.animType = false;
|
|
}
|
|
if (bodyStyle.transform !== undefined && _.animType !== false) {
|
|
_.animType = 'transform';
|
|
_.transformType = 'transform';
|
|
_.transitionType = 'transition';
|
|
}
|
|
_.transformsEnabled = _.options.useTransform && (_.animType !== null && _.animType !== false);
|
|
};
|
|
|
|
|
|
Slick.prototype.setSlideClasses = function(index) {
|
|
|
|
var _ = this,
|
|
centerOffset, allSlides, indexOffset, remainder;
|
|
|
|
allSlides = _.$slider
|
|
.find('.slick-slide')
|
|
.removeClass('slick-active slick-center slick-current')
|
|
.attr('aria-hidden', 'true');
|
|
|
|
_.$slides
|
|
.eq(index)
|
|
.addClass('slick-current');
|
|
|
|
if (_.options.centerMode === true) {
|
|
|
|
var evenCoef = _.options.slidesToShow % 2 === 0 ? 1 : 0;
|
|
|
|
centerOffset = Math.floor(_.options.slidesToShow / 2);
|
|
|
|
if (_.options.infinite === true) {
|
|
|
|
if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) {
|
|
_.$slides
|
|
.slice(index - centerOffset + evenCoef, index + centerOffset + 1)
|
|
.addClass('slick-active')
|
|
.attr('aria-hidden', 'false');
|
|
|
|
} else {
|
|
|
|
indexOffset = _.options.slidesToShow + index;
|
|
allSlides
|
|
.slice(indexOffset - centerOffset + 1 + evenCoef, indexOffset + centerOffset + 2)
|
|
.addClass('slick-active')
|
|
.attr('aria-hidden', 'false');
|
|
|
|
}
|
|
|
|
if (index === 0) {
|
|
|
|
allSlides
|
|
.eq(allSlides.length - 1 - _.options.slidesToShow)
|
|
.addClass('slick-center');
|
|
|
|
} else if (index === _.slideCount - 1) {
|
|
|
|
allSlides
|
|
.eq(_.options.slidesToShow)
|
|
.addClass('slick-center');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_.$slides
|
|
.eq(index)
|
|
.addClass('slick-center');
|
|
|
|
} else {
|
|
|
|
if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) {
|
|
|
|
_.$slides
|
|
.slice(index, index + _.options.slidesToShow)
|
|
.addClass('slick-active')
|
|
.attr('aria-hidden', 'false');
|
|
|
|
} else if (allSlides.length <= _.options.slidesToShow) {
|
|
|
|
allSlides
|
|
.addClass('slick-active')
|
|
.attr('aria-hidden', 'false');
|
|
|
|
} else {
|
|
|
|
remainder = _.slideCount % _.options.slidesToShow;
|
|
indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;
|
|
|
|
if (_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) {
|
|
|
|
allSlides
|
|
.slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder)
|
|
.addClass('slick-active')
|
|
.attr('aria-hidden', 'false');
|
|
|
|
} else {
|
|
|
|
allSlides
|
|
.slice(indexOffset, indexOffset + _.options.slidesToShow)
|
|
.addClass('slick-active')
|
|
.attr('aria-hidden', 'false');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (_.options.lazyLoad === 'ondemand' || _.options.lazyLoad === 'anticipated') {
|
|
_.lazyLoad();
|
|
}
|
|
};
|
|
|
|
Slick.prototype.setupInfinite = function() {
|
|
|
|
var _ = this,
|
|
i, slideIndex, infiniteCount;
|
|
|
|
if (_.options.fade === true) {
|
|
_.options.centerMode = false;
|
|
}
|
|
|
|
if (_.options.infinite === true && _.options.fade === false) {
|
|
|
|
slideIndex = null;
|
|
|
|
if (_.slideCount > _.options.slidesToShow) {
|
|
|
|
if (_.options.centerMode === true) {
|
|
infiniteCount = _.options.slidesToShow + 1;
|
|
} else {
|
|
infiniteCount = _.options.slidesToShow;
|
|
}
|
|
|
|
for (i = _.slideCount; i > (_.slideCount -
|
|
infiniteCount); i -= 1) {
|
|
slideIndex = i - 1;
|
|
$(_.$slides[slideIndex]).clone(true).attr('id', '')
|
|
.attr('data-slick-index', slideIndex - _.slideCount)
|
|
.prependTo(_.$slideTrack).addClass('slick-cloned');
|
|
}
|
|
for (i = 0; i < infiniteCount + _.slideCount; i += 1) {
|
|
slideIndex = i;
|
|
$(_.$slides[slideIndex]).clone(true).attr('id', '')
|
|
.attr('data-slick-index', slideIndex + _.slideCount)
|
|
.appendTo(_.$slideTrack).addClass('slick-cloned');
|
|
}
|
|
_.$slideTrack.find('.slick-cloned').find('[id]').each(function() {
|
|
$(this).attr('id', '');
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.interrupt = function( toggle ) {
|
|
|
|
var _ = this;
|
|
|
|
if( !toggle ) {
|
|
_.autoPlay();
|
|
}
|
|
_.interrupted = toggle;
|
|
|
|
};
|
|
|
|
Slick.prototype.selectHandler = function(event) {
|
|
|
|
var _ = this;
|
|
|
|
var targetElement =
|
|
$(event.target).is('.slick-slide') ?
|
|
$(event.target) :
|
|
$(event.target).parents('.slick-slide');
|
|
|
|
var index = parseInt(targetElement.attr('data-slick-index'));
|
|
|
|
if (!index) index = 0;
|
|
|
|
if (_.slideCount <= _.options.slidesToShow) {
|
|
|
|
_.slideHandler(index, false, true);
|
|
return;
|
|
|
|
}
|
|
|
|
_.slideHandler(index);
|
|
|
|
};
|
|
|
|
Slick.prototype.slideHandler = function(index, sync, dontAnimate) {
|
|
|
|
var targetSlide, animSlide, oldSlide, slideLeft, targetLeft = null,
|
|
_ = this, navTarget;
|
|
|
|
sync = sync || false;
|
|
|
|
if (_.animating === true && _.options.waitForAnimate === true) {
|
|
return;
|
|
}
|
|
|
|
if (_.options.fade === true && _.currentSlide === index) {
|
|
return;
|
|
}
|
|
|
|
if (sync === false) {
|
|
_.asNavFor(index);
|
|
}
|
|
|
|
targetSlide = index;
|
|
targetLeft = _.getLeft(targetSlide);
|
|
slideLeft = _.getLeft(_.currentSlide);
|
|
|
|
_.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;
|
|
|
|
if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
|
|
if (_.options.fade === false) {
|
|
targetSlide = _.currentSlide;
|
|
if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
|
|
_.animateSlide(slideLeft, function() {
|
|
_.postSlide(targetSlide);
|
|
});
|
|
} else {
|
|
_.postSlide(targetSlide);
|
|
}
|
|
}
|
|
return;
|
|
} else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) {
|
|
if (_.options.fade === false) {
|
|
targetSlide = _.currentSlide;
|
|
if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
|
|
_.animateSlide(slideLeft, function() {
|
|
_.postSlide(targetSlide);
|
|
});
|
|
} else {
|
|
_.postSlide(targetSlide);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
if ( _.options.autoplay ) {
|
|
clearInterval(_.autoPlayTimer);
|
|
}
|
|
|
|
if (targetSlide < 0) {
|
|
if (_.slideCount % _.options.slidesToScroll !== 0) {
|
|
animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll);
|
|
} else {
|
|
animSlide = _.slideCount + targetSlide;
|
|
}
|
|
} else if (targetSlide >= _.slideCount) {
|
|
if (_.slideCount % _.options.slidesToScroll !== 0) {
|
|
animSlide = 0;
|
|
} else {
|
|
animSlide = targetSlide - _.slideCount;
|
|
}
|
|
} else {
|
|
animSlide = targetSlide;
|
|
}
|
|
|
|
_.animating = true;
|
|
|
|
_.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]);
|
|
|
|
oldSlide = _.currentSlide;
|
|
_.currentSlide = animSlide;
|
|
|
|
_.setSlideClasses(_.currentSlide);
|
|
|
|
if ( _.options.asNavFor ) {
|
|
|
|
navTarget = _.getNavTarget();
|
|
navTarget = navTarget.slick('getSlick');
|
|
|
|
if ( navTarget.slideCount <= navTarget.options.slidesToShow ) {
|
|
navTarget.setSlideClasses(_.currentSlide);
|
|
}
|
|
|
|
}
|
|
|
|
_.updateDots();
|
|
_.updateArrows();
|
|
|
|
if (_.options.fade === true) {
|
|
if (dontAnimate !== true) {
|
|
|
|
_.fadeSlideOut(oldSlide);
|
|
|
|
_.fadeSlide(animSlide, function() {
|
|
_.postSlide(animSlide);
|
|
});
|
|
|
|
} else {
|
|
_.postSlide(animSlide);
|
|
}
|
|
_.animateHeight();
|
|
return;
|
|
}
|
|
|
|
if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) {
|
|
_.animateSlide(targetLeft, function() {
|
|
_.postSlide(animSlide);
|
|
});
|
|
} else {
|
|
_.postSlide(animSlide);
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.startLoad = function() {
|
|
|
|
var _ = this;
|
|
|
|
if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
|
|
|
|
_.$prevArrow.hide();
|
|
_.$nextArrow.hide();
|
|
|
|
}
|
|
|
|
if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
|
|
|
|
_.$dots.hide();
|
|
|
|
}
|
|
|
|
_.$slider.addClass('slick-loading');
|
|
|
|
};
|
|
|
|
Slick.prototype.swipeDirection = function() {
|
|
|
|
var xDist, yDist, r, swipeAngle, _ = this;
|
|
|
|
xDist = _.touchObject.startX - _.touchObject.curX;
|
|
yDist = _.touchObject.startY - _.touchObject.curY;
|
|
r = Math.atan2(yDist, xDist);
|
|
|
|
swipeAngle = Math.round(r * 180 / Math.PI);
|
|
if (swipeAngle < 0) {
|
|
swipeAngle = 360 - Math.abs(swipeAngle);
|
|
}
|
|
|
|
if ((swipeAngle <= 45) && (swipeAngle >= 0)) {
|
|
return (_.options.rtl === false ? 'left' : 'right');
|
|
}
|
|
if ((swipeAngle <= 360) && (swipeAngle >= 315)) {
|
|
return (_.options.rtl === false ? 'left' : 'right');
|
|
}
|
|
if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
|
|
return (_.options.rtl === false ? 'right' : 'left');
|
|
}
|
|
if (_.options.verticalSwiping === true) {
|
|
if ((swipeAngle >= 35) && (swipeAngle <= 135)) {
|
|
return 'down';
|
|
} else {
|
|
return 'up';
|
|
}
|
|
}
|
|
|
|
return 'vertical';
|
|
|
|
};
|
|
|
|
Slick.prototype.swipeEnd = function(event) {
|
|
|
|
var _ = this,
|
|
slideCount,
|
|
direction;
|
|
|
|
_.dragging = false;
|
|
_.swiping = false;
|
|
|
|
if (_.scrolling) {
|
|
_.scrolling = false;
|
|
return false;
|
|
}
|
|
|
|
_.interrupted = false;
|
|
_.shouldClick = ( _.touchObject.swipeLength > 10 ) ? false : true;
|
|
|
|
if ( _.touchObject.curX === undefined ) {
|
|
return false;
|
|
}
|
|
|
|
if ( _.touchObject.edgeHit === true ) {
|
|
_.$slider.trigger('edge', [_, _.swipeDirection() ]);
|
|
}
|
|
|
|
if ( _.touchObject.swipeLength >= _.touchObject.minSwipe ) {
|
|
|
|
direction = _.swipeDirection();
|
|
|
|
switch ( direction ) {
|
|
|
|
case 'left':
|
|
case 'down':
|
|
|
|
slideCount =
|
|
_.options.swipeToSlide ?
|
|
_.checkNavigable( _.currentSlide + _.getSlideCount() ) :
|
|
_.currentSlide + _.getSlideCount();
|
|
|
|
_.currentDirection = 0;
|
|
|
|
break;
|
|
|
|
case 'right':
|
|
case 'up':
|
|
|
|
slideCount =
|
|
_.options.swipeToSlide ?
|
|
_.checkNavigable( _.currentSlide - _.getSlideCount() ) :
|
|
_.currentSlide - _.getSlideCount();
|
|
|
|
_.currentDirection = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
|
|
}
|
|
|
|
if( direction != 'vertical' ) {
|
|
|
|
_.slideHandler( slideCount );
|
|
_.touchObject = {};
|
|
_.$slider.trigger('swipe', [_, direction ]);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( _.touchObject.startX !== _.touchObject.curX ) {
|
|
|
|
_.slideHandler( _.currentSlide );
|
|
_.touchObject = {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.swipeHandler = function(event) {
|
|
|
|
var _ = this;
|
|
|
|
if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) {
|
|
return;
|
|
} else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
|
|
return;
|
|
}
|
|
|
|
_.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ?
|
|
event.originalEvent.touches.length : 1;
|
|
|
|
_.touchObject.minSwipe = _.listWidth / _.options
|
|
.touchThreshold;
|
|
|
|
if (_.options.verticalSwiping === true) {
|
|
_.touchObject.minSwipe = _.listHeight / _.options
|
|
.touchThreshold;
|
|
}
|
|
|
|
switch (event.data.action) {
|
|
|
|
case 'start':
|
|
_.swipeStart(event);
|
|
break;
|
|
|
|
case 'move':
|
|
_.swipeMove(event);
|
|
break;
|
|
|
|
case 'end':
|
|
_.swipeEnd(event);
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.swipeMove = function(event) {
|
|
|
|
var _ = this,
|
|
edgeWasHit = false,
|
|
curLeft, swipeDirection, swipeLength, positionOffset, touches, verticalSwipeLength;
|
|
|
|
touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;
|
|
|
|
if (!_.dragging || _.scrolling || touches && touches.length !== 1) {
|
|
return false;
|
|
}
|
|
|
|
curLeft = _.getLeft(_.currentSlide);
|
|
|
|
_.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
|
|
_.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;
|
|
|
|
_.touchObject.swipeLength = Math.round(Math.sqrt(
|
|
Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));
|
|
|
|
verticalSwipeLength = Math.round(Math.sqrt(
|
|
Math.pow(_.touchObject.curY - _.touchObject.startY, 2)));
|
|
|
|
if (!_.options.verticalSwiping && !_.swiping && verticalSwipeLength > 4) {
|
|
_.scrolling = true;
|
|
return false;
|
|
}
|
|
|
|
if (_.options.verticalSwiping === true) {
|
|
_.touchObject.swipeLength = verticalSwipeLength;
|
|
}
|
|
|
|
swipeDirection = _.swipeDirection();
|
|
|
|
if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
|
|
_.swiping = true;
|
|
event.preventDefault();
|
|
}
|
|
|
|
positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
|
|
if (_.options.verticalSwiping === true) {
|
|
positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1;
|
|
}
|
|
|
|
|
|
swipeLength = _.touchObject.swipeLength;
|
|
|
|
_.touchObject.edgeHit = false;
|
|
|
|
if (_.options.infinite === false) {
|
|
if ((_.currentSlide === 0 && swipeDirection === 'right') || (_.currentSlide >= _.getDotCount() && swipeDirection === 'left')) {
|
|
swipeLength = _.touchObject.swipeLength * _.options.edgeFriction;
|
|
_.touchObject.edgeHit = true;
|
|
}
|
|
}
|
|
|
|
if (_.options.vertical === false) {
|
|
_.swipeLeft = curLeft + swipeLength * positionOffset;
|
|
} else {
|
|
_.swipeLeft = curLeft + (swipeLength * (_.$list.height() / _.listWidth)) * positionOffset;
|
|
}
|
|
if (_.options.verticalSwiping === true) {
|
|
_.swipeLeft = curLeft + swipeLength * positionOffset;
|
|
}
|
|
|
|
if (_.options.fade === true || _.options.touchMove === false) {
|
|
return false;
|
|
}
|
|
|
|
if (_.animating === true) {
|
|
_.swipeLeft = null;
|
|
return false;
|
|
}
|
|
|
|
_.setCSS(_.swipeLeft);
|
|
|
|
};
|
|
|
|
Slick.prototype.swipeStart = function(event) {
|
|
|
|
var _ = this,
|
|
touches;
|
|
|
|
_.interrupted = true;
|
|
|
|
if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
|
|
_.touchObject = {};
|
|
return false;
|
|
}
|
|
|
|
if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
|
|
touches = event.originalEvent.touches[0];
|
|
}
|
|
|
|
_.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
|
|
_.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;
|
|
|
|
_.dragging = true;
|
|
|
|
};
|
|
|
|
Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function() {
|
|
|
|
var _ = this;
|
|
|
|
if (_.$slidesCache !== null) {
|
|
|
|
_.unload();
|
|
|
|
_.$slideTrack.children(this.options.slide).detach();
|
|
|
|
_.$slidesCache.appendTo(_.$slideTrack);
|
|
|
|
_.reinit();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.unload = function() {
|
|
|
|
var _ = this;
|
|
|
|
$('.slick-cloned', _.$slider).remove();
|
|
|
|
if (_.$dots) {
|
|
_.$dots.remove();
|
|
}
|
|
|
|
if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) {
|
|
_.$prevArrow.remove();
|
|
}
|
|
|
|
if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) {
|
|
_.$nextArrow.remove();
|
|
}
|
|
|
|
_.$slides
|
|
.removeClass('slick-slide slick-active slick-visible slick-current')
|
|
.attr('aria-hidden', 'true')
|
|
.css('width', '');
|
|
|
|
};
|
|
|
|
Slick.prototype.unslick = function(fromBreakpoint) {
|
|
|
|
var _ = this;
|
|
_.$slider.trigger('unslick', [_, fromBreakpoint]);
|
|
_.destroy();
|
|
|
|
};
|
|
|
|
Slick.prototype.updateArrows = function() {
|
|
|
|
var _ = this,
|
|
centerOffset;
|
|
|
|
centerOffset = Math.floor(_.options.slidesToShow / 2);
|
|
|
|
if ( _.options.arrows === true &&
|
|
_.slideCount > _.options.slidesToShow &&
|
|
!_.options.infinite ) {
|
|
|
|
_.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
|
|
_.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
|
|
|
|
if (_.currentSlide === 0) {
|
|
|
|
_.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
|
|
_.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
|
|
|
|
} else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {
|
|
|
|
_.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
|
|
_.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
|
|
|
|
} else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) {
|
|
|
|
_.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
|
|
_.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.updateDots = function() {
|
|
|
|
var _ = this;
|
|
|
|
if (_.$dots !== null) {
|
|
|
|
_.$dots
|
|
.find('li')
|
|
.removeClass('slick-active')
|
|
.end();
|
|
|
|
_.$dots
|
|
.find('li')
|
|
.eq(Math.floor(_.currentSlide / _.options.slidesToScroll))
|
|
.addClass('slick-active');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Slick.prototype.visibility = function() {
|
|
|
|
var _ = this;
|
|
|
|
if ( _.options.autoplay ) {
|
|
|
|
if ( document[_.hidden] ) {
|
|
|
|
_.interrupted = true;
|
|
|
|
} else {
|
|
|
|
_.interrupted = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
$.fn.slick = function() {
|
|
var _ = this,
|
|
opt = arguments[0],
|
|
args = Array.prototype.slice.call(arguments, 1),
|
|
l = _.length,
|
|
i,
|
|
ret;
|
|
for (i = 0; i < l; i++) {
|
|
if (typeof opt == 'object' || typeof opt == 'undefined')
|
|
_[i].slick = new Slick(_[i], opt);
|
|
else
|
|
ret = _[i].slick[opt].apply(_[i].slick, args);
|
|
if (typeof ret != 'undefined') return ret;
|
|
}
|
|
return _;
|
|
};
|
|
|
|
}));
|
|
|
|
/*! Magnific Popup - v1.1.0 - 2016-02-20
|
|
* http://dimsemenov.com/plugins/magnific-popup/
|
|
* Copyright (c) 2016 Dmitry Semenov; */
|
|
;(function (factory) {
|
|
if (typeof define === 'function' && define.amd) {
|
|
// AMD. Register as an anonymous module.
|
|
define(['jquery'], factory);
|
|
} else if (typeof exports === 'object') {
|
|
// Node/CommonJS
|
|
factory(require('jquery'));
|
|
} else {
|
|
// Browser globals
|
|
factory(window.jQuery || window.Zepto);
|
|
}
|
|
}(function($) {
|
|
|
|
/*>>core*/
|
|
/**
|
|
*
|
|
* Magnific Popup Core JS file
|
|
*
|
|
*/
|
|
|
|
|
|
/**
|
|
* Private static constants
|
|
*/
|
|
var CLOSE_EVENT = 'Close',
|
|
BEFORE_CLOSE_EVENT = 'BeforeClose',
|
|
AFTER_CLOSE_EVENT = 'AfterClose',
|
|
BEFORE_APPEND_EVENT = 'BeforeAppend',
|
|
MARKUP_PARSE_EVENT = 'MarkupParse',
|
|
OPEN_EVENT = 'Open',
|
|
CHANGE_EVENT = 'Change',
|
|
NS = 'mfp',
|
|
EVENT_NS = '.' + NS,
|
|
READY_CLASS = 'mfp-ready',
|
|
REMOVING_CLASS = 'mfp-removing',
|
|
PREVENT_CLOSE_CLASS = 'mfp-prevent-close';
|
|
|
|
|
|
/**
|
|
* Private vars
|
|
*/
|
|
/*jshint -W079 */
|
|
var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this'
|
|
MagnificPopup = function(){},
|
|
_isJQ = !!(window.jQuery),
|
|
_prevStatus,
|
|
_window = $(window),
|
|
_document,
|
|
_prevContentType,
|
|
_wrapClasses,
|
|
_currPopupType;
|
|
|
|
|
|
/**
|
|
* Private functions
|
|
*/
|
|
var _mfpOn = function(name, f) {
|
|
mfp.ev.on(NS + name + EVENT_NS, f);
|
|
},
|
|
_getEl = function(className, appendTo, html, raw) {
|
|
var el = document.createElement('div');
|
|
el.className = 'mfp-'+className;
|
|
if(html) {
|
|
el.innerHTML = html;
|
|
}
|
|
if(!raw) {
|
|
el = $(el);
|
|
if(appendTo) {
|
|
el.appendTo(appendTo);
|
|
}
|
|
} else if(appendTo) {
|
|
appendTo.appendChild(el);
|
|
}
|
|
return el;
|
|
},
|
|
_mfpTrigger = function(e, data) {
|
|
mfp.ev.triggerHandler(NS + e, data);
|
|
|
|
if(mfp.st.callbacks) {
|
|
// converts "mfpEventName" to "eventName" callback and triggers it if it's present
|
|
e = e.charAt(0).toLowerCase() + e.slice(1);
|
|
if(mfp.st.callbacks[e]) {
|
|
mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]);
|
|
}
|
|
}
|
|
},
|
|
_getCloseBtn = function(type) {
|
|
if(type !== _currPopupType || !mfp.currTemplate.closeBtn) {
|
|
mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) );
|
|
_currPopupType = type;
|
|
}
|
|
return mfp.currTemplate.closeBtn;
|
|
},
|
|
// Initialize Magnific Popup only when called at least once
|
|
_checkInstance = function() {
|
|
if(!$.magnificPopup.instance) {
|
|
/*jshint -W020 */
|
|
mfp = new MagnificPopup();
|
|
mfp.init();
|
|
$.magnificPopup.instance = mfp;
|
|
}
|
|
},
|
|
// CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr
|
|
supportsTransitions = function() {
|
|
var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist
|
|
v = ['ms','O','Moz','Webkit']; // 'v' for vendor
|
|
|
|
if( s['transition'] !== undefined ) {
|
|
return true;
|
|
}
|
|
|
|
while( v.length ) {
|
|
if( v.pop() + 'Transition' in s ) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
* Public functions
|
|
*/
|
|
MagnificPopup.prototype = {
|
|
|
|
constructor: MagnificPopup,
|
|
|
|
/**
|
|
* Initializes Magnific Popup plugin.
|
|
* This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed
|
|
*/
|
|
init: function() {
|
|
var appVersion = navigator.appVersion;
|
|
mfp.isLowIE = mfp.isIE8 = document.all && !document.addEventListener;
|
|
mfp.isAndroid = (/android/gi).test(appVersion);
|
|
mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);
|
|
mfp.supportsTransition = supportsTransitions();
|
|
|
|
// We disable fixed positioned lightbox on devices that don't handle it nicely.
|
|
// If you know a better way of detecting this - let me know.
|
|
mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) );
|
|
_document = $(document);
|
|
|
|
mfp.popupsCache = {};
|
|
},
|
|
|
|
/**
|
|
* Opens popup
|
|
* @param data [description]
|
|
*/
|
|
open: function(data) {
|
|
|
|
var i;
|
|
|
|
if(data.isObj === false) {
|
|
// convert jQuery collection to array to avoid conflicts later
|
|
mfp.items = data.items.toArray();
|
|
|
|
mfp.index = 0;
|
|
var items = data.items,
|
|
item;
|
|
for(i = 0; i < items.length; i++) {
|
|
item = items[i];
|
|
if(item.parsed) {
|
|
item = item.el[0];
|
|
}
|
|
if(item === data.el[0]) {
|
|
mfp.index = i;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
mfp.items = $.isArray(data.items) ? data.items : [data.items];
|
|
mfp.index = data.index || 0;
|
|
}
|
|
|
|
// if popup is already opened - we just update the content
|
|
if(mfp.isOpen) {
|
|
mfp.updateItemHTML();
|
|
return;
|
|
}
|
|
|
|
mfp.types = [];
|
|
_wrapClasses = '';
|
|
if(data.mainEl && data.mainEl.length) {
|
|
mfp.ev = data.mainEl.eq(0);
|
|
} else {
|
|
mfp.ev = _document;
|
|
}
|
|
|
|
if(data.key) {
|
|
if(!mfp.popupsCache[data.key]) {
|
|
mfp.popupsCache[data.key] = {};
|
|
}
|
|
mfp.currTemplate = mfp.popupsCache[data.key];
|
|
} else {
|
|
mfp.currTemplate = {};
|
|
}
|
|
|
|
|
|
|
|
mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data );
|
|
mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos;
|
|
|
|
if(mfp.st.modal) {
|
|
mfp.st.closeOnContentClick = false;
|
|
mfp.st.closeOnBgClick = false;
|
|
mfp.st.showCloseBtn = false;
|
|
mfp.st.enableEscapeKey = false;
|
|
}
|
|
|
|
|
|
// Building markup
|
|
// main containers are created only once
|
|
if(!mfp.bgOverlay) {
|
|
|
|
// Dark overlay
|
|
mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() {
|
|
mfp.close();
|
|
});
|
|
|
|
mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) {
|
|
if(mfp._checkIfClose(e.target)) {
|
|
mfp.close();
|
|
}
|
|
});
|
|
|
|
mfp.container = _getEl('container', mfp.wrap);
|
|
}
|
|
|
|
mfp.contentContainer = _getEl('content');
|
|
if(mfp.st.preloader) {
|
|
mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading);
|
|
}
|
|
|
|
|
|
// Initializing modules
|
|
var modules = $.magnificPopup.modules;
|
|
for(i = 0; i < modules.length; i++) {
|
|
var n = modules[i];
|
|
n = n.charAt(0).toUpperCase() + n.slice(1);
|
|
mfp['init'+n].call(mfp);
|
|
}
|
|
_mfpTrigger('BeforeOpen');
|
|
|
|
|
|
if(mfp.st.showCloseBtn) {
|
|
// Close button
|
|
if(!mfp.st.closeBtnInside) {
|
|
mfp.wrap.append( _getCloseBtn() );
|
|
} else {
|
|
_mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {
|
|
values.close_replaceWith = _getCloseBtn(item.type);
|
|
});
|
|
_wrapClasses += ' mfp-close-btn-in';
|
|
}
|
|
}
|
|
|
|
if(mfp.st.alignTop) {
|
|
_wrapClasses += ' mfp-align-top';
|
|
}
|
|
|
|
|
|
|
|
if(mfp.fixedContentPos) {
|
|
mfp.wrap.css({
|
|
overflow: mfp.st.overflowY,
|
|
overflowX: 'hidden',
|
|
overflowY: mfp.st.overflowY
|
|
});
|
|
} else {
|
|
mfp.wrap.css({
|
|
top: _window.scrollTop(),
|
|
position: 'absolute'
|
|
});
|
|
}
|
|
if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) {
|
|
mfp.bgOverlay.css({
|
|
height: _document.height(),
|
|
position: 'absolute'
|
|
});
|
|
}
|
|
|
|
|
|
|
|
if(mfp.st.enableEscapeKey) {
|
|
// Close on ESC key
|
|
_document.on('keyup' + EVENT_NS, function(e) {
|
|
if(e.keyCode === 27) {
|
|
mfp.close();
|
|
}
|
|
});
|
|
}
|
|
|
|
_window.on('resize' + EVENT_NS, function() {
|
|
mfp.updateSize();
|
|
});
|
|
|
|
|
|
if(!mfp.st.closeOnContentClick) {
|
|
_wrapClasses += ' mfp-auto-cursor';
|
|
}
|
|
|
|
if(_wrapClasses)
|
|
mfp.wrap.addClass(_wrapClasses);
|
|
|
|
|
|
// this triggers recalculation of layout, so we get it once to not to trigger twice
|
|
var windowHeight = mfp.wH = _window.height();
|
|
|
|
|
|
var windowStyles = {};
|
|
|
|
if( mfp.fixedContentPos ) {
|
|
if(mfp._hasScrollBar(windowHeight)){
|
|
var s = mfp._getScrollbarSize();
|
|
if(s) {
|
|
windowStyles.marginRight = s;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(mfp.fixedContentPos) {
|
|
if(!mfp.isIE7) {
|
|
windowStyles.overflow = 'hidden';
|
|
} else {
|
|
// ie7 double-scroll bug
|
|
$('body, html').css('overflow', 'hidden');
|
|
}
|
|
}
|
|
|
|
|
|
|
|
var classesToadd = mfp.st.mainClass;
|
|
if(mfp.isIE7) {
|
|
classesToadd += ' mfp-ie7';
|
|
}
|
|
if(classesToadd) {
|
|
mfp._addClassToMFP( classesToadd );
|
|
}
|
|
|
|
// add content
|
|
mfp.updateItemHTML();
|
|
|
|
_mfpTrigger('BuildControls');
|
|
|
|
// remove scrollbar, add margin e.t.c
|
|
$('html').css(windowStyles);
|
|
|
|
// add everything to DOM
|
|
mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) );
|
|
|
|
// Save last focused element
|
|
mfp._lastFocusedEl = document.activeElement;
|
|
|
|
// Wait for next cycle to allow CSS transition
|
|
setTimeout(function() {
|
|
|
|
if(mfp.content) {
|
|
mfp._addClassToMFP(READY_CLASS);
|
|
mfp._setFocus();
|
|
} else {
|
|
// if content is not defined (not loaded e.t.c) we add class only for BG
|
|
mfp.bgOverlay.addClass(READY_CLASS);
|
|
}
|
|
|
|
// Trap the focus in popup
|
|
_document.on('focusin' + EVENT_NS, mfp._onFocusIn);
|
|
|
|
}, 16);
|
|
|
|
mfp.isOpen = true;
|
|
mfp.updateSize(windowHeight);
|
|
_mfpTrigger(OPEN_EVENT);
|
|
|
|
return data;
|
|
},
|
|
|
|
/**
|
|
* Closes the popup
|
|
*/
|
|
close: function() {
|
|
if(!mfp.isOpen) return;
|
|
_mfpTrigger(BEFORE_CLOSE_EVENT);
|
|
|
|
mfp.isOpen = false;
|
|
// for CSS3 animation
|
|
if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition ) {
|
|
mfp._addClassToMFP(REMOVING_CLASS);
|
|
setTimeout(function() {
|
|
mfp._close();
|
|
}, mfp.st.removalDelay);
|
|
} else {
|
|
mfp._close();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Helper for close() function
|
|
*/
|
|
_close: function() {
|
|
_mfpTrigger(CLOSE_EVENT);
|
|
|
|
var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' ';
|
|
|
|
mfp.bgOverlay.detach();
|
|
mfp.wrap.detach();
|
|
mfp.container.empty();
|
|
|
|
if(mfp.st.mainClass) {
|
|
classesToRemove += mfp.st.mainClass + ' ';
|
|
}
|
|
|
|
mfp._removeClassFromMFP(classesToRemove);
|
|
|
|
if(mfp.fixedContentPos) {
|
|
var windowStyles = {marginRight: ''};
|
|
if(mfp.isIE7) {
|
|
$('body, html').css('overflow', '');
|
|
} else {
|
|
windowStyles.overflow = '';
|
|
}
|
|
$('html').css(windowStyles);
|
|
}
|
|
|
|
_document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS);
|
|
mfp.ev.off(EVENT_NS);
|
|
|
|
// clean up DOM elements that aren't removed
|
|
mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style');
|
|
mfp.bgOverlay.attr('class', 'mfp-bg');
|
|
mfp.container.attr('class', 'mfp-container');
|
|
|
|
// remove close button from target element
|
|
if(mfp.st.showCloseBtn &&
|
|
(!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) {
|
|
if(mfp.currTemplate.closeBtn)
|
|
mfp.currTemplate.closeBtn.detach();
|
|
}
|
|
|
|
|
|
if(mfp.st.autoFocusLast && mfp._lastFocusedEl) {
|
|
$(mfp._lastFocusedEl).focus(); // put tab focus back
|
|
}
|
|
mfp.currItem = null;
|
|
mfp.content = null;
|
|
mfp.currTemplate = null;
|
|
mfp.prevHeight = 0;
|
|
|
|
_mfpTrigger(AFTER_CLOSE_EVENT);
|
|
},
|
|
|
|
updateSize: function(winHeight) {
|
|
|
|
if(mfp.isIOS) {
|
|
// fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2
|
|
var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
|
|
var height = window.innerHeight * zoomLevel;
|
|
mfp.wrap.css('height', height);
|
|
mfp.wH = height;
|
|
} else {
|
|
mfp.wH = winHeight || _window.height();
|
|
}
|
|
// Fixes #84: popup incorrectly positioned with position:relative on body
|
|
if(!mfp.fixedContentPos) {
|
|
mfp.wrap.css('height', mfp.wH);
|
|
}
|
|
|
|
_mfpTrigger('Resize');
|
|
|
|
},
|
|
|
|
/**
|
|
* Set content of popup based on current index
|
|
*/
|
|
updateItemHTML: function() {
|
|
var item = mfp.items[mfp.index];
|
|
|
|
// Detach and perform modifications
|
|
mfp.contentContainer.detach();
|
|
|
|
if(mfp.content)
|
|
mfp.content.detach();
|
|
|
|
if(!item.parsed) {
|
|
item = mfp.parseEl( mfp.index );
|
|
}
|
|
|
|
var type = item.type;
|
|
|
|
_mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);
|
|
// BeforeChange event works like so:
|
|
// _mfpOn('BeforeChange', function(e, prevType, newType) { });
|
|
|
|
mfp.currItem = item;
|
|
|
|
if(!mfp.currTemplate[type]) {
|
|
var markup = mfp.st[type] ? mfp.st[type].markup : false;
|
|
|
|
// allows to modify markup
|
|
_mfpTrigger('FirstMarkupParse', markup);
|
|
|
|
if(markup) {
|
|
mfp.currTemplate[type] = $(markup);
|
|
} else {
|
|
// if there is no markup found we just define that template is parsed
|
|
mfp.currTemplate[type] = true;
|
|
}
|
|
}
|
|
|
|
if(_prevContentType && _prevContentType !== item.type) {
|
|
mfp.container.removeClass('mfp-'+_prevContentType+'-holder');
|
|
}
|
|
|
|
var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);
|
|
mfp.appendContent(newContent, type);
|
|
|
|
item.preloaded = true;
|
|
|
|
_mfpTrigger(CHANGE_EVENT, item);
|
|
_prevContentType = item.type;
|
|
|
|
// Append container back after its content changed
|
|
mfp.container.prepend(mfp.contentContainer);
|
|
|
|
_mfpTrigger('AfterChange');
|
|
},
|
|
|
|
|
|
/**
|
|
* Set HTML content of popup
|
|
*/
|
|
appendContent: function(newContent, type) {
|
|
mfp.content = newContent;
|
|
|
|
if(newContent) {
|
|
if(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&
|
|
mfp.currTemplate[type] === true) {
|
|
// if there is no markup, we just append close button element inside
|
|
if(!mfp.content.find('.mfp-close').length) {
|
|
mfp.content.append(_getCloseBtn());
|
|
}
|
|
} else {
|
|
mfp.content = newContent;
|
|
}
|
|
} else {
|
|
mfp.content = '';
|
|
}
|
|
|
|
_mfpTrigger(BEFORE_APPEND_EVENT);
|
|
mfp.container.addClass('mfp-'+type+'-holder');
|
|
|
|
mfp.contentContainer.append(mfp.content);
|
|
},
|
|
|
|
|
|
/**
|
|
* Creates Magnific Popup data object based on given data
|
|
* @param {int} index Index of item to parse
|
|
*/
|
|
parseEl: function(index) {
|
|
var item = mfp.items[index],
|
|
type;
|
|
|
|
if(item.tagName) {
|
|
item = { el: $(item) };
|
|
} else {
|
|
type = item.type;
|
|
item = { data: item, src: item.src };
|
|
}
|
|
|
|
if(item.el) {
|
|
var types = mfp.types;
|
|
|
|
// check for 'mfp-TYPE' class
|
|
for(var i = 0; i < types.length; i++) {
|
|
if( item.el.hasClass('mfp-'+types[i]) ) {
|
|
type = types[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
item.src = item.el.attr('data-mfp-src');
|
|
if(!item.src) {
|
|
item.src = item.el.attr('href');
|
|
}
|
|
}
|
|
|
|
item.type = type || mfp.st.type || 'inline';
|
|
item.index = index;
|
|
item.parsed = true;
|
|
mfp.items[index] = item;
|
|
_mfpTrigger('ElementParse', item);
|
|
|
|
return mfp.items[index];
|
|
},
|
|
|
|
|
|
/**
|
|
* Initializes single popup or a group of popups
|
|
*/
|
|
addGroup: function(el, options) {
|
|
var eHandler = function(e) {
|
|
e.mfpEl = this;
|
|
mfp._openClick(e, el, options);
|
|
};
|
|
|
|
if(!options) {
|
|
options = {};
|
|
}
|
|
|
|
var eName = 'click.magnificPopup';
|
|
options.mainEl = el;
|
|
|
|
if(options.items) {
|
|
options.isObj = true;
|
|
el.off(eName).on(eName, eHandler);
|
|
} else {
|
|
options.isObj = false;
|
|
if(options.delegate) {
|
|
el.off(eName).on(eName, options.delegate , eHandler);
|
|
} else {
|
|
options.items = el;
|
|
el.off(eName).on(eName, eHandler);
|
|
}
|
|
}
|
|
},
|
|
_openClick: function(e, el, options) {
|
|
var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick;
|
|
|
|
|
|
if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) {
|
|
return;
|
|
}
|
|
|
|
var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn;
|
|
|
|
if(disableOn) {
|
|
if($.isFunction(disableOn)) {
|
|
if( !disableOn.call(mfp) ) {
|
|
return true;
|
|
}
|
|
} else { // else it's number
|
|
if( _window.width() < disableOn ) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(e.type) {
|
|
e.preventDefault();
|
|
|
|
// This will prevent popup from closing if element is inside and popup is already opened
|
|
if(mfp.isOpen) {
|
|
e.stopPropagation();
|
|
}
|
|
}
|
|
|
|
options.el = $(e.mfpEl);
|
|
if(options.delegate) {
|
|
options.items = el.find(options.delegate);
|
|
}
|
|
mfp.open(options);
|
|
},
|
|
|
|
|
|
/**
|
|
* Updates text on preloader
|
|
*/
|
|
updateStatus: function(status, text) {
|
|
|
|
if(mfp.preloader) {
|
|
if(_prevStatus !== status) {
|
|
mfp.container.removeClass('mfp-s-'+_prevStatus);
|
|
}
|
|
|
|
if(!text && status === 'loading') {
|
|
text = mfp.st.tLoading;
|
|
}
|
|
|
|
var data = {
|
|
status: status,
|
|
text: text
|
|
};
|
|
// allows to modify status
|
|
_mfpTrigger('UpdateStatus', data);
|
|
|
|
status = data.status;
|
|
text = data.text;
|
|
|
|
mfp.preloader.html(text);
|
|
|
|
mfp.preloader.find('a').on('click', function(e) {
|
|
e.stopImmediatePropagation();
|
|
});
|
|
|
|
mfp.container.addClass('mfp-s-'+status);
|
|
_prevStatus = status;
|
|
}
|
|
},
|
|
|
|
|
|
/*
|
|
"Private" helpers that aren't private at all
|
|
*/
|
|
// Check to close popup or not
|
|
// "target" is an element that was clicked
|
|
_checkIfClose: function(target) {
|
|
|
|
if($(target).hasClass(PREVENT_CLOSE_CLASS)) {
|
|
return;
|
|
}
|
|
|
|
var closeOnContent = mfp.st.closeOnContentClick;
|
|
var closeOnBg = mfp.st.closeOnBgClick;
|
|
|
|
if(closeOnContent && closeOnBg) {
|
|
return true;
|
|
} else {
|
|
|
|
// We close the popup if click is on close button or on preloader. Or if there is no content.
|
|
if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) {
|
|
return true;
|
|
}
|
|
|
|
// if click is outside the content
|
|
if( (target !== mfp.content[0] && !$.contains(mfp.content[0], target)) ) {
|
|
if(closeOnBg) {
|
|
// last check, if the clicked element is in DOM, (in case it's removed onclick)
|
|
if( $.contains(document, target) ) {
|
|
return true;
|
|
}
|
|
}
|
|
} else if(closeOnContent) {
|
|
return true;
|
|
}
|
|
|
|
}
|
|
return false;
|
|
},
|
|
_addClassToMFP: function(cName) {
|
|
mfp.bgOverlay.addClass(cName);
|
|
mfp.wrap.addClass(cName);
|
|
},
|
|
_removeClassFromMFP: function(cName) {
|
|
this.bgOverlay.removeClass(cName);
|
|
mfp.wrap.removeClass(cName);
|
|
},
|
|
_hasScrollBar: function(winHeight) {
|
|
return ( (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) );
|
|
},
|
|
_setFocus: function() {
|
|
(mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();
|
|
},
|
|
_onFocusIn: function(e) {
|
|
if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {
|
|
mfp._setFocus();
|
|
return false;
|
|
}
|
|
},
|
|
_parseMarkup: function(template, values, item) {
|
|
var arr;
|
|
if(item.data) {
|
|
values = $.extend(item.data, values);
|
|
}
|
|
_mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );
|
|
|
|
$.each(values, function(key, value) {
|
|
if(value === undefined || value === false) {
|
|
return true;
|
|
}
|
|
arr = key.split('_');
|
|
if(arr.length > 1) {
|
|
var el = template.find(EVENT_NS + '-'+arr[0]);
|
|
|
|
if(el.length > 0) {
|
|
var attr = arr[1];
|
|
if(attr === 'replaceWith') {
|
|
if(el[0] !== value[0]) {
|
|
el.replaceWith(value);
|
|
}
|
|
} else if(attr === 'img') {
|
|
if(el.is('img')) {
|
|
el.attr('src', value);
|
|
} else {
|
|
el.replaceWith( $('<img>').attr('src', value).attr('class', el.attr('class')) );
|
|
}
|
|
} else {
|
|
el.attr(arr[1], value);
|
|
}
|
|
}
|
|
|
|
} else {
|
|
template.find(EVENT_NS + '-'+key).html(value);
|
|
}
|
|
});
|
|
},
|
|
|
|
_getScrollbarSize: function() {
|
|
// thx David
|
|
if(mfp.scrollbarSize === undefined) {
|
|
var scrollDiv = document.createElement("div");
|
|
scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
|
|
document.body.appendChild(scrollDiv);
|
|
mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
|
|
document.body.removeChild(scrollDiv);
|
|
}
|
|
return mfp.scrollbarSize;
|
|
}
|
|
|
|
}; /* MagnificPopup core prototype end */
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Public static functions
|
|
*/
|
|
$.magnificPopup = {
|
|
instance: null,
|
|
proto: MagnificPopup.prototype,
|
|
modules: [],
|
|
|
|
open: function(options, index) {
|
|
_checkInstance();
|
|
|
|
if(!options) {
|
|
options = {};
|
|
} else {
|
|
options = $.extend(true, {}, options);
|
|
}
|
|
|
|
options.isObj = true;
|
|
options.index = index || 0;
|
|
return this.instance.open(options);
|
|
},
|
|
|
|
close: function() {
|
|
return $.magnificPopup.instance && $.magnificPopup.instance.close();
|
|
},
|
|
|
|
registerModule: function(name, module) {
|
|
if(module.options) {
|
|
$.magnificPopup.defaults[name] = module.options;
|
|
}
|
|
$.extend(this.proto, module.proto);
|
|
this.modules.push(name);
|
|
},
|
|
|
|
defaults: {
|
|
|
|
// Info about options is in docs:
|
|
// http://dimsemenov.com/plugins/magnific-popup/documentation.html#options
|
|
|
|
disableOn: 0,
|
|
|
|
key: null,
|
|
|
|
midClick: false,
|
|
|
|
mainClass: '',
|
|
|
|
preloader: true,
|
|
|
|
focus: '', // CSS selector of input to focus after popup is opened
|
|
|
|
closeOnContentClick: false,
|
|
|
|
closeOnBgClick: true,
|
|
|
|
closeBtnInside: true,
|
|
|
|
showCloseBtn: true,
|
|
|
|
enableEscapeKey: true,
|
|
|
|
modal: false,
|
|
|
|
alignTop: false,
|
|
|
|
removalDelay: 0,
|
|
|
|
prependTo: null,
|
|
|
|
fixedContentPos: 'auto',
|
|
|
|
fixedBgPos: 'auto',
|
|
|
|
overflowY: 'auto',
|
|
|
|
closeMarkup: '<button title="%title%" type="button" class="mfp-close">×</button>',
|
|
|
|
tClose: 'Close (Esc)',
|
|
|
|
tLoading: 'Loading...',
|
|
|
|
autoFocusLast: true
|
|
|
|
}
|
|
};
|
|
|
|
|
|
|
|
$.fn.magnificPopup = function(options) {
|
|
_checkInstance();
|
|
|
|
var jqEl = $(this);
|
|
|
|
// We call some API method of first param is a string
|
|
if (typeof options === "string" ) {
|
|
|
|
if(options === 'open') {
|
|
var items,
|
|
itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup,
|
|
index = parseInt(arguments[1], 10) || 0;
|
|
|
|
if(itemOpts.items) {
|
|
items = itemOpts.items[index];
|
|
} else {
|
|
items = jqEl;
|
|
if(itemOpts.delegate) {
|
|
items = items.find(itemOpts.delegate);
|
|
}
|
|
items = items.eq( index );
|
|
}
|
|
mfp._openClick({mfpEl:items}, jqEl, itemOpts);
|
|
} else {
|
|
if(mfp.isOpen)
|
|
mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));
|
|
}
|
|
|
|
} else {
|
|
// clone options obj
|
|
options = $.extend(true, {}, options);
|
|
|
|
/*
|
|
* As Zepto doesn't support .data() method for objects
|
|
* and it works only in normal browsers
|
|
* we assign "options" object directly to the DOM element. FTW!
|
|
*/
|
|
if(_isJQ) {
|
|
jqEl.data('magnificPopup', options);
|
|
} else {
|
|
jqEl[0].magnificPopup = options;
|
|
}
|
|
|
|
mfp.addGroup(jqEl, options);
|
|
|
|
}
|
|
return jqEl;
|
|
};
|
|
|
|
/*>>core*/
|
|
|
|
/*>>inline*/
|
|
|
|
var INLINE_NS = 'inline',
|
|
_hiddenClass,
|
|
_inlinePlaceholder,
|
|
_lastInlineElement,
|
|
_putInlineElementsBack = function() {
|
|
if(_lastInlineElement) {
|
|
_inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach();
|
|
_lastInlineElement = null;
|
|
}
|
|
};
|
|
|
|
$.magnificPopup.registerModule(INLINE_NS, {
|
|
options: {
|
|
hiddenClass: 'hide', // will be appended with `mfp-` prefix
|
|
markup: '',
|
|
tNotFound: 'Content not found'
|
|
},
|
|
proto: {
|
|
|
|
initInline: function() {
|
|
mfp.types.push(INLINE_NS);
|
|
|
|
_mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {
|
|
_putInlineElementsBack();
|
|
});
|
|
},
|
|
|
|
getInline: function(item, template) {
|
|
|
|
_putInlineElementsBack();
|
|
|
|
if(item.src) {
|
|
var inlineSt = mfp.st.inline,
|
|
el = $(item.src);
|
|
|
|
if(el.length) {
|
|
|
|
// If target element has parent - we replace it with placeholder and put it back after popup is closed
|
|
var parent = el[0].parentNode;
|
|
if(parent && parent.tagName) {
|
|
if(!_inlinePlaceholder) {
|
|
_hiddenClass = inlineSt.hiddenClass;
|
|
_inlinePlaceholder = _getEl(_hiddenClass);
|
|
_hiddenClass = 'mfp-'+_hiddenClass;
|
|
}
|
|
// replace target inline element with placeholder
|
|
_lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);
|
|
}
|
|
|
|
mfp.updateStatus('ready');
|
|
} else {
|
|
mfp.updateStatus('error', inlineSt.tNotFound);
|
|
el = $('<div>');
|
|
}
|
|
|
|
item.inlineElement = el;
|
|
return el;
|
|
}
|
|
|
|
mfp.updateStatus('ready');
|
|
mfp._parseMarkup(template, {}, item);
|
|
return template;
|
|
}
|
|
}
|
|
});
|
|
|
|
/*>>inline*/
|
|
|
|
/*>>ajax*/
|
|
var AJAX_NS = 'ajax',
|
|
_ajaxCur,
|
|
_removeAjaxCursor = function() {
|
|
if(_ajaxCur) {
|
|
$(document.body).removeClass(_ajaxCur);
|
|
}
|
|
},
|
|
_destroyAjaxRequest = function() {
|
|
_removeAjaxCursor();
|
|
if(mfp.req) {
|
|
mfp.req.abort();
|
|
}
|
|
};
|
|
|
|
$.magnificPopup.registerModule(AJAX_NS, {
|
|
|
|
options: {
|
|
settings: null,
|
|
cursor: 'mfp-ajax-cur',
|
|
tError: '<a href="%url%">The content</a> could not be loaded.'
|
|
},
|
|
|
|
proto: {
|
|
initAjax: function() {
|
|
mfp.types.push(AJAX_NS);
|
|
_ajaxCur = mfp.st.ajax.cursor;
|
|
|
|
_mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest);
|
|
_mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest);
|
|
},
|
|
getAjax: function(item) {
|
|
|
|
if(_ajaxCur) {
|
|
$(document.body).addClass(_ajaxCur);
|
|
}
|
|
|
|
mfp.updateStatus('loading');
|
|
|
|
var opts = $.extend({
|
|
url: item.src,
|
|
success: function(data, textStatus, jqXHR) {
|
|
var temp = {
|
|
data:data,
|
|
xhr:jqXHR
|
|
};
|
|
|
|
_mfpTrigger('ParseAjax', temp);
|
|
|
|
mfp.appendContent( $(temp.data), AJAX_NS );
|
|
|
|
item.finished = true;
|
|
|
|
_removeAjaxCursor();
|
|
|
|
mfp._setFocus();
|
|
|
|
setTimeout(function() {
|
|
mfp.wrap.addClass(READY_CLASS);
|
|
}, 16);
|
|
|
|
mfp.updateStatus('ready');
|
|
|
|
_mfpTrigger('AjaxContentAdded');
|
|
},
|
|
error: function() {
|
|
_removeAjaxCursor();
|
|
item.finished = item.loadError = true;
|
|
mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src));
|
|
}
|
|
}, mfp.st.ajax.settings);
|
|
|
|
mfp.req = $.ajax(opts);
|
|
|
|
return '';
|
|
}
|
|
}
|
|
});
|
|
|
|
/*>>ajax*/
|
|
|
|
/*>>image*/
|
|
var _imgInterval,
|
|
_getTitle = function(item) {
|
|
if(item.data && item.data.title !== undefined)
|
|
return item.data.title;
|
|
|
|
var src = mfp.st.image.titleSrc;
|
|
|
|
if(src) {
|
|
if($.isFunction(src)) {
|
|
return src.call(mfp, item);
|
|
} else if(item.el) {
|
|
return item.el.attr(src) || '';
|
|
}
|
|
}
|
|
return '';
|
|
};
|
|
|
|
$.magnificPopup.registerModule('image', {
|
|
|
|
options: {
|
|
markup: '<div class="mfp-figure">'+
|
|
'<div class="mfp-close"></div>'+
|
|
'<figure>'+
|
|
'<div class="mfp-img"></div>'+
|
|
'<figcaption>'+
|
|
'<div class="mfp-bottom-bar">'+
|
|
'<div class="mfp-title"></div>'+
|
|
'<div class="mfp-counter"></div>'+
|
|
'</div>'+
|
|
'</figcaption>'+
|
|
'</figure>'+
|
|
'</div>',
|
|
cursor: 'mfp-zoom-out-cur',
|
|
titleSrc: 'title',
|
|
verticalFit: true,
|
|
tError: '<a href="%url%">The image</a> could not be loaded.'
|
|
},
|
|
|
|
proto: {
|
|
initImage: function() {
|
|
var imgSt = mfp.st.image,
|
|
ns = '.image';
|
|
|
|
mfp.types.push('image');
|
|
|
|
_mfpOn(OPEN_EVENT+ns, function() {
|
|
if(mfp.currItem.type === 'image' && imgSt.cursor) {
|
|
$(document.body).addClass(imgSt.cursor);
|
|
}
|
|
});
|
|
|
|
_mfpOn(CLOSE_EVENT+ns, function() {
|
|
if(imgSt.cursor) {
|
|
$(document.body).removeClass(imgSt.cursor);
|
|
}
|
|
_window.off('resize' + EVENT_NS);
|
|
});
|
|
|
|
_mfpOn('Resize'+ns, mfp.resizeImage);
|
|
if(mfp.isLowIE) {
|
|
_mfpOn('AfterChange', mfp.resizeImage);
|
|
}
|
|
},
|
|
resizeImage: function() {
|
|
var item = mfp.currItem;
|
|
if(!item || !item.img) return;
|
|
|
|
if(mfp.st.image.verticalFit) {
|
|
var decr = 0;
|
|
// fix box-sizing in ie7/8
|
|
if(mfp.isLowIE) {
|
|
decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10);
|
|
}
|
|
item.img.css('max-height', mfp.wH-decr);
|
|
}
|
|
},
|
|
_onImageHasSize: function(item) {
|
|
if(item.img) {
|
|
|
|
item.hasSize = true;
|
|
|
|
if(_imgInterval) {
|
|
clearInterval(_imgInterval);
|
|
}
|
|
|
|
item.isCheckingImgSize = false;
|
|
|
|
_mfpTrigger('ImageHasSize', item);
|
|
|
|
if(item.imgHidden) {
|
|
if(mfp.content)
|
|
mfp.content.removeClass('mfp-loading');
|
|
|
|
item.imgHidden = false;
|
|
}
|
|
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Function that loops until the image has size to display elements that rely on it asap
|
|
*/
|
|
findImageSize: function(item) {
|
|
|
|
var counter = 0,
|
|
img = item.img[0],
|
|
mfpSetInterval = function(delay) {
|
|
|
|
if(_imgInterval) {
|
|
clearInterval(_imgInterval);
|
|
}
|
|
// decelerating interval that checks for size of an image
|
|
_imgInterval = setInterval(function() {
|
|
if(img.naturalWidth > 0) {
|
|
mfp._onImageHasSize(item);
|
|
return;
|
|
}
|
|
|
|
if(counter > 200) {
|
|
clearInterval(_imgInterval);
|
|
}
|
|
|
|
counter++;
|
|
if(counter === 3) {
|
|
mfpSetInterval(10);
|
|
} else if(counter === 40) {
|
|
mfpSetInterval(50);
|
|
} else if(counter === 100) {
|
|
mfpSetInterval(500);
|
|
}
|
|
}, delay);
|
|
};
|
|
|
|
mfpSetInterval(1);
|
|
},
|
|
|
|
getImage: function(item, template) {
|
|
|
|
var guard = 0,
|
|
|
|
// image load complete handler
|
|
onLoadComplete = function() {
|
|
if(item) {
|
|
if (item.img[0].complete) {
|
|
item.img.off('.mfploader');
|
|
|
|
if(item === mfp.currItem){
|
|
mfp._onImageHasSize(item);
|
|
|
|
mfp.updateStatus('ready');
|
|
}
|
|
|
|
item.hasSize = true;
|
|
item.loaded = true;
|
|
|
|
_mfpTrigger('ImageLoadComplete');
|
|
|
|
}
|
|
else {
|
|
// if image complete check fails 200 times (20 sec), we assume that there was an error.
|
|
guard++;
|
|
if(guard < 200) {
|
|
setTimeout(onLoadComplete,100);
|
|
} else {
|
|
onLoadError();
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
// image error handler
|
|
onLoadError = function() {
|
|
if(item) {
|
|
item.img.off('.mfploader');
|
|
if(item === mfp.currItem){
|
|
mfp._onImageHasSize(item);
|
|
mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
|
|
}
|
|
|
|
item.hasSize = true;
|
|
item.loaded = true;
|
|
item.loadError = true;
|
|
}
|
|
},
|
|
imgSt = mfp.st.image;
|
|
|
|
|
|
var el = template.find('.mfp-img');
|
|
if(el.length) {
|
|
var img = document.createElement('img');
|
|
img.className = 'mfp-img';
|
|
if(item.el && item.el.find('img').length) {
|
|
img.alt = item.el.find('img').attr('alt');
|
|
}
|
|
item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);
|
|
img.src = item.src;
|
|
|
|
// without clone() "error" event is not firing when IMG is replaced by new IMG
|
|
// TODO: find a way to avoid such cloning
|
|
if(el.is('img')) {
|
|
item.img = item.img.clone();
|
|
}
|
|
|
|
img = item.img[0];
|
|
if(img.naturalWidth > 0) {
|
|
item.hasSize = true;
|
|
} else if(!img.width) {
|
|
item.hasSize = false;
|
|
}
|
|
}
|
|
|
|
mfp._parseMarkup(template, {
|
|
title: _getTitle(item),
|
|
img_replaceWith: item.img
|
|
}, item);
|
|
|
|
mfp.resizeImage();
|
|
|
|
if(item.hasSize) {
|
|
if(_imgInterval) clearInterval(_imgInterval);
|
|
|
|
if(item.loadError) {
|
|
template.addClass('mfp-loading');
|
|
mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
|
|
} else {
|
|
template.removeClass('mfp-loading');
|
|
mfp.updateStatus('ready');
|
|
}
|
|
return template;
|
|
}
|
|
|
|
mfp.updateStatus('loading');
|
|
item.loading = true;
|
|
|
|
if(!item.hasSize) {
|
|
item.imgHidden = true;
|
|
template.addClass('mfp-loading');
|
|
mfp.findImageSize(item);
|
|
}
|
|
|
|
return template;
|
|
}
|
|
}
|
|
});
|
|
|
|
/*>>image*/
|
|
|
|
/*>>zoom*/
|
|
var hasMozTransform,
|
|
getHasMozTransform = function() {
|
|
if(hasMozTransform === undefined) {
|
|
hasMozTransform = document.createElement('p').style.MozTransform !== undefined;
|
|
}
|
|
return hasMozTransform;
|
|
};
|
|
|
|
$.magnificPopup.registerModule('zoom', {
|
|
|
|
options: {
|
|
enabled: false,
|
|
easing: 'ease-in-out',
|
|
duration: 300,
|
|
opener: function(element) {
|
|
return element.is('img') ? element : element.find('img');
|
|
}
|
|
},
|
|
|
|
proto: {
|
|
|
|
initZoom: function() {
|
|
var zoomSt = mfp.st.zoom,
|
|
ns = '.zoom',
|
|
image;
|
|
|
|
if(!zoomSt.enabled || !mfp.supportsTransition) {
|
|
return;
|
|
}
|
|
|
|
var duration = zoomSt.duration,
|
|
getElToAnimate = function(image) {
|
|
var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),
|
|
transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing,
|
|
cssObj = {
|
|
position: 'fixed',
|
|
zIndex: 9999,
|
|
left: 0,
|
|
top: 0,
|
|
'-webkit-backface-visibility': 'hidden'
|
|
},
|
|
t = 'transition';
|
|
|
|
cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition;
|
|
|
|
newImg.css(cssObj);
|
|
return newImg;
|
|
},
|
|
showMainContent = function() {
|
|
mfp.content.css('visibility', 'visible');
|
|
},
|
|
openTimeout,
|
|
animatedImg;
|
|
|
|
_mfpOn('BuildControls'+ns, function() {
|
|
if(mfp._allowZoom()) {
|
|
|
|
clearTimeout(openTimeout);
|
|
mfp.content.css('visibility', 'hidden');
|
|
|
|
// Basically, all code below does is clones existing image, puts in on top of the current one and animated it
|
|
|
|
image = mfp._getItemToZoom();
|
|
|
|
if(!image) {
|
|
showMainContent();
|
|
return;
|
|
}
|
|
|
|
animatedImg = getElToAnimate(image);
|
|
|
|
animatedImg.css( mfp._getOffset() );
|
|
|
|
mfp.wrap.append(animatedImg);
|
|
|
|
openTimeout = setTimeout(function() {
|
|
animatedImg.css( mfp._getOffset( true ) );
|
|
openTimeout = setTimeout(function() {
|
|
|
|
showMainContent();
|
|
|
|
setTimeout(function() {
|
|
animatedImg.remove();
|
|
image = animatedImg = null;
|
|
_mfpTrigger('ZoomAnimationEnded');
|
|
}, 16); // avoid blink when switching images
|
|
|
|
}, duration); // this timeout equals animation duration
|
|
|
|
}, 16); // by adding this timeout we avoid short glitch at the beginning of animation
|
|
|
|
|
|
// Lots of timeouts...
|
|
}
|
|
});
|
|
_mfpOn(BEFORE_CLOSE_EVENT+ns, function() {
|
|
if(mfp._allowZoom()) {
|
|
|
|
clearTimeout(openTimeout);
|
|
|
|
mfp.st.removalDelay = duration;
|
|
|
|
if(!image) {
|
|
image = mfp._getItemToZoom();
|
|
if(!image) {
|
|
return;
|
|
}
|
|
animatedImg = getElToAnimate(image);
|
|
}
|
|
|
|
animatedImg.css( mfp._getOffset(true) );
|
|
mfp.wrap.append(animatedImg);
|
|
mfp.content.css('visibility', 'hidden');
|
|
|
|
setTimeout(function() {
|
|
animatedImg.css( mfp._getOffset() );
|
|
}, 16);
|
|
}
|
|
|
|
});
|
|
|
|
_mfpOn(CLOSE_EVENT+ns, function() {
|
|
if(mfp._allowZoom()) {
|
|
showMainContent();
|
|
if(animatedImg) {
|
|
animatedImg.remove();
|
|
}
|
|
image = null;
|
|
}
|
|
});
|
|
},
|
|
|
|
_allowZoom: function() {
|
|
return mfp.currItem.type === 'image';
|
|
},
|
|
|
|
_getItemToZoom: function() {
|
|
if(mfp.currItem.hasSize) {
|
|
return mfp.currItem.img;
|
|
} else {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
// Get element postion relative to viewport
|
|
_getOffset: function(isLarge) {
|
|
var el;
|
|
if(isLarge) {
|
|
el = mfp.currItem.img;
|
|
} else {
|
|
el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);
|
|
}
|
|
|
|
var offset = el.offset();
|
|
var paddingTop = parseInt(el.css('padding-top'),10);
|
|
var paddingBottom = parseInt(el.css('padding-bottom'),10);
|
|
offset.top -= ( $(window).scrollTop() - paddingTop );
|
|
|
|
|
|
/*
|
|
|
|
Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa.
|
|
|
|
*/
|
|
var obj = {
|
|
width: el.width(),
|
|
// fix Zepto height+padding issue
|
|
height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop
|
|
};
|
|
|
|
// I hate to do this, but there is no another option
|
|
if( getHasMozTransform() ) {
|
|
obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)';
|
|
} else {
|
|
obj.left = offset.left;
|
|
obj.top = offset.top;
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
}
|
|
});
|
|
|
|
|
|
|
|
/*>>zoom*/
|
|
|
|
/*>>iframe*/
|
|
|
|
var IFRAME_NS = 'iframe',
|
|
_emptyPage = '//about:blank',
|
|
|
|
_fixIframeBugs = function(isShowing) {
|
|
if(mfp.currTemplate[IFRAME_NS]) {
|
|
var el = mfp.currTemplate[IFRAME_NS].find('iframe');
|
|
if(el.length) {
|
|
// reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug
|
|
if(!isShowing) {
|
|
el[0].src = _emptyPage;
|
|
}
|
|
|
|
// IE8 black screen bug fix
|
|
if(mfp.isIE8) {
|
|
el.css('display', isShowing ? 'block' : 'none');
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
$.magnificPopup.registerModule(IFRAME_NS, {
|
|
|
|
options: {
|
|
markup: '<div class="mfp-iframe-scaler">'+
|
|
'<div class="mfp-close"></div>'+
|
|
'<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+
|
|
'</div>',
|
|
|
|
srcAction: 'iframe_src',
|
|
|
|
// we don't care and support only one default type of URL by default
|
|
patterns: {
|
|
youtube: {
|
|
index: 'youtube.com',
|
|
id: 'v=',
|
|
src: '//www.youtube.com/embed/%id%?autoplay=1'
|
|
},
|
|
vimeo: {
|
|
index: 'vimeo.com/',
|
|
id: '/',
|
|
src: '//player.vimeo.com/video/%id%?autoplay=1'
|
|
},
|
|
gmaps: {
|
|
index: '//maps.google.',
|
|
src: '%id%&output=embed'
|
|
}
|
|
}
|
|
},
|
|
|
|
proto: {
|
|
initIframe: function() {
|
|
mfp.types.push(IFRAME_NS);
|
|
|
|
_mfpOn('BeforeChange', function(e, prevType, newType) {
|
|
if(prevType !== newType) {
|
|
if(prevType === IFRAME_NS) {
|
|
_fixIframeBugs(); // iframe if removed
|
|
} else if(newType === IFRAME_NS) {
|
|
_fixIframeBugs(true); // iframe is showing
|
|
}
|
|
}// else {
|
|
// iframe source is switched, don't do anything
|
|
//}
|
|
});
|
|
|
|
_mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {
|
|
_fixIframeBugs();
|
|
});
|
|
},
|
|
|
|
getIframe: function(item, template) {
|
|
var embedSrc = item.src;
|
|
var iframeSt = mfp.st.iframe;
|
|
|
|
$.each(iframeSt.patterns, function() {
|
|
if(embedSrc.indexOf( this.index ) > -1) {
|
|
if(this.id) {
|
|
if(typeof this.id === 'string') {
|
|
embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length);
|
|
} else {
|
|
embedSrc = this.id.call( this, embedSrc );
|
|
}
|
|
}
|
|
embedSrc = this.src.replace('%id%', embedSrc );
|
|
return false; // break;
|
|
}
|
|
});
|
|
|
|
var dataObj = {};
|
|
if(iframeSt.srcAction) {
|
|
dataObj[iframeSt.srcAction] = embedSrc;
|
|
}
|
|
mfp._parseMarkup(template, dataObj, item);
|
|
|
|
mfp.updateStatus('ready');
|
|
|
|
return template;
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
|
|
/*>>iframe*/
|
|
|
|
/*>>gallery*/
|
|
/**
|
|
* Get looped index depending on number of slides
|
|
*/
|
|
var _getLoopedId = function(index) {
|
|
var numSlides = mfp.items.length;
|
|
if(index > numSlides - 1) {
|
|
return index - numSlides;
|
|
} else if(index < 0) {
|
|
return numSlides + index;
|
|
}
|
|
return index;
|
|
},
|
|
_replaceCurrTotal = function(text, curr, total) {
|
|
return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);
|
|
};
|
|
|
|
$.magnificPopup.registerModule('gallery', {
|
|
|
|
options: {
|
|
enabled: false,
|
|
arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>',
|
|
preload: [0,2],
|
|
navigateByImgClick: true,
|
|
arrows: true,
|
|
|
|
tPrev: 'Previous (Left arrow key)',
|
|
tNext: 'Next (Right arrow key)',
|
|
tCounter: '%curr% of %total%'
|
|
},
|
|
|
|
proto: {
|
|
initGallery: function() {
|
|
|
|
var gSt = mfp.st.gallery,
|
|
ns = '.mfp-gallery';
|
|
|
|
mfp.direction = true; // true - next, false - prev
|
|
|
|
if(!gSt || !gSt.enabled ) return false;
|
|
|
|
_wrapClasses += ' mfp-gallery';
|
|
|
|
_mfpOn(OPEN_EVENT+ns, function() {
|
|
|
|
if(gSt.navigateByImgClick) {
|
|
mfp.wrap.on('click'+ns, '.mfp-img', function() {
|
|
if(mfp.items.length > 1) {
|
|
mfp.next();
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
|
|
_document.on('keydown'+ns, function(e) {
|
|
if (e.keyCode === 37) {
|
|
mfp.prev();
|
|
} else if (e.keyCode === 39) {
|
|
mfp.next();
|
|
}
|
|
});
|
|
});
|
|
|
|
_mfpOn('UpdateStatus'+ns, function(e, data) {
|
|
if(data.text) {
|
|
data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length);
|
|
}
|
|
});
|
|
|
|
_mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {
|
|
var l = mfp.items.length;
|
|
values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : '';
|
|
});
|
|
|
|
_mfpOn('BuildControls' + ns, function() {
|
|
if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) {
|
|
var markup = gSt.arrowMarkup,
|
|
arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS),
|
|
arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS);
|
|
|
|
arrowLeft.click(function() {
|
|
mfp.prev();
|
|
});
|
|
arrowRight.click(function() {
|
|
mfp.next();
|
|
});
|
|
|
|
mfp.container.append(arrowLeft.add(arrowRight));
|
|
}
|
|
});
|
|
|
|
_mfpOn(CHANGE_EVENT+ns, function() {
|
|
if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);
|
|
|
|
mfp._preloadTimeout = setTimeout(function() {
|
|
mfp.preloadNearbyImages();
|
|
mfp._preloadTimeout = null;
|
|
}, 16);
|
|
});
|
|
|
|
|
|
_mfpOn(CLOSE_EVENT+ns, function() {
|
|
_document.off(ns);
|
|
mfp.wrap.off('click'+ns);
|
|
mfp.arrowRight = mfp.arrowLeft = null;
|
|
});
|
|
|
|
},
|
|
next: function() {
|
|
mfp.direction = true;
|
|
mfp.index = _getLoopedId(mfp.index + 1);
|
|
mfp.updateItemHTML();
|
|
},
|
|
prev: function() {
|
|
mfp.direction = false;
|
|
mfp.index = _getLoopedId(mfp.index - 1);
|
|
mfp.updateItemHTML();
|
|
},
|
|
goTo: function(newIndex) {
|
|
mfp.direction = (newIndex >= mfp.index);
|
|
mfp.index = newIndex;
|
|
mfp.updateItemHTML();
|
|
},
|
|
preloadNearbyImages: function() {
|
|
var p = mfp.st.gallery.preload,
|
|
preloadBefore = Math.min(p[0], mfp.items.length),
|
|
preloadAfter = Math.min(p[1], mfp.items.length),
|
|
i;
|
|
|
|
for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) {
|
|
mfp._preloadItem(mfp.index+i);
|
|
}
|
|
for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) {
|
|
mfp._preloadItem(mfp.index-i);
|
|
}
|
|
},
|
|
_preloadItem: function(index) {
|
|
index = _getLoopedId(index);
|
|
|
|
if(mfp.items[index].preloaded) {
|
|
return;
|
|
}
|
|
|
|
var item = mfp.items[index];
|
|
if(!item.parsed) {
|
|
item = mfp.parseEl( index );
|
|
}
|
|
|
|
_mfpTrigger('LazyLoad', item);
|
|
|
|
if(item.type === 'image') {
|
|
item.img = $('<img class="mfp-img" />').on('load.mfploader', function() {
|
|
item.hasSize = true;
|
|
}).on('error.mfploader', function() {
|
|
item.hasSize = true;
|
|
item.loadError = true;
|
|
_mfpTrigger('LazyLoadError', item);
|
|
}).attr('src', item.src);
|
|
}
|
|
|
|
|
|
item.preloaded = true;
|
|
}
|
|
}
|
|
});
|
|
|
|
/*>>gallery*/
|
|
|
|
/*>>retina*/
|
|
|
|
var RETINA_NS = 'retina';
|
|
|
|
$.magnificPopup.registerModule(RETINA_NS, {
|
|
options: {
|
|
replaceSrc: function(item) {
|
|
return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; });
|
|
},
|
|
ratio: 1 // Function or number. Set to 1 to disable.
|
|
},
|
|
proto: {
|
|
initRetina: function() {
|
|
if(window.devicePixelRatio > 1) {
|
|
|
|
var st = mfp.st.retina,
|
|
ratio = st.ratio;
|
|
|
|
ratio = !isNaN(ratio) ? ratio : ratio();
|
|
|
|
if(ratio > 1) {
|
|
_mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) {
|
|
item.img.css({
|
|
'max-width': item.img[0].naturalWidth / ratio,
|
|
'width': '100%'
|
|
});
|
|
});
|
|
_mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) {
|
|
item.src = st.replaceSrc(item, ratio);
|
|
});
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
});
|
|
|
|
/*>>retina*/
|
|
_checkInstance(); }));
|
|
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AOS=t():e.AOS=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={exports:{},id:o,loaded:!1};return e[o].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="dist/",t(0)}([function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}var i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o])}return e},r=n(1),a=(o(r),n(6)),u=o(a),c=n(7),f=o(c),s=n(8),d=o(s),l=n(9),p=o(l),m=n(10),b=o(m),v=n(11),y=o(v),g=n(14),h=o(g),w=[],k=!1,x=document.all&&!window.atob,j={offset:120,delay:0,easing:"ease",duration:400,disable:!1,once:!1,startEvent:"DOMContentLoaded"},O=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(e&&(k=!0),k)return w=(0,y.default)(w,j),(0,b.default)(w,j.once),w},S=function(){w=(0,h.default)(),O()},_=function(){w.forEach(function(e,t){e.node.removeAttribute("data-aos"),e.node.removeAttribute("data-aos-easing"),e.node.removeAttribute("data-aos-duration"),e.node.removeAttribute("data-aos-delay")})},E=function(e){return e===!0||"mobile"===e&&p.default.mobile()||"phone"===e&&p.default.phone()||"tablet"===e&&p.default.tablet()||"function"==typeof e&&e()===!0},z=function(e){return j=i(j,e),w=(0,h.default)(),E(j.disable)||x?_():(document.querySelector("body").setAttribute("data-aos-easing",j.easing),document.querySelector("body").setAttribute("data-aos-duration",j.duration),document.querySelector("body").setAttribute("data-aos-delay",j.delay),"DOMContentLoaded"===j.startEvent&&["complete","interactive"].indexOf(document.readyState)>-1?O(!0):"load"===j.startEvent?window.addEventListener(j.startEvent,function(){O(!0)}):document.addEventListener(j.startEvent,function(){O(!0)}),window.addEventListener("resize",(0,f.default)(O,50,!0)),window.addEventListener("orientationchange",(0,f.default)(O,50,!0)),window.addEventListener("scroll",(0,u.default)(function(){(0,b.default)(w,j.once)},99)),document.addEventListener("DOMNodeRemoved",function(e){var t=e.target;t&&1===t.nodeType&&t.hasAttribute&&t.hasAttribute("data-aos")&&(0,f.default)(S,50,!0)}),(0,d.default)("[data-aos]",S),w)};e.exports={init:z,refresh:O,refreshHard:S}},function(e,t){},,,,,function(e,t){(function(t){"use strict";function n(e,t,n){function o(t){var n=b,o=v;return b=v=void 0,k=t,g=e.apply(o,n)}function r(e){return k=e,h=setTimeout(s,t),S?o(e):g}function a(e){var n=e-w,o=e-k,i=t-n;return _?j(i,y-o):i}function c(e){var n=e-w,o=e-k;return void 0===w||n>=t||n<0||_&&o>=y}function s(){var e=O();return c(e)?d(e):void(h=setTimeout(s,a(e)))}function d(e){return h=void 0,E&&b?o(e):(b=v=void 0,g)}function l(){void 0!==h&&clearTimeout(h),k=0,b=w=v=h=void 0}function p(){return void 0===h?g:d(O())}function m(){var e=O(),n=c(e);if(b=arguments,v=this,w=e,n){if(void 0===h)return r(w);if(_)return h=setTimeout(s,t),o(w)}return void 0===h&&(h=setTimeout(s,t)),g}var b,v,y,g,h,w,k=0,S=!1,_=!1,E=!0;if("function"!=typeof e)throw new TypeError(f);return t=u(t)||0,i(n)&&(S=!!n.leading,_="maxWait"in n,y=_?x(u(n.maxWait)||0,t):y,E="trailing"in n?!!n.trailing:E),m.cancel=l,m.flush=p,m}function o(e,t,o){var r=!0,a=!0;if("function"!=typeof e)throw new TypeError(f);return i(o)&&(r="leading"in o?!!o.leading:r,a="trailing"in o?!!o.trailing:a),n(e,t,{leading:r,maxWait:t,trailing:a})}function i(e){var t="undefined"==typeof e?"undefined":c(e);return!!e&&("object"==t||"function"==t)}function r(e){return!!e&&"object"==("undefined"==typeof e?"undefined":c(e))}function a(e){return"symbol"==("undefined"==typeof e?"undefined":c(e))||r(e)&&k.call(e)==d}function u(e){if("number"==typeof e)return e;if(a(e))return s;if(i(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=i(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(l,"");var n=m.test(e);return n||b.test(e)?v(e.slice(2),n?2:8):p.test(e)?s:+e}var c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},f="Expected a function",s=NaN,d="[object Symbol]",l=/^\s+|\s+$/g,p=/^[-+]0x[0-9a-f]+$/i,m=/^0b[01]+$/i,b=/^0o[0-7]+$/i,v=parseInt,y="object"==("undefined"==typeof t?"undefined":c(t))&&t&&t.Object===Object&&t,g="object"==("undefined"==typeof self?"undefined":c(self))&&self&&self.Object===Object&&self,h=y||g||Function("return this")(),w=Object.prototype,k=w.toString,x=Math.max,j=Math.min,O=function(){return h.Date.now()};e.exports=o}).call(t,function(){return this}())},function(e,t){(function(t){"use strict";function n(e,t,n){function i(t){var n=b,o=v;return b=v=void 0,O=t,g=e.apply(o,n)}function r(e){return O=e,h=setTimeout(s,t),S?i(e):g}function u(e){var n=e-w,o=e-O,i=t-n;return _?x(i,y-o):i}function f(e){var n=e-w,o=e-O;return void 0===w||n>=t||n<0||_&&o>=y}function s(){var e=j();return f(e)?d(e):void(h=setTimeout(s,u(e)))}function d(e){return h=void 0,E&&b?i(e):(b=v=void 0,g)}function l(){void 0!==h&&clearTimeout(h),O=0,b=w=v=h=void 0}function p(){return void 0===h?g:d(j())}function m(){var e=j(),n=f(e);if(b=arguments,v=this,w=e,n){if(void 0===h)return r(w);if(_)return h=setTimeout(s,t),i(w)}return void 0===h&&(h=setTimeout(s,t)),g}var b,v,y,g,h,w,O=0,S=!1,_=!1,E=!0;if("function"!=typeof e)throw new TypeError(c);return t=a(t)||0,o(n)&&(S=!!n.leading,_="maxWait"in n,y=_?k(a(n.maxWait)||0,t):y,E="trailing"in n?!!n.trailing:E),m.cancel=l,m.flush=p,m}function o(e){var t="undefined"==typeof e?"undefined":u(e);return!!e&&("object"==t||"function"==t)}function i(e){return!!e&&"object"==("undefined"==typeof e?"undefined":u(e))}function r(e){return"symbol"==("undefined"==typeof e?"undefined":u(e))||i(e)&&w.call(e)==s}function a(e){if("number"==typeof e)return e;if(r(e))return f;if(o(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(d,"");var n=p.test(e);return n||m.test(e)?b(e.slice(2),n?2:8):l.test(e)?f:+e}var u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c="Expected a function",f=NaN,s="[object Symbol]",d=/^\s+|\s+$/g,l=/^[-+]0x[0-9a-f]+$/i,p=/^0b[01]+$/i,m=/^0o[0-7]+$/i,b=parseInt,v="object"==("undefined"==typeof t?"undefined":u(t))&&t&&t.Object===Object&&t,y="object"==("undefined"==typeof self?"undefined":u(self))&&self&&self.Object===Object&&self,g=v||y||Function("return this")(),h=Object.prototype,w=h.toString,k=Math.max,x=Math.min,j=function(){return g.Date.now()};e.exports=n}).call(t,function(){return this}())},function(e,t){"use strict";function n(e,t){a.push({selector:e,fn:t}),!u&&r&&(u=new r(o),u.observe(i.documentElement,{childList:!0,subtree:!0,removedNodes:!0})),o()}function o(){for(var e,t,n=0,o=a.length;n<o;n++){e=a[n],t=i.querySelectorAll(e.selector);for(var r,u=0,c=t.length;u<c;u++)r=t[u],r.ready||(r.ready=!0,e.fn.call(r,r))}}Object.defineProperty(t,"__esModule",{value:!0});var i=window.document,r=window.MutationObserver||window.WebKitMutationObserver,a=[],u=void 0;t.default=n},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(){return navigator.userAgent||navigator.vendor||window.opera||""}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}(),r=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i,a=/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,u=/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i,c=/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i,f=function(){function e(){n(this,e)}return i(e,[{key:"phone",value:function(){var e=o();return!(!r.test(e)&&!a.test(e.substr(0,4)))}},{key:"mobile",value:function(){var e=o();return!(!u.test(e)&&!c.test(e.substr(0,4)))}},{key:"tablet",value:function(){return this.mobile()&&!this.phone()}}]),e}();t.default=new f},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e,t,n){var o=e.node.getAttribute("data-aos-once");t>e.position?e.node.classList.add("aos-animate"):"undefined"!=typeof o&&("false"===o||!n&&"true"!==o)&&e.node.classList.remove("aos-animate")},o=function(e,t){var o=window.pageYOffset,i=window.innerHeight;e.forEach(function(e,r){n(e,i+o,t)})};t.default=o},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(12),r=o(i),a=function(e,t){return e.forEach(function(e,n){e.node.classList.add("aos-init"),e.position=(0,r.default)(e.node,t.offset)}),e};t.default=a},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(13),r=o(i),a=function(e,t){var n=0,o=0,i=window.innerHeight,a={offset:e.getAttribute("data-aos-offset"),anchor:e.getAttribute("data-aos-anchor"),anchorPlacement:e.getAttribute("data-aos-anchor-placement")};switch(a.offset&&!isNaN(a.offset)&&(o=parseInt(a.offset)),a.anchor&&document.querySelectorAll(a.anchor)&&(e=document.querySelectorAll(a.anchor)[0]),n=(0,r.default)(e).top,a.anchorPlacement){case"top-bottom":break;case"center-bottom":n+=e.offsetHeight/2;break;case"bottom-bottom":n+=e.offsetHeight;break;case"top-center":n+=i/2;break;case"bottom-center":n+=i/2+e.offsetHeight;break;case"center-center":n+=i/2+e.offsetHeight/2;break;case"top-top":n+=i;break;case"bottom-top":n+=e.offsetHeight+i;break;case"center-top":n+=e.offsetHeight/2+i}return a.anchorPlacement||a.offset||isNaN(t)||(o=t),n+o};t.default=a},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){for(var t=0,n=0;e&&!isNaN(e.offsetLeft)&&!isNaN(e.offsetTop);)t+=e.offsetLeft-("BODY"!=e.tagName?e.scrollLeft:0),n+=e.offsetTop-("BODY"!=e.tagName?e.scrollTop:0),e=e.offsetParent;return{top:n,left:t}};t.default=n},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){e=e||document.querySelectorAll("[data-aos]");var t=[];return[].forEach.call(e,function(e,n){t.push({node:e})}),t};t.default=n}])});
|
|
//# sourceMappingURL=aos.js.map
|
|
|
|
//# sourceMappingURL=maps/core.js.map
|