17518 lines
790 KiB
JavaScript
17518 lines
790 KiB
JavaScript
/**
|
||
* Framework7 1.5.0
|
||
* Full featured mobile HTML framework for building iOS & Android apps
|
||
*
|
||
* http://framework7.io/
|
||
*
|
||
* Copyright 2016, Vladimir Kharlampidi
|
||
* The iDangero.us
|
||
* http://www.idangero.us/
|
||
*
|
||
* Licensed under MIT
|
||
*
|
||
* Released on: November 8, 2016
|
||
*/
|
||
(function () {
|
||
|
||
'use strict';
|
||
/*===========================
|
||
Framework 7
|
||
===========================*/
|
||
window.Framework7 = function (params) {
|
||
// App
|
||
var app = this;
|
||
|
||
// Version
|
||
app.version = '1.5.0';
|
||
|
||
// Default Parameters
|
||
app.params = {
|
||
//
|
||
root: 'body',
|
||
//
|
||
cache: true,
|
||
cacheIgnore: [],
|
||
cacheIgnoreGetParameters: false,
|
||
cacheDuration: 1000 * 60 * 10, // Ten minutes
|
||
preloadPreviousPage: true,
|
||
uniqueHistory: false,
|
||
uniqueHistoryIgnoreGetParameters: false,
|
||
dynamicPageUrl: 'content-{{index}}',
|
||
allowDuplicateUrls: false,
|
||
router: true,
|
||
routerRemoveTimeout: false,
|
||
routerRemoveWithTimeout: false,
|
||
// Push State
|
||
pushState: false,
|
||
pushStateRoot: undefined,
|
||
pushStateNoAnimation: false,
|
||
pushStateSeparator: '#!/',
|
||
pushStateOnLoad: true,
|
||
// Fast clicks
|
||
fastClicks: true,
|
||
fastClicksDistanceThreshold: 10,
|
||
fastClicksDelayBetweenClicks: 50,
|
||
fastClicksExclude: '', // CSS selector
|
||
// Tap Hold
|
||
tapHold: false,
|
||
tapHoldDelay: 750,
|
||
tapHoldPreventClicks: true,
|
||
// Active State
|
||
activeState: true,
|
||
activeStateElements: 'a, button, label, span',
|
||
// Animate Nav Back Icon
|
||
animateNavBackIcon: false,
|
||
// Swipe Back
|
||
swipeBackPage: true,
|
||
swipeBackPageThreshold: 0,
|
||
swipeBackPageActiveArea: 30,
|
||
swipeBackPageAnimateShadow: true,
|
||
swipeBackPageAnimateOpacity: true,
|
||
// Ajax
|
||
ajaxLinks: undefined, // or CSS selector
|
||
// External Links
|
||
externalLinks: '.external', // CSS selector
|
||
// Sortable
|
||
sortable: true,
|
||
// Scroll toolbars
|
||
hideNavbarOnPageScroll: false,
|
||
hideToolbarOnPageScroll: false,
|
||
hideTabbarOnPageScroll: false,
|
||
showBarsOnPageScrollEnd: true,
|
||
showBarsOnPageScrollTop: true,
|
||
// Swipeout
|
||
swipeout: true,
|
||
swipeoutActionsNoFold: false,
|
||
swipeoutNoFollow: false,
|
||
swipeoutRemoveWithTimeout: false,
|
||
// Smart Select Back link template
|
||
smartSelectOpenIn: 'page', // or 'popup' or 'picker'
|
||
smartSelectBackText: 'Back',
|
||
smartSelectPopupCloseText: 'Close',
|
||
smartSelectPickerCloseText: 'Done',
|
||
smartSelectSearchbar: false,
|
||
smartSelectBackOnSelect: false,
|
||
// Tap Navbar or Statusbar to scroll to top
|
||
scrollTopOnNavbarClick: false,
|
||
scrollTopOnStatusbarClick: false,
|
||
// Panels
|
||
swipePanel: false, // or 'left' or 'right'
|
||
swipePanelActiveArea: 0,
|
||
swipePanelCloseOpposite: true,
|
||
swipePanelOnlyClose: false,
|
||
swipePanelNoFollow: false,
|
||
swipePanelThreshold: 0,
|
||
panelsCloseByOutside: true,
|
||
// Modals
|
||
modalButtonOk: 'OK',
|
||
modalButtonCancel: 'Cancel',
|
||
modalUsernamePlaceholder: 'Username',
|
||
modalPasswordPlaceholder: 'Password',
|
||
modalTitle: 'Framework7',
|
||
modalCloseByOutside: false,
|
||
actionsCloseByOutside: true,
|
||
popupCloseByOutside: true,
|
||
modalPreloaderTitle: 'Loading... ',
|
||
modalStack: true,
|
||
// Lazy Load
|
||
imagesLazyLoadThreshold: 0,
|
||
imagesLazyLoadSequential: true,
|
||
// Name space
|
||
viewClass: 'view',
|
||
viewMainClass: 'view-main',
|
||
viewsClass: 'views',
|
||
// Notifications defaults
|
||
notificationCloseOnClick: false,
|
||
notificationCloseIcon: true,
|
||
notificationCloseButtonText: 'Close',
|
||
// Animate Pages
|
||
animatePages: true,
|
||
// Template7
|
||
templates: {},
|
||
template7Data: {},
|
||
template7Pages: false,
|
||
precompileTemplates: false,
|
||
// Material
|
||
material: false,
|
||
materialPageLoadDelay: 0,
|
||
materialPreloaderSvg: '<svg xmlns="http://www.w3.org/2000/svg" height="75" width="75" viewbox="0 0 75 75"><circle cx="37.5" cy="37.5" r="33.5" stroke-width="8"/></svg>',
|
||
materialPreloaderHtml:
|
||
'<span class="preloader-inner">' +
|
||
'<span class="preloader-inner-gap"></span>' +
|
||
'<span class="preloader-inner-left">' +
|
||
'<span class="preloader-inner-half-circle"></span>' +
|
||
'</span>' +
|
||
'<span class="preloader-inner-right">' +
|
||
'<span class="preloader-inner-half-circle"></span>' +
|
||
'</span>' +
|
||
'</span>',
|
||
materialRipple: true,
|
||
materialRippleElements: '.ripple, a.link, a.item-link, .button, .modal-button, .tab-link, .label-radio, .label-checkbox, .actions-modal-button, a.searchbar-clear, a.floating-button, .floating-button > a, .speed-dial-buttons a',
|
||
// Auto init
|
||
init: true,
|
||
};
|
||
|
||
// Extend defaults with parameters
|
||
for (var param in params) {
|
||
app.params[param] = params[param];
|
||
}
|
||
|
||
// DOM lib
|
||
var $ = Dom7;
|
||
|
||
// Template7 lib
|
||
var t7 = Template7;
|
||
app._compiledTemplates = {};
|
||
|
||
// App Root
|
||
app.root = $(app.params.root);
|
||
app.root.eq(0).addClass('framework7-root');
|
||
|
||
// Touch events
|
||
app.touchEvents = {
|
||
start: app.support.touch ? 'touchstart' : 'mousedown',
|
||
move: app.support.touch ? 'touchmove' : 'mousemove',
|
||
end: app.support.touch ? 'touchend' : 'mouseup'
|
||
};
|
||
|
||
// Link to local storage
|
||
app.ls = window.localStorage;
|
||
|
||
// RTL
|
||
app.rtl = $('body').css('direction') === 'rtl';
|
||
if (app.rtl) $('html').attr('dir', 'rtl');
|
||
|
||
// Overwrite statusbar overlay
|
||
if (typeof app.params.statusbarOverlay !== 'undefined') {
|
||
if (app.params.statusbarOverlay) $('html').addClass('with-statusbar-overlay');
|
||
else $('html').removeClass('with-statusbar-overlay');
|
||
}
|
||
|
||
|
||
/*======================================================
|
||
************ Views ************
|
||
======================================================*/
|
||
app.views = [];
|
||
var View = function (selector, params) {
|
||
var defaults = {
|
||
dynamicNavbar: false,
|
||
domCache: false,
|
||
linksView: undefined,
|
||
reloadPages: false,
|
||
uniqueHistory: app.params.uniqueHistory,
|
||
uniqueHistoryIgnoreGetParameters: app.params.uniqueHistoryIgnoreGetParameters,
|
||
allowDuplicateUrls: app.params.allowDuplicateUrls,
|
||
swipeBackPage: app.params.swipeBackPage,
|
||
swipeBackPageAnimateShadow: app.params.swipeBackPageAnimateShadow,
|
||
swipeBackPageAnimateOpacity: app.params.swipeBackPageAnimateOpacity,
|
||
swipeBackPageActiveArea: app.params.swipeBackPageActiveArea,
|
||
swipeBackPageThreshold: app.params.swipeBackPageThreshold,
|
||
animatePages: app.params.animatePages,
|
||
preloadPreviousPage: app.params.preloadPreviousPage
|
||
};
|
||
var i;
|
||
|
||
// Params
|
||
params = params || {};
|
||
|
||
// Disable dynamic navbar for material theme
|
||
if (params.dynamicNavbar && app.params.material) params.dynamicNavbar = false;
|
||
|
||
// Extend params with defaults
|
||
for (var def in defaults) {
|
||
if (typeof params[def] === 'undefined') {
|
||
params[def] = defaults[def];
|
||
}
|
||
}
|
||
// View
|
||
var view = this;
|
||
view.params = params;
|
||
|
||
// Selector
|
||
view.selector = selector;
|
||
|
||
// Container
|
||
var container = $(selector);
|
||
view.container = container[0];
|
||
|
||
// Fix Selector
|
||
|
||
if (typeof selector !== 'string') {
|
||
// Supposed to be HTMLElement or Dom7
|
||
selector = (container.attr('id') ? '#' + container.attr('id') : '') + (container.attr('class') ? '.' + container.attr('class').replace(/ /g, '.').replace('.active', '') : '');
|
||
view.selector = selector;
|
||
}
|
||
|
||
// Is main
|
||
view.main = container.hasClass(app.params.viewMainClass);
|
||
|
||
// Content cache
|
||
view.contentCache = {};
|
||
|
||
// Context cache
|
||
view.contextCache = {};
|
||
|
||
// Pages cache
|
||
view.pagesCache = {};
|
||
view.pageElementsCache = {};
|
||
|
||
// Store View in element for easy access
|
||
container[0].f7View = view;
|
||
|
||
// Pages
|
||
view.pagesContainer = container.find('.pages')[0];
|
||
view.initialPages = [];
|
||
view.initialPagesUrl = [];
|
||
view.initialNavbars = [];
|
||
if (view.params.domCache) {
|
||
var initialPages = container.find('.page');
|
||
for (i = 0; i < initialPages.length; i++) {
|
||
view.initialPages.push(initialPages[i]);
|
||
view.initialPagesUrl.push('#' + initialPages.eq(i).attr('data-page'));
|
||
}
|
||
if (view.params.dynamicNavbar) {
|
||
var initialNavbars = container.find('.navbar-inner');
|
||
for (i = 0; i < initialNavbars.length; i++) {
|
||
view.initialNavbars.push(initialNavbars[i]);
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
view.allowPageChange = true;
|
||
|
||
// Location
|
||
var docLocation = document.location.href;
|
||
|
||
// History
|
||
view.history = [];
|
||
var viewURL = docLocation;
|
||
var pushStateSeparator = app.params.pushStateSeparator;
|
||
var pushStateRoot = app.params.pushStateRoot;
|
||
if (app.params.pushState && view.main) {
|
||
if (pushStateRoot) {
|
||
viewURL = pushStateRoot;
|
||
}
|
||
else {
|
||
if (pushStateSeparator && viewURL.indexOf(pushStateSeparator) >= 0 && viewURL.indexOf(pushStateSeparator + '#') < 0) viewURL = viewURL.split(pushStateSeparator)[0];
|
||
}
|
||
|
||
}
|
||
|
||
// Active Page
|
||
var currentPage, currentPageData;
|
||
if (!view.activePage) {
|
||
currentPage = $(view.pagesContainer).find('.page-on-center');
|
||
if (currentPage.length === 0) {
|
||
currentPage = $(view.pagesContainer).find('.page:not(.cached)');
|
||
currentPage = currentPage.eq(currentPage.length - 1);
|
||
}
|
||
if (currentPage.length > 0) {
|
||
currentPageData = currentPage[0].f7PageData;
|
||
}
|
||
}
|
||
|
||
// View startup URL
|
||
if (view.params.domCache && currentPage) {
|
||
view.url = container.attr('data-url') || view.params.url || '#' + currentPage.attr('data-page');
|
||
view.pagesCache[view.url] = currentPage.attr('data-page');
|
||
}
|
||
else view.url = container.attr('data-url') || view.params.url || viewURL;
|
||
|
||
// Update current page Data
|
||
if (currentPageData) {
|
||
currentPageData.view = view;
|
||
currentPageData.url = view.url;
|
||
if (view.params.domCache && view.params.dynamicNavbar && !currentPageData.navbarInnerContainer) {
|
||
currentPageData.navbarInnerContainer = view.initialNavbars[view.initialPages.indexOf(currentPageData.container)];
|
||
}
|
||
view.activePage = currentPageData;
|
||
currentPage[0].f7PageData = currentPageData;
|
||
}
|
||
|
||
// Store to history main view's url
|
||
if (view.url) {
|
||
view.history.push(view.url);
|
||
}
|
||
|
||
// Touch events
|
||
var isTouched = false,
|
||
isMoved = false,
|
||
touchesStart = {},
|
||
isScrolling,
|
||
activePage = [],
|
||
previousPage = [],
|
||
viewContainerWidth,
|
||
touchesDiff,
|
||
allowViewTouchMove = true,
|
||
touchStartTime,
|
||
activeNavbar = [],
|
||
previousNavbar = [],
|
||
activeNavElements,
|
||
previousNavElements,
|
||
activeNavBackIcon,
|
||
previousNavBackIcon,
|
||
dynamicNavbar,
|
||
pageShadow,
|
||
el;
|
||
|
||
view.handleTouchStart = function (e) {
|
||
if (!allowViewTouchMove || !view.params.swipeBackPage || isTouched || app.swipeoutOpenedEl || !view.allowPageChange) return;
|
||
isMoved = false;
|
||
isTouched = true;
|
||
isScrolling = undefined;
|
||
touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
|
||
touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
|
||
touchStartTime = (new Date()).getTime();
|
||
dynamicNavbar = view.params.dynamicNavbar && container.find('.navbar-inner').length > 1;
|
||
};
|
||
|
||
view.handleTouchMove = function (e) {
|
||
if (!isTouched) return;
|
||
var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
|
||
var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
if (typeof isScrolling === 'undefined') {
|
||
isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));
|
||
}
|
||
if (isScrolling || e.f7PreventSwipeBack || app.preventSwipeBack) {
|
||
isTouched = false;
|
||
return;
|
||
}
|
||
if (!isMoved) {
|
||
var cancel = false;
|
||
// Calc values during first move fired
|
||
viewContainerWidth = container.width();
|
||
var target = $(e.target);
|
||
var swipeout = target.hasClass('swipeout') ? target : target.parents('.swipeout');
|
||
if (swipeout.length > 0) {
|
||
if (!app.rtl && swipeout.find('.swipeout-actions-left').length > 0) cancel = true;
|
||
if (app.rtl && swipeout.find('.swipeout-actions-right').length > 0) cancel = true;
|
||
}
|
||
activePage = target.is('.page') ? target : target.parents('.page');
|
||
if (activePage.hasClass('no-swipeback')) cancel = true;
|
||
previousPage = container.find('.page-on-left:not(.cached)');
|
||
var notFromBorder = touchesStart.x - container.offset().left > view.params.swipeBackPageActiveArea;
|
||
if (app.rtl) {
|
||
notFromBorder = touchesStart.x < container.offset().left - container[0].scrollLeft + viewContainerWidth - view.params.swipeBackPageActiveArea;
|
||
}
|
||
else {
|
||
notFromBorder = touchesStart.x - container.offset().left > view.params.swipeBackPageActiveArea;
|
||
}
|
||
if (notFromBorder) cancel = true;
|
||
if (previousPage.length === 0 || activePage.length === 0) cancel = true;
|
||
if (cancel) {
|
||
isTouched = false;
|
||
return;
|
||
}
|
||
|
||
if (view.params.swipeBackPageAnimateShadow && !app.device.android) {
|
||
pageShadow = activePage.find('.swipeback-page-shadow');
|
||
if (pageShadow.length === 0) {
|
||
pageShadow = $('<div class="swipeback-page-shadow"></div>');
|
||
activePage.append(pageShadow);
|
||
}
|
||
}
|
||
|
||
if (dynamicNavbar) {
|
||
activeNavbar = container.find('.navbar-on-center:not(.cached)');
|
||
previousNavbar = container.find('.navbar-on-left:not(.cached)');
|
||
activeNavElements = activeNavbar.find('.left, .center, .right, .subnavbar, .fading');
|
||
previousNavElements = previousNavbar.find('.left, .center, .right, .subnavbar, .fading');
|
||
if (app.params.animateNavBackIcon) {
|
||
activeNavBackIcon = activeNavbar.find('.left.sliding .back .icon');
|
||
previousNavBackIcon = previousNavbar.find('.left.sliding .back .icon');
|
||
}
|
||
}
|
||
|
||
// Close/Hide Any Picker
|
||
if ($('.picker-modal.modal-in').length > 0) {
|
||
app.closeModal($('.picker-modal.modal-in'));
|
||
}
|
||
}
|
||
e.f7PreventPanelSwipe = true;
|
||
isMoved = true;
|
||
e.preventDefault();
|
||
|
||
// RTL inverter
|
||
var inverter = app.rtl ? -1 : 1;
|
||
|
||
// Touches diff
|
||
touchesDiff = (pageX - touchesStart.x - view.params.swipeBackPageThreshold) * inverter;
|
||
if (touchesDiff < 0) touchesDiff = 0;
|
||
var percentage = touchesDiff / viewContainerWidth;
|
||
|
||
// Swipe Back Callback
|
||
var callbackData = {
|
||
percentage: percentage,
|
||
activePage: activePage[0],
|
||
previousPage: previousPage[0],
|
||
activeNavbar: activeNavbar[0],
|
||
previousNavbar: previousNavbar[0]
|
||
};
|
||
if (view.params.onSwipeBackMove) {
|
||
view.params.onSwipeBackMove(callbackData);
|
||
}
|
||
container.trigger('swipeBackMove', callbackData);
|
||
|
||
// Transform pages
|
||
var activePageTranslate = touchesDiff * inverter;
|
||
var previousPageTranslate = (touchesDiff / 5 - viewContainerWidth / 5) * inverter;
|
||
if (app.device.pixelRatio === 1) {
|
||
activePageTranslate = Math.round(activePageTranslate);
|
||
previousPageTranslate = Math.round(previousPageTranslate);
|
||
}
|
||
|
||
activePage.transform('translate3d(' + activePageTranslate + 'px,0,0)');
|
||
if (view.params.swipeBackPageAnimateShadow && !app.device.android) pageShadow[0].style.opacity = 1 - 1 * percentage;
|
||
|
||
previousPage.transform('translate3d(' + previousPageTranslate + 'px,0,0)');
|
||
if (view.params.swipeBackPageAnimateOpacity) previousPage[0].style.opacity = 0.9 + 0.1 * percentage;
|
||
|
||
// Dynamic Navbars Animation
|
||
if (dynamicNavbar) {
|
||
var i;
|
||
for (i = 0; i < activeNavElements.length; i++) {
|
||
el = $(activeNavElements[i]);
|
||
if (!el.is('.subnavbar.sliding')) el[0].style.opacity = (1 - percentage * 1.3);
|
||
if (el[0].className.indexOf('sliding') >= 0) {
|
||
var activeNavTranslate = percentage * el[0].f7NavbarRightOffset;
|
||
if (app.device.pixelRatio === 1) activeNavTranslate = Math.round(activeNavTranslate);
|
||
el.transform('translate3d(' + activeNavTranslate + 'px,0,0)');
|
||
if (app.params.animateNavBackIcon) {
|
||
if (el[0].className.indexOf('left') >= 0 && activeNavBackIcon.length > 0) {
|
||
activeNavBackIcon.transform('translate3d(' + -activeNavTranslate + 'px,0,0)');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
for (i = 0; i < previousNavElements.length; i++) {
|
||
el = $(previousNavElements[i]);
|
||
if (!el.is('.subnavbar.sliding')) el[0].style.opacity = percentage * 1.3 - 0.3;
|
||
if (el[0].className.indexOf('sliding') >= 0) {
|
||
var previousNavTranslate = el[0].f7NavbarLeftOffset * (1 - percentage);
|
||
if (app.device.pixelRatio === 1) previousNavTranslate = Math.round(previousNavTranslate);
|
||
el.transform('translate3d(' + previousNavTranslate + 'px,0,0)');
|
||
if (app.params.animateNavBackIcon) {
|
||
if (el[0].className.indexOf('left') >= 0 && previousNavBackIcon.length > 0) {
|
||
previousNavBackIcon.transform('translate3d(' + -previousNavTranslate + 'px,0,0)');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
view.handleTouchEnd = function (e) {
|
||
if (!isTouched || !isMoved) {
|
||
isTouched = false;
|
||
isMoved = false;
|
||
return;
|
||
}
|
||
isTouched = false;
|
||
isMoved = false;
|
||
if (touchesDiff === 0) {
|
||
$([activePage[0], previousPage[0]]).transform('').css({opacity: '', boxShadow: ''});
|
||
if (dynamicNavbar) {
|
||
activeNavElements.transform('').css({opacity: ''});
|
||
previousNavElements.transform('').css({opacity: ''});
|
||
if (activeNavBackIcon && activeNavBackIcon.length > 0) activeNavBackIcon.transform('');
|
||
if (previousNavBackIcon && activeNavBackIcon.length > 0) previousNavBackIcon.transform('');
|
||
}
|
||
return;
|
||
}
|
||
var timeDiff = (new Date()).getTime() - touchStartTime;
|
||
var pageChanged = false;
|
||
// Swipe back to previous page
|
||
if (
|
||
timeDiff < 300 && touchesDiff > 10 ||
|
||
timeDiff >= 300 && touchesDiff > viewContainerWidth / 2
|
||
) {
|
||
activePage.removeClass('page-on-center').addClass('page-on-right');
|
||
previousPage.removeClass('page-on-left').addClass('page-on-center');
|
||
if (dynamicNavbar) {
|
||
activeNavbar.removeClass('navbar-on-center').addClass('navbar-on-right');
|
||
previousNavbar.removeClass('navbar-on-left').addClass('navbar-on-center');
|
||
}
|
||
pageChanged = true;
|
||
}
|
||
// Reset custom styles
|
||
// Add transitioning class for transition-duration
|
||
$([activePage[0], previousPage[0]]).transform('').css({opacity: '', boxShadow: ''}).addClass('page-transitioning');
|
||
if (dynamicNavbar) {
|
||
activeNavElements.css({opacity: ''})
|
||
.each(function () {
|
||
var translate = pageChanged ? this.f7NavbarRightOffset : 0;
|
||
var sliding = $(this);
|
||
sliding.transform('translate3d(' + translate + 'px,0,0)');
|
||
if (app.params.animateNavBackIcon) {
|
||
if (sliding.hasClass('left') && activeNavBackIcon.length > 0) {
|
||
activeNavBackIcon.addClass('page-transitioning').transform('translate3d(' + -translate + 'px,0,0)');
|
||
}
|
||
}
|
||
|
||
}).addClass('page-transitioning');
|
||
|
||
previousNavElements.transform('').css({opacity: ''}).each(function () {
|
||
var translate = pageChanged ? 0 : this.f7NavbarLeftOffset;
|
||
var sliding = $(this);
|
||
sliding.transform('translate3d(' + translate + 'px,0,0)');
|
||
if (app.params.animateNavBackIcon) {
|
||
if (sliding.hasClass('left') && previousNavBackIcon.length > 0) {
|
||
previousNavBackIcon.addClass('page-transitioning').transform('translate3d(' + -translate + 'px,0,0)');
|
||
}
|
||
}
|
||
}).addClass('page-transitioning');
|
||
}
|
||
allowViewTouchMove = false;
|
||
view.allowPageChange = false;
|
||
// Swipe Back Callback
|
||
var callbackData = {
|
||
activePage: activePage[0],
|
||
previousPage: previousPage[0],
|
||
activeNavbar: activeNavbar[0],
|
||
previousNavbar: previousNavbar[0]
|
||
};
|
||
if (pageChanged) {
|
||
// Update View's URL
|
||
var url = view.history[view.history.length - 2];
|
||
view.url = url;
|
||
|
||
// Page before animation callback
|
||
app.pageBackCallback('before', view, {pageContainer: activePage[0], url: url, position: 'center', newPage: previousPage, oldPage: activePage, swipeBack: true});
|
||
app.pageAnimCallback('before', view, {pageContainer: previousPage[0], url: url, position: 'left', newPage: previousPage, oldPage: activePage, swipeBack: true});
|
||
|
||
if (view.params.onSwipeBackBeforeChange) {
|
||
view.params.onSwipeBackBeforeChange(callbackData);
|
||
}
|
||
container.trigger('swipeBackBeforeChange', callbackData);
|
||
}
|
||
else {
|
||
if (view.params.onSwipeBackBeforeReset) {
|
||
view.params.onSwipeBackBeforeReset(callbackData);
|
||
}
|
||
container.trigger('swipeBackBeforeReset', callbackData);
|
||
}
|
||
|
||
activePage.transitionEnd(function () {
|
||
$([activePage[0], previousPage[0]]).removeClass('page-transitioning');
|
||
if (dynamicNavbar) {
|
||
activeNavElements.removeClass('page-transitioning').css({opacity: ''});
|
||
previousNavElements.removeClass('page-transitioning').css({opacity: ''});
|
||
if (activeNavBackIcon && activeNavBackIcon.length > 0) activeNavBackIcon.removeClass('page-transitioning');
|
||
if (previousNavBackIcon && previousNavBackIcon.length > 0) previousNavBackIcon.removeClass('page-transitioning');
|
||
}
|
||
allowViewTouchMove = true;
|
||
view.allowPageChange = true;
|
||
if (pageChanged) {
|
||
if (app.params.pushState && view.main) history.back();
|
||
// Page after animation callback
|
||
app.pageBackCallback('after', view, {pageContainer: activePage[0], url: url, position: 'center', newPage: previousPage, oldPage: activePage, swipeBack: true});
|
||
app.pageAnimCallback('after', view, {pageContainer: previousPage[0], url: url, position: 'left', newPage: previousPage, oldPage: activePage, swipeBack: true});
|
||
app.router.afterBack(view, activePage, previousPage);
|
||
|
||
if (view.params.onSwipeBackAfterChange) {
|
||
view.params.onSwipeBackAfterChange(callbackData);
|
||
}
|
||
container.trigger('swipeBackAfterChange', callbackData);
|
||
}
|
||
else {
|
||
if (view.params.onSwipeBackAfterReset) {
|
||
view.params.onSwipeBackAfterReset(callbackData);
|
||
}
|
||
container.trigger('swipeBackAfterReset', callbackData);
|
||
}
|
||
if (pageShadow && pageShadow.length > 0) pageShadow.remove();
|
||
});
|
||
};
|
||
view.attachEvents = function (detach) {
|
||
var action = detach ? 'off' : 'on';
|
||
var passiveListener = app.touchEvents.start === 'touchstart' && app.support.passiveListener ? {passive: true, capture: false} : false;
|
||
container[action](app.touchEvents.start, view.handleTouchStart, passiveListener);
|
||
container[action](app.touchEvents.move, view.handleTouchMove);
|
||
container[action](app.touchEvents.end, view.handleTouchEnd, passiveListener);
|
||
};
|
||
view.detachEvents = function () {
|
||
view.attachEvents(true);
|
||
};
|
||
|
||
// Init
|
||
if (view.params.swipeBackPage && !app.params.material) {
|
||
view.attachEvents();
|
||
}
|
||
|
||
// Add view to app
|
||
app.views.push(view);
|
||
if (view.main) app.mainView = view;
|
||
|
||
// Router
|
||
view.router = {
|
||
load: function (options) {
|
||
return app.router.load(view, options);
|
||
},
|
||
back: function (options) {
|
||
return app.router.back(view, options);
|
||
},
|
||
// Shortcuts
|
||
loadPage: function (options) {
|
||
options = options || {};
|
||
if (typeof options === 'string') {
|
||
var url = options;
|
||
options = {};
|
||
if (url && url.indexOf('#') === 0 && view.params.domCache) {
|
||
options.pageName = url.split('#')[1];
|
||
}
|
||
else options.url = url;
|
||
}
|
||
return app.router.load(view, options);
|
||
},
|
||
loadContent: function (content) {
|
||
return app.router.load(view, {content: content});
|
||
},
|
||
reloadPage: function (url) {
|
||
return app.router.load(view, {url: url, reload: true});
|
||
},
|
||
reloadContent: function (content) {
|
||
return app.router.load(view, {content: content, reload: true});
|
||
},
|
||
reloadPreviousPage: function (url) {
|
||
return app.router.load(view, {url: url, reloadPrevious: true, reload: true});
|
||
},
|
||
reloadPreviousContent: function (content) {
|
||
return app.router.load(view, {content: content, reloadPrevious: true, reload: true});
|
||
},
|
||
refreshPage: function () {
|
||
var options = {
|
||
url: view.url,
|
||
reload: true,
|
||
ignoreCache: true
|
||
};
|
||
if (options.url && options.url.indexOf('#') === 0) {
|
||
if (view.params.domCache && view.pagesCache[options.url]) {
|
||
options.pageName = view.pagesCache[options.url];
|
||
options.url = undefined;
|
||
delete options.url;
|
||
}
|
||
else if (view.contentCache[options.url]) {
|
||
options.content = view.contentCache[options.url];
|
||
options.url = undefined;
|
||
delete options.url;
|
||
}
|
||
}
|
||
return app.router.load(view, options);
|
||
},
|
||
refreshPreviousPage: function () {
|
||
var options = {
|
||
url: view.history[view.history.length - 2],
|
||
reload: true,
|
||
reloadPrevious: true,
|
||
ignoreCache: true
|
||
};
|
||
if (options.url && options.url.indexOf('#') === 0 && view.params.domCache && view.pagesCache[options.url]) {
|
||
options.pageName = view.pagesCache[options.url];
|
||
options.url = undefined;
|
||
delete options.url;
|
||
}
|
||
return app.router.load(view, options);
|
||
}
|
||
};
|
||
|
||
// Aliases for temporary backward compatibility
|
||
view.loadPage = view.router.loadPage;
|
||
view.loadContent = view.router.loadContent;
|
||
view.reloadPage = view.router.reloadPage;
|
||
view.reloadContent = view.router.reloadContent;
|
||
view.reloadPreviousPage = view.router.reloadPreviousPage;
|
||
view.reloadPreviousContent = view.router.reloadPreviousContent;
|
||
view.refreshPage = view.router.refreshPage;
|
||
view.refreshPreviousPage = view.router.refreshPreviousPage;
|
||
view.back = view.router.back;
|
||
|
||
// Bars methods
|
||
view.hideNavbar = function () {
|
||
return app.hideNavbar(container.find('.navbar'));
|
||
};
|
||
view.showNavbar = function () {
|
||
return app.showNavbar(container.find('.navbar'));
|
||
};
|
||
view.hideToolbar = function () {
|
||
return app.hideToolbar(container.find('.toolbar'));
|
||
};
|
||
view.showToolbar = function () {
|
||
return app.showToolbar(container.find('.toolbar'));
|
||
};
|
||
|
||
// Push State on load
|
||
if (app.params.pushState && app.params.pushStateOnLoad && view.main) {
|
||
var pushStateUrl;
|
||
var pushStateUrlSplit = docLocation.split(pushStateSeparator)[1];
|
||
if (pushStateRoot) {
|
||
pushStateUrl = docLocation.split(app.params.pushStateRoot + pushStateSeparator)[1];
|
||
}
|
||
else if (pushStateSeparator && docLocation.indexOf(pushStateSeparator) >= 0 && docLocation.indexOf(pushStateSeparator + '#') < 0) {
|
||
pushStateUrl = pushStateUrlSplit;
|
||
}
|
||
var pushStateAnimatePages = app.params.pushStateNoAnimation ? false : undefined;
|
||
var historyState = history.state;
|
||
if (pushStateUrl) {
|
||
if (pushStateUrl.indexOf('#') >= 0 && view.params.domCache && historyState && historyState.pageName && 'viewIndex' in historyState) {
|
||
app.router.load(view, {pageName: historyState.pageName, url: historyState.url, animatePages: pushStateAnimatePages, pushState: false});
|
||
}
|
||
else if (pushStateUrl.indexOf('#') >= 0 && view.params.domCache && view.initialPagesUrl.indexOf(pushStateUrl) >= 0) {
|
||
app.router.load(view, {pageName: pushStateUrl.replace('#',''), animatePages: pushStateAnimatePages, pushState: false});
|
||
}
|
||
else app.router.load(view, {url: pushStateUrl, animatePages: pushStateAnimatePages, pushState: false});
|
||
}
|
||
else if (view.params.domCache && docLocation.indexOf(pushStateSeparator + '#') >= 0) {
|
||
if (historyState && historyState.pageName && 'viewIndex' in historyState) {
|
||
app.router.load(view, {pageName: historyState.pageName, url: historyState.url, animatePages: pushStateAnimatePages, pushState: false});
|
||
}
|
||
else if (pushStateSeparator && pushStateUrlSplit.indexOf('#') === 0) {
|
||
if (view.initialPagesUrl.indexOf(pushStateUrlSplit)) {
|
||
app.router.load(view, {pageName: pushStateUrlSplit.replace('#', ''), animatePages: pushStateAnimatePages, pushState: false});
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Destroy
|
||
view.destroy = function () {
|
||
view.detachEvents();
|
||
view = undefined;
|
||
};
|
||
|
||
// Plugin hook
|
||
app.pluginHook('addView', view);
|
||
|
||
// Return view
|
||
return view;
|
||
};
|
||
|
||
app.addView = function (selector, params) {
|
||
return new View(selector, params);
|
||
};
|
||
|
||
app.getCurrentView = function (index) {
|
||
var popoverView = $('.popover.modal-in .view');
|
||
var popupView = $('.popup.modal-in .view');
|
||
var panelView = $('.panel.active .view');
|
||
var appViews = $('.views');
|
||
// Find active view as tab
|
||
var appView = appViews.children('.view');
|
||
// Propably in tabs or split view
|
||
if (appView.length > 1) {
|
||
if (appView.hasClass('tab')) {
|
||
// Tabs
|
||
appView = appViews.children('.view.active');
|
||
}
|
||
else {
|
||
// Split View, leave appView intact
|
||
}
|
||
}
|
||
if (popoverView.length > 0 && popoverView[0].f7View) return popoverView[0].f7View;
|
||
if (popupView.length > 0 && popupView[0].f7View) return popupView[0].f7View;
|
||
if (panelView.length > 0 && panelView[0].f7View) return panelView[0].f7View;
|
||
if (appView.length > 0) {
|
||
if (appView.length === 1 && appView[0].f7View) return appView[0].f7View;
|
||
if (appView.length > 1) {
|
||
var currentViews = [];
|
||
for (var i = 0; i < appView.length; i++) {
|
||
if (appView[i].f7View) currentViews.push(appView[i].f7View);
|
||
}
|
||
if (currentViews.length > 0 && typeof index !== 'undefined') return currentViews[index];
|
||
if (currentViews.length > 1) return currentViews;
|
||
if (currentViews.length === 1) return currentViews[0];
|
||
return undefined;
|
||
}
|
||
}
|
||
return undefined;
|
||
};
|
||
|
||
|
||
/*======================================================
|
||
************ Navbars && Toolbars ************
|
||
======================================================*/
|
||
// On Navbar Init Callback
|
||
app.navbarInitCallback = function (view, pageContainer, navbarContainer, navbarInnerContainer) {
|
||
if (!navbarContainer && navbarInnerContainer) navbarContainer = $(navbarInnerContainer).parent('.navbar')[0];
|
||
if (!navbarInnerContainer || navbarInnerContainer.f7NavbarInitialized && view && !view.params.domCache) return;
|
||
var navbarData = {
|
||
container: navbarContainer,
|
||
innerContainer: navbarInnerContainer
|
||
};
|
||
var pageData = pageContainer && pageContainer.f7PageData;
|
||
|
||
var eventData = {
|
||
page: pageData,
|
||
navbar: navbarData
|
||
};
|
||
|
||
if (navbarInnerContainer.f7NavbarInitialized && ((view && view.params.domCache) || (!view && $(navbarContainer).parents('.popup, .popover, .login-screen, .modal, .actions-modal, .picker-modal').length > 0))) {
|
||
// Reinit Navbar
|
||
app.reinitNavbar(navbarContainer, navbarInnerContainer);
|
||
|
||
// Plugin hook
|
||
app.pluginHook('navbarReinit', eventData);
|
||
|
||
// Event
|
||
$(navbarInnerContainer).trigger('navbarReinit', eventData);
|
||
return;
|
||
}
|
||
navbarInnerContainer.f7NavbarInitialized = true;
|
||
// Before Init
|
||
app.pluginHook('navbarBeforeInit', navbarData, pageData);
|
||
$(navbarInnerContainer).trigger('navbarBeforeInit', eventData);
|
||
|
||
// Initialize Navbar
|
||
app.initNavbar(navbarContainer, navbarInnerContainer);
|
||
|
||
// On init
|
||
app.pluginHook('navbarInit', navbarData, pageData);
|
||
$(navbarInnerContainer).trigger('navbarInit', eventData);
|
||
};
|
||
// Navbar Remove Callback
|
||
app.navbarRemoveCallback = function (view, pageContainer, navbarContainer, navbarInnerContainer) {
|
||
if (!navbarContainer && navbarInnerContainer) navbarContainer = $(navbarInnerContainer).parent('.navbar')[0];
|
||
var navbarData = {
|
||
container: navbarContainer,
|
||
innerContainer: navbarInnerContainer
|
||
};
|
||
var pageData;
|
||
if (pageContainer) {
|
||
pageData = pageContainer.f7PageData;
|
||
}
|
||
|
||
var eventData = {
|
||
page: pageData,
|
||
navbar: navbarData
|
||
};
|
||
app.pluginHook('navbarBeforeRemove', navbarData, pageData);
|
||
$(navbarInnerContainer).trigger('navbarBeforeRemove', eventData);
|
||
navbarData = null;
|
||
pageData = null;
|
||
};
|
||
app.initNavbar = function (navbarContainer, navbarInnerContainer) {
|
||
// Init Subnavbar Searchbar
|
||
if (app.initSearchbar) app.initSearchbar(navbarInnerContainer);
|
||
};
|
||
app.reinitNavbar = function (navbarContainer, navbarInnerContainer) {
|
||
// Re init navbar methods
|
||
};
|
||
app.initNavbarWithCallback = function (navbarContainer) {
|
||
navbarContainer = $(navbarContainer);
|
||
var viewContainer = navbarContainer.parents('.' + app.params.viewClass);
|
||
var view;
|
||
if (viewContainer.length === 0) return;
|
||
if (navbarContainer.parents('.navbar-through').length === 0 && viewContainer.find('.navbar-through').length === 0) return;
|
||
view = viewContainer[0].f7View || undefined;
|
||
|
||
navbarContainer.find('.navbar-inner').each(function () {
|
||
var navbarInnerContainer = this;
|
||
var pageContainer;
|
||
if ($(navbarInnerContainer).attr('data-page')) {
|
||
// For dom cache
|
||
pageContainer = viewContainer.find('.page[data-page="' + $(navbarInnerContainer).attr('data-page') + '"]')[0];
|
||
}
|
||
if (!pageContainer) {
|
||
var pages = viewContainer.find('.page');
|
||
if (pages.length === 1) {
|
||
pageContainer = pages[0];
|
||
}
|
||
else {
|
||
viewContainer.find('.page').each(function () {
|
||
if (this.f7PageData && this.f7PageData.navbarInnerContainer === navbarInnerContainer) {
|
||
pageContainer = this;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
app.navbarInitCallback(view, pageContainer, navbarContainer[0], navbarInnerContainer);
|
||
});
|
||
};
|
||
|
||
// Size Navbars
|
||
app.sizeNavbars = function (viewContainer) {
|
||
if (app.params.material) return;
|
||
var navbarInner = viewContainer ? $(viewContainer).find('.navbar .navbar-inner:not(.cached)') : $('.navbar .navbar-inner:not(.cached)');
|
||
navbarInner.each(function () {
|
||
var n = $(this);
|
||
if (n.hasClass('cached')) return;
|
||
var left = app.rtl ? n.find('.right') : n.find('.left'),
|
||
right = app.rtl ? n.find('.left') : n.find('.right'),
|
||
center = n.find('.center'),
|
||
subnavbar = n.find('.subnavbar'),
|
||
noLeft = left.length === 0,
|
||
noRight = right.length === 0,
|
||
leftWidth = noLeft ? 0 : left.outerWidth(true),
|
||
rightWidth = noRight ? 0 : right.outerWidth(true),
|
||
centerWidth = center.outerWidth(true),
|
||
navbarStyles = n.styles(),
|
||
navbarWidth = n[0].offsetWidth - parseInt(navbarStyles.paddingLeft, 10) - parseInt(navbarStyles.paddingRight, 10),
|
||
onLeft = n.hasClass('navbar-on-left'),
|
||
currLeft, diff;
|
||
|
||
if (noRight) {
|
||
currLeft = navbarWidth - centerWidth;
|
||
}
|
||
if (noLeft) {
|
||
currLeft = 0;
|
||
}
|
||
if (!noLeft && !noRight) {
|
||
currLeft = (navbarWidth - rightWidth - centerWidth + leftWidth) / 2;
|
||
}
|
||
var requiredLeft = (navbarWidth - centerWidth) / 2;
|
||
if (navbarWidth - leftWidth - rightWidth > centerWidth) {
|
||
if (requiredLeft < leftWidth) {
|
||
requiredLeft = leftWidth;
|
||
}
|
||
if (requiredLeft + centerWidth > navbarWidth - rightWidth) {
|
||
requiredLeft = navbarWidth - rightWidth - centerWidth;
|
||
}
|
||
diff = requiredLeft - currLeft;
|
||
}
|
||
else {
|
||
diff = 0;
|
||
}
|
||
// RTL inverter
|
||
var inverter = app.rtl ? -1 : 1;
|
||
|
||
if (center.hasClass('sliding')) {
|
||
center[0].f7NavbarLeftOffset = -(currLeft + diff) * inverter;
|
||
center[0].f7NavbarRightOffset = (navbarWidth - currLeft - diff - centerWidth) * inverter;
|
||
if (onLeft) {
|
||
if (app.params.animateNavBackIcon) {
|
||
var activeNavbarBackLink = n.parent().find('.navbar-on-center').find('.left.sliding .back .icon ~ span');
|
||
if (activeNavbarBackLink.length > 0) {
|
||
center[0].f7NavbarLeftOffset += activeNavbarBackLink[0].offsetLeft;
|
||
}
|
||
}
|
||
center.transform('translate3d(' + center[0].f7NavbarLeftOffset + 'px, 0, 0)');
|
||
}
|
||
}
|
||
if (!noLeft && left.hasClass('sliding')) {
|
||
if (app.rtl) {
|
||
left[0].f7NavbarLeftOffset = -(navbarWidth - left[0].offsetWidth) / 2 * inverter;
|
||
left[0].f7NavbarRightOffset = leftWidth * inverter;
|
||
}
|
||
else {
|
||
left[0].f7NavbarLeftOffset = -leftWidth;
|
||
left[0].f7NavbarRightOffset = (navbarWidth - left[0].offsetWidth) / 2;
|
||
if (app.params.animateNavBackIcon && left.find('.back .icon').length > 0) {
|
||
left[0].f7NavbarRightOffset -= left.find('.back .icon')[0].offsetWidth;
|
||
}
|
||
}
|
||
if (onLeft) left.transform('translate3d(' + left[0].f7NavbarLeftOffset + 'px, 0, 0)');
|
||
}
|
||
if (!noRight && right.hasClass('sliding')) {
|
||
if (app.rtl) {
|
||
right[0].f7NavbarLeftOffset = -rightWidth * inverter;
|
||
right[0].f7NavbarRightOffset = (navbarWidth - right[0].offsetWidth) / 2 * inverter;
|
||
}
|
||
else {
|
||
right[0].f7NavbarLeftOffset = -(navbarWidth - right[0].offsetWidth) / 2;
|
||
right[0].f7NavbarRightOffset = rightWidth;
|
||
}
|
||
if (onLeft) right.transform('translate3d(' + right[0].f7NavbarLeftOffset + 'px, 0, 0)');
|
||
}
|
||
if (subnavbar.length && subnavbar.hasClass('sliding')) {
|
||
subnavbar[0].f7NavbarLeftOffset = app.rtl ? subnavbar[0].offsetWidth : -subnavbar[0].offsetWidth;
|
||
subnavbar[0].f7NavbarRightOffset = -subnavbar[0].f7NavbarLeftOffset;
|
||
}
|
||
|
||
// Center left
|
||
var centerLeft = diff;
|
||
if (app.rtl && noLeft && noRight && center.length > 0) centerLeft = -centerLeft;
|
||
center.css({left: centerLeft + 'px'});
|
||
|
||
});
|
||
};
|
||
|
||
// Hide/Show Navbars/Toolbars
|
||
app.hideNavbar = function (navbarContainer) {
|
||
$(navbarContainer).addClass('navbar-hidden');
|
||
return true;
|
||
};
|
||
app.showNavbar = function (navbarContainer) {
|
||
var navbar = $(navbarContainer);
|
||
navbar.addClass('navbar-hiding').removeClass('navbar-hidden').transitionEnd(function () {
|
||
navbar.removeClass('navbar-hiding');
|
||
});
|
||
return true;
|
||
};
|
||
app.hideToolbar = function (toolbarContainer) {
|
||
$(toolbarContainer).addClass('toolbar-hidden');
|
||
return true;
|
||
};
|
||
app.showToolbar = function (toolbarContainer) {
|
||
var toolbar = $(toolbarContainer);
|
||
toolbar.addClass('toolbar-hiding').removeClass('toolbar-hidden').transitionEnd(function () {
|
||
toolbar.removeClass('toolbar-hiding');
|
||
});
|
||
};
|
||
|
||
|
||
/*======================================================
|
||
************ Searchbar ************
|
||
======================================================*/
|
||
var Searchbar = function (container, params) {
|
||
var defaults = {
|
||
input: null,
|
||
clearButton: null,
|
||
cancelButton: null,
|
||
searchList: null,
|
||
searchIn: '.item-title',
|
||
searchBy: '',
|
||
found: null,
|
||
notFound: null,
|
||
overlay: null,
|
||
ignore: '.searchbar-ignore',
|
||
customSearch: false,
|
||
removeDiacritics: false,
|
||
hideDividers: true,
|
||
hideGroups: true,
|
||
/* Callbacks
|
||
onSearch
|
||
onEnable
|
||
onDisable
|
||
onClear
|
||
*/
|
||
|
||
};
|
||
params = params || {};
|
||
for (var def in defaults) {
|
||
if (typeof params[def] === 'undefined' || params[def] === null) {
|
||
params[def] = defaults[def];
|
||
}
|
||
}
|
||
|
||
// Instance
|
||
var s = this;
|
||
|
||
// Material
|
||
s.material = app.params.material;
|
||
|
||
// Params
|
||
s.params = params;
|
||
|
||
// Container
|
||
container = $(container);
|
||
s.container = container;
|
||
|
||
// Active
|
||
s.active = false;
|
||
|
||
// Input
|
||
s.input = s.params.input ? $(s.params.input) : s.container.find('input[type="search"]');
|
||
s.clearButton = s.params.clearButton ? $(s.params.clearButton) : s.container.find('.searchbar-clear');
|
||
s.cancelButton = s.params.cancelButton ? $(s.params.cancelButton) : s.container.find('.searchbar-cancel');
|
||
|
||
// Search List
|
||
s.searchList = $(s.params.searchList);
|
||
|
||
// Is Virtual List
|
||
s.isVirtualList = s.searchList.hasClass('virtual-list');
|
||
|
||
// Is In Page
|
||
s.pageContainer = s.container.parents('.page').eq(0);
|
||
|
||
// Overlay
|
||
if (!s.params.overlay) {
|
||
s.overlay = s.pageContainer.length > 0 ? s.pageContainer.find('.searchbar-overlay') : $('.searchbar-overlay');
|
||
}
|
||
else {
|
||
s.overlay = $(s.params.overlay);
|
||
}
|
||
// Found and not found
|
||
if (!s.params.found) {
|
||
s.found = s.pageContainer.length > 0 ? s.pageContainer.find('.searchbar-found') : $('.searchbar-found');
|
||
}
|
||
else {
|
||
s.found = $(s.params.found);
|
||
}
|
||
if (!s.params.notFound) {
|
||
s.notFound = s.pageContainer.length > 0 ? s.pageContainer.find('.searchbar-not-found') : $('.searchbar-not-found');
|
||
}
|
||
else {
|
||
s.notFound = $(s.params.notFound);
|
||
}
|
||
|
||
// Set Cancel button
|
||
var cancelMarginProp = app.rtl ? 'margin-left' : 'margin-right';
|
||
var cancelButtonHasMargin = false;
|
||
s.setCancelButtonMargin = function () {
|
||
s.cancelButton.transition(0).show();
|
||
s.cancelButton.css(cancelMarginProp, -s.cancelButton[0].offsetWidth + 'px');
|
||
var clientLeft = s.cancelButton[0].clientLeft;
|
||
s.cancelButton.transition('');
|
||
cancelButtonHasMargin = true;
|
||
};
|
||
|
||
// Trigger
|
||
s.triggerEvent = function (eventName, callbackName, eventData) {
|
||
s.container.trigger(eventName, eventData);
|
||
if (s.searchList.length > 0) s.searchList.trigger(eventName, eventData);
|
||
if (callbackName && s.params[callbackName]) s.params[callbackName](s, eventData);
|
||
};
|
||
|
||
// Enable/disalbe
|
||
s.enable = function (e) {
|
||
function _enable() {
|
||
if ((s.searchList.length || s.params.customSearch) && !s.container.hasClass('searchbar-active') && !s.query) s.overlay.addClass('searchbar-overlay-active');
|
||
s.container.addClass('searchbar-active');
|
||
if (s.cancelButton.length > 0 && !s.material) {
|
||
if (!cancelButtonHasMargin) {
|
||
s.setCancelButtonMargin();
|
||
}
|
||
s.cancelButton.css(cancelMarginProp, '0px');
|
||
}
|
||
s.triggerEvent('enableSearch', 'onEnable');
|
||
s.active = true;
|
||
}
|
||
if (app.device.ios && !app.params.material && e && e.type === 'focus') {
|
||
setTimeout(function () {
|
||
_enable();
|
||
}, 400);
|
||
}
|
||
else {
|
||
_enable();
|
||
}
|
||
};
|
||
|
||
s.disable = function () {
|
||
s.input.val('').trigger('change');
|
||
s.container.removeClass('searchbar-active searchbar-not-empty');
|
||
if (s.cancelButton.length > 0 && !s.material) s.cancelButton.css(cancelMarginProp, -s.cancelButton[0].offsetWidth + 'px');
|
||
|
||
if (s.searchList.length || s.params.customSearch) s.overlay.removeClass('searchbar-overlay-active');
|
||
|
||
s.active = false;
|
||
function _disable() {
|
||
s.input.blur();
|
||
}
|
||
if (app.device.ios) {
|
||
setTimeout(function () {
|
||
_disable();
|
||
}, 400);
|
||
}
|
||
else {
|
||
_disable();
|
||
}
|
||
s.triggerEvent('disableSearch', 'onDisable');
|
||
};
|
||
|
||
// Clear
|
||
s.clear = function (e) {
|
||
if (!s.query && e && $(e.target).hasClass('searchbar-clear')) {
|
||
s.disable();
|
||
return;
|
||
}
|
||
s.input.val('').trigger('change').focus();
|
||
s.triggerEvent('clearSearch', 'onClear');
|
||
};
|
||
|
||
// Search
|
||
s.handleInput = function () {
|
||
setTimeout(function () {
|
||
var value = s.input.val().trim();
|
||
if ((s.searchList.length > 0 || s.params.customSearch) && (s.params.searchIn || s.isVirtualList)) s.search(value, true);
|
||
}, 0);
|
||
};
|
||
|
||
var previousQuery = '';
|
||
var virtualList;
|
||
s.search = function (query, internal) {
|
||
if (query.trim() === previousQuery) return;
|
||
previousQuery = query.trim();
|
||
|
||
if (!internal) {
|
||
if (!s.active) {
|
||
s.enable();
|
||
}
|
||
s.input.val(query);
|
||
}
|
||
s.query = s.value = query;
|
||
// Add active/inactive classes on overlay
|
||
if (query.length === 0) {
|
||
s.container.removeClass('searchbar-not-empty');
|
||
if (s.searchList.length && s.container.hasClass('searchbar-active')) s.overlay.addClass('searchbar-overlay-active');
|
||
}
|
||
else {
|
||
s.container.addClass('searchbar-not-empty');
|
||
if (s.searchList.length && s.container.hasClass('searchbar-active')) s.overlay.removeClass('searchbar-overlay-active');
|
||
}
|
||
|
||
if (s.params.customSearch) {
|
||
s.triggerEvent('search', 'onSearch', {query: query});
|
||
return;
|
||
}
|
||
|
||
var foundItems = [], _vlQuery;
|
||
if (s.isVirtualList) {
|
||
virtualList = s.searchList[0].f7VirtualList;
|
||
if (query.trim() === '') {
|
||
virtualList.resetFilter();
|
||
s.notFound.hide();
|
||
s.found.show();
|
||
return;
|
||
}
|
||
_vlQuery = s.params.removeDiacritics ? $.removeDiacritics(query) : query;
|
||
if (virtualList.params.searchAll) {
|
||
foundItems = virtualList.params.searchAll(_vlQuery, virtualList.items) || [];
|
||
}
|
||
else if (virtualList.params.searchByItem) {
|
||
for (var i = 0; i < virtualList.items.length; i++) {
|
||
if(virtualList.params.searchByItem(_vlQuery, i, virtualList.params.items[i])) {
|
||
foundItems.push(i);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
var values;
|
||
if (s.params.removeDiacritics) values = $.removeDiacritics(query.trim().toLowerCase()).split(' ');
|
||
else {
|
||
values = query.trim().toLowerCase().split(' ');
|
||
}
|
||
s.searchList.find('li').removeClass('hidden-by-searchbar').each(function (index, el) {
|
||
el = $(el);
|
||
var compareWithText = [];
|
||
el.find(s.params.searchIn).each(function () {
|
||
var itemText = $(this).text().trim().toLowerCase();
|
||
if (s.params.removeDiacritics) itemText = $.removeDiacritics(itemText);
|
||
compareWithText.push(itemText);
|
||
});
|
||
compareWithText = compareWithText.join(' ');
|
||
var wordsMatch = 0;
|
||
for (var i = 0; i < values.length; i++) {
|
||
if (compareWithText.indexOf(values[i]) >= 0) wordsMatch++;
|
||
}
|
||
if (wordsMatch !== values.length && !(s.params.ignore && el.is(s.params.ignore))) {
|
||
el.addClass('hidden-by-searchbar');
|
||
}
|
||
else {
|
||
foundItems.push(el[0]);
|
||
}
|
||
});
|
||
|
||
if (s.params.hideDividers) {
|
||
s.searchList.find('.item-divider, .list-group-title').each(function () {
|
||
var title = $(this);
|
||
var nextElements = title.nextAll('li');
|
||
var hide = true;
|
||
for (var i = 0; i < nextElements.length; i++) {
|
||
var nextEl = $(nextElements[i]);
|
||
if (nextEl.hasClass('list-group-title') || nextEl.hasClass('item-divider')) break;
|
||
if (!nextEl.hasClass('hidden-by-searchbar')) {
|
||
hide = false;
|
||
}
|
||
}
|
||
var ignore = s.params.ignore && title.is(s.params.ignore);
|
||
if (hide && !ignore) title.addClass('hidden-by-searchbar');
|
||
else title.removeClass('hidden-by-searchbar');
|
||
});
|
||
}
|
||
if (s.params.hideGroups) {
|
||
s.searchList.find('.list-group').each(function () {
|
||
var group = $(this);
|
||
var ignore = s.params.ignore && group.is(s.params.ignore);
|
||
var notHidden = group.find('li:not(.hidden-by-searchbar)');
|
||
if (notHidden.length === 0 && !ignore) {
|
||
group.addClass('hidden-by-searchbar');
|
||
}
|
||
else {
|
||
group.removeClass('hidden-by-searchbar');
|
||
}
|
||
});
|
||
}
|
||
}
|
||
s.triggerEvent('search', 'onSearch', {query: query, foundItems: foundItems});
|
||
if (foundItems.length === 0) {
|
||
s.notFound.show();
|
||
s.found.hide();
|
||
}
|
||
else {
|
||
s.notFound.hide();
|
||
s.found.show();
|
||
}
|
||
if (s.isVirtualList) {
|
||
virtualList.filterItems(foundItems);
|
||
}
|
||
};
|
||
|
||
// Events
|
||
function preventSubmit(e) {
|
||
e.preventDefault();
|
||
}
|
||
|
||
s.attachEvents = function (destroy) {
|
||
var method = destroy ? 'off' : 'on';
|
||
s.container[method]('submit', preventSubmit);
|
||
if (!s.material) s.cancelButton[method]('click', s.disable);
|
||
s.overlay[method]('click', s.disable);
|
||
s.input[method]('focus', s.enable);
|
||
s.input[method]('change keydown keypress keyup', s.handleInput);
|
||
s.clearButton[method]('click', s.clear);
|
||
|
||
};
|
||
s.detachEvents = function() {
|
||
s.attachEvents(true);
|
||
};
|
||
|
||
// Init Destroy
|
||
s.init = function () {
|
||
s.attachEvents();
|
||
};
|
||
s.destroy = function () {
|
||
if (!s) return;
|
||
s.detachEvents();
|
||
s = null;
|
||
};
|
||
|
||
// Init
|
||
s.init();
|
||
|
||
s.container[0].f7Searchbar = s;
|
||
return s;
|
||
|
||
};
|
||
app.searchbar = function (container, params) {
|
||
return new Searchbar(container, params);
|
||
};
|
||
app.initSearchbar = function (container) {
|
||
container = $(container);
|
||
var searchbar = container.hasClass('searchbar') ? container : container.find('.searchbar');
|
||
if (searchbar.length === 0) return;
|
||
if (!searchbar.hasClass('searchbar-init')) return;
|
||
|
||
var sb = app.searchbar(searchbar, searchbar.dataset());
|
||
|
||
function onBeforeRemove() {
|
||
if (sb) sb.destroy();
|
||
}
|
||
if (container.hasClass('page')) {
|
||
container.once('pageBeforeRemove', onBeforeRemove);
|
||
}
|
||
else if (container.hasClass('navbar-inner')) {
|
||
container.once('navbarBeforeRemove', onBeforeRemove);
|
||
}
|
||
};
|
||
|
||
/*======================================================
|
||
************ Messagebar ************
|
||
======================================================*/
|
||
var Messagebar = function (container, params) {
|
||
var defaults = {
|
||
textarea: null,
|
||
maxHeight: null,
|
||
};
|
||
params = params || {};
|
||
for (var def in defaults) {
|
||
if (typeof params[def] === 'undefined' || params[def] === null) {
|
||
params[def] = defaults[def];
|
||
}
|
||
}
|
||
|
||
// Instance
|
||
var m = this;
|
||
|
||
// Params
|
||
m.params = params;
|
||
|
||
// Container
|
||
m.container = $(container);
|
||
if (m.container.length === 0) return;
|
||
|
||
// Textarea
|
||
m.textarea = m.params.textarea ? $(m.params.textarea) : m.container.find('textarea');
|
||
|
||
// Is In Page
|
||
m.pageContainer = m.container.parents('.page').eq(0);
|
||
m.pageContent = m.pageContainer.find('.page-content');
|
||
|
||
// Initial Sizes
|
||
m.pageContentPadding = parseInt(m.pageContent.css('padding-bottom'));
|
||
m.initialBarHeight = m.container[0].offsetHeight;
|
||
m.initialAreaHeight = m.textarea[0].offsetHeight;
|
||
|
||
|
||
// Resize textarea
|
||
m.sizeTextarea = function () {
|
||
// Reset
|
||
m.textarea.css({'height': ''});
|
||
|
||
var height = m.textarea[0].offsetHeight;
|
||
var diff = height - m.textarea[0].clientHeight;
|
||
var scrollHeight = m.textarea[0].scrollHeight;
|
||
|
||
// Update
|
||
if (scrollHeight + diff > height) {
|
||
var newAreaHeight = scrollHeight + diff;
|
||
var newBarHeight = m.initialBarHeight + (newAreaHeight - m.initialAreaHeight);
|
||
var maxBarHeight = m.params.maxHeight || m.container.parents('.view')[0].offsetHeight - 88;
|
||
if (newBarHeight > maxBarHeight) {
|
||
newBarHeight = parseInt(maxBarHeight, 10);
|
||
newAreaHeight = newBarHeight - m.initialBarHeight + m.initialAreaHeight;
|
||
}
|
||
m.textarea.css('height', newAreaHeight + 'px');
|
||
m.container.css('height', newBarHeight + 'px');
|
||
var onBottom = (m.pageContent[0].scrollTop === m.pageContent[0].scrollHeight - m.pageContent[0].offsetHeight);
|
||
if (m.pageContent.length > 0) {
|
||
m.pageContent.css('padding-bottom', newBarHeight + 'px');
|
||
if (m.pageContent.find('.messages-new-first').length === 0 && onBottom) {
|
||
m.pageContent.scrollTop(m.pageContent[0].scrollHeight - m.pageContent[0].offsetHeight);
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
if (m.pageContent.length > 0) {
|
||
m.container.css({'height': '', 'bottom': ''});
|
||
m.pageContent.css({'padding-bottom': ''});
|
||
}
|
||
}
|
||
};
|
||
|
||
// Clear
|
||
m.clear = function () {
|
||
m.textarea.val('').trigger('change');
|
||
};
|
||
m.value = function (value) {
|
||
if (typeof value === 'undefined') return m.textarea.val();
|
||
else m.textarea.val(value).trigger('change');
|
||
};
|
||
|
||
// Handle textarea
|
||
m.textareaTimeout = undefined;
|
||
m.handleTextarea = function (e) {
|
||
clearTimeout(m.textareaTimeout);
|
||
m.textareaTimeout = setTimeout(function () {
|
||
m.sizeTextarea();
|
||
}, 0);
|
||
};
|
||
|
||
//Events
|
||
function preventSubmit(e) {
|
||
e.preventDefault();
|
||
}
|
||
|
||
m.attachEvents = function (destroy) {
|
||
var method = destroy ? 'off' : 'on';
|
||
m.container[method]('submit', preventSubmit);
|
||
m.textarea[method]('change keydown keypress keyup paste cut', m.handleTextarea);
|
||
};
|
||
m.detachEvents = function () {
|
||
m.attachEvents(true);
|
||
};
|
||
|
||
// Init Destroy
|
||
m.init = function () {
|
||
m.attachEvents();
|
||
};
|
||
m.destroy = function () {
|
||
m.detachEvents();
|
||
m = null;
|
||
};
|
||
|
||
// Init
|
||
m.init();
|
||
|
||
m.container[0].f7Messagebar = m;
|
||
return m;
|
||
};
|
||
app.messagebar = function (container, params) {
|
||
return new Messagebar(container, params);
|
||
};
|
||
app.initPageMessagebar = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var messagebar = pageContainer.hasClass('messagebar') ? pageContainer : pageContainer.find('.messagebar');
|
||
if (messagebar.length === 0) return;
|
||
if (!messagebar.hasClass('messagebar-init')) return;
|
||
var mb = app.messagebar(messagebar, messagebar.dataset());
|
||
|
||
// Destroy on page remove
|
||
function pageBeforeRemove() {
|
||
mb.destroy();
|
||
pageContainer.off('pageBeforeRemove', pageBeforeRemove);
|
||
}
|
||
if (pageContainer.hasClass('page')) {
|
||
pageContainer.on('pageBeforeRemove', pageBeforeRemove);
|
||
}
|
||
};
|
||
|
||
/*======================================================
|
||
************ XHR ************
|
||
======================================================*/
|
||
// XHR Caching
|
||
app.cache = [];
|
||
app.removeFromCache = function (url) {
|
||
var index = false;
|
||
for (var i = 0; i < app.cache.length; i++) {
|
||
if (app.cache[i].url === url) index = i;
|
||
}
|
||
if (index !== false) app.cache.splice(index, 1);
|
||
};
|
||
|
||
// XHR
|
||
app.xhr = false;
|
||
app.get = function (url, view, ignoreCache, callback) {
|
||
// should we ignore get params or not
|
||
var _url = url;
|
||
if (app.params.cacheIgnoreGetParameters && url.indexOf('?') >= 0) {
|
||
_url = url.split('?')[0];
|
||
}
|
||
if (app.params.cache && !ignoreCache && url.indexOf('nocache') < 0 && app.params.cacheIgnore.indexOf(_url) < 0) {
|
||
// Check is the url cached
|
||
for (var i = 0; i < app.cache.length; i++) {
|
||
if (app.cache[i].url === _url) {
|
||
// Check expiration
|
||
if ((new Date()).getTime() - app.cache[i].time < app.params.cacheDuration) {
|
||
// Load from cache
|
||
callback(app.cache[i].content);
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
app.xhr = $.ajax({
|
||
url: url,
|
||
method: 'GET',
|
||
beforeSend: app.params.onAjaxStart,
|
||
complete: function (xhr) {
|
||
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {
|
||
if (app.params.cache) {
|
||
app.removeFromCache(_url);
|
||
app.cache.push({
|
||
url: _url,
|
||
time: (new Date()).getTime(),
|
||
content: xhr.responseText
|
||
});
|
||
}
|
||
callback(xhr.responseText, false);
|
||
}
|
||
else {
|
||
callback(xhr.responseText, true);
|
||
}
|
||
if (app.params.onAjaxComplete) app.params.onAjaxComplete(xhr);
|
||
},
|
||
error: function (xhr) {
|
||
callback(xhr.responseText, true);
|
||
if (app.params.onAjaxError) app.params.onAjaxError(xhr);
|
||
}
|
||
});
|
||
if (view) view.xhr = app.xhr;
|
||
|
||
return app.xhr;
|
||
};
|
||
|
||
|
||
/*======================================================
|
||
************ Pages ************
|
||
======================================================*/
|
||
// Page Callbacks API
|
||
app.pageCallbacks = {};
|
||
|
||
app.onPage = function (callbackName, pageName, callback) {
|
||
if (pageName && pageName.split(' ').length > 1) {
|
||
var pageNames = pageName.split(' ');
|
||
var returnCallbacks = [];
|
||
for (var i = 0; i < pageNames.length; i++) {
|
||
returnCallbacks.push(app.onPage(callbackName, pageNames[i], callback));
|
||
}
|
||
returnCallbacks.remove = function () {
|
||
for (var i = 0; i < returnCallbacks.length; i++) {
|
||
returnCallbacks[i].remove();
|
||
}
|
||
};
|
||
returnCallbacks.trigger = function () {
|
||
for (var i = 0; i < returnCallbacks.length; i++) {
|
||
returnCallbacks[i].trigger();
|
||
}
|
||
};
|
||
return returnCallbacks;
|
||
}
|
||
var callbacks = app.pageCallbacks[callbackName][pageName];
|
||
if (!callbacks) {
|
||
callbacks = app.pageCallbacks[callbackName][pageName] = [];
|
||
}
|
||
app.pageCallbacks[callbackName][pageName].push(callback);
|
||
return {
|
||
remove: function () {
|
||
var removeIndex;
|
||
for (var i = 0; i < callbacks.length; i++) {
|
||
if (callbacks[i].toString() === callback.toString()) {
|
||
removeIndex = i;
|
||
}
|
||
}
|
||
if (typeof removeIndex !== 'undefined') callbacks.splice(removeIndex, 1);
|
||
},
|
||
trigger: callback
|
||
};
|
||
};
|
||
|
||
//Create callbacks methods dynamically
|
||
function createPageCallback(callbackName) {
|
||
var capitalized = callbackName.replace(/^./, function (match) {
|
||
return match.toUpperCase();
|
||
});
|
||
app['onPage' + capitalized] = function (pageName, callback) {
|
||
return app.onPage(callbackName, pageName, callback);
|
||
};
|
||
}
|
||
|
||
var pageCallbacksNames = ('beforeInit init reinit beforeAnimation afterAnimation back afterBack beforeRemove').split(' ');
|
||
for (var i = 0; i < pageCallbacksNames.length; i++) {
|
||
app.pageCallbacks[pageCallbacksNames[i]] = {};
|
||
createPageCallback(pageCallbacksNames[i]);
|
||
}
|
||
|
||
app.triggerPageCallbacks = function (callbackName, pageName, pageData) {
|
||
var allPagesCallbacks = app.pageCallbacks[callbackName]['*'];
|
||
if (allPagesCallbacks) {
|
||
for (var j = 0; j < allPagesCallbacks.length; j++) {
|
||
allPagesCallbacks[j](pageData);
|
||
}
|
||
}
|
||
var callbacks = app.pageCallbacks[callbackName][pageName];
|
||
if (!callbacks || callbacks.length === 0) return;
|
||
for (var i = 0; i < callbacks.length; i++) {
|
||
callbacks[i](pageData);
|
||
}
|
||
};
|
||
|
||
// On Page Init Callback
|
||
app.pageInitCallback = function (view, params) {
|
||
var pageContainer = params.pageContainer;
|
||
if (!pageContainer) return;
|
||
if (pageContainer.f7PageInitialized && view && !view.params.domCache) return;
|
||
|
||
var pageQuery = params.query;
|
||
if (!pageQuery) {
|
||
if (params.url && params.url.indexOf('?') > 0) {
|
||
pageQuery = $.parseUrlQuery(params.url || '');
|
||
}
|
||
else if (pageContainer.f7PageData && pageContainer.f7PageData.query) {
|
||
pageQuery = pageContainer.f7PageData.query;
|
||
}
|
||
else {
|
||
pageQuery = {};
|
||
}
|
||
}
|
||
|
||
// Page Data
|
||
var pageData = {
|
||
container: pageContainer,
|
||
url: params.url,
|
||
query: pageQuery,
|
||
name: $(pageContainer).attr('data-page'),
|
||
view: view,
|
||
from: params.position,
|
||
context: params.context,
|
||
navbarInnerContainer: params.navbarInnerContainer,
|
||
fromPage: params.fromPage
|
||
};
|
||
if (params.fromPage && !params.fromPage.navbarInnerContainer && params.oldNavbarInnerContainer) {
|
||
params.fromPage.navbarInnerContainer = params.oldNavbarInnerContainer;
|
||
}
|
||
|
||
if (pageContainer.f7PageInitialized && ((view && view.params.domCache) || (!view && $(pageContainer).parents('.popup, .popover, .login-screen, .modal, .actions-modal, .picker-modal').length > 0))) {
|
||
// Reinit Page
|
||
app.reinitPage(pageContainer);
|
||
|
||
// Callbacks
|
||
app.pluginHook('pageReinit', pageData);
|
||
if (app.params.onPageReinit) app.params.onPageReinit(app, pageData);
|
||
app.triggerPageCallbacks('reinit', pageData.name, pageData);
|
||
$(pageData.container).trigger('pageReinit', {page: pageData});
|
||
return;
|
||
}
|
||
pageContainer.f7PageInitialized = true;
|
||
|
||
// Store pagedata in page
|
||
pageContainer.f7PageData = pageData;
|
||
|
||
// Update View's activePage
|
||
if (view && !params.preloadOnly && !params.reloadPrevious) {
|
||
// Add data-page on view
|
||
$(view.container).attr('data-page', pageData.name);
|
||
// Update View active page data
|
||
view.activePage = pageData;
|
||
}
|
||
|
||
// Before Init Callbacks
|
||
app.pluginHook('pageBeforeInit', pageData);
|
||
if (app.params.onPageBeforeInit) app.params.onPageBeforeInit(app, pageData);
|
||
app.triggerPageCallbacks('beforeInit', pageData.name, pageData);
|
||
$(pageData.container).trigger('pageBeforeInit', {page: pageData});
|
||
|
||
// Init page
|
||
app.initPage(pageContainer);
|
||
|
||
// Init Callback
|
||
app.pluginHook('pageInit', pageData);
|
||
if (app.params.onPageInit) app.params.onPageInit(app, pageData);
|
||
app.triggerPageCallbacks('init', pageData.name, pageData);
|
||
$(pageData.container).trigger('pageInit', {page: pageData});
|
||
};
|
||
app.pageRemoveCallback = function (view, pageContainer, position) {
|
||
var pageContext;
|
||
if (!pageContainer) return;
|
||
if (pageContainer.f7PageData) pageContext = pageContainer.f7PageData.context;
|
||
// Page Data
|
||
var pageData = {
|
||
container: pageContainer,
|
||
name: $(pageContainer).attr('data-page'),
|
||
view: view,
|
||
url: pageContainer.f7PageData && pageContainer.f7PageData.url,
|
||
query: pageContainer.f7PageData && pageContainer.f7PageData.query,
|
||
navbarInnerContainer: pageContainer.f7PageData && pageContainer.f7PageData.navbarInnerContainer,
|
||
from: position,
|
||
context: pageContext
|
||
};
|
||
// Before Init Callback
|
||
app.pluginHook('pageBeforeRemove', pageData);
|
||
if (app.params.onPageBeforeRemove) app.params.onPageBeforeRemove(app, pageData);
|
||
app.triggerPageCallbacks('beforeRemove', pageData.name, pageData);
|
||
$(pageData.container).trigger('pageBeforeRemove', {page: pageData});
|
||
pageData = null;
|
||
};
|
||
app.pageBackCallback = function (callback, view, params) {
|
||
// Page Data
|
||
var pageContainer = params.pageContainer;
|
||
var pageContext;
|
||
if (!pageContainer) return;
|
||
if (pageContainer.f7PageData) pageContext = pageContainer.f7PageData.context;
|
||
|
||
var pageData = {
|
||
container: pageContainer,
|
||
name: $(pageContainer).attr('data-page'),
|
||
url: pageContainer.f7PageData && pageContainer.f7PageData.url,
|
||
query: pageContainer.f7PageData && pageContainer.f7PageData.query,
|
||
view: view,
|
||
from: params.position,
|
||
context: pageContext,
|
||
navbarInnerContainer: pageContainer.f7PageData && pageContainer.f7PageData.navbarInnerContainer,
|
||
swipeBack: params.swipeBack
|
||
};
|
||
|
||
if (callback === 'after') {
|
||
app.pluginHook('pageAfterBack', pageData);
|
||
if (app.params.onPageAfterBack) app.params.onPageAfterBack(app, pageData);
|
||
app.triggerPageCallbacks('afterBack', pageData.name, pageData);
|
||
$(pageContainer).trigger('pageAfterBack', {page: pageData});
|
||
|
||
}
|
||
if (callback === 'before') {
|
||
app.pluginHook('pageBack', pageData);
|
||
if (app.params.onPageBack) app.params.onPageBack(app, pageData);
|
||
app.triggerPageCallbacks('back', pageData.name, pageData);
|
||
$(pageData.container).trigger('pageBack', {page: pageData});
|
||
}
|
||
};
|
||
app.pageAnimCallback = function (callback, view, params) {
|
||
var pageContainer = params.pageContainer;
|
||
var pageContext;
|
||
if (!pageContainer) return;
|
||
if (pageContainer.f7PageData) pageContext = pageContainer.f7PageData.context;
|
||
|
||
var pageQuery = params.query;
|
||
if (!pageQuery) {
|
||
if (params.url && params.url.indexOf('?') > 0) {
|
||
pageQuery = $.parseUrlQuery(params.url || '');
|
||
}
|
||
else if (pageContainer.f7PageData && pageContainer.f7PageData.query) {
|
||
pageQuery = pageContainer.f7PageData.query;
|
||
}
|
||
else {
|
||
pageQuery = {};
|
||
}
|
||
}
|
||
// Page Data
|
||
var pageData = {
|
||
container: pageContainer,
|
||
url: params.url,
|
||
query: pageQuery,
|
||
name: $(pageContainer).attr('data-page'),
|
||
view: view,
|
||
from: params.position,
|
||
context: pageContext,
|
||
swipeBack: params.swipeBack,
|
||
navbarInnerContainer: pageContainer.f7PageData && pageContainer.f7PageData.navbarInnerContainer,
|
||
fromPage: params.fromPage
|
||
};
|
||
var oldPage = params.oldPage,
|
||
newPage = params.newPage;
|
||
|
||
// Update page date
|
||
pageContainer.f7PageData = pageData;
|
||
|
||
if (callback === 'after') {
|
||
app.pluginHook('pageAfterAnimation', pageData);
|
||
if (app.params.onPageAfterAnimation) app.params.onPageAfterAnimation(app, pageData);
|
||
app.triggerPageCallbacks('afterAnimation', pageData.name, pageData);
|
||
$(pageData.container).trigger('pageAfterAnimation', {page: pageData});
|
||
|
||
}
|
||
if (callback === 'before') {
|
||
// Add data-page on view
|
||
$(view.container).attr('data-page', pageData.name);
|
||
|
||
// Update View's activePage
|
||
if (view) view.activePage = pageData;
|
||
|
||
// Hide/show navbar dynamically
|
||
if (newPage.hasClass('no-navbar') && !oldPage.hasClass('no-navbar')) {
|
||
view.hideNavbar();
|
||
}
|
||
if (!newPage.hasClass('no-navbar') && (oldPage.hasClass('no-navbar') || oldPage.hasClass('no-navbar-by-scroll'))) {
|
||
view.showNavbar();
|
||
}
|
||
// Hide/show navbar toolbar
|
||
if (newPage.hasClass('no-toolbar') && !oldPage.hasClass('no-toolbar')) {
|
||
view.hideToolbar();
|
||
}
|
||
if (!newPage.hasClass('no-toolbar') && (oldPage.hasClass('no-toolbar') || oldPage.hasClass('no-toolbar-by-scroll'))) {
|
||
view.showToolbar();
|
||
}
|
||
// Hide/show tabbar
|
||
var tabBar;
|
||
if (newPage.hasClass('no-tabbar') && !oldPage.hasClass('no-tabbar')) {
|
||
tabBar = $(view.container).find('.tabbar');
|
||
if (tabBar.length === 0) tabBar = $(view.container).parents('.' + app.params.viewsClass).find('.tabbar');
|
||
app.hideToolbar(tabBar);
|
||
}
|
||
if (!newPage.hasClass('no-tabbar') && (oldPage.hasClass('no-tabbar') || oldPage.hasClass('no-tabbar-by-scroll'))) {
|
||
tabBar = $(view.container).find('.tabbar');
|
||
if (tabBar.length === 0) tabBar = $(view.container).parents('.' + app.params.viewsClass).find('.tabbar');
|
||
app.showToolbar(tabBar);
|
||
}
|
||
|
||
oldPage.removeClass('no-navbar-by-scroll no-toolbar-by-scroll');
|
||
// Callbacks
|
||
app.pluginHook('pageBeforeAnimation', pageData);
|
||
if (app.params.onPageBeforeAnimation) app.params.onPageBeforeAnimation(app, pageData);
|
||
app.triggerPageCallbacks('beforeAnimation', pageData.name, pageData);
|
||
$(pageData.container).trigger('pageBeforeAnimation', {page: pageData});
|
||
}
|
||
};
|
||
|
||
// Init Page Events and Manipulations
|
||
app.initPage = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
if (pageContainer.length === 0) return;
|
||
// Size navbars on page load
|
||
if (app.sizeNavbars) app.sizeNavbars(pageContainer.parents('.' + app.params.viewClass)[0]);
|
||
// Init messages
|
||
if (app.initPageMessages) app.initPageMessages(pageContainer);
|
||
// Init forms storage
|
||
if (app.initFormsStorage) app.initFormsStorage(pageContainer);
|
||
// Init smart select
|
||
if (app.initSmartSelects) app.initSmartSelects(pageContainer);
|
||
// Init slider
|
||
if (app.initPageSwiper) app.initPageSwiper(pageContainer);
|
||
// Init pull to refres
|
||
if (app.initPullToRefresh) app.initPullToRefresh(pageContainer);
|
||
// Init infinite scroll
|
||
if (app.initPageInfiniteScroll) app.initPageInfiniteScroll(pageContainer);
|
||
// Init searchbar
|
||
if (app.initSearchbar) app.initSearchbar(pageContainer);
|
||
// Init message bar
|
||
if (app.initPageMessagebar) app.initPageMessagebar(pageContainer);
|
||
// Init scroll toolbars
|
||
if (app.initPageScrollToolbars) app.initPageScrollToolbars(pageContainer);
|
||
// Init lazy images
|
||
if (app.initImagesLazyLoad) app.initImagesLazyLoad(pageContainer);
|
||
// Init progress bars
|
||
if (app.initPageProgressbar) app.initPageProgressbar(pageContainer);
|
||
// Init resizeable textareas
|
||
if (app.initPageResizableTextarea) app.initPageResizableTextarea(pageContainer);
|
||
// Init Material Preloader
|
||
if (app.params.material && app.initPageMaterialPreloader) app.initPageMaterialPreloader(pageContainer);
|
||
// Init Material Inputs
|
||
if (app.params.material && app.initPageMaterialInputs) app.initPageMaterialInputs(pageContainer);
|
||
// Init Material Tabbar
|
||
if (app.params.material && app.initPageMaterialTabbar) app.initPageMaterialTabbar(pageContainer);
|
||
};
|
||
app.reinitPage = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
if (pageContainer.length === 0) return;
|
||
// Size navbars on page reinit
|
||
if (app.sizeNavbars) app.sizeNavbars(pageContainer.parents('.' + app.params.viewClass)[0]);
|
||
// Reinit slider
|
||
if (app.reinitPageSwiper) app.reinitPageSwiper(pageContainer);
|
||
// Reinit lazy load
|
||
if (app.reinitLazyLoad) app.reinitLazyLoad(pageContainer);
|
||
};
|
||
app.initPageWithCallback = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var viewContainer = pageContainer.parents('.' + app.params.viewClass);
|
||
if (viewContainer.length === 0) return;
|
||
var view = viewContainer[0].f7View || undefined;
|
||
var url = view && view.url ? view.url : undefined;
|
||
if (viewContainer && pageContainer.attr('data-page')) {
|
||
viewContainer.attr('data-page', pageContainer.attr('data-page'));
|
||
}
|
||
app.pageInitCallback(view, {pageContainer: pageContainer[0], url: url, position: 'center'});
|
||
};
|
||
|
||
/*======================================================
|
||
************ Navigation / Router ************
|
||
======================================================*/
|
||
app.router = {
|
||
_remove: function (el) {
|
||
if (app.params.routerRemoveTimeout || app.params.routerRemoveWithTimeout) {
|
||
setTimeout(function () {
|
||
$(el).remove();
|
||
}, 0);
|
||
}
|
||
else $(el).remove();
|
||
},
|
||
// Temporary DOM Element
|
||
temporaryDom: document.createElement('div'),
|
||
|
||
// Find page or navbar in passed container which are related to View
|
||
findElement: function (selector, container, view, notCached) {
|
||
container = $(container);
|
||
if (notCached) selector = selector + ':not(.cached)';
|
||
var found = container.find(selector);
|
||
if (found.length > 1) {
|
||
if (typeof view.selector === 'string') {
|
||
// Search in related view
|
||
found = container.find(view.selector + ' ' + selector);
|
||
}
|
||
if (found.length > 1) {
|
||
// Search in main view
|
||
found = container.find('.' + app.params.viewMainClass + ' ' + selector);
|
||
}
|
||
}
|
||
if (found.length === 1) return found;
|
||
else {
|
||
// Try to find non cached
|
||
if (!notCached) found = app.router.findElement(selector, container, view, true);
|
||
if (found && found.length === 1) return found;
|
||
if (found && found.length > 1) return $(found[0]);
|
||
else return undefined;
|
||
}
|
||
},
|
||
|
||
// Set pages classess for animationEnd
|
||
animatePages: function (leftPage, rightPage, direction, view) {
|
||
// Loading new page
|
||
var removeClasses = 'page-on-center page-on-right page-on-left';
|
||
if (direction === 'to-left') {
|
||
leftPage.removeClass(removeClasses).addClass('page-from-center-to-left');
|
||
rightPage.removeClass(removeClasses).addClass('page-from-right-to-center');
|
||
}
|
||
// Go back
|
||
if (direction === 'to-right') {
|
||
leftPage.removeClass(removeClasses).addClass('page-from-left-to-center');
|
||
rightPage.removeClass(removeClasses).addClass('page-from-center-to-right');
|
||
|
||
}
|
||
},
|
||
|
||
// Prepare navbar before animarion
|
||
prepareNavbar: function (newNavbarInner, oldNavbarInner, newNavbarPosition) {
|
||
$(newNavbarInner).find('.sliding').each(function () {
|
||
var sliding = $(this);
|
||
var slidingOffset = newNavbarPosition === 'right' ? this.f7NavbarRightOffset : this.f7NavbarLeftOffset;
|
||
|
||
if (app.params.animateNavBackIcon) {
|
||
if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {
|
||
sliding.find('.back .icon').transform('translate3d(' + (-slidingOffset) + 'px,0,0)');
|
||
}
|
||
}
|
||
sliding.transform('translate3d(' + slidingOffset + 'px,0,0)');
|
||
});
|
||
},
|
||
|
||
// Set navbars classess for animation
|
||
animateNavbars: function (leftNavbarInner, rightNavbarInner, direction, view) {
|
||
// Loading new page
|
||
var removeClasses = 'navbar-on-right navbar-on-center navbar-on-left';
|
||
if (direction === 'to-left') {
|
||
rightNavbarInner.removeClass(removeClasses).addClass('navbar-from-right-to-center');
|
||
rightNavbarInner.find('.sliding').each(function () {
|
||
var sliding = $(this);
|
||
sliding.transform('translate3d(0px,0,0)');
|
||
if (app.params.animateNavBackIcon) {
|
||
if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {
|
||
sliding.find('.back .icon').transform('translate3d(0px,0,0)');
|
||
}
|
||
}
|
||
});
|
||
|
||
leftNavbarInner.removeClass(removeClasses).addClass('navbar-from-center-to-left');
|
||
leftNavbarInner.find('.sliding').each(function () {
|
||
var sliding = $(this);
|
||
var rightText;
|
||
if (app.params.animateNavBackIcon) {
|
||
if (sliding.hasClass('center') && rightNavbarInner.find('.sliding.left .back .icon').length > 0) {
|
||
rightText = rightNavbarInner.find('.sliding.left .back span');
|
||
if (rightText.length > 0) this.f7NavbarLeftOffset += rightText[0].offsetLeft;
|
||
}
|
||
if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {
|
||
sliding.find('.back .icon').transform('translate3d(' + (-this.f7NavbarLeftOffset) + 'px,0,0)');
|
||
}
|
||
}
|
||
sliding.transform('translate3d(' + (this.f7NavbarLeftOffset) + 'px,0,0)');
|
||
});
|
||
}
|
||
// Go back
|
||
if (direction === 'to-right') {
|
||
leftNavbarInner.removeClass(removeClasses).addClass('navbar-from-left-to-center');
|
||
leftNavbarInner.find('.sliding').each(function () {
|
||
var sliding = $(this);
|
||
sliding.transform('translate3d(0px,0,0)');
|
||
if (app.params.animateNavBackIcon) {
|
||
if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {
|
||
sliding.find('.back .icon').transform('translate3d(0px,0,0)');
|
||
}
|
||
}
|
||
});
|
||
|
||
rightNavbarInner.removeClass(removeClasses).addClass('navbar-from-center-to-right');
|
||
rightNavbarInner.find('.sliding').each(function () {
|
||
var sliding = $(this);
|
||
if (app.params.animateNavBackIcon) {
|
||
if (sliding.hasClass('left') && sliding.find('.back .icon').length > 0) {
|
||
sliding.find('.back .icon').transform('translate3d(' + (-this.f7NavbarRightOffset) + 'px,0,0)');
|
||
}
|
||
}
|
||
sliding.transform('translate3d(' + (this.f7NavbarRightOffset) + 'px,0,0)');
|
||
});
|
||
}
|
||
},
|
||
|
||
preprocess: function(view, content, url, next) {
|
||
// Plugin hook
|
||
app.pluginHook('routerPreprocess', view, content, url, next);
|
||
|
||
// Preprocess by plugin
|
||
content = app.pluginProcess('preprocess', content);
|
||
|
||
if (view && view.params && view.params.preprocess) {
|
||
content = view.params.preprocess(content, url, next);
|
||
if (typeof content !== 'undefined') {
|
||
next(content);
|
||
}
|
||
}
|
||
else if (app.params.preprocess) {
|
||
content = app.params.preprocess(content, url, next);
|
||
if (typeof content !== 'undefined') {
|
||
next(content);
|
||
}
|
||
}
|
||
else {
|
||
next(content);
|
||
}
|
||
},
|
||
preroute: function(view, options, isBack) {
|
||
if (isBack) options.isBack = true;
|
||
app.pluginHook('routerPreroute', view, options);
|
||
if ((app.params.preroute && app.params.preroute(view, options) === false) || (view && view.params.preroute && view.params.preroute(view, options) === false)) {
|
||
return true;
|
||
}
|
||
else {
|
||
return false;
|
||
}
|
||
},
|
||
|
||
template7Render: function (view, options) {
|
||
var url = options.url,
|
||
content = options.content, //initial content
|
||
t7_rendered_content = options.content, // will be rendered using Template7
|
||
context = options.context, // Context data for Template7
|
||
contextName = options.contextName,
|
||
template = options.template, // Template 7 compiled template
|
||
pageName = options.pageName;
|
||
|
||
var t7_ctx, t7_template;
|
||
if (typeof content === 'string') {
|
||
if (url) {
|
||
if (app.template7Cache[url] && !options.ignoreCache) t7_template = t7.cache[url];
|
||
else {
|
||
t7_template = t7.compile(content);
|
||
t7.cache[url] = t7_template;
|
||
}
|
||
}
|
||
else t7_template = t7.compile(content);
|
||
}
|
||
else if (template) {
|
||
t7_template = template;
|
||
}
|
||
|
||
if (context) {
|
||
t7_ctx = context;
|
||
if (context && url) {
|
||
view.contextCache[url] = context;
|
||
}
|
||
}
|
||
else {
|
||
if (contextName) {
|
||
if (contextName.indexOf('.') >= 0) {
|
||
var _ctx_path = contextName.split('.');
|
||
var _ctx = t7.data[_ctx_path[0]];
|
||
for (var i = 1; i < _ctx_path.length; i++) {
|
||
if (_ctx_path[i]) _ctx = _ctx[_ctx_path[i]];
|
||
}
|
||
t7_ctx = _ctx;
|
||
}
|
||
else t7_ctx = t7.data[contextName];
|
||
}
|
||
if (!t7_ctx && url) {
|
||
t7_ctx = t7.data['url:' + url];
|
||
}
|
||
if (!t7_ctx && typeof content === 'string' && !template) {
|
||
//try to find by page name in content
|
||
var pageNameMatch = content.match(/(data-page=["'][^"^']*["'])/);
|
||
if (pageNameMatch) {
|
||
var page = pageNameMatch[0].split('data-page=')[1].replace(/['"]/g, '');
|
||
if (page) t7_ctx = t7.data['page:' + page];
|
||
}
|
||
}
|
||
if (!t7_ctx && template && t7.templates) {
|
||
// Try to find matched template name in t7.templates
|
||
for (var templateName in t7.templates) {
|
||
if (t7.templates[templateName] === template) t7_ctx = t7.data[templateName];
|
||
}
|
||
}
|
||
if (!t7_ctx && url && url in view.contextCache) {
|
||
t7_ctx = view.contextCache[url];
|
||
}
|
||
if (!t7_ctx) {
|
||
t7_ctx = {};
|
||
}
|
||
}
|
||
|
||
if (t7_template && t7_ctx) {
|
||
if (typeof t7_ctx === 'function') t7_ctx = t7_ctx();
|
||
if (url) {
|
||
// Extend data with URL query
|
||
var query = $.parseUrlQuery(url);
|
||
t7_ctx.url_query = {};
|
||
for (var key in query) {
|
||
t7_ctx.url_query[key] = query[key];
|
||
}
|
||
}
|
||
try {
|
||
t7_rendered_content = t7_template(t7_ctx);
|
||
}
|
||
catch (e) {
|
||
t7_rendered_content = '';
|
||
if (window.console && window.console.error) {
|
||
console.error(e);
|
||
}
|
||
}
|
||
}
|
||
|
||
return {content: t7_rendered_content, context: t7_ctx};
|
||
}
|
||
};
|
||
|
||
|
||
app.router._load = function (view, options) {
|
||
options = options || {};
|
||
|
||
var url = options.url,
|
||
content = options.content, //initial content
|
||
t7_rendered = {content: options.content},
|
||
template = options.template, // Template 7 compiled template
|
||
pageName = options.pageName,
|
||
viewContainer = $(view.container),
|
||
pagesContainer = $(view.pagesContainer),
|
||
animatePages = options.animatePages,
|
||
newPage, oldPage, pagesInView, i, oldNavbarInner, newNavbarInner, navbar, dynamicNavbar, reloadPosition,
|
||
isDynamicPage = typeof url === 'undefined' && content || template,
|
||
pushState = options.pushState,
|
||
pageElement = options.pageElement;
|
||
|
||
if (typeof animatePages === 'undefined') animatePages = view.params.animatePages;
|
||
// Plugin hook
|
||
app.pluginHook('routerLoad', view, options);
|
||
|
||
// Render with Template7
|
||
if (app.params.template7Pages && typeof content === 'string' || template) {
|
||
t7_rendered = app.router.template7Render(view, options);
|
||
if (t7_rendered.content && !content) {
|
||
content = t7_rendered.content;
|
||
}
|
||
}
|
||
|
||
app.router.temporaryDom.innerHTML = '';
|
||
|
||
// Parse DOM
|
||
if (!pageName && !pageElement) {
|
||
if ((typeof content === 'string') || (url && (typeof content === 'string'))) {
|
||
app.router.temporaryDom.innerHTML = t7_rendered.content;
|
||
} else {
|
||
if ('length' in content && content.length > 1) {
|
||
for (var ci = 0; ci < content.length; ci++) {
|
||
$(app.router.temporaryDom).append(content[ci]);
|
||
}
|
||
} else {
|
||
$(app.router.temporaryDom).append(content);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Reload position
|
||
reloadPosition = options.reload && (options.reloadPrevious ? 'left' : 'center');
|
||
|
||
// Find new page
|
||
if (pageName) newPage = pagesContainer.find('.page[data-page="' + pageName + '"]');
|
||
else {
|
||
if (pageElement) newPage = $(pageElement);
|
||
else newPage = app.router.findElement('.page', app.router.temporaryDom, view);
|
||
}
|
||
|
||
// If page not found exit
|
||
if (!newPage || newPage.length === 0 || (pageName && view.activePage && view.activePage.name === pageName)) {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
|
||
newPage.addClass(options.reload ? 'page-on-' + reloadPosition : 'page-on-right');
|
||
|
||
// Find old page (should be the last one) and remove older pages
|
||
pagesInView = pagesContainer.children('.page:not(.cached)');
|
||
if (pageElement) {
|
||
pagesInView = pagesInView.filter(function (index, page) {
|
||
if (page !== pageElement) return page;
|
||
});
|
||
}
|
||
|
||
if (options.reload && options.reloadPrevious && pagesInView.length === 1) {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
|
||
if (options.reload) {
|
||
oldPage = pagesInView.eq(pagesInView.length - 1);
|
||
}
|
||
else {
|
||
if (pagesInView.length > 1) {
|
||
for (i = 0; i < pagesInView.length - 2; i++) {
|
||
if (!view.params.domCache) {
|
||
app.pageRemoveCallback(view, pagesInView[i], 'left');
|
||
app.router._remove(pagesInView[i]);
|
||
}
|
||
else {
|
||
$(pagesInView[i]).addClass('cached');
|
||
}
|
||
}
|
||
if (!view.params.domCache) {
|
||
app.pageRemoveCallback(view, pagesInView[i], 'left');
|
||
app.router._remove(pagesInView[i]);
|
||
}
|
||
else {
|
||
$(pagesInView[i]).addClass('cached');
|
||
}
|
||
}
|
||
oldPage = pagesContainer.children('.page:not(.cached)');
|
||
}
|
||
if (pageElement && oldPage.length > 1) {
|
||
oldPage = oldPage.filter(function (index, page) {
|
||
if (page !== pageElement) return page;
|
||
});
|
||
}
|
||
if(view.params.domCache || pageElement) newPage.removeClass('cached');
|
||
|
||
// Dynamic navbar
|
||
if (view.params.dynamicNavbar) {
|
||
dynamicNavbar = true;
|
||
// Find navbar
|
||
if (pageName) {
|
||
newNavbarInner = viewContainer.find('.navbar-inner[data-page="' + pageName + '"]');
|
||
}
|
||
else {
|
||
newNavbarInner = app.router.findElement('.navbar-inner', app.router.temporaryDom, view);
|
||
}
|
||
if (!newNavbarInner || newNavbarInner.length === 0) {
|
||
// Look in page
|
||
newNavbarInner = newPage.find('.navbar-inner');
|
||
if (!newNavbarInner || newNavbarInner.length === 0) {
|
||
// Set false
|
||
dynamicNavbar = false;
|
||
}
|
||
else {
|
||
if (newNavbarInner.parent('.navbar').length > 0) {
|
||
newNavbarInner.prependTo(newPage);
|
||
}
|
||
}
|
||
}
|
||
if (dynamicNavbar && newPage.find('.navbar').length > 0) {
|
||
app.router._remove(newPage.find('.navbar'));
|
||
}
|
||
navbar = viewContainer.children('.navbar');
|
||
if (options.reload) {
|
||
oldNavbarInner = navbar.find('.navbar-inner:not(.cached):last-child');
|
||
}
|
||
else {
|
||
oldNavbarInner = navbar.find('.navbar-inner:not(.cached)');
|
||
|
||
if (oldNavbarInner.length > 0) {
|
||
for (i = 0; i < oldNavbarInner.length - 1; i++) {
|
||
if (!view.params.domCache) {
|
||
app.navbarRemoveCallback(view, pagesInView[i], navbar[0], oldNavbarInner[i]);
|
||
app.router._remove(oldNavbarInner[i]);
|
||
}
|
||
else
|
||
$(oldNavbarInner[i]).addClass('cached');
|
||
}
|
||
if (!newNavbarInner && oldNavbarInner.length === 1) {
|
||
if (!view.params.domCache) {
|
||
app.navbarRemoveCallback(view, pagesInView[0], navbar[0], oldNavbarInner[0]);
|
||
app.router._remove(oldNavbarInner[0]);
|
||
}
|
||
else
|
||
$(oldNavbarInner[0]).addClass('cached');
|
||
}
|
||
oldNavbarInner = navbar.find('.navbar-inner:not(.cached)');
|
||
}
|
||
}
|
||
}
|
||
if (dynamicNavbar) {
|
||
newNavbarInner.addClass(options.reload ? 'navbar-on-' + reloadPosition : 'navbar-on-right');
|
||
if(view.params.domCache || pageElement) newNavbarInner.removeClass('cached');
|
||
newPage[0].f7RelatedNavbar = newNavbarInner[0];
|
||
newNavbarInner[0].f7RelatedPage = newPage[0];
|
||
}
|
||
|
||
// save content areas into view's cache
|
||
if (!url) {
|
||
var newPageName = pageName || newPage.attr('data-page');
|
||
if (isDynamicPage) url = '#' + app.params.dynamicPageUrl.replace(/{{name}}/g, newPageName).replace(/{{index}}/g, view.history.length - (options.reload ? 1 : 0));
|
||
else url = '#' + newPageName;
|
||
if (!view.params.domCache) {
|
||
view.contentCache[url] = content;
|
||
}
|
||
if (view.params.domCache && pageName) {
|
||
view.pagesCache[url] = pageName;
|
||
}
|
||
}
|
||
else if (url && pageElement) {
|
||
view.pageElementsCache[url] = {
|
||
page: newPage,
|
||
navbarInner: newNavbarInner
|
||
};
|
||
}
|
||
|
||
// Push State
|
||
if (app.params.pushState && !options.reloadPrevious && view.main) {
|
||
if (typeof pushState === 'undefined') pushState = true;
|
||
var pushStateRoot = app.params.pushStateRoot || '';
|
||
var method = options.reload ? 'replaceState' : 'pushState';
|
||
if (pushState) {
|
||
if (!isDynamicPage && !pageName) {
|
||
history[method]({url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);
|
||
}
|
||
else if (isDynamicPage && content) {
|
||
history[method]({content: typeof content === 'string' ? content : '', url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);
|
||
}
|
||
else if (pageName) {
|
||
history[method]({pageName: pageName, url: url, viewIndex: app.views.indexOf(view)}, '', pushStateRoot + app.params.pushStateSeparator + url);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Update View history
|
||
view.url = url;
|
||
if (options.reload) {
|
||
var lastUrl = view.history[view.history.length - (options.reloadPrevious ? 2 : 1)];
|
||
if (lastUrl &&
|
||
lastUrl.indexOf('#') === 0 &&
|
||
lastUrl in view.contentCache &&
|
||
lastUrl !== url &&
|
||
view.history.indexOf(lastUrl) === -1) {
|
||
view.contentCache[lastUrl] = null;
|
||
delete view.contentCache[lastUrl];
|
||
}
|
||
else if (lastUrl &&
|
||
lastUrl in view.pageElementsCache &&
|
||
lastUrl !== url &&
|
||
(view.history.indexOf(lastUrl) === -1 || view.history.indexOf(lastUrl) === view.history.length - 1)) {
|
||
view.pageElementsCache[lastUrl] = null;
|
||
delete view.pageElementsCache[lastUrl];
|
||
}
|
||
if (lastUrl &&
|
||
lastUrl in view.contextCache &&
|
||
lastUrl !== url &&
|
||
(view.history.indexOf(lastUrl) === -1 || view.history.indexOf(lastUrl) === view.history.length - 1)) {
|
||
view.contextCache[lastUrl] = null;
|
||
delete view.contextCache[lastUrl];
|
||
}
|
||
view.history[view.history.length - (options.reloadPrevious ? 2 : 1)] = url;
|
||
}
|
||
else {
|
||
view.history.push(url);
|
||
}
|
||
|
||
// Unique history
|
||
var historyBecameUnique = false;
|
||
if (view.params.uniqueHistory) {
|
||
var _history = view.history;
|
||
var _url = url;
|
||
if (view.params.uniqueHistoryIgnoreGetParameters) {
|
||
_history = [];
|
||
_url = url.split('?')[0];
|
||
for (i = 0; i < view.history.length; i++) {
|
||
_history.push(view.history[i].split('?')[0]);
|
||
}
|
||
}
|
||
|
||
if (_history.indexOf(_url) !== _history.lastIndexOf(_url)) {
|
||
view.history = view.history.slice(0, _history.indexOf(_url));
|
||
view.history.push(url);
|
||
historyBecameUnique = true;
|
||
}
|
||
}
|
||
// Dom manipulations
|
||
if (options.reloadPrevious) {
|
||
oldPage = oldPage.prev('.page');
|
||
newPage.insertBefore(oldPage);
|
||
if (dynamicNavbar) {
|
||
oldNavbarInner = oldNavbarInner.prev('.navbar-inner');
|
||
newNavbarInner.insertAfter(oldNavbarInner);
|
||
}
|
||
}
|
||
else {
|
||
pagesContainer.append(newPage[0]);
|
||
if (dynamicNavbar) navbar.append(newNavbarInner[0]);
|
||
}
|
||
// Remove Old Page And Navbar
|
||
if (options.reload) {
|
||
if (view.params.domCache && view.initialPages.indexOf(oldPage[0]) >= 0) {
|
||
oldPage.addClass('cached');
|
||
if (dynamicNavbar) oldNavbarInner.addClass('cached');
|
||
}
|
||
else {
|
||
app.pageRemoveCallback(view, oldPage[0], reloadPosition);
|
||
if (dynamicNavbar) app.navbarRemoveCallback(view, oldPage[0], navbar[0], oldNavbarInner[0]);
|
||
app.router._remove(oldPage);
|
||
if (dynamicNavbar) app.router._remove(oldNavbarInner);
|
||
}
|
||
}
|
||
|
||
// Page Init Events
|
||
app.pageInitCallback(view, {
|
||
pageContainer: newPage[0],
|
||
url: url,
|
||
position: options.reload ? reloadPosition : 'right',
|
||
navbarInnerContainer: dynamicNavbar ? newNavbarInner && newNavbarInner[0] : undefined,
|
||
oldNavbarInnerContainer: dynamicNavbar ? oldNavbarInner && oldNavbarInner[0] : undefined,
|
||
context: t7_rendered.context,
|
||
query: options.query,
|
||
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData,
|
||
reload: options.reload,
|
||
reloadPrevious: options.reloadPrevious
|
||
});
|
||
|
||
// Navbar init event
|
||
if (dynamicNavbar) {
|
||
app.navbarInitCallback(view, newPage[0], navbar[0], newNavbarInner[0], url, options.reload ? reloadPosition : 'right');
|
||
}
|
||
|
||
if (options.reload) {
|
||
view.allowPageChange = true;
|
||
if (historyBecameUnique) view.refreshPreviousPage();
|
||
return;
|
||
}
|
||
|
||
if (dynamicNavbar && animatePages) {
|
||
app.router.prepareNavbar(newNavbarInner, oldNavbarInner, 'right');
|
||
}
|
||
// Force reLayout
|
||
var clientLeft = newPage[0].clientLeft;
|
||
|
||
// Before Anim Callback
|
||
app.pageAnimCallback('before', view, {
|
||
pageContainer: newPage[0],
|
||
url: url,
|
||
position: 'right',
|
||
oldPage: oldPage,
|
||
newPage: newPage,
|
||
query: options.query,
|
||
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData
|
||
});
|
||
|
||
function afterAnimation() {
|
||
view.allowPageChange = true;
|
||
newPage.removeClass('page-from-right-to-center page-on-right page-on-left').addClass('page-on-center');
|
||
oldPage.removeClass('page-from-center-to-left page-on-center page-on-right').addClass('page-on-left');
|
||
if (dynamicNavbar) {
|
||
newNavbarInner.removeClass('navbar-from-right-to-center navbar-on-left navbar-on-right').addClass('navbar-on-center');
|
||
oldNavbarInner.removeClass('navbar-from-center-to-left navbar-on-center navbar-on-right').addClass('navbar-on-left');
|
||
}
|
||
app.pageAnimCallback('after', view, {
|
||
pageContainer: newPage[0],
|
||
url: url,
|
||
position: 'right',
|
||
oldPage: oldPage,
|
||
newPage: newPage,
|
||
query: options.query,
|
||
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData
|
||
});
|
||
if (app.params.pushState && view.main) app.pushStateClearQueue();
|
||
if (!(view.params.swipeBackPage || view.params.preloadPreviousPage)) {
|
||
if (view.params.domCache) {
|
||
oldPage.addClass('cached');
|
||
if (dynamicNavbar) oldNavbarInner.addClass('cached');
|
||
}
|
||
else {
|
||
if (!(url.indexOf('#') === 0 && newPage.attr('data-page').indexOf('smart-select-') === 0)) {
|
||
app.pageRemoveCallback(view, oldPage[0], 'left');
|
||
if (dynamicNavbar) app.navbarRemoveCallback(view, oldPage[0], navbar[0], oldNavbarInner[0]);
|
||
app.router._remove(oldPage);
|
||
if (dynamicNavbar) app.router._remove(oldNavbarInner);
|
||
}
|
||
}
|
||
}
|
||
if (view.params.uniqueHistory && historyBecameUnique) {
|
||
view.refreshPreviousPage();
|
||
}
|
||
}
|
||
if (animatePages) {
|
||
// Set pages before animation
|
||
if (app.params.material && app.params.materialPageLoadDelay) {
|
||
setTimeout(function () {
|
||
app.router.animatePages(oldPage, newPage, 'to-left', view);
|
||
}, app.params.materialPageLoadDelay);
|
||
}
|
||
else {
|
||
app.router.animatePages(oldPage, newPage, 'to-left', view);
|
||
}
|
||
|
||
// Dynamic navbar animation
|
||
if (dynamicNavbar) {
|
||
setTimeout(function() {
|
||
app.router.animateNavbars(oldNavbarInner, newNavbarInner, 'to-left', view);
|
||
}, 0);
|
||
}
|
||
newPage.animationEnd(function (e) {
|
||
afterAnimation();
|
||
});
|
||
}
|
||
else {
|
||
if (dynamicNavbar) newNavbarInner.find('.sliding, .sliding .back .icon').transform('');
|
||
afterAnimation();
|
||
}
|
||
|
||
};
|
||
|
||
app.router.load = function (view, options) {
|
||
options = options || {};
|
||
if (app.router.preroute(view, options)) {
|
||
return false;
|
||
}
|
||
var url = options.url;
|
||
var content = options.content;
|
||
var pageName = options.pageName;
|
||
var pageElement = options.pageElement;
|
||
if (pageName) {
|
||
if (pageName.indexOf('?') > 0) {
|
||
options.query = $.parseUrlQuery(pageName);
|
||
options.pageName = pageName = pageName.split('?')[0];
|
||
}
|
||
}
|
||
var template = options.template;
|
||
if (view.params.reloadPages === true) options.reload = true;
|
||
|
||
if (!view.allowPageChange) return false;
|
||
if (url && view.url === url && !options.reload && !view.params.allowDuplicateUrls) return false;
|
||
view.allowPageChange = false;
|
||
if (app.xhr && view.xhr && view.xhr === app.xhr) {
|
||
app.xhr.abort();
|
||
app.xhr = false;
|
||
}
|
||
function proceed(content) {
|
||
app.router.preprocess(view, content, url, function (content) {
|
||
options.content = content;
|
||
app.router._load(view, options);
|
||
});
|
||
}
|
||
if (content || pageName || pageElement) {
|
||
proceed(content);
|
||
return;
|
||
}
|
||
else if (template) {
|
||
app.router._load(view, options);
|
||
return;
|
||
}
|
||
|
||
if (!options.url || options.url === '#') {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
app.get(options.url, view, options.ignoreCache, function (content, error) {
|
||
if (error) {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
proceed(content);
|
||
});
|
||
};
|
||
|
||
app.router._back = function (view, options) {
|
||
options = options || {};
|
||
var url = options.url,
|
||
content = options.content,
|
||
t7_rendered = {content: options.content}, // will be rendered using Template7
|
||
template = options.template, // Template 7 compiled template
|
||
animatePages = options.animatePages,
|
||
preloadOnly = options.preloadOnly,
|
||
pushState = options.pushState,
|
||
ignoreCache = options.ignoreCache,
|
||
force = options.force,
|
||
pageName = options.pageName,
|
||
pageElement = options.pageElement;
|
||
|
||
var viewContainer = $(view.container),
|
||
pagesContainer = $(view.pagesContainer),
|
||
pagesInView = pagesContainer.children('.page:not(.cached)'),
|
||
oldPage, newPage, oldNavbarInner, newNavbarInner, navbar, navbarInners, dynamicNavbar, manipulateDom = true;
|
||
|
||
if (typeof animatePages === 'undefined') animatePages = view.params.animatePages;
|
||
|
||
app.pluginHook('routerBack', view, options);
|
||
|
||
// Render with Template7
|
||
if (app.params.template7Pages && typeof content === 'string' || template) {
|
||
t7_rendered = app.router.template7Render(view, options);
|
||
if (t7_rendered.content && !content) {
|
||
content = t7_rendered.content;
|
||
}
|
||
}
|
||
|
||
// Animation
|
||
function afterAnimation() {
|
||
app.pageBackCallback('after', view, {
|
||
pageContainer: oldPage[0],
|
||
url: url,
|
||
position: 'center',
|
||
oldPage: oldPage,
|
||
newPage: newPage,
|
||
});
|
||
app.pageAnimCallback('after', view, {
|
||
pageContainer: newPage[0],
|
||
url: url,
|
||
position: 'left',
|
||
oldPage: oldPage,
|
||
newPage: newPage,
|
||
query: options.query,
|
||
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData
|
||
});
|
||
app.router.afterBack(view, oldPage[0], newPage[0]);
|
||
}
|
||
function animateBack() {
|
||
// Page before animation callback
|
||
app.pageBackCallback('before', view, {
|
||
pageContainer: oldPage[0],
|
||
url: url,
|
||
position: 'center',
|
||
oldPage: oldPage,
|
||
newPage: newPage,
|
||
});
|
||
app.pageAnimCallback('before', view, {
|
||
pageContainer: newPage[0],
|
||
url: url,
|
||
position: 'left',
|
||
oldPage: oldPage,
|
||
newPage: newPage,
|
||
query: options.query,
|
||
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData
|
||
});
|
||
|
||
if (animatePages) {
|
||
// Set pages before animation
|
||
app.router.animatePages(newPage, oldPage, 'to-right', view);
|
||
|
||
// Dynamic navbar animation
|
||
if (dynamicNavbar) {
|
||
setTimeout(function () {
|
||
app.router.animateNavbars(newNavbarInner, oldNavbarInner, 'to-right', view);
|
||
}, 0);
|
||
}
|
||
|
||
newPage.animationEnd(function () {
|
||
afterAnimation();
|
||
});
|
||
}
|
||
else {
|
||
if (dynamicNavbar) newNavbarInner.find('.sliding, .sliding .back .icon').transform('');
|
||
afterAnimation();
|
||
}
|
||
}
|
||
|
||
function parseNewPage() {
|
||
app.router.temporaryDom.innerHTML = '';
|
||
// Parse DOM
|
||
if ((typeof content === 'string') || (url && (typeof content === 'string'))) {
|
||
app.router.temporaryDom.innerHTML = t7_rendered.content;
|
||
} else {
|
||
if ('length' in content && content.length > 1) {
|
||
for (var ci = 0; ci < content.length; ci++) {
|
||
$(app.router.temporaryDom).append(content[ci]);
|
||
}
|
||
} else {
|
||
$(app.router.temporaryDom).append(content);
|
||
}
|
||
}
|
||
if (pageElement) newPage = $(pageElement);
|
||
else newPage = app.router.findElement('.page', app.router.temporaryDom, view);
|
||
|
||
if (view.params.dynamicNavbar) {
|
||
// Find navbar
|
||
newNavbarInner = app.router.findElement('.navbar-inner', app.router.temporaryDom, view);
|
||
}
|
||
}
|
||
function setPages() {
|
||
// If pages not found or there are still more than one, exit
|
||
if (!newPage || newPage.length === 0) {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
if (view.params.dynamicNavbar && typeof dynamicNavbar === 'undefined') {
|
||
if (!newNavbarInner || newNavbarInner.length === 0) {
|
||
dynamicNavbar = false;
|
||
}
|
||
else {
|
||
dynamicNavbar = true;
|
||
}
|
||
}
|
||
|
||
newPage.addClass('page-on-left').removeClass('cached');
|
||
if (dynamicNavbar) {
|
||
navbar = viewContainer.children('.navbar');
|
||
navbarInners = navbar.find('.navbar-inner:not(.cached)');
|
||
newNavbarInner.addClass('navbar-on-left').removeClass('cached');
|
||
}
|
||
// Remove/hide previous page in force mode
|
||
if (force) {
|
||
var pageToRemove, navbarToRemove;
|
||
pageToRemove = $(pagesInView[pagesInView.length - 2]);
|
||
|
||
if (dynamicNavbar) navbarToRemove = $(pageToRemove[0] && pageToRemove[0].f7RelatedNavbar || navbarInners[navbarInners.length - 2]);
|
||
if (view.params.domCache && view.initialPages.indexOf(pageToRemove[0]) >= 0) {
|
||
if (pageToRemove.length && pageToRemove[0] !== newPage[0]) pageToRemove.addClass('cached');
|
||
if (dynamicNavbar && navbarToRemove.length && navbarToRemove[0] !== newNavbarInner[0]) {
|
||
navbarToRemove.addClass('cached');
|
||
}
|
||
}
|
||
else {
|
||
var removeNavbar = dynamicNavbar && navbarToRemove.length;
|
||
if (pageToRemove.length) {
|
||
app.pageRemoveCallback(view, pageToRemove[0], 'right');
|
||
if (removeNavbar) {
|
||
app.navbarRemoveCallback(view, pageToRemove[0], navbar[0], navbarToRemove[0]);
|
||
}
|
||
app.router._remove(pageToRemove);
|
||
if (removeNavbar) app.router._remove(navbarToRemove);
|
||
}
|
||
else if (removeNavbar) {
|
||
app.navbarRemoveCallback(view, pageToRemove[0], navbar[0], navbarToRemove[0]);
|
||
app.router._remove(navbarToRemove);
|
||
}
|
||
}
|
||
pagesInView = pagesContainer.children('.page:not(.cached)');
|
||
if (dynamicNavbar) {
|
||
navbarInners = viewContainer.children('.navbar').find('.navbar-inner:not(.cached)');
|
||
}
|
||
if (view.history.indexOf(url) >= 0) {
|
||
view.history = view.history.slice(0, view.history.indexOf(url) + 2);
|
||
}
|
||
else {
|
||
if (view.history[[view.history.length - 2]]) {
|
||
view.history[view.history.length - 2] = url;
|
||
}
|
||
else {
|
||
view.history.unshift(url);
|
||
}
|
||
}
|
||
}
|
||
|
||
oldPage = $(pagesInView[pagesInView.length - 1]);
|
||
if (view.params.domCache) {
|
||
if (oldPage[0] === newPage[0]) {
|
||
oldPage = pagesContainer.children('.page.page-on-center');
|
||
if (oldPage.length === 0 && view.activePage) oldPage = $(view.activePage.container);
|
||
}
|
||
}
|
||
|
||
if (dynamicNavbar && !oldNavbarInner) {
|
||
oldNavbarInner = $(navbarInners[navbarInners.length - 1]);
|
||
if (view.params.domCache) {
|
||
if (oldNavbarInner[0] === newNavbarInner[0]) {
|
||
oldNavbarInner = navbar.children('.navbar-inner.navbar-on-center:not(.cached)');
|
||
}
|
||
if (oldNavbarInner.length === 0) {
|
||
oldNavbarInner = navbar.children('.navbar-inner[data-page="'+oldPage.attr('data-page')+'"]');
|
||
}
|
||
}
|
||
if (oldNavbarInner.length === 0 || newNavbarInner[0] === oldNavbarInner[0]) dynamicNavbar = false;
|
||
}
|
||
|
||
if (dynamicNavbar) {
|
||
if (manipulateDom) newNavbarInner.insertBefore(oldNavbarInner);
|
||
newNavbarInner[0].f7RelatedPage = newPage[0];
|
||
newPage[0].f7RelatedNavbar = newNavbarInner[0];
|
||
}
|
||
if (manipulateDom) newPage.insertBefore(oldPage);
|
||
|
||
// Page Init Events
|
||
app.pageInitCallback(view, {
|
||
pageContainer: newPage[0],
|
||
url: url,
|
||
position: 'left',
|
||
navbarInnerContainer: dynamicNavbar ? newNavbarInner[0] : undefined,
|
||
oldNavbarInnerContainer: dynamicNavbar ? oldNavbarInner && oldNavbarInner[0] : undefined,
|
||
context: t7_rendered.context,
|
||
query: options.query,
|
||
fromPage: oldPage && oldPage.length && oldPage[0].f7PageData,
|
||
preloadOnly: preloadOnly
|
||
});
|
||
if (dynamicNavbar) {
|
||
app.navbarInitCallback(view, newPage[0], navbar[0], newNavbarInner[0], url, 'right');
|
||
}
|
||
|
||
if (dynamicNavbar && newNavbarInner.hasClass('navbar-on-left') && animatePages) {
|
||
app.router.prepareNavbar(newNavbarInner, oldNavbarInner, 'left');
|
||
}
|
||
|
||
if (preloadOnly) {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
|
||
// Update View's URL
|
||
view.url = url;
|
||
|
||
// Force reLayout
|
||
var clientLeft = newPage[0].clientLeft;
|
||
|
||
animateBack();
|
||
|
||
// Push state
|
||
if (app.params.pushState && view.main) {
|
||
if (typeof pushState === 'undefined') pushState = true;
|
||
if (!preloadOnly && history.state && pushState) {
|
||
history.back();
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
// Simple go back when we have pages on left
|
||
if (pagesInView.length > 1 && !force) {
|
||
// Exit if only preloadOnly
|
||
if (preloadOnly) {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
// Update View's URL
|
||
view.url = view.history[view.history.length - 2];
|
||
url = view.url;
|
||
|
||
// Define old and new pages
|
||
newPage = $(pagesInView[pagesInView.length - 2]);
|
||
oldPage = $(pagesInView[pagesInView.length - 1]);
|
||
|
||
// Dynamic navbar
|
||
if (view.params.dynamicNavbar) {
|
||
dynamicNavbar = true;
|
||
// Find navbar
|
||
navbarInners = viewContainer.children('.navbar').find('.navbar-inner:not(.cached)');
|
||
newNavbarInner = $(navbarInners[0]);
|
||
oldNavbarInner = $(navbarInners[1]);
|
||
if (newNavbarInner.length === 0 || oldNavbarInner.length === 0 || oldNavbarInner[0] === newNavbarInner[0]) {
|
||
dynamicNavbar = false;
|
||
}
|
||
}
|
||
manipulateDom = false;
|
||
setPages();
|
||
return;
|
||
}
|
||
|
||
if (!force) {
|
||
// Go back when there is no pages on left
|
||
if (!preloadOnly) {
|
||
view.url = view.history[view.history.length - 2];
|
||
url = view.url;
|
||
}
|
||
|
||
if (content) {
|
||
parseNewPage();
|
||
setPages();
|
||
return;
|
||
}
|
||
else if (pageName) {
|
||
// Get dom cached pages
|
||
newPage = $(viewContainer).find('.page[data-page="' + pageName + '"]');
|
||
if (view.params.dynamicNavbar) {
|
||
newNavbarInner = $(viewContainer).children('.navbar').find('.navbar-inner[data-page="' + pageName + '"]');
|
||
if (newNavbarInner.length === 0 && newPage[0].f7RelatedNavbar) {
|
||
newNavbarInner = $(newPage[0].f7RelatedNavbar);
|
||
}
|
||
if (newNavbarInner.length === 0 && newPage[0].f7PageData) {
|
||
newNavbarInner = $(newPage[0].f7PageData.navbarInnerContainer);
|
||
}
|
||
}
|
||
setPages();
|
||
return;
|
||
}
|
||
else if (url && url in view.pageElementsCache) {
|
||
newPage = view.pageElementsCache[url].page;
|
||
newNavbarInner = view.pageElementsCache[url].navbarInner;
|
||
setPages();
|
||
return;
|
||
}
|
||
else {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
}
|
||
else {
|
||
if (url && url === view.url || pageName && view.activePage && view.activePage.name === pageName) {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
// Go back with force url
|
||
if (content) {
|
||
parseNewPage();
|
||
setPages();
|
||
return;
|
||
}
|
||
else if (pageName && view.params.domCache) {
|
||
if (pageName) url = '#' + pageName;
|
||
|
||
newPage = $(viewContainer).find('.page[data-page="' + pageName + '"]');
|
||
if (newPage[0].f7PageData && newPage[0].f7PageData.url) {
|
||
url = newPage[0].f7PageData.url;
|
||
}
|
||
if (view.params.dynamicNavbar) {
|
||
newNavbarInner = $(viewContainer).children('.navbar').find('.navbar-inner[data-page="' + pageName + '"]');
|
||
if (newNavbarInner.length === 0 && newPage[0].f7RelatedNavbar) {
|
||
newNavbarInner = $(newPage[0].f7RelatedNavbar);
|
||
}
|
||
if (newNavbarInner.length === 0 && newPage[0].f7PageData) {
|
||
newNavbarInner = $(newPage[0].f7PageData.navbarInnerContainer);
|
||
}
|
||
}
|
||
setPages();
|
||
return;
|
||
}
|
||
else if (pageElement && url) {
|
||
newPage = $(pageElement);
|
||
if (view.params.dynamicNavbar) {
|
||
newNavbarInner = newPage.find('.navbar-inner');
|
||
if (newNavbarInner.length > 0) {
|
||
newPage.prepend(newNavbarInner);
|
||
app.router._remove(newPage.find('.navbar'));
|
||
}
|
||
}
|
||
setPages();
|
||
return;
|
||
}
|
||
else {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
}
|
||
|
||
};
|
||
app.router.back = function (view, options) {
|
||
options = options || {};
|
||
if (app.router.preroute(view, options, true)) {
|
||
return false;
|
||
}
|
||
var url = options.url;
|
||
var content = options.content;
|
||
var pageName = options.pageName;
|
||
var pageElement = options.pageElement;
|
||
if (pageName) {
|
||
if (pageName.indexOf('?') > 0) {
|
||
options.query = $.parseUrlQuery(pageName);
|
||
options.pageName = pageName = pageName.split('?')[0];
|
||
}
|
||
}
|
||
var force = options.force;
|
||
if (!view.allowPageChange) return false;
|
||
view.allowPageChange = false;
|
||
if (app.xhr && view.xhr && view.xhr === app.xhr) {
|
||
app.xhr.abort();
|
||
app.xhr = false;
|
||
}
|
||
var pagesInView = $(view.pagesContainer).find('.page:not(.cached)');
|
||
|
||
function proceed(content) {
|
||
app.router.preprocess(view, content, url, function (content) {
|
||
options.content = content;
|
||
app.router._back(view, options);
|
||
});
|
||
}
|
||
if (pagesInView.length > 1 && !force) {
|
||
// Simple go back to previos page in view
|
||
app.router._back(view, options);
|
||
return;
|
||
}
|
||
if (!force) {
|
||
url = view.history[view.history.length - 2] || options.url;
|
||
if (!options.url) options.url = url;
|
||
if (!url) {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
if (url.indexOf('#') === 0 && view.contentCache[url]) {
|
||
proceed(view.contentCache[url]);
|
||
return;
|
||
}
|
||
else if (url.indexOf('#') === 0 && view.params.domCache) {
|
||
if (!pageName) options.pageName = url.split('#')[1];
|
||
proceed();
|
||
return;
|
||
}
|
||
else if (url && url in view.pageElementsCache) {
|
||
proceed();
|
||
}
|
||
else if (url.indexOf('#') !== 0) {
|
||
// Load ajax page
|
||
app.get(options.url, view, options.ignoreCache, function (content, error) {
|
||
if (error) {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
proceed(content);
|
||
});
|
||
return;
|
||
}
|
||
}
|
||
else {
|
||
// Go back with force url
|
||
if (!url && content) {
|
||
proceed(content);
|
||
return;
|
||
}
|
||
else if (!url && pageName) {
|
||
if (pageName) url = '#' + pageName;
|
||
proceed();
|
||
return;
|
||
}
|
||
else if (url && pageElement) {
|
||
proceed();
|
||
return;
|
||
}
|
||
else if (url) {
|
||
app.get(options.url, view, options.ignoreCache, function (content, error) {
|
||
if (error) {
|
||
view.allowPageChange = true;
|
||
return;
|
||
}
|
||
proceed(content);
|
||
});
|
||
return;
|
||
}
|
||
}
|
||
view.allowPageChange = true;
|
||
return;
|
||
};
|
||
|
||
app.router.afterBack = function (view, oldPage, newPage) {
|
||
// Remove old page and set classes on new one
|
||
oldPage = $(oldPage);
|
||
newPage = $(newPage);
|
||
|
||
if (view.params.domCache && view.initialPages.indexOf(oldPage[0]) >= 0) {
|
||
oldPage.removeClass('page-from-center-to-right').addClass('cached');
|
||
}
|
||
else {
|
||
app.pageRemoveCallback(view, oldPage[0], 'right');
|
||
app.router._remove(oldPage);
|
||
}
|
||
|
||
newPage.removeClass('page-from-left-to-center page-on-left').addClass('page-on-center');
|
||
view.allowPageChange = true;
|
||
|
||
// Update View's History
|
||
var previousURL = view.history.pop();
|
||
|
||
var newNavbar;
|
||
|
||
// Updated dynamic navbar
|
||
if (view.params.dynamicNavbar) {
|
||
var inners = $(view.container).children('.navbar').find('.navbar-inner:not(.cached)');
|
||
var oldNavbar = $(oldPage[0].f7RelatedNavbar || inners[1]);
|
||
if (view.params.domCache && view.initialNavbars.indexOf(oldNavbar[0]) >= 0) {
|
||
oldNavbar.removeClass('navbar-from-center-to-right').addClass('cached');
|
||
}
|
||
else {
|
||
app.navbarRemoveCallback(view, oldPage[0], undefined, oldNavbar[0]);
|
||
app.router._remove(oldNavbar);
|
||
}
|
||
newNavbar = $(inners[0]).removeClass('navbar-on-left navbar-from-left-to-center').addClass('navbar-on-center');
|
||
}
|
||
|
||
// Remove pages in dom cache
|
||
if (view.params.domCache) {
|
||
$(view.container).find('.page.cached').each(function () {
|
||
var page = $(this);
|
||
var index = page.index();
|
||
var pageUrl = page[0].f7PageData && page[0].f7PageData.url;
|
||
if (pageUrl && view.history.indexOf(pageUrl) < 0 && view.initialPages.indexOf(this) < 0) {
|
||
app.pageRemoveCallback(view, page[0], 'right');
|
||
if (page[0].f7RelatedNavbar && view.params.dynamicNavbar) app.navbarRemoveCallback(view, page[0], undefined, page[0].f7RelatedNavbar);
|
||
app.router._remove(page);
|
||
if (page[0].f7RelatedNavbar && view.params.dynamicNavbar) app.router._remove(page[0].f7RelatedNavbar);
|
||
}
|
||
});
|
||
}
|
||
|
||
// Check previous page is content based only and remove it from content cache
|
||
if (!view.params.domCache &&
|
||
previousURL &&
|
||
previousURL.indexOf('#') > -1 &&
|
||
(previousURL in view.contentCache) &&
|
||
// If the same page is in the history multiple times, don't remove it.
|
||
view.history.indexOf(previousURL) === -1) {
|
||
view.contentCache[previousURL] = null;
|
||
delete view.contentCache[previousURL];
|
||
}
|
||
if (previousURL &&
|
||
(previousURL in view.pageElementsCache) &&
|
||
// If the same page is in the history multiple times, don't remove it.
|
||
view.history.indexOf(previousURL) === -1) {
|
||
view.pageElementsCache[previousURL] = null;
|
||
delete view.pageElementsCache[previousURL];
|
||
}
|
||
// Check for context cache
|
||
if (previousURL &&
|
||
(previousURL in view.contextCache) &&
|
||
// If the same page is in the history multiple times, don't remove it.
|
||
view.history.indexOf(previousURL) === -1) {
|
||
view.contextCache[previousURL] = null;
|
||
delete view.contextCache[previousURL];
|
||
}
|
||
|
||
if (app.params.pushState && view.main) app.pushStateClearQueue();
|
||
|
||
// Preload previous page
|
||
if (view.params.preloadPreviousPage) {
|
||
if (view.params.domCache && view.history.length > 1) {
|
||
var preloadUrl = view.history[view.history.length - 2];
|
||
var previousPage;
|
||
var previousNavbar;
|
||
if (preloadUrl && view.pagesCache[preloadUrl]) {
|
||
// Load by page name
|
||
previousPage = $(view.container).find('.page[data-page="' + view.pagesCache[preloadUrl] + '"]');
|
||
if (previousPage.next('.page')[0] !== newPage[0]) previousPage.insertBefore(newPage);
|
||
if (newNavbar) {
|
||
previousNavbar = $(view.container).children('.navbar').find('.navbar-inner[data-page="' + view.pagesCache[preloadUrl] + '"]');
|
||
if(!previousNavbar || previousNavbar.length === 0) previousNavbar = newNavbar.prev('.navbar-inner.cached');
|
||
if (previousNavbar.next('.navbar-inner')[0] !== newNavbar[0]) previousNavbar.insertBefore(newNavbar);
|
||
}
|
||
}
|
||
else {
|
||
// Just load previous page
|
||
previousPage = newPage.prev('.page.cached');
|
||
if (newNavbar) previousNavbar = newNavbar.prev('.navbar-inner.cached');
|
||
}
|
||
if (previousPage && previousPage.length > 0) previousPage.removeClass('cached page-on-right page-on-center').addClass('page-on-left');
|
||
if (previousNavbar && previousNavbar.length > 0) previousNavbar.removeClass('cached navbar-on-right navbar-on-center').addClass('navbar-on-left');
|
||
}
|
||
else {
|
||
app.router.back(view, {preloadOnly: true});
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
/*======================================================
|
||
************ Modals ************
|
||
======================================================*/
|
||
var _modalTemplateTempDiv = document.createElement('div');
|
||
app.modalStack = [];
|
||
app.modalStackClearQueue = function () {
|
||
if (app.modalStack.length) {
|
||
(app.modalStack.shift())();
|
||
}
|
||
};
|
||
app.modal = function (params) {
|
||
params = params || {};
|
||
var modalHTML = '';
|
||
if (app.params.modalTemplate) {
|
||
if (!app._compiledTemplates.modal) app._compiledTemplates.modal = t7.compile(app.params.modalTemplate);
|
||
modalHTML = app._compiledTemplates.modal(params);
|
||
}
|
||
else {
|
||
var buttonsHTML = '';
|
||
if (params.buttons && params.buttons.length > 0) {
|
||
for (var i = 0; i < params.buttons.length; i++) {
|
||
buttonsHTML += '<span class="modal-button' + (params.buttons[i].bold ? ' modal-button-bold' : '') + '">' + params.buttons[i].text + '</span>';
|
||
}
|
||
}
|
||
var titleHTML = params.title ? '<div class="modal-title">' + params.title + '</div>' : '';
|
||
var textHTML = params.text ? '<div class="modal-text">' + params.text + '</div>' : '';
|
||
var afterTextHTML = params.afterText ? params.afterText : '';
|
||
var noButtons = !params.buttons || params.buttons.length === 0 ? 'modal-no-buttons' : '';
|
||
var verticalButtons = params.verticalButtons ? 'modal-buttons-vertical': '';
|
||
var modalButtonsHTML = params.buttons && params.buttons.length > 0 ? '<div class="modal-buttons modal-buttons-' + params.buttons.length + ' ' + verticalButtons + '">' + buttonsHTML + '</div>' : '';
|
||
modalHTML = '<div class="modal ' + noButtons + ' ' + (params.cssClass || '') + '"><div class="modal-inner">' + (titleHTML + textHTML + afterTextHTML) + '</div>' + modalButtonsHTML + '</div>';
|
||
}
|
||
|
||
_modalTemplateTempDiv.innerHTML = modalHTML;
|
||
|
||
var modal = $(_modalTemplateTempDiv).children();
|
||
|
||
app.root.append(modal[0]);
|
||
|
||
// Add events on buttons
|
||
modal.find('.modal-button').each(function (index, el) {
|
||
$(el).on('click', function (e) {
|
||
if (params.buttons[index].close !== false) app.closeModal(modal);
|
||
if (params.buttons[index].onClick) params.buttons[index].onClick(modal, e);
|
||
if (params.onClick) params.onClick(modal, index);
|
||
});
|
||
});
|
||
app.openModal(modal);
|
||
return modal[0];
|
||
};
|
||
app.alert = function (text, title, callbackOk) {
|
||
if (typeof title === 'function') {
|
||
callbackOk = arguments[1];
|
||
title = undefined;
|
||
}
|
||
return app.modal({
|
||
text: text || '',
|
||
title: typeof title === 'undefined' ? app.params.modalTitle : title,
|
||
buttons: [ {text: app.params.modalButtonOk, bold: true, onClick: callbackOk} ]
|
||
});
|
||
};
|
||
app.confirm = function (text, title, callbackOk, callbackCancel) {
|
||
if (typeof title === 'function') {
|
||
callbackCancel = arguments[2];
|
||
callbackOk = arguments[1];
|
||
title = undefined;
|
||
}
|
||
return app.modal({
|
||
text: text || '',
|
||
title: typeof title === 'undefined' ? app.params.modalTitle : title,
|
||
buttons: [
|
||
{text: app.params.modalButtonCancel, onClick: callbackCancel},
|
||
{text: app.params.modalButtonOk, bold: true, onClick: callbackOk}
|
||
]
|
||
});
|
||
};
|
||
app.prompt = function (text, title, callbackOk, callbackCancel) {
|
||
if (typeof title === 'function') {
|
||
callbackCancel = arguments[2];
|
||
callbackOk = arguments[1];
|
||
title = undefined;
|
||
}
|
||
return app.modal({
|
||
text: text || '',
|
||
title: typeof title === 'undefined' ? app.params.modalTitle : title,
|
||
afterText: '<div class="input-field"><input type="text" class="modal-text-input"></div>',
|
||
buttons: [
|
||
{
|
||
text: app.params.modalButtonCancel
|
||
},
|
||
{
|
||
text: app.params.modalButtonOk,
|
||
bold: true
|
||
}
|
||
],
|
||
onClick: function (modal, index) {
|
||
if (index === 0 && callbackCancel) callbackCancel($(modal).find('.modal-text-input').val());
|
||
if (index === 1 && callbackOk) callbackOk($(modal).find('.modal-text-input').val());
|
||
}
|
||
});
|
||
};
|
||
app.modalLogin = function (text, title, callbackOk, callbackCancel) {
|
||
if (typeof title === 'function') {
|
||
callbackCancel = arguments[2];
|
||
callbackOk = arguments[1];
|
||
title = undefined;
|
||
}
|
||
return app.modal({
|
||
text: text || '',
|
||
title: typeof title === 'undefined' ? app.params.modalTitle : title,
|
||
afterText: '<div class="input-field modal-input-double"><input type="text" name="modal-username" placeholder="' + app.params.modalUsernamePlaceholder + '" class="modal-text-input"></div><div class="input-field modal-input-double"><input type="password" name="modal-password" placeholder="' + app.params.modalPasswordPlaceholder + '" class="modal-text-input"></div>',
|
||
buttons: [
|
||
{
|
||
text: app.params.modalButtonCancel
|
||
},
|
||
{
|
||
text: app.params.modalButtonOk,
|
||
bold: true
|
||
}
|
||
],
|
||
onClick: function (modal, index) {
|
||
var username = $(modal).find('.modal-text-input[name="modal-username"]').val();
|
||
var password = $(modal).find('.modal-text-input[name="modal-password"]').val();
|
||
if (index === 0 && callbackCancel) callbackCancel(username, password);
|
||
if (index === 1 && callbackOk) callbackOk(username, password);
|
||
}
|
||
});
|
||
};
|
||
app.modalPassword = function (text, title, callbackOk, callbackCancel) {
|
||
if (typeof title === 'function') {
|
||
callbackCancel = arguments[2];
|
||
callbackOk = arguments[1];
|
||
title = undefined;
|
||
}
|
||
return app.modal({
|
||
text: text || '',
|
||
title: typeof title === 'undefined' ? app.params.modalTitle : title,
|
||
afterText: '<div class="input-field"><input type="password" name="modal-password" placeholder="' + app.params.modalPasswordPlaceholder + '" class="modal-text-input"></div>',
|
||
buttons: [
|
||
{
|
||
text: app.params.modalButtonCancel
|
||
},
|
||
{
|
||
text: app.params.modalButtonOk,
|
||
bold: true
|
||
}
|
||
],
|
||
onClick: function (modal, index) {
|
||
var password = $(modal).find('.modal-text-input[name="modal-password"]').val();
|
||
if (index === 0 && callbackCancel) callbackCancel(password);
|
||
if (index === 1 && callbackOk) callbackOk(password);
|
||
}
|
||
});
|
||
};
|
||
app.showPreloader = function (title) {
|
||
return app.modal({
|
||
title: title || app.params.modalPreloaderTitle,
|
||
text: '<div class="preloader">' + (app.params.material ? app.params.materialPreloaderHtml : '') + '</div>',
|
||
cssClass: 'modal-preloader'
|
||
});
|
||
};
|
||
app.hidePreloader = function () {
|
||
app.closeModal('.modal.modal-in');
|
||
};
|
||
app.showIndicator = function () {
|
||
if ($('.preloader-indicator-overlay').length > 0) return;
|
||
app.root.append('<div class="preloader-indicator-overlay"></div><div class="preloader-indicator-modal"><span class="preloader preloader-white">' + (app.params.material ? app.params.materialPreloaderHtml : '') + '</span></div>');
|
||
};
|
||
app.hideIndicator = function () {
|
||
$('.preloader-indicator-overlay, .preloader-indicator-modal').remove();
|
||
};
|
||
// Action Sheet
|
||
app.actions = function (target, params) {
|
||
var toPopover = false, modal, groupSelector, buttonSelector;
|
||
if (arguments.length === 1) {
|
||
// Actions
|
||
params = target;
|
||
}
|
||
else {
|
||
// Popover
|
||
if (app.device.ios) {
|
||
if (app.device.ipad) toPopover = true;
|
||
}
|
||
else {
|
||
if ($(window).width() >= 768) toPopover = true;
|
||
}
|
||
}
|
||
params = params || [];
|
||
|
||
if (params.length > 0 && !$.isArray(params[0])) {
|
||
params = [params];
|
||
}
|
||
var modalHTML;
|
||
if (toPopover) {
|
||
var actionsToPopoverTemplate = app.params.modalActionsToPopoverTemplate ||
|
||
'<div class="popover actions-popover">' +
|
||
'<div class="popover-inner">' +
|
||
'{{#each this}}' +
|
||
'<div class="list-block">' +
|
||
'<ul>' +
|
||
'{{#each this}}' +
|
||
'{{#if label}}' +
|
||
'<li class="actions-popover-label {{#if color}}color-{{color}}{{/if}} {{#if bold}}actions-popover-bold{{/if}}">{{text}}</li>' +
|
||
'{{else}}' +
|
||
'<li><a href="#" class="item-link list-button {{#if color}}color-{{color}}{{/if}} {{#if bg}}bg-{{bg}}{{/if}} {{#if bold}}actions-popover-bold{{/if}} {{#if disabled}}disabled{{/if}}">{{text}}</a></li>' +
|
||
'{{/if}}' +
|
||
'{{/each}}' +
|
||
'</ul>' +
|
||
'</div>' +
|
||
'{{/each}}' +
|
||
'</div>' +
|
||
'</div>';
|
||
if (!app._compiledTemplates.actionsToPopover) {
|
||
app._compiledTemplates.actionsToPopover = t7.compile(actionsToPopoverTemplate);
|
||
}
|
||
var popoverHTML = app._compiledTemplates.actionsToPopover(params);
|
||
modal = $(app.popover(popoverHTML, target, true));
|
||
groupSelector = '.list-block ul';
|
||
buttonSelector = '.list-button';
|
||
}
|
||
else {
|
||
if (app.params.modalActionsTemplate) {
|
||
if (!app._compiledTemplates.actions) app._compiledTemplates.actions = t7.compile(app.params.modalActionsTemplate);
|
||
modalHTML = app._compiledTemplates.actions(params);
|
||
}
|
||
else {
|
||
var buttonsHTML = '';
|
||
for (var i = 0; i < params.length; i++) {
|
||
for (var j = 0; j < params[i].length; j++) {
|
||
if (j === 0) buttonsHTML += '<div class="actions-modal-group">';
|
||
var button = params[i][j];
|
||
var buttonClass = button.label ? 'actions-modal-label' : 'actions-modal-button';
|
||
if (button.bold) buttonClass += ' actions-modal-button-bold';
|
||
if (button.color) buttonClass += ' color-' + button.color;
|
||
if (button.bg) buttonClass += ' bg-' + button.bg;
|
||
if (button.disabled) buttonClass += ' disabled';
|
||
buttonsHTML += '<div class="' + buttonClass + '">' + button.text + '</div>';
|
||
if (j === params[i].length - 1) buttonsHTML += '</div>';
|
||
}
|
||
}
|
||
modalHTML = '<div class="actions-modal">' + buttonsHTML + '</div>';
|
||
}
|
||
_modalTemplateTempDiv.innerHTML = modalHTML;
|
||
modal = $(_modalTemplateTempDiv).children();
|
||
app.root.append(modal[0]);
|
||
groupSelector = '.actions-modal-group';
|
||
buttonSelector = '.actions-modal-button';
|
||
}
|
||
|
||
var groups = modal.find(groupSelector);
|
||
groups.each(function (index, el) {
|
||
var groupIndex = index;
|
||
$(el).children().each(function (index, el) {
|
||
var buttonIndex = index;
|
||
var buttonParams = params[groupIndex][buttonIndex];
|
||
var clickTarget;
|
||
if (!toPopover && $(el).is(buttonSelector)) clickTarget = $(el);
|
||
if (toPopover && $(el).find(buttonSelector).length > 0) clickTarget = $(el).find(buttonSelector);
|
||
|
||
if (clickTarget) {
|
||
clickTarget.on('click', function (e) {
|
||
if (buttonParams.close !== false) app.closeModal(modal);
|
||
if (buttonParams.onClick) buttonParams.onClick(modal, e);
|
||
});
|
||
}
|
||
});
|
||
});
|
||
if (!toPopover) app.openModal(modal);
|
||
return modal[0];
|
||
};
|
||
app.popover = function (modal, target, removeOnClose) {
|
||
if (typeof removeOnClose === 'undefined') removeOnClose = true;
|
||
if (typeof modal === 'string' && modal.indexOf('<') >= 0) {
|
||
var _modal = document.createElement('div');
|
||
_modal.innerHTML = modal.trim();
|
||
if (_modal.childNodes.length > 0) {
|
||
modal = _modal.childNodes[0];
|
||
if (removeOnClose) modal.classList.add('remove-on-close');
|
||
app.root.append(modal);
|
||
}
|
||
else return false; //nothing found
|
||
}
|
||
modal = $(modal);
|
||
target = $(target);
|
||
if (modal.length === 0 || target.length === 0) return false;
|
||
if (modal.parents('body').length === 0) {
|
||
if (removeOnClose) modal.addClass('remove-on-close');
|
||
app.root.append(modal[0]);
|
||
}
|
||
if (modal.find('.popover-angle').length === 0 && !app.params.material) {
|
||
modal.append('<div class="popover-angle"></div>');
|
||
}
|
||
modal.show();
|
||
|
||
var material = app.params.material;
|
||
|
||
function sizePopover() {
|
||
modal.css({left: '', top: ''});
|
||
var modalWidth = modal.width();
|
||
var modalHeight = modal.height(); // 13 - height of angle
|
||
var modalAngle, modalAngleSize = 0, modalAngleLeft, modalAngleTop;
|
||
if (!material) {
|
||
modalAngle = modal.find('.popover-angle');
|
||
modalAngleSize = modalAngle.width() / 2;
|
||
modalAngle.removeClass('on-left on-right on-top on-bottom').css({left: '', top: ''});
|
||
}
|
||
else {
|
||
modal.removeClass('popover-on-left popover-on-right popover-on-top popover-on-bottom').css({left: '', top: ''});
|
||
}
|
||
|
||
var targetWidth = target.outerWidth();
|
||
var targetHeight = target.outerHeight();
|
||
var targetOffset = target.offset();
|
||
var targetParentPage = target.parents('.page');
|
||
if (targetParentPage.length > 0) {
|
||
targetOffset.top = targetOffset.top - targetParentPage[0].scrollTop;
|
||
}
|
||
|
||
var windowHeight = $(window).height();
|
||
var windowWidth = $(window).width();
|
||
|
||
var modalTop = 0;
|
||
var modalLeft = 0;
|
||
var diff = 0;
|
||
// Top Position
|
||
var modalPosition = material ? 'bottom' : 'top';
|
||
if (material) {
|
||
if (modalHeight < windowHeight - targetOffset.top - targetHeight) {
|
||
// On bottom
|
||
modalPosition = 'bottom';
|
||
modalTop = targetOffset.top;
|
||
}
|
||
else if (modalHeight < targetOffset.top) {
|
||
// On top
|
||
modalTop = targetOffset.top - modalHeight + targetHeight;
|
||
modalPosition = 'top';
|
||
}
|
||
else {
|
||
// On middle
|
||
modalPosition = 'bottom';
|
||
modalTop = targetOffset.top;
|
||
}
|
||
|
||
if (modalTop <= 0) {
|
||
modalTop = 8;
|
||
}
|
||
else if (modalTop + modalHeight >= windowHeight) {
|
||
modalTop = windowHeight - modalHeight - 8;
|
||
}
|
||
|
||
// Horizontal Position
|
||
modalLeft = targetOffset.left;
|
||
if (modalLeft + modalWidth >= windowWidth - 8) {
|
||
modalLeft = targetOffset.left + targetWidth - modalWidth - 8;
|
||
}
|
||
if (modalLeft < 8) {
|
||
modalLeft = 8;
|
||
}
|
||
if (modalPosition === 'top') {
|
||
modal.addClass('popover-on-top');
|
||
}
|
||
if (modalPosition === 'bottom') {
|
||
modal.addClass('popover-on-bottom');
|
||
}
|
||
if (target.hasClass('floating-button-to-popover') && !modal.hasClass('modal-in')) {
|
||
modal.addClass('popover-floating-button');
|
||
var diffX = (modalLeft + modalWidth / 2) - (targetOffset.left + targetWidth / 2),
|
||
diffY = (modalTop + modalHeight / 2) - (targetOffset.top + targetHeight / 2);
|
||
target
|
||
.addClass('floating-button-to-popover-in')
|
||
.transform('translate3d(' + diffX + 'px, ' + diffY + 'px,0)')
|
||
.transitionEnd(function (e) {
|
||
if (!target.hasClass('floating-button-to-popover-in')) return;
|
||
target
|
||
.addClass('floating-button-to-popover-scale')
|
||
.transform('translate3d(' + diffX + 'px, ' + diffY + 'px,0) scale(' + (modalWidth/targetWidth) + ', ' + (modalHeight/targetHeight) + ')');
|
||
});
|
||
|
||
modal.once('close', function () {
|
||
target
|
||
.removeClass('floating-button-to-popover-in floating-button-to-popover-scale')
|
||
.addClass('floating-button-to-popover-out')
|
||
.transform('')
|
||
.transitionEnd(function (e) {
|
||
target.removeClass('floating-button-to-popover-out');
|
||
});
|
||
});
|
||
modal.once('closed', function () {
|
||
modal.removeClass('popover-floating-button');
|
||
});
|
||
}
|
||
|
||
}
|
||
else {
|
||
if ((modalHeight + modalAngleSize) < targetOffset.top) {
|
||
// On top
|
||
modalTop = targetOffset.top - modalHeight - modalAngleSize;
|
||
}
|
||
else if ((modalHeight + modalAngleSize) < windowHeight - targetOffset.top - targetHeight) {
|
||
// On bottom
|
||
modalPosition = 'bottom';
|
||
modalTop = targetOffset.top + targetHeight + modalAngleSize;
|
||
}
|
||
else {
|
||
// On middle
|
||
modalPosition = 'middle';
|
||
modalTop = targetHeight / 2 + targetOffset.top - modalHeight / 2;
|
||
diff = modalTop;
|
||
if (modalTop <= 0) {
|
||
modalTop = 5;
|
||
}
|
||
else if (modalTop + modalHeight >= windowHeight) {
|
||
modalTop = windowHeight - modalHeight - 5;
|
||
}
|
||
diff = diff - modalTop;
|
||
}
|
||
|
||
// Horizontal Position
|
||
if (modalPosition === 'top' || modalPosition === 'bottom') {
|
||
modalLeft = targetWidth / 2 + targetOffset.left - modalWidth / 2;
|
||
diff = modalLeft;
|
||
if (modalLeft < 5) modalLeft = 5;
|
||
if (modalLeft + modalWidth > windowWidth) modalLeft = windowWidth - modalWidth - 5;
|
||
if (modalPosition === 'top') {
|
||
modalAngle.addClass('on-bottom');
|
||
}
|
||
if (modalPosition === 'bottom') {
|
||
modalAngle.addClass('on-top');
|
||
}
|
||
diff = diff - modalLeft;
|
||
modalAngleLeft = (modalWidth / 2 - modalAngleSize + diff);
|
||
modalAngleLeft = Math.max(Math.min(modalAngleLeft, modalWidth - modalAngleSize * 2 - 13), 13);
|
||
modalAngle.css({left: modalAngleLeft + 'px'});
|
||
|
||
}
|
||
else if (modalPosition === 'middle') {
|
||
modalLeft = targetOffset.left - modalWidth - modalAngleSize;
|
||
modalAngle.addClass('on-right');
|
||
if (modalLeft < 5 || (modalLeft + modalWidth > windowWidth)) {
|
||
if (modalLeft < 5) modalLeft = targetOffset.left + targetWidth + modalAngleSize;
|
||
if (modalLeft + modalWidth > windowWidth) modalLeft = windowWidth - modalWidth - 5;
|
||
modalAngle.removeClass('on-right').addClass('on-left');
|
||
}
|
||
modalAngleTop = (modalHeight / 2 - modalAngleSize + diff);
|
||
modalAngleTop = Math.max(Math.min(modalAngleTop, modalHeight - modalAngleSize * 2 - 13), 13);
|
||
modalAngle.css({top: modalAngleTop + 'px'});
|
||
}
|
||
}
|
||
|
||
|
||
// Apply Styles
|
||
modal.css({top: modalTop + 'px', left: modalLeft + 'px'});
|
||
}
|
||
|
||
sizePopover();
|
||
|
||
$(window).on('resize', sizePopover);
|
||
|
||
modal.on('close', function () {
|
||
$(window).off('resize', sizePopover);
|
||
});
|
||
|
||
app.openModal(modal);
|
||
return modal[0];
|
||
};
|
||
app.popup = function (modal, removeOnClose) {
|
||
if (typeof removeOnClose === 'undefined') removeOnClose = true;
|
||
if (typeof modal === 'string' && modal.indexOf('<') >= 0) {
|
||
var _modal = document.createElement('div');
|
||
_modal.innerHTML = modal.trim();
|
||
if (_modal.childNodes.length > 0) {
|
||
modal = _modal.childNodes[0];
|
||
if (removeOnClose) modal.classList.add('remove-on-close');
|
||
app.root.append(modal);
|
||
}
|
||
else return false; //nothing found
|
||
}
|
||
modal = $(modal);
|
||
if (modal.length === 0) return false;
|
||
if (modal.parents('body').length === 0) {
|
||
if (removeOnClose) modal.addClass('remove-on-close');
|
||
app.root.append(modal[0]);
|
||
}
|
||
modal.show();
|
||
|
||
app.openModal(modal);
|
||
return modal[0];
|
||
};
|
||
app.pickerModal = function (modal, removeOnClose) {
|
||
if (typeof removeOnClose === 'undefined') removeOnClose = true;
|
||
if (typeof modal === 'string' && modal.indexOf('<') >= 0) {
|
||
modal = $(modal);
|
||
if (modal.length > 0) {
|
||
if (removeOnClose) modal.addClass('remove-on-close');
|
||
app.root.append(modal[0]);
|
||
}
|
||
else return false; //nothing found
|
||
}
|
||
modal = $(modal);
|
||
if (modal.length === 0) return false;
|
||
if (modal.parents('body').length === 0) {
|
||
if (removeOnClose) modal.addClass('remove-on-close');
|
||
app.root.append(modal[0]);
|
||
}
|
||
if ($('.picker-modal.modal-in:not(.modal-out)').length > 0 && !modal.hasClass('modal-in')) {
|
||
app.closeModal('.picker-modal.modal-in:not(.modal-out)');
|
||
}
|
||
modal.show();
|
||
app.openModal(modal);
|
||
return modal[0];
|
||
};
|
||
app.loginScreen = function (modal) {
|
||
if (!modal) modal = '.login-screen';
|
||
modal = $(modal);
|
||
if (modal.length === 0) return false;
|
||
if ($('.login-screen.modal-in:not(.modal-out)').length > 0 && !modal.hasClass('modal-in')) {
|
||
app.closeModal('.login-screen.modal-in:not(.modal-out)');
|
||
}
|
||
modal.show();
|
||
|
||
app.openModal(modal);
|
||
return modal[0];
|
||
};
|
||
app.openModal = function (modal) {
|
||
modal = $(modal);
|
||
var isModal = modal.hasClass('modal');
|
||
if ($('.modal.modal-in:not(.modal-out)').length && app.params.modalStack && isModal) {
|
||
app.modalStack.push(function () {
|
||
app.openModal(modal);
|
||
});
|
||
return;
|
||
}
|
||
// do nothing if this modal already shown
|
||
if (true === modal.data('f7-modal-shown')) {
|
||
return;
|
||
}
|
||
modal.data('f7-modal-shown', true);
|
||
modal.once('close', function() {
|
||
modal.removeData('f7-modal-shown');
|
||
});
|
||
var isPopover = modal.hasClass('popover');
|
||
var isPopup = modal.hasClass('popup');
|
||
var isLoginScreen = modal.hasClass('login-screen');
|
||
var isPickerModal = modal.hasClass('picker-modal');
|
||
if (isModal) {
|
||
modal.show();
|
||
modal.css({
|
||
marginTop: - Math.round(modal.outerHeight() / 2) + 'px'
|
||
});
|
||
}
|
||
|
||
var overlay;
|
||
if (!isLoginScreen && !isPickerModal) {
|
||
if ($('.modal-overlay').length === 0 && !isPopup) {
|
||
app.root.append('<div class="modal-overlay"></div>');
|
||
}
|
||
if ($('.popup-overlay').length === 0 && isPopup) {
|
||
app.root.append('<div class="popup-overlay"></div>');
|
||
}
|
||
overlay = isPopup ? $('.popup-overlay') : $('.modal-overlay');
|
||
}
|
||
if (app.params.material && isPickerModal) {
|
||
if (modal.hasClass('picker-calendar')) {
|
||
if ($('.picker-modal-overlay').length === 0 && !isPopup) {
|
||
app.root.append('<div class="picker-modal-overlay"></div>');
|
||
}
|
||
overlay = $('.picker-modal-overlay');
|
||
}
|
||
}
|
||
|
||
//Make sure that styles are applied, trigger relayout;
|
||
var clientLeft = modal[0].clientLeft;
|
||
|
||
// Trugger open event
|
||
modal.trigger('open');
|
||
|
||
// Picker modal body class
|
||
if (isPickerModal) {
|
||
$('body').addClass('with-picker-modal');
|
||
}
|
||
|
||
// Init Pages and Navbars in modal
|
||
if (modal.find('.' + app.params.viewClass).length > 0) {
|
||
modal.find('.page').each(function () {
|
||
app.initPageWithCallback(this);
|
||
});
|
||
modal.find('.navbar').each(function () {
|
||
app.initNavbarWithCallback(this);
|
||
});
|
||
}
|
||
|
||
// Classes for transition in
|
||
if (!isLoginScreen && !isPickerModal) overlay.addClass('modal-overlay-visible');
|
||
if (app.params.material && isPickerModal && overlay) overlay.addClass('modal-overlay-visible');
|
||
modal.removeClass('modal-out').addClass('modal-in').transitionEnd(function (e) {
|
||
if (modal.hasClass('modal-out')) modal.trigger('closed');
|
||
else modal.trigger('opened');
|
||
});
|
||
return true;
|
||
};
|
||
app.closeModal = function (modal) {
|
||
modal = $(modal || '.modal-in');
|
||
if (typeof modal !== 'undefined' && modal.length === 0) {
|
||
return;
|
||
}
|
||
var isModal = modal.hasClass('modal');
|
||
var isPopover = modal.hasClass('popover');
|
||
var isPopup = modal.hasClass('popup');
|
||
var isLoginScreen = modal.hasClass('login-screen');
|
||
var isPickerModal = modal.hasClass('picker-modal');
|
||
|
||
var removeOnClose = modal.hasClass('remove-on-close');
|
||
|
||
var overlay;
|
||
|
||
if (isPopup) overlay = $('.popup-overlay');
|
||
else {
|
||
if (isPickerModal && app.params.material) overlay = $('.picker-modal-overlay');
|
||
else if (!isPickerModal) overlay = $('.modal-overlay');
|
||
}
|
||
|
||
if (isPopup){
|
||
if (modal.length === $('.popup.modal-in').length) {
|
||
overlay.removeClass('modal-overlay-visible');
|
||
}
|
||
}
|
||
else if (overlay && overlay.length > 0) {
|
||
overlay.removeClass('modal-overlay-visible');
|
||
}
|
||
|
||
modal.trigger('close');
|
||
|
||
// Picker modal body class
|
||
if (isPickerModal) {
|
||
$('body').removeClass('with-picker-modal');
|
||
$('body').addClass('picker-modal-closing');
|
||
}
|
||
|
||
if (!(isPopover && !app.params.material)) {
|
||
modal.removeClass('modal-in').addClass('modal-out').transitionEnd(function (e) {
|
||
if (modal.hasClass('modal-out')) modal.trigger('closed');
|
||
else {
|
||
modal.trigger('opened');
|
||
if (isPopover) return;
|
||
}
|
||
|
||
if (isPickerModal) {
|
||
$('body').removeClass('picker-modal-closing');
|
||
}
|
||
if (isPopup || isLoginScreen || isPickerModal || isPopover) {
|
||
modal.removeClass('modal-out').hide();
|
||
if (removeOnClose && modal.length > 0) {
|
||
modal.remove();
|
||
}
|
||
}
|
||
else {
|
||
modal.remove();
|
||
}
|
||
});
|
||
if (isModal && app.params.modalStack) {
|
||
app.modalStackClearQueue();
|
||
}
|
||
}
|
||
else {
|
||
modal.removeClass('modal-in modal-out').trigger('closed').hide();
|
||
if (removeOnClose) {
|
||
modal.remove();
|
||
}
|
||
}
|
||
return true;
|
||
};
|
||
|
||
|
||
/*===============================================================================
|
||
************ Progress Bar ************
|
||
===============================================================================*/
|
||
app.setProgressbar = function (container, progress, speed) {
|
||
container = $(container || app.root);
|
||
if (container.length === 0) return;
|
||
if (progress) progress = Math.min(Math.max(progress, 0), 100);
|
||
var progressbar;
|
||
if (container.hasClass('progressbar')) progressbar = container;
|
||
else {
|
||
progressbar = container.children('.progressbar');
|
||
}
|
||
if (progressbar.length === 0 || progressbar.hasClass('progressbar-infinite')) return;
|
||
var clientLeft = progressbar[0].clientLeft;
|
||
progressbar.children('span').transform('translate3d(' + (-100 + progress) + '%,0,0)');
|
||
if (typeof speed !== 'undefined') {
|
||
progressbar.children('span').transition(speed);
|
||
}
|
||
else {
|
||
progressbar.children('span').transition('');
|
||
}
|
||
return progressbar[0];
|
||
};
|
||
app.showProgressbar = function (container, progress, color) {
|
||
if (typeof container === 'number') {
|
||
container = app.root;
|
||
progress = arguments[0];
|
||
color = arguments[1];
|
||
}
|
||
if (progress && typeof progress === 'string' && parseFloat(progress) !== progress * 1) {
|
||
color = progress;
|
||
progress = undefined;
|
||
}
|
||
container = $(container || app.root);
|
||
if (container.length === 0) return;
|
||
var progressbar;
|
||
if (container.hasClass('progressbar')) progressbar = container;
|
||
else {
|
||
progressbar = container.children('.progressbar:not(.progressbar-out), .progressbar-infinite:not(.progressbar-out)');
|
||
if (progressbar.length === 0) {
|
||
// Create one
|
||
if (typeof progress !== 'undefined') {
|
||
// Determined
|
||
progressbar = $('<span class="progressbar progressbar-in' + (color ? ' color-' + color : '') + '"><span></span></span>');
|
||
}
|
||
else {
|
||
// Infinite
|
||
progressbar = $('<span class="progressbar-infinite progressbar-in' + (color ? ' color-' + color : '') + '"></span>');
|
||
}
|
||
container.append(progressbar);
|
||
}
|
||
}
|
||
if (progress) app.setProgressbar(container, progress);
|
||
return progressbar[0];
|
||
};
|
||
app.hideProgressbar = function (container) {
|
||
container = $(container || app.root);
|
||
if (container.length === 0) return;
|
||
var progressbar;
|
||
if (container.hasClass('progressbar')) progressbar = container;
|
||
else {
|
||
progressbar = container.children('.progressbar, .progressbar-infinite');
|
||
}
|
||
if (progressbar.length === 0 || !progressbar.hasClass('progressbar-in') || progressbar.hasClass('progressbar-out')) return;
|
||
progressbar.removeClass('progressbar-in').addClass('progressbar-out').animationEnd(function () {
|
||
progressbar.remove();
|
||
progressbar = null;
|
||
});
|
||
return;
|
||
};
|
||
app.initPageProgressbar = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
pageContainer.find('.progressbar').each(function () {
|
||
var p = $(this);
|
||
if (p.children('span').length === 0) p.append('<span></span>');
|
||
if (p.attr('data-progress')) app.setProgressbar(p, p.attr('data-progress'));
|
||
});
|
||
};
|
||
|
||
/*======================================================
|
||
************ Panels ************
|
||
======================================================*/
|
||
app.allowPanelOpen = true;
|
||
app.openPanel = function (panelPosition) {
|
||
if (!app.allowPanelOpen) return false;
|
||
var panel = $('.panel-' + panelPosition);
|
||
if (panel.length === 0 || panel.hasClass('active')) return false;
|
||
app.closePanel(); // Close if some panel is opened
|
||
app.allowPanelOpen = false;
|
||
var effect = panel.hasClass('panel-reveal') ? 'reveal' : 'cover';
|
||
panel.css({display: 'block'}).addClass('active');
|
||
panel.trigger('open');
|
||
if (app.params.material) {
|
||
$('.panel-overlay').show();
|
||
}
|
||
if (panel.find('.' + app.params.viewClass).length > 0) {
|
||
if (app.sizeNavbars) app.sizeNavbars(panel.find('.' + app.params.viewClass)[0]);
|
||
}
|
||
|
||
// Trigger reLayout
|
||
var clientLeft = panel[0].clientLeft;
|
||
|
||
// Transition End;
|
||
var transitionEndTarget = effect === 'reveal' ? $('.' + app.params.viewsClass) : panel;
|
||
var openedTriggered = false;
|
||
|
||
function panelTransitionEnd() {
|
||
transitionEndTarget.transitionEnd(function (e) {
|
||
if ($(e.target).is(transitionEndTarget)) {
|
||
if (panel.hasClass('active')) {
|
||
panel.trigger('opened');
|
||
}
|
||
else {
|
||
panel.trigger('closed');
|
||
}
|
||
if (app.params.material) $('.panel-overlay').css({display: ''});
|
||
app.allowPanelOpen = true;
|
||
}
|
||
else panelTransitionEnd();
|
||
});
|
||
}
|
||
panelTransitionEnd();
|
||
|
||
$('body').addClass('with-panel-' + panelPosition + '-' + effect);
|
||
return true;
|
||
};
|
||
app.closePanel = function () {
|
||
var activePanel = $('.panel.active');
|
||
if (activePanel.length === 0) return false;
|
||
var effect = activePanel.hasClass('panel-reveal') ? 'reveal' : 'cover';
|
||
var panelPosition = activePanel.hasClass('panel-left') ? 'left' : 'right';
|
||
activePanel.removeClass('active');
|
||
var transitionEndTarget = effect === 'reveal' ? $('.' + app.params.viewsClass) : activePanel;
|
||
activePanel.trigger('close');
|
||
app.allowPanelOpen = false;
|
||
|
||
transitionEndTarget.transitionEnd(function () {
|
||
if (activePanel.hasClass('active')) return;
|
||
activePanel.css({display: ''});
|
||
activePanel.trigger('closed');
|
||
$('body').removeClass('panel-closing');
|
||
app.allowPanelOpen = true;
|
||
});
|
||
|
||
$('body').addClass('panel-closing').removeClass('with-panel-' + panelPosition + '-' + effect);
|
||
};
|
||
/*======================================================
|
||
************ Swipe panels ************
|
||
======================================================*/
|
||
app.initSwipePanels = function () {
|
||
var panel, side;
|
||
if (app.params.swipePanel) {
|
||
panel = $('.panel.panel-' + app.params.swipePanel);
|
||
side = app.params.swipePanel;
|
||
if (panel.length === 0 && side !== 'both') return;
|
||
}
|
||
else {
|
||
if (app.params.swipePanelOnlyClose) {
|
||
if ($('.panel').length === 0) return;
|
||
}
|
||
else return;
|
||
}
|
||
|
||
var panelOverlay = $('.panel-overlay');
|
||
var isTouched, isMoved, isScrolling, touchesStart = {}, touchStartTime, touchesDiff, translate, overlayOpacity, opened, panelWidth, effect, direction;
|
||
var views = $('.' + app.params.viewsClass);
|
||
|
||
function handleTouchStart(e) {
|
||
if (!app.allowPanelOpen || (!app.params.swipePanel && !app.params.swipePanelOnlyClose) || isTouched) return;
|
||
if ($('.modal-in, .photo-browser-in').length > 0) return;
|
||
if (!(app.params.swipePanelCloseOpposite || app.params.swipePanelOnlyClose)) {
|
||
if ($('.panel.active').length > 0 && !panel.hasClass('active')) return;
|
||
}
|
||
touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
|
||
touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
|
||
if (app.params.swipePanelCloseOpposite || app.params.swipePanelOnlyClose) {
|
||
if ($('.panel.active').length > 0) {
|
||
side = $('.panel.active').hasClass('panel-left') ? 'left' : 'right';
|
||
}
|
||
else {
|
||
if (app.params.swipePanelOnlyClose) return;
|
||
side = app.params.swipePanel;
|
||
}
|
||
if (!side) return;
|
||
}
|
||
panel = $('.panel.panel-' + side);
|
||
opened = panel.hasClass('active');
|
||
if (app.params.swipePanelActiveArea && !opened) {
|
||
if (side === 'left') {
|
||
if (touchesStart.x > app.params.swipePanelActiveArea) return;
|
||
}
|
||
if (side === 'right') {
|
||
if (touchesStart.x < window.innerWidth - app.params.swipePanelActiveArea) return;
|
||
}
|
||
}
|
||
isMoved = false;
|
||
isTouched = true;
|
||
isScrolling = undefined;
|
||
|
||
touchStartTime = (new Date()).getTime();
|
||
direction = undefined;
|
||
}
|
||
function handleTouchMove(e) {
|
||
if (!isTouched) return;
|
||
if (e.f7PreventPanelSwipe) return;
|
||
var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
|
||
var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
if (typeof isScrolling === 'undefined') {
|
||
isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));
|
||
}
|
||
if (isScrolling) {
|
||
isTouched = false;
|
||
return;
|
||
}
|
||
if (!direction) {
|
||
if (pageX > touchesStart.x) {
|
||
direction = 'to-right';
|
||
}
|
||
else {
|
||
direction = 'to-left';
|
||
}
|
||
|
||
if(side === 'both'){
|
||
if ($('.panel.active').length > 0) {
|
||
side = $('.panel.active').hasClass('panel-left') ? 'left' : 'right';
|
||
}
|
||
else {
|
||
side = direction === 'to-right' ? 'left' : 'right';
|
||
}
|
||
panel = $('.panel.panel-' + side);
|
||
}
|
||
|
||
if (
|
||
side === 'left' &&
|
||
(
|
||
direction === 'to-left' && !panel.hasClass('active')
|
||
) ||
|
||
side === 'right' &&
|
||
(
|
||
direction === 'to-right' && !panel.hasClass('active')
|
||
)
|
||
)
|
||
{
|
||
isTouched = false;
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (app.params.swipePanelNoFollow) {
|
||
var timeDiff = (new Date()).getTime() - touchStartTime;
|
||
if (timeDiff < 300) {
|
||
if (direction === 'to-left') {
|
||
if (side === 'right') app.openPanel(side);
|
||
if (side === 'left' && panel.hasClass('active')) app.closePanel();
|
||
}
|
||
if (direction === 'to-right') {
|
||
if (side === 'left') app.openPanel(side);
|
||
if (side === 'right' && panel.hasClass('active')) app.closePanel();
|
||
}
|
||
}
|
||
isTouched = false;
|
||
isMoved = false;
|
||
return;
|
||
}
|
||
|
||
if (!isMoved) {
|
||
effect = panel.hasClass('panel-cover') ? 'cover' : 'reveal';
|
||
if (!opened) {
|
||
panel.show();
|
||
panelOverlay.show();
|
||
}
|
||
panelWidth = panel[0].offsetWidth;
|
||
panel.transition(0);
|
||
if (panel.find('.' + app.params.viewClass).length > 0) {
|
||
if (app.sizeNavbars) app.sizeNavbars(panel.find('.' + app.params.viewClass)[0]);
|
||
}
|
||
}
|
||
|
||
isMoved = true;
|
||
|
||
e.preventDefault();
|
||
var threshold = opened ? 0 : -app.params.swipePanelThreshold;
|
||
if (side === 'right') threshold = -threshold;
|
||
|
||
touchesDiff = pageX - touchesStart.x + threshold;
|
||
|
||
if (side === 'right') {
|
||
translate = touchesDiff - (opened ? panelWidth : 0);
|
||
if (translate > 0) translate = 0;
|
||
if (translate < -panelWidth) {
|
||
translate = -panelWidth;
|
||
}
|
||
}
|
||
else {
|
||
translate = touchesDiff + (opened ? panelWidth : 0);
|
||
if (translate < 0) translate = 0;
|
||
if (translate > panelWidth) {
|
||
translate = panelWidth;
|
||
}
|
||
}
|
||
if (effect === 'reveal') {
|
||
views.transform('translate3d(' + translate + 'px,0,0)').transition(0);
|
||
panelOverlay.transform('translate3d(' + translate + 'px,0,0)').transition(0);
|
||
|
||
app.pluginHook('swipePanelSetTransform', views[0], panel[0], Math.abs(translate / panelWidth));
|
||
}
|
||
else {
|
||
panel.transform('translate3d(' + translate + 'px,0,0)').transition(0);
|
||
if (app.params.material) {
|
||
panelOverlay.transition(0);
|
||
overlayOpacity = Math.abs(translate/panelWidth);
|
||
panelOverlay.css({opacity: overlayOpacity});
|
||
}
|
||
app.pluginHook('swipePanelSetTransform', views[0], panel[0], Math.abs(translate / panelWidth));
|
||
}
|
||
}
|
||
function handleTouchEnd(e) {
|
||
if (!isTouched || !isMoved) {
|
||
isTouched = false;
|
||
isMoved = false;
|
||
return;
|
||
}
|
||
isTouched = false;
|
||
isMoved = false;
|
||
var timeDiff = (new Date()).getTime() - touchStartTime;
|
||
var action;
|
||
var edge = (translate === 0 || Math.abs(translate) === panelWidth);
|
||
|
||
if (!opened) {
|
||
if (translate === 0) {
|
||
action = 'reset';
|
||
}
|
||
else if (
|
||
timeDiff < 300 && Math.abs(translate) > 0 ||
|
||
timeDiff >= 300 && (Math.abs(translate) >= panelWidth / 2)
|
||
) {
|
||
action = 'swap';
|
||
}
|
||
else {
|
||
action = 'reset';
|
||
}
|
||
}
|
||
else {
|
||
if (translate === -panelWidth) {
|
||
action = 'reset';
|
||
}
|
||
else if (
|
||
timeDiff < 300 && Math.abs(translate) >= 0 ||
|
||
timeDiff >= 300 && (Math.abs(translate) <= panelWidth / 2)
|
||
) {
|
||
if (side === 'left' && translate === panelWidth) action = 'reset';
|
||
else action = 'swap';
|
||
}
|
||
else {
|
||
action = 'reset';
|
||
}
|
||
}
|
||
if (action === 'swap') {
|
||
app.allowPanelOpen = true;
|
||
if (opened) {
|
||
app.closePanel();
|
||
if (edge) {
|
||
panel.css({display: ''});
|
||
$('body').removeClass('panel-closing');
|
||
}
|
||
}
|
||
else {
|
||
app.openPanel(side);
|
||
}
|
||
if (edge) app.allowPanelOpen = true;
|
||
}
|
||
if (action === 'reset') {
|
||
if (opened) {
|
||
app.allowPanelOpen = true;
|
||
app.openPanel(side);
|
||
}
|
||
else {
|
||
app.closePanel();
|
||
if (edge) {
|
||
app.allowPanelOpen = true;
|
||
panel.css({display: ''});
|
||
}
|
||
else {
|
||
var target = effect === 'reveal' ? views : panel;
|
||
panel.trigger('close');
|
||
$('body').addClass('panel-closing');
|
||
target.transitionEnd(function () {
|
||
panel.trigger('closed');
|
||
panel.css({display: ''});
|
||
$('body').removeClass('panel-closing');
|
||
app.allowPanelOpen = true;
|
||
});
|
||
}
|
||
}
|
||
}
|
||
if (effect === 'reveal') {
|
||
views.transition('');
|
||
views.transform('');
|
||
}
|
||
panel.transition('').transform('');
|
||
panelOverlay.css({display: ''}).transform('').transition('').css('opacity', '');
|
||
}
|
||
var passiveListener = app.touchEvents.start === 'touchstart' && app.support.passiveListener ? {passive: true, capture: false} : false;
|
||
$(document).on(app.touchEvents.start, handleTouchStart, passiveListener);
|
||
$(document).on(app.touchEvents.move, handleTouchMove);
|
||
$(document).on(app.touchEvents.end, handleTouchEnd, passiveListener);
|
||
};
|
||
|
||
|
||
/*======================================================
|
||
************ Image Lazy Loading ************
|
||
************ Based on solution by Marc Godard, https://github.com/MarcGodard ************
|
||
======================================================*/
|
||
app.initImagesLazyLoad = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
|
||
// Lazy images
|
||
var lazyLoadImages;
|
||
if (pageContainer.hasClass('lazy')) {
|
||
lazyLoadImages = pageContainer;
|
||
pageContainer = lazyLoadImages.parents('.page');
|
||
}
|
||
else {
|
||
lazyLoadImages = pageContainer.find('.lazy');
|
||
}
|
||
if (lazyLoadImages.length === 0) return;
|
||
|
||
// Scrollable page content
|
||
var pageContent;
|
||
if (pageContainer.hasClass('page-content')) {
|
||
pageContent = pageContainer;
|
||
pageContainer = pageContainer.parents('.page');
|
||
}
|
||
else {
|
||
pageContent = pageContainer.find('.page-content');
|
||
}
|
||
if (pageContent.length === 0) return;
|
||
|
||
// Placeholder
|
||
var placeholderSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEXCwsK592mkAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==';
|
||
if (typeof app.params.imagesLazyLoadPlaceholder === 'string') {
|
||
placeholderSrc = app.params.imagesLazyLoadPlaceholder;
|
||
}
|
||
if (app.params.imagesLazyLoadPlaceholder !== false) lazyLoadImages.each(function(){
|
||
if ($(this).attr('data-src')) $(this).attr('src', placeholderSrc);
|
||
});
|
||
|
||
// load image
|
||
var imagesSequence = [];
|
||
var imageIsLoading = false;
|
||
function loadImage(el) {
|
||
el = $(el);
|
||
|
||
var bg = el.attr('data-background');
|
||
var src = bg ? bg : el.attr('data-src');
|
||
if (!src) return;
|
||
|
||
function onLoad() {
|
||
el.removeClass('lazy').addClass('lazy-loaded');
|
||
if (bg) {
|
||
el.css('background-image', 'url(' + src + ')');
|
||
}
|
||
else {
|
||
el.attr('src', src);
|
||
}
|
||
|
||
if (app.params.imagesLazyLoadSequential) {
|
||
imageIsLoading = false;
|
||
if (imagesSequence.length > 0) {
|
||
loadImage(imagesSequence.shift());
|
||
}
|
||
}
|
||
}
|
||
|
||
if (app.params.imagesLazyLoadSequential) {
|
||
if (imageIsLoading) {
|
||
if (imagesSequence.indexOf(el[0]) < 0) imagesSequence.push(el[0]);
|
||
return;
|
||
}
|
||
}
|
||
|
||
// Loading flag
|
||
imageIsLoading = true;
|
||
|
||
var image = new Image();
|
||
image.onload = onLoad;
|
||
image.onerror = onLoad;
|
||
image.src =src;
|
||
}
|
||
function lazyHandler() {
|
||
lazyLoadImages = pageContainer.find('.lazy');
|
||
lazyLoadImages.each(function(index, el) {
|
||
el = $(el);
|
||
if (el.parents('.tab:not(.active)').length > 0) {
|
||
return;
|
||
}
|
||
if (isElementInViewport(el[0])) {
|
||
loadImage(el);
|
||
}
|
||
});
|
||
}
|
||
|
||
function isElementInViewport (el) {
|
||
var rect = el.getBoundingClientRect();
|
||
var threshold = app.params.imagesLazyLoadThreshold || 0;
|
||
return (
|
||
rect.top >= (0 - threshold) &&
|
||
rect.left >= (0 - threshold) &&
|
||
rect.top <= (window.innerHeight + threshold) &&
|
||
rect.left <= (window.innerWidth + threshold)
|
||
);
|
||
}
|
||
|
||
function attachEvents(destroy) {
|
||
var method = destroy ? 'off' : 'on';
|
||
lazyLoadImages[method]('lazy', lazyHandler);
|
||
lazyLoadImages.parents('.tab')[method]('show', lazyHandler);
|
||
pageContainer[method]('lazy', lazyHandler);
|
||
pageContent[method]('lazy', lazyHandler);
|
||
pageContent[method]('scroll', lazyHandler);
|
||
$(window)[method]('resize', lazyHandler);
|
||
}
|
||
function detachEvents() {
|
||
attachEvents(true);
|
||
}
|
||
|
||
// Store detach function
|
||
pageContainer[0].f7DestroyImagesLazyLoad = detachEvents;
|
||
|
||
// Attach events
|
||
attachEvents();
|
||
|
||
// Destroy on page remove
|
||
if (pageContainer.hasClass('page')) {
|
||
pageContainer.once('pageBeforeRemove', detachEvents);
|
||
}
|
||
|
||
// Run loader on page load/init
|
||
lazyHandler();
|
||
|
||
// Run after page animation
|
||
pageContainer.once('pageAfterAnimation', lazyHandler);
|
||
};
|
||
app.destroyImagesLazyLoad = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
if (pageContainer.length > 0 && pageContainer[0].f7DestroyImagesLazyLoad) {
|
||
pageContainer[0].f7DestroyImagesLazyLoad();
|
||
}
|
||
};
|
||
app.reinitImagesLazyLoad = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
if (pageContainer.length > 0) {
|
||
pageContainer.trigger('lazy');
|
||
}
|
||
};
|
||
|
||
/*======================================================
|
||
************ Material Preloader ************
|
||
======================================================*/
|
||
app.initPageMaterialPreloader = function (pageContainer) {
|
||
$(pageContainer).find('.preloader').each(function () {
|
||
if ($(this).children().length === 0) {
|
||
$(this).html(app.params.materialPreloaderHtml);
|
||
}
|
||
});
|
||
};
|
||
|
||
/*======================================================
|
||
************ Messages ************
|
||
======================================================*/
|
||
var Messages = function (container, params) {
|
||
var defaults = {
|
||
autoLayout: true,
|
||
newMessagesFirst: false,
|
||
scrollMessages: true,
|
||
scrollMessagesOnlyOnEdge: false,
|
||
messageTemplate:
|
||
'{{#if day}}' +
|
||
'<div class="messages-date">{{day}} {{#if time}}, <span>{{time}}</span>{{/if}}</div>' +
|
||
'{{/if}}' +
|
||
'<div class="message message-{{type}} {{#if hasImage}}message-pic{{/if}} {{#if avatar}}message-with-avatar{{/if}} {{#if position}}message-appear-from-{{position}}{{/if}}">' +
|
||
'{{#if name}}<div class="message-name">{{name}}</div>{{/if}}' +
|
||
'<div class="message-text">{{text}}{{#if date}}<div class="message-date">{{date}}</div>{{/if}}</div>' +
|
||
'{{#if avatar}}<div class="message-avatar" style="background-image:url({{avatar}})"></div>{{/if}}' +
|
||
'{{#if label}}<div class="message-label">{{label}}</div>{{/if}}' +
|
||
'</div>'
|
||
};
|
||
params = params || {};
|
||
for (var def in defaults) {
|
||
if (typeof params[def] === 'undefined' || params[def] === null) {
|
||
params[def] = defaults[def];
|
||
}
|
||
}
|
||
|
||
// Instance
|
||
var m = this;
|
||
|
||
// Params
|
||
m.params = params;
|
||
|
||
// Container
|
||
m.container = $(container);
|
||
if (m.container.length === 0) return;
|
||
|
||
// Autolayout
|
||
if (m.params.autoLayout) m.container.addClass('messages-auto-layout');
|
||
|
||
// New messages first
|
||
if (m.params.newMessagesFirst) m.container.addClass('messages-new-first');
|
||
|
||
// Is In Page
|
||
m.pageContainer = m.container.parents('.page').eq(0);
|
||
m.pageContent = m.pageContainer.find('.page-content');
|
||
|
||
// Compiled template
|
||
m.template = Template7.compile(m.params.messageTemplate);
|
||
|
||
// Auto Layout
|
||
m.layout = function () {
|
||
if (!m.container.hasClass('messages-auto-layout')) m.container.addClass('messages-auto-layout');
|
||
m.container.find('.message').each(function () {
|
||
var message = $(this);
|
||
if (message.find('.message-text img').length > 0) {
|
||
var childNodes = message.find('.message-text')[0].childNodes;
|
||
var onlyPic = true;
|
||
for (var i = 0 ; i < childNodes.length; i++) {
|
||
if (childNodes[i].nodeType === 1 && childNodes[i].nodeName.toLowerCase() !== 'img') onlyPic = false;
|
||
if (childNodes[i].nodeType === 3 && childNodes[i].textContent.trim() !== '') onlyPic = false;
|
||
}
|
||
if (onlyPic) message.addClass('message-pic');
|
||
else message.removeClass('message-pic');
|
||
}
|
||
if (message.find('.message-avatar').length > 0) message.addClass('message-with-avatar');
|
||
});
|
||
m.container.find('.message').each(function () {
|
||
var message = $(this);
|
||
var isSent = message.hasClass('message-sent');
|
||
var next = message.next('.message-' + (isSent ? 'sent' : 'received'));
|
||
var prev = message.prev('.message-' + (isSent ? 'sent' : 'received'));
|
||
if (next.length === 0) {
|
||
message.addClass('message-last message-with-tail');
|
||
}
|
||
else message.removeClass('message-last message-with-tail');
|
||
|
||
if (prev.length === 0) {
|
||
message.addClass('message-first');
|
||
}
|
||
else message.removeClass('message-first');
|
||
|
||
if (prev.length > 0 && prev.find('.message-name').length > 0 && message.find('.message-name').length > 0) {
|
||
if (prev.find('.message-name').text() !== message.find('.message-name').text()) {
|
||
prev.addClass('message-last message-with-tail');
|
||
message.addClass('message-first');
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
// Add Message
|
||
m.appendMessage = function (props, animate) {
|
||
return m.addMessage(props, 'append', animate);
|
||
};
|
||
m.prependMessage = function (props, animate) {
|
||
return m.addMessage(props, 'prepend', animate);
|
||
};
|
||
m.addMessage = function (props, method, animate) {
|
||
return m.addMessages([props], method, animate);
|
||
};
|
||
m.addMessages = function (newMessages, method, animate) {
|
||
if (typeof animate === 'undefined') {
|
||
animate = true;
|
||
}
|
||
if (typeof method === 'undefined') {
|
||
method = m.params.newMessagesFirst ? 'prepend' : 'append';
|
||
}
|
||
var newMessagesHTML = '', i;
|
||
for (i = 0; i < newMessages.length; i++) {
|
||
var props = newMessages[i] || {};
|
||
props.type = props.type || 'sent';
|
||
if (!props.text) continue;
|
||
props.hasImage = props.text.indexOf('<img') >= 0;
|
||
if (props.onlyImage === false) props.hasImage = false;
|
||
if (animate) props.position = method === 'append' ? 'bottom' : 'top';
|
||
|
||
newMessagesHTML += m.template(props);
|
||
}
|
||
var scrollHeightBefore = m.pageContent[0].scrollHeight,
|
||
heightBefore = m.pageContent[0].offsetHeight,
|
||
scrollBefore = m.pageContent[0].scrollTop;
|
||
m.container[method](newMessagesHTML);
|
||
if (m.params.autoLayout) m.layout();
|
||
if (method === 'prepend') {
|
||
m.pageContent[0].scrollTop = scrollBefore + (m.pageContent[0].scrollHeight - scrollHeightBefore);
|
||
}
|
||
if (m.params.scrollMessages && (method === 'append' && !m.params.newMessagesFirst) || (method === 'prepend' && m.params.newMessagesFirst)) {
|
||
if (m.params.scrollMessagesOnlyOnEdge) {
|
||
var onEdge = false;
|
||
if (m.params.newMessagesFirst) {
|
||
if (scrollBefore === 0) onEdge = true;
|
||
}
|
||
else {
|
||
if (scrollBefore - (scrollHeightBefore - heightBefore) >= -10) onEdge = true;
|
||
}
|
||
if (onEdge) m.scrollMessages(animate ? undefined : 0);
|
||
}
|
||
else m.scrollMessages(animate ? undefined : 0);
|
||
}
|
||
var messages = m.container.find('.message');
|
||
if (newMessages.length === 1) {
|
||
return method === 'append' ? messages[messages.length - 1] : messages[0];
|
||
}
|
||
else {
|
||
var messagesToReturn = [];
|
||
if (method === 'append') {
|
||
for (i = messages.length - newMessages.length; i < messages.length; i++) {
|
||
messagesToReturn.push(messages[i]);
|
||
}
|
||
}
|
||
else {
|
||
for (i = 0; i < newMessages.length; i++) {
|
||
messagesToReturn.push(messages[i]);
|
||
}
|
||
}
|
||
return messagesToReturn;
|
||
}
|
||
|
||
};
|
||
m.removeMessage = function (message) {
|
||
message = $(message);
|
||
if (message.length === 0) {
|
||
return false;
|
||
}
|
||
else {
|
||
message.remove();
|
||
if (m.params.autoLayout) m.layout();
|
||
return true;
|
||
}
|
||
};
|
||
m.removeMessages = function (messages) {
|
||
m.removeMessage(messages);
|
||
};
|
||
m.clean = function () {
|
||
m.container.html('');
|
||
};
|
||
|
||
// Scroll
|
||
m.scrollMessages = function (duration, scrollTop) {
|
||
if (typeof duration === 'undefined') duration = 400;
|
||
var currentScroll = m.pageContent[0].scrollTop;
|
||
var newScroll;
|
||
if (typeof scrollTop !== 'undefined') newScroll = scrollTop;
|
||
else {
|
||
newScroll = m.params.newMessagesFirst ? 0 : m.pageContent[0].scrollHeight - m.pageContent[0].offsetHeight;
|
||
if (newScroll === currentScroll) return;
|
||
}
|
||
m.pageContent.scrollTop(newScroll, duration);
|
||
};
|
||
|
||
// Init Destroy
|
||
m.init = function () {
|
||
if (m.params.messages) {
|
||
m.addMessages(m.params.messages, undefined, false);
|
||
}
|
||
else {
|
||
if (m.params.autoLayout) m.layout();
|
||
m.scrollMessages(0);
|
||
}
|
||
|
||
};
|
||
m.destroy = function () {
|
||
m = null;
|
||
};
|
||
|
||
// Init
|
||
m.init();
|
||
|
||
m.container[0].f7Messages = m;
|
||
return m;
|
||
};
|
||
app.messages = function (container, params) {
|
||
return new Messages (container, params);
|
||
};
|
||
app.initPageMessages = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var messages = pageContainer.find('.messages');
|
||
if (messages.length === 0) return;
|
||
if (!messages.hasClass('messages-init')) {
|
||
return;
|
||
}
|
||
var m = app.messages(messages, messages.dataset());
|
||
|
||
// Destroy on page remove
|
||
function pageBeforeRemove() {
|
||
m.destroy();
|
||
pageContainer.off('pageBeforeRemove', pageBeforeRemove);
|
||
}
|
||
if (pageContainer.hasClass('page')) {
|
||
pageContainer.on('pageBeforeRemove', pageBeforeRemove);
|
||
}
|
||
};
|
||
|
||
|
||
/*===============================================================================
|
||
************ Swipeout Actions (Swipe to delete) ************
|
||
===============================================================================*/
|
||
app.swipeoutOpenedEl = undefined;
|
||
app.allowSwipeout = true;
|
||
app.initSwipeout = function (swipeoutEl) {
|
||
var isTouched, isMoved, isScrolling, touchesStart = {}, touchStartTime, touchesDiff, swipeOutEl, swipeOutContent, actionsRight, actionsLeft, actionsLeftWidth, actionsRightWidth, translate, opened, openedActions, buttonsLeft, buttonsRight, direction, overswipeLeftButton, overswipeRightButton, overswipeLeft, overswipeRight, noFoldLeft, noFoldRight;
|
||
$(document).on(app.touchEvents.start, function (e) {
|
||
if (app.swipeoutOpenedEl) {
|
||
var target = $(e.target);
|
||
if (!(
|
||
app.swipeoutOpenedEl.is(target[0]) ||
|
||
target.parents('.swipeout').is(app.swipeoutOpenedEl) ||
|
||
target.hasClass('modal-in') ||
|
||
target.hasClass('modal-overlay') ||
|
||
target.hasClass('actions-modal') ||
|
||
target.parents('.actions-modal.modal-in, .modal.modal-in').length > 0
|
||
)) {
|
||
app.swipeoutClose(app.swipeoutOpenedEl);
|
||
}
|
||
}
|
||
});
|
||
|
||
function handleTouchStart(e) {
|
||
if (!app.allowSwipeout) return;
|
||
isMoved = false;
|
||
isTouched = true;
|
||
isScrolling = undefined;
|
||
touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
|
||
touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
|
||
touchStartTime = (new Date()).getTime();
|
||
}
|
||
function handleTouchMove(e) {
|
||
if (!isTouched) return;
|
||
var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
|
||
var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
if (typeof isScrolling === 'undefined') {
|
||
isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));
|
||
}
|
||
if (isScrolling) {
|
||
isTouched = false;
|
||
return;
|
||
}
|
||
|
||
if (!isMoved) {
|
||
if ($('.list-block.sortable-opened').length > 0) return;
|
||
/*jshint validthis:true */
|
||
swipeOutEl = $(this);
|
||
swipeOutContent = swipeOutEl.find('.swipeout-content');
|
||
actionsRight = swipeOutEl.find('.swipeout-actions-right');
|
||
actionsLeft = swipeOutEl.find('.swipeout-actions-left');
|
||
actionsLeftWidth = actionsRightWidth = buttonsLeft = buttonsRight = overswipeRightButton = overswipeLeftButton = null;
|
||
noFoldLeft = actionsLeft.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;
|
||
noFoldRight = actionsRight.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;
|
||
if (actionsLeft.length > 0) {
|
||
actionsLeftWidth = actionsLeft.outerWidth();
|
||
buttonsLeft = actionsLeft.children('a');
|
||
overswipeLeftButton = actionsLeft.find('.swipeout-overswipe');
|
||
}
|
||
if (actionsRight.length > 0) {
|
||
actionsRightWidth = actionsRight.outerWidth();
|
||
buttonsRight = actionsRight.children('a');
|
||
overswipeRightButton = actionsRight.find('.swipeout-overswipe');
|
||
}
|
||
opened = swipeOutEl.hasClass('swipeout-opened');
|
||
if (opened) {
|
||
openedActions = swipeOutEl.find('.swipeout-actions-left.swipeout-actions-opened').length > 0 ? 'left' : 'right';
|
||
}
|
||
swipeOutEl.removeClass('transitioning');
|
||
if (!app.params.swipeoutNoFollow) {
|
||
swipeOutEl.find('.swipeout-actions-opened').removeClass('swipeout-actions-opened');
|
||
swipeOutEl.removeClass('swipeout-opened');
|
||
}
|
||
}
|
||
isMoved = true;
|
||
e.preventDefault();
|
||
|
||
touchesDiff = pageX - touchesStart.x;
|
||
translate = touchesDiff;
|
||
|
||
if (opened) {
|
||
if (openedActions === 'right') translate = translate - actionsRightWidth;
|
||
else translate = translate + actionsLeftWidth;
|
||
}
|
||
|
||
if (translate > 0 && actionsLeft.length === 0 || translate < 0 && actionsRight.length === 0) {
|
||
if (!opened) {
|
||
isTouched = isMoved = false;
|
||
swipeOutContent.transform('');
|
||
if (buttonsRight && buttonsRight.length > 0) {
|
||
buttonsRight.transform('');
|
||
}
|
||
if (buttonsLeft && buttonsLeft.length > 0) {
|
||
buttonsLeft.transform('');
|
||
}
|
||
return;
|
||
}
|
||
translate = 0;
|
||
}
|
||
|
||
if (translate < 0) direction = 'to-left';
|
||
else if (translate > 0) direction = 'to-right';
|
||
else {
|
||
if (direction) direction = direction;
|
||
else direction = 'to-left';
|
||
}
|
||
|
||
var i, buttonOffset, progress;
|
||
|
||
e.f7PreventPanelSwipe = true;
|
||
if (app.params.swipeoutNoFollow) {
|
||
if (opened) {
|
||
if (openedActions === 'right' && touchesDiff > 0) {
|
||
app.swipeoutClose(swipeOutEl);
|
||
}
|
||
if (openedActions === 'left' && touchesDiff < 0) {
|
||
app.swipeoutClose(swipeOutEl);
|
||
}
|
||
}
|
||
else {
|
||
if (touchesDiff < 0 && actionsRight.length > 0) {
|
||
app.swipeoutOpen(swipeOutEl, 'right');
|
||
}
|
||
if (touchesDiff > 0 && actionsLeft.length > 0) {
|
||
app.swipeoutOpen(swipeOutEl, 'left');
|
||
}
|
||
}
|
||
isTouched = false;
|
||
isMoved = false;
|
||
return;
|
||
}
|
||
overswipeLeft = false;
|
||
overswipeRight = false;
|
||
var $button;
|
||
if (actionsRight.length > 0) {
|
||
// Show right actions
|
||
progress = translate / actionsRightWidth;
|
||
if (translate < -actionsRightWidth) {
|
||
translate = -actionsRightWidth - Math.pow(-translate - actionsRightWidth, 0.8);
|
||
if (overswipeRightButton.length > 0) {
|
||
overswipeRight = true;
|
||
}
|
||
}
|
||
for (i = 0; i < buttonsRight.length; i++) {
|
||
if (typeof buttonsRight[i]._buttonOffset === 'undefined') {
|
||
buttonsRight[i]._buttonOffset = buttonsRight[i].offsetLeft;
|
||
}
|
||
buttonOffset = buttonsRight[i]._buttonOffset;
|
||
$button = $(buttonsRight[i]);
|
||
if (overswipeRightButton.length > 0 && $button.hasClass('swipeout-overswipe')) {
|
||
$button.css({left: (overswipeRight ? -buttonOffset : 0) + 'px'});
|
||
if (overswipeRight) {
|
||
$button.addClass('swipeout-overswipe-active');
|
||
}
|
||
else {
|
||
$button.removeClass('swipeout-overswipe-active');
|
||
}
|
||
}
|
||
$button.transform('translate3d(' + (translate - buttonOffset * (1 + Math.max(progress, -1))) + 'px,0,0)');
|
||
}
|
||
}
|
||
if (actionsLeft.length > 0) {
|
||
// Show left actions
|
||
progress = translate / actionsLeftWidth;
|
||
if (translate > actionsLeftWidth) {
|
||
translate = actionsLeftWidth + Math.pow(translate - actionsLeftWidth, 0.8);
|
||
if (overswipeLeftButton.length > 0) {
|
||
overswipeLeft = true;
|
||
}
|
||
}
|
||
for (i = 0; i < buttonsLeft.length; i++) {
|
||
if (typeof buttonsLeft[i]._buttonOffset === 'undefined') {
|
||
buttonsLeft[i]._buttonOffset = actionsLeftWidth - buttonsLeft[i].offsetLeft - buttonsLeft[i].offsetWidth;
|
||
}
|
||
buttonOffset = buttonsLeft[i]._buttonOffset;
|
||
$button = $(buttonsLeft[i]);
|
||
if (overswipeLeftButton.length > 0 && $button.hasClass('swipeout-overswipe')) {
|
||
$button.css({left: (overswipeLeft ? buttonOffset : 0) + 'px'});
|
||
if (overswipeLeft) {
|
||
$button.addClass('swipeout-overswipe-active');
|
||
}
|
||
else {
|
||
$button.removeClass('swipeout-overswipe-active');
|
||
}
|
||
}
|
||
if (buttonsLeft.length > 1) {
|
||
$button.css('z-index', buttonsLeft.length - i);
|
||
}
|
||
$button.transform('translate3d(' + (translate + buttonOffset * (1 - Math.min(progress, 1))) + 'px,0,0)');
|
||
}
|
||
}
|
||
swipeOutContent.transform('translate3d(' + translate + 'px,0,0)');
|
||
}
|
||
function handleTouchEnd(e) {
|
||
if (!isTouched || !isMoved) {
|
||
isTouched = false;
|
||
isMoved = false;
|
||
return;
|
||
}
|
||
|
||
isTouched = false;
|
||
isMoved = false;
|
||
var timeDiff = (new Date()).getTime() - touchStartTime;
|
||
var action, actionsWidth, actions, buttons, i, noFold;
|
||
|
||
noFold = direction === 'to-left' ? noFoldRight : noFoldLeft;
|
||
actions = direction === 'to-left' ? actionsRight : actionsLeft;
|
||
actionsWidth = direction === 'to-left' ? actionsRightWidth : actionsLeftWidth;
|
||
|
||
if (
|
||
timeDiff < 300 && (touchesDiff < -10 && direction === 'to-left' || touchesDiff > 10 && direction === 'to-right') ||
|
||
timeDiff >= 300 && Math.abs(translate) > actionsWidth / 2
|
||
) {
|
||
action = 'open';
|
||
}
|
||
else {
|
||
action = 'close';
|
||
}
|
||
if (timeDiff < 300) {
|
||
if (Math.abs(translate) === 0) action = 'close';
|
||
if (Math.abs(translate) === actionsWidth) action = 'open';
|
||
}
|
||
|
||
if (action === 'open') {
|
||
app.swipeoutOpenedEl = swipeOutEl;
|
||
swipeOutEl.trigger('open');
|
||
swipeOutEl.addClass('swipeout-opened transitioning');
|
||
var newTranslate = direction === 'to-left' ? -actionsWidth : actionsWidth;
|
||
swipeOutContent.transform('translate3d(' + newTranslate + 'px,0,0)');
|
||
actions.addClass('swipeout-actions-opened');
|
||
buttons = direction === 'to-left' ? buttonsRight : buttonsLeft;
|
||
if (buttons) {
|
||
for (i = 0; i < buttons.length; i++) {
|
||
$(buttons[i]).transform('translate3d(' + newTranslate + 'px,0,0)');
|
||
}
|
||
}
|
||
if (overswipeRight) {
|
||
actionsRight.find('.swipeout-overswipe')[0].click();
|
||
}
|
||
if (overswipeLeft) {
|
||
actionsLeft.find('.swipeout-overswipe')[0].click();
|
||
}
|
||
}
|
||
else {
|
||
swipeOutEl.trigger('close');
|
||
app.swipeoutOpenedEl = undefined;
|
||
swipeOutEl.addClass('transitioning').removeClass('swipeout-opened');
|
||
swipeOutContent.transform('');
|
||
actions.removeClass('swipeout-actions-opened');
|
||
}
|
||
|
||
var buttonOffset;
|
||
if (buttonsLeft && buttonsLeft.length > 0 && buttonsLeft !== buttons) {
|
||
for (i = 0; i < buttonsLeft.length; i++) {
|
||
buttonOffset = buttonsLeft[i]._buttonOffset;
|
||
if (typeof buttonOffset === 'undefined') {
|
||
buttonsLeft[i]._buttonOffset = actionsLeftWidth - buttonsLeft[i].offsetLeft - buttonsLeft[i].offsetWidth;
|
||
}
|
||
$(buttonsLeft[i]).transform('translate3d(' + (buttonOffset) + 'px,0,0)');
|
||
}
|
||
}
|
||
if (buttonsRight && buttonsRight.length > 0 && buttonsRight !== buttons) {
|
||
for (i = 0; i < buttonsRight.length; i++) {
|
||
buttonOffset = buttonsRight[i]._buttonOffset;
|
||
if (typeof buttonOffset === 'undefined') {
|
||
buttonsRight[i]._buttonOffset = buttonsRight[i].offsetLeft;
|
||
}
|
||
$(buttonsRight[i]).transform('translate3d(' + (-buttonOffset) + 'px,0,0)');
|
||
}
|
||
}
|
||
swipeOutContent.transitionEnd(function (e) {
|
||
if (opened && action === 'open' || closed && action === 'close') return;
|
||
swipeOutEl.trigger(action === 'open' ? 'opened' : 'closed');
|
||
if (opened && action === 'close') {
|
||
if (actionsRight.length > 0) {
|
||
buttonsRight.transform('');
|
||
}
|
||
if (actionsLeft.length > 0) {
|
||
buttonsLeft.transform('');
|
||
}
|
||
}
|
||
});
|
||
}
|
||
if (swipeoutEl) {
|
||
$(swipeoutEl).on(app.touchEvents.start, handleTouchStart);
|
||
$(swipeoutEl).on(app.touchEvents.move, handleTouchMove);
|
||
$(swipeoutEl).on(app.touchEvents.end, handleTouchEnd);
|
||
}
|
||
else {
|
||
$(document).on(app.touchEvents.start, '.list-block li.swipeout', handleTouchStart);
|
||
$(document).on(app.touchEvents.move, '.list-block li.swipeout', handleTouchMove);
|
||
$(document).on(app.touchEvents.end, '.list-block li.swipeout', handleTouchEnd);
|
||
}
|
||
|
||
};
|
||
app.swipeoutOpen = function (el, dir, callback) {
|
||
el = $(el);
|
||
if (arguments.length === 2) {
|
||
if (typeof arguments[1] === 'function') {
|
||
callback = dir;
|
||
}
|
||
}
|
||
|
||
if (el.length === 0) return;
|
||
if (el.length > 1) el = $(el[0]);
|
||
if (!el.hasClass('swipeout') || el.hasClass('swipeout-opened')) return;
|
||
if (!dir) {
|
||
if (el.find('.swipeout-actions-right').length > 0) dir = 'right';
|
||
else dir = 'left';
|
||
}
|
||
var swipeOutActions = el.find('.swipeout-actions-' + dir);
|
||
if (swipeOutActions.length === 0) return;
|
||
var noFold = swipeOutActions.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;
|
||
el.trigger('open').addClass('swipeout-opened').removeClass('transitioning');
|
||
swipeOutActions.addClass('swipeout-actions-opened');
|
||
var buttons = swipeOutActions.children('a');
|
||
var swipeOutActionsWidth = swipeOutActions.outerWidth();
|
||
var translate = dir === 'right' ? -swipeOutActionsWidth : swipeOutActionsWidth;
|
||
var i;
|
||
if (buttons.length > 1) {
|
||
for (i = 0; i < buttons.length; i++) {
|
||
if (dir === 'right') {
|
||
$(buttons[i]).transform('translate3d(' + (- buttons[i].offsetLeft) + 'px,0,0)');
|
||
}
|
||
else {
|
||
$(buttons[i]).css('z-index', buttons.length - i).transform('translate3d(' + (swipeOutActionsWidth - buttons[i].offsetWidth - buttons[i].offsetLeft) + 'px,0,0)');
|
||
}
|
||
}
|
||
var clientLeft = buttons[1].clientLeft;
|
||
}
|
||
el.addClass('transitioning');
|
||
for (i = 0; i < buttons.length; i++) {
|
||
$(buttons[i]).transform('translate3d(' + (translate) + 'px,0,0)');
|
||
}
|
||
el.find('.swipeout-content').transform('translate3d(' + translate + 'px,0,0)').transitionEnd(function () {
|
||
el.trigger('opened');
|
||
if (callback) callback.call(el[0]);
|
||
});
|
||
app.swipeoutOpenedEl = el;
|
||
};
|
||
app.swipeoutClose = function (el, callback) {
|
||
el = $(el);
|
||
if (el.length === 0) return;
|
||
if (!el.hasClass('swipeout-opened')) return;
|
||
var dir = el.find('.swipeout-actions-opened').hasClass('swipeout-actions-right') ? 'right' : 'left';
|
||
var swipeOutActions = el.find('.swipeout-actions-opened').removeClass('swipeout-actions-opened');
|
||
var noFold = swipeOutActions.hasClass('swipeout-actions-no-fold') || app.params.swipeoutActionsNoFold;
|
||
var buttons = swipeOutActions.children('a');
|
||
var swipeOutActionsWidth = swipeOutActions.outerWidth();
|
||
app.allowSwipeout = false;
|
||
el.trigger('close');
|
||
el.removeClass('swipeout-opened').addClass('transitioning');
|
||
|
||
var closeTO;
|
||
function onSwipeoutClose() {
|
||
app.allowSwipeout = true;
|
||
if (el.hasClass('swipeout-opened')) return;
|
||
el.removeClass('transitioning');
|
||
buttons.transform('');
|
||
el.trigger('closed');
|
||
if (callback) callback.call(el[0]);
|
||
if (closeTO) clearTimeout(closeTO);
|
||
}
|
||
el.find('.swipeout-content').transform('').transitionEnd(onSwipeoutClose);
|
||
closeTO = setTimeout(onSwipeoutClose, 500);
|
||
|
||
for (var i = 0; i < buttons.length; i++) {
|
||
if (dir === 'right') {
|
||
$(buttons[i]).transform('translate3d(' + (-buttons[i].offsetLeft) + 'px,0,0)');
|
||
}
|
||
else {
|
||
$(buttons[i]).transform('translate3d(' + (swipeOutActionsWidth - buttons[i].offsetWidth - buttons[i].offsetLeft) + 'px,0,0)');
|
||
}
|
||
$(buttons[i]).css({left:0 + 'px'}).removeClass('swipeout-overswipe-active');
|
||
}
|
||
if (app.swipeoutOpenedEl && app.swipeoutOpenedEl[0] === el[0]) app.swipeoutOpenedEl = undefined;
|
||
};
|
||
app.swipeoutDelete = function (el, callback) {
|
||
el = $(el);
|
||
if (el.length === 0) return;
|
||
if (el.length > 1) el = $(el[0]);
|
||
app.swipeoutOpenedEl = undefined;
|
||
el.trigger('delete');
|
||
el.css({height: el.outerHeight() + 'px'});
|
||
var clientLeft = el[0].clientLeft;
|
||
el.css({height: 0 + 'px'}).addClass('deleting transitioning').transitionEnd(function () {
|
||
el.trigger('deleted');
|
||
if (callback) callback.call(el[0]);
|
||
if (el.parents('.virtual-list').length > 0) {
|
||
var virtualList = el.parents('.virtual-list')[0].f7VirtualList;
|
||
var virtualIndex = el[0].f7VirtualListIndex;
|
||
if (virtualList && typeof virtualIndex !== 'undefined') virtualList.deleteItem(virtualIndex);
|
||
}
|
||
else {
|
||
if (app.params.swipeoutRemoveWithTimeout) {
|
||
setTimeout(function () {
|
||
el.remove();
|
||
}, 0);
|
||
}
|
||
else el.remove();
|
||
}
|
||
});
|
||
var translate = '-100%';
|
||
el.find('.swipeout-content').transform('translate3d(' + translate + ',0,0)');
|
||
};
|
||
|
||
|
||
/*===============================================================================
|
||
************ Sortable ************
|
||
===============================================================================*/
|
||
app.sortableToggle = function (sortableContainer) {
|
||
sortableContainer = $(sortableContainer);
|
||
if (sortableContainer.length === 0) sortableContainer = $('.list-block.sortable');
|
||
sortableContainer.toggleClass('sortable-opened');
|
||
if (sortableContainer.hasClass('sortable-opened')) {
|
||
sortableContainer.trigger('open');
|
||
}
|
||
else {
|
||
sortableContainer.trigger('close');
|
||
}
|
||
return sortableContainer;
|
||
};
|
||
app.sortableOpen = function (sortableContainer) {
|
||
sortableContainer = $(sortableContainer);
|
||
if (sortableContainer.length === 0) sortableContainer = $('.list-block.sortable');
|
||
sortableContainer.addClass('sortable-opened');
|
||
sortableContainer.trigger('open');
|
||
return sortableContainer;
|
||
};
|
||
app.sortableClose = function (sortableContainer) {
|
||
sortableContainer = $(sortableContainer);
|
||
if (sortableContainer.length === 0) sortableContainer = $('.list-block.sortable');
|
||
sortableContainer.removeClass('sortable-opened');
|
||
sortableContainer.trigger('close');
|
||
return sortableContainer;
|
||
};
|
||
app.initSortable = function () {
|
||
var isTouched, isMoved, touchStartY, touchesDiff, sortingEl, sortingElHeight, sortingItems, minTop, maxTop, insertAfter, insertBefore, sortableContainer, startIndex;
|
||
|
||
function handleTouchStart(e) {
|
||
isMoved = false;
|
||
isTouched = true;
|
||
touchStartY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
|
||
/*jshint validthis:true */
|
||
sortingEl = $(this).parent();
|
||
startIndex = sortingEl.index();
|
||
sortingItems = sortingEl.parent().find('li');
|
||
sortableContainer = sortingEl.parents('.sortable');
|
||
e.preventDefault();
|
||
app.allowPanelOpen = app.allowSwipeout = false;
|
||
}
|
||
function handleTouchMove(e) {
|
||
if (!isTouched || !sortingEl) return;
|
||
var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
|
||
var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
if (!isMoved) {
|
||
sortingEl.addClass('sorting');
|
||
sortableContainer.addClass('sortable-sorting');
|
||
minTop = sortingEl[0].offsetTop;
|
||
maxTop = sortingEl.parent().height() - sortingEl[0].offsetTop - sortingEl.height();
|
||
sortingElHeight = sortingEl[0].offsetHeight;
|
||
}
|
||
isMoved = true;
|
||
|
||
e.preventDefault();
|
||
e.f7PreventPanelSwipe = true;
|
||
touchesDiff = pageY - touchStartY;
|
||
var translate = touchesDiff;
|
||
if (translate < -minTop) translate = -minTop;
|
||
if (translate > maxTop) translate = maxTop;
|
||
sortingEl.transform('translate3d(0,' + translate + 'px,0)');
|
||
|
||
insertBefore = insertAfter = undefined;
|
||
|
||
sortingItems.each(function () {
|
||
var currentEl = $(this);
|
||
if (currentEl[0] === sortingEl[0]) return;
|
||
var currentElOffset = currentEl[0].offsetTop;
|
||
var currentElHeight = currentEl.height();
|
||
var sortingElOffset = sortingEl[0].offsetTop + translate;
|
||
|
||
if ((sortingElOffset >= currentElOffset - currentElHeight / 2) && sortingEl.index() < currentEl.index()) {
|
||
currentEl.transform('translate3d(0, '+(-sortingElHeight)+'px,0)');
|
||
insertAfter = currentEl;
|
||
insertBefore = undefined;
|
||
}
|
||
else if ((sortingElOffset <= currentElOffset + currentElHeight / 2) && sortingEl.index() > currentEl.index()) {
|
||
currentEl.transform('translate3d(0, '+(sortingElHeight)+'px,0)');
|
||
insertAfter = undefined;
|
||
if (!insertBefore) insertBefore = currentEl;
|
||
}
|
||
else {
|
||
$(this).transform('translate3d(0, 0%,0)');
|
||
}
|
||
});
|
||
}
|
||
function handleTouchEnd(e) {
|
||
app.allowPanelOpen = app.allowSwipeout = true;
|
||
if (!isTouched || !isMoved) {
|
||
isTouched = false;
|
||
isMoved = false;
|
||
return;
|
||
}
|
||
e.preventDefault();
|
||
sortingItems.transform('');
|
||
sortingEl.removeClass('sorting');
|
||
sortableContainer.removeClass('sortable-sorting');
|
||
var virtualList, oldIndex, newIndex;
|
||
if (insertAfter) {
|
||
sortingEl.insertAfter(insertAfter);
|
||
sortingEl.trigger('sort', {startIndex: startIndex, newIndex: sortingEl.index()});
|
||
}
|
||
if (insertBefore) {
|
||
sortingEl.insertBefore(insertBefore);
|
||
sortingEl.trigger('sort', {startIndex: startIndex, newIndex: sortingEl.index()});
|
||
}
|
||
if ((insertAfter || insertBefore) && sortableContainer.hasClass('virtual-list')) {
|
||
virtualList = sortableContainer[0].f7VirtualList;
|
||
oldIndex = sortingEl[0].f7VirtualListIndex;
|
||
newIndex = insertBefore ? insertBefore[0].f7VirtualListIndex : insertAfter[0].f7VirtualListIndex;
|
||
if (virtualList) virtualList.moveItem(oldIndex, newIndex);
|
||
}
|
||
insertAfter = insertBefore = undefined;
|
||
isTouched = false;
|
||
isMoved = false;
|
||
}
|
||
$(document).on(app.touchEvents.start, '.list-block.sortable .sortable-handler', handleTouchStart);
|
||
if (app.support.touch) {
|
||
$(document).on(app.touchEvents.move, '.list-block.sortable .sortable-handler', handleTouchMove);
|
||
$(document).on(app.touchEvents.end, '.list-block.sortable .sortable-handler', handleTouchEnd);
|
||
}
|
||
else {
|
||
$(document).on(app.touchEvents.move, handleTouchMove);
|
||
$(document).on(app.touchEvents.end, handleTouchEnd);
|
||
}
|
||
};
|
||
|
||
|
||
/*===============================================================================
|
||
************ Smart Select ************
|
||
===============================================================================*/
|
||
app.initSmartSelects = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var selects;
|
||
if (pageContainer.is('.smart-select')) {
|
||
selects = pageContainer;
|
||
}
|
||
else {
|
||
selects = pageContainer.find('.smart-select');
|
||
}
|
||
if (selects.length === 0) return;
|
||
|
||
selects.each(function () {
|
||
var smartSelect = $(this);
|
||
|
||
var $select = smartSelect.find('select');
|
||
if ($select.length === 0) return;
|
||
|
||
var select = $select[0];
|
||
if (select.length === 0) return;
|
||
|
||
var valueText = [];
|
||
for (var i = 0; i < select.length; i++) {
|
||
if (select[i].selected) valueText.push(select[i].textContent.trim());
|
||
}
|
||
|
||
var itemAfter = smartSelect.find('.item-after');
|
||
if (itemAfter.length === 0) {
|
||
smartSelect.find('.item-inner').append('<div class="item-after">' + valueText.join(', ') + '</div>');
|
||
}
|
||
else {
|
||
var selectedText = itemAfter.text();
|
||
if (itemAfter.hasClass('smart-select-value')) {
|
||
for (i = 0; i < select.length; i++) {
|
||
select[i].selected = select[i].textContent.trim() === selectedText.trim();
|
||
}
|
||
} else {
|
||
itemAfter.text(valueText.join(', '));
|
||
}
|
||
}
|
||
|
||
$select.on('change', function () {
|
||
var valueText = [];
|
||
for (var i = 0; i < select.length; i++) {
|
||
if (select[i].selected) valueText.push(select[i].textContent.trim());
|
||
}
|
||
smartSelect.find('.item-after').text(valueText.join(', '));
|
||
});
|
||
|
||
});
|
||
|
||
};
|
||
app.smartSelectAddOption = function (select, option, index) {
|
||
select = $(select);
|
||
var smartSelect = select.parents('.smart-select');
|
||
if (typeof index === 'undefined') {
|
||
select.append(option);
|
||
}
|
||
else {
|
||
$(option).insertBefore(select.find('option').eq(index));
|
||
}
|
||
app.initSmartSelects(smartSelect);
|
||
var selectName = smartSelect.find('select').attr('name');
|
||
var opened = $('.page.smart-select-page[data-select-name="' + selectName + '"]').length > 0;
|
||
if (opened) {
|
||
app.smartSelectOpen(smartSelect, true);
|
||
}
|
||
};
|
||
app.smartSelectOpen = function (smartSelect, reLayout) {
|
||
smartSelect = $(smartSelect);
|
||
if (smartSelect.length === 0) return;
|
||
|
||
// Find related view
|
||
var view = smartSelect.parents('.' + app.params.viewClass);
|
||
if (view.length === 0) return;
|
||
view = view[0].f7View;
|
||
|
||
// Parameters
|
||
var openIn = smartSelect.attr('data-open-in') || app.params.smartSelectOpenIn;
|
||
if (openIn === 'popup') {
|
||
if ($('.popup.smart-select-popup').length > 0) return;
|
||
}
|
||
else if (openIn === 'picker') {
|
||
if ($('.picker-modal.modal-in').length > 0 && !reLayout){
|
||
if (smartSelect[0].f7SmartSelectPicker !== $('.picker-modal.modal-in:not(.modal-out)')[0]) app.closeModal($('.picker-modal.modal-in:not(.modal-out)'));
|
||
else return;
|
||
}
|
||
}
|
||
else {
|
||
if (!view) return;
|
||
}
|
||
|
||
var smartSelectData = smartSelect.dataset();
|
||
var pageTitle = smartSelectData.pageTitle || smartSelect.find('.item-title').text();
|
||
var backText = smartSelectData.backText || app.params.smartSelectBackText;
|
||
var closeText;
|
||
if (openIn === 'picker') {
|
||
closeText = smartSelectData.pickerCloseText || smartSelectData.backText || app.params.smartSelectPickerCloseText ;
|
||
}
|
||
else {
|
||
closeText = smartSelectData.popupCloseText || smartSelectData.backText || app.params.smartSelectPopupCloseText ;
|
||
}
|
||
var backOnSelect = smartSelectData.backOnSelect !== undefined ? smartSelectData.backOnSelect : app.params.smartSelectBackOnSelect;
|
||
var formTheme = smartSelectData.formTheme || app.params.smartSelectFormTheme;
|
||
var navbarTheme = smartSelectData.navbarTheme || app.params.smartSelectNavbarTheme;
|
||
var toolbarTheme = smartSelectData.toolbarTheme || app.params.smartSelectToolbarTheme;
|
||
var virtualList = smartSelectData.virtualList;
|
||
var virtualListHeight = smartSelectData.virtualListHeight;
|
||
var material = app.params.material;
|
||
var pickerHeight = smartSelectData.pickerHeight || app.params.smartSelectPickerHeight;
|
||
|
||
// Collect all options/values
|
||
var select = smartSelect.find('select')[0];
|
||
var $select = $(select);
|
||
var $selectData = $select.dataset();
|
||
if (select.disabled || smartSelect.hasClass('disabled') || $select.hasClass('disabled')) {
|
||
return;
|
||
}
|
||
var values = [];
|
||
var id = (new Date()).getTime();
|
||
var inputType = select.multiple ? 'checkbox' : 'radio';
|
||
var inputName = inputType + '-' + id;
|
||
var maxLength = $select.attr('maxlength');
|
||
var selectName = select.name;
|
||
var option, optionHasMedia, optionImage, optionIcon, optionGroup, optionGroupLabel, optionPreviousGroup, optionIsLabel, previousGroup, optionColor, optionClassName, optionData;
|
||
for (var i = 0; i < select.length; i++) {
|
||
option = $(select[i]);
|
||
optionData = option.dataset();
|
||
optionImage = optionData.optionImage || $selectData.optionImage || smartSelectData.optionImage;
|
||
optionIcon = optionData.optionIcon || $selectData.optionIcon || smartSelectData.optionIcon;
|
||
optionHasMedia = optionImage || optionIcon || inputType === 'checkbox';
|
||
if (material) optionHasMedia = optionImage || optionIcon;
|
||
optionColor = optionData.optionColor;
|
||
optionClassName = optionData.optionClass;
|
||
if (option[0].disabled) optionClassName += ' disabled';
|
||
optionGroup = option.parent('optgroup')[0];
|
||
optionGroupLabel = optionGroup && optionGroup.label;
|
||
optionIsLabel = false;
|
||
if (optionGroup) {
|
||
if (optionGroup !== previousGroup) {
|
||
optionIsLabel = true;
|
||
previousGroup = optionGroup;
|
||
values.push({
|
||
groupLabel: optionGroupLabel,
|
||
isLabel: optionIsLabel
|
||
});
|
||
}
|
||
}
|
||
values.push({
|
||
value: option[0].value,
|
||
text: option[0].textContent.trim(),
|
||
selected: option[0].selected,
|
||
group: optionGroup,
|
||
groupLabel: optionGroupLabel,
|
||
image: optionImage,
|
||
icon: optionIcon,
|
||
color: optionColor,
|
||
className: optionClassName,
|
||
disabled: option[0].disabled,
|
||
inputType: inputType,
|
||
id: id,
|
||
hasMedia: optionHasMedia,
|
||
checkbox: inputType === 'checkbox',
|
||
inputName: inputName,
|
||
material: app.params.material
|
||
});
|
||
}
|
||
|
||
|
||
// Item template/HTML
|
||
if (!app._compiledTemplates.smartSelectItem) {
|
||
app._compiledTemplates.smartSelectItem = t7.compile(app.params.smartSelectItemTemplate ||
|
||
'{{#if isLabel}}' +
|
||
'<li class="item-divider">{{groupLabel}}</li>' +
|
||
'{{else}}' +
|
||
'<li{{#if className}} class="{{className}}"{{/if}}>' +
|
||
'<label class="label-{{inputType}} item-content">' +
|
||
'<input type="{{inputType}}" name="{{inputName}}" value="{{value}}" {{#if selected}}checked{{/if}}>' +
|
||
'{{#if material}}' +
|
||
'{{#if hasMedia}}' +
|
||
'<div class="item-media">' +
|
||
'{{#if icon}}<i class="icon {{icon}}"></i>{{/if}}' +
|
||
'{{#if image}}<img src="{{image}}">{{/if}}' +
|
||
'</div>' +
|
||
'<div class="item-inner">' +
|
||
'<div class="item-title{{#if color}} color-{{color}}{{/if}}">{{text}}</div>' +
|
||
'</div>' +
|
||
'<div class="item-after">' +
|
||
'<i class="icon icon-form-{{inputType}}"></i>' +
|
||
'</div>' +
|
||
'{{else}}' +
|
||
'<div class="item-media">' +
|
||
'<i class="icon icon-form-{{inputType}}"></i>' +
|
||
'</div>' +
|
||
'<div class="item-inner">' +
|
||
'<div class="item-title{{#if color}} color-{{color}}{{/if}}">{{text}}</div>' +
|
||
'</div>' +
|
||
'{{/if}}' +
|
||
'{{else}}' +
|
||
'{{#if hasMedia}}' +
|
||
'<div class="item-media">' +
|
||
'{{#if checkbox}}<i class="icon icon-form-checkbox"></i>{{/if}}' +
|
||
'{{#if icon}}<i class="icon {{icon}}"></i>{{/if}}' +
|
||
'{{#if image}}<img src="{{image}}">{{/if}}' +
|
||
'</div>' +
|
||
'{{/if}}' +
|
||
'<div class="item-inner">' +
|
||
'<div class="item-title{{#if color}} color-{{color}}{{/if}}">{{text}}</div>' +
|
||
'</div>' +
|
||
'{{/if}}' +
|
||
'</label>' +
|
||
'</li>' +
|
||
'{{/if}}'
|
||
);
|
||
}
|
||
var smartSelectItemTemplate = app._compiledTemplates.smartSelectItem;
|
||
|
||
var inputsHTML = '';
|
||
if (!virtualList) {
|
||
for (var j = 0; j < values.length; j++) {
|
||
inputsHTML += smartSelectItemTemplate(values[j]);
|
||
}
|
||
}
|
||
|
||
// Toolbar / Navbar
|
||
var toolbarHTML = '', navbarHTML;
|
||
var noNavbar = '', noToolbar = '', noTabbar = '', navbarLayout;
|
||
|
||
if (openIn === 'picker') {
|
||
if (!app._compiledTemplates.smartSelectToolbar) {
|
||
app._compiledTemplates.smartSelectToolbar = t7.compile(app.params.smartSelectToolbarTemplate ||
|
||
'<div class="toolbar {{#if toolbarTheme}}theme-{{toolbarTheme}}{{/if}}">' +
|
||
'<div class="toolbar-inner">' +
|
||
'<div class="left"></div>' +
|
||
'<div class="right"><a href="#" class="link close-picker"><span>{{closeText}}</span></a></div>' +
|
||
'</div>' +
|
||
'</div>'
|
||
);
|
||
}
|
||
|
||
toolbarHTML = app._compiledTemplates.smartSelectToolbar({
|
||
pageTitle: pageTitle,
|
||
closeText: closeText,
|
||
openIn: openIn,
|
||
toolbarTheme: toolbarTheme,
|
||
inPicker: openIn === 'picker'
|
||
});
|
||
}
|
||
else {
|
||
// Navbar HTML
|
||
if (!app._compiledTemplates.smartSelectNavbar) {
|
||
app._compiledTemplates.smartSelectNavbar = t7.compile(app.params.smartSelectNavbarTemplate ||
|
||
'<div class="navbar {{#if navbarTheme}}theme-{{navbarTheme}}{{/if}}">' +
|
||
'<div class="navbar-inner">' +
|
||
'{{leftTemplate}}' +
|
||
'<div class="center sliding">{{pageTitle}}</div>' +
|
||
'</div>' +
|
||
'</div>'
|
||
);
|
||
}
|
||
navbarHTML = app._compiledTemplates.smartSelectNavbar({
|
||
pageTitle: pageTitle,
|
||
backText: backText,
|
||
closeText: closeText,
|
||
openIn: openIn,
|
||
navbarTheme: navbarTheme,
|
||
inPopup: openIn === 'popup',
|
||
inPage: openIn === 'page',
|
||
leftTemplate: openIn === 'popup' ?
|
||
(app.params.smartSelectPopupCloseTemplate || (material ? '<div class="left"><a href="#" class="link close-popup icon-only"><i class="icon icon-back"></i></a></div>' : '<div class="left"><a href="#" class="link close-popup"><i class="icon icon-back"></i><span>{{closeText}}</span></a></div>')).replace(/{{closeText}}/g, closeText) :
|
||
(app.params.smartSelectBackTemplate || (material ? '<div class="left"><a href="#" class="back link icon-only"><i class="icon icon-back"></i></a></div>' : '<div class="left sliding"><a href="#" class="back link"><i class="icon icon-back"></i><span>{{backText}}</span></a></div>')).replace(/{{backText}}/g, backText)
|
||
});
|
||
// Determine navbar layout type - static/fixed/through
|
||
if (openIn === 'page') {
|
||
navbarLayout = 'static';
|
||
if (smartSelect.parents('.navbar-through').length > 0) navbarLayout = 'through';
|
||
if (smartSelect.parents('.navbar-fixed').length > 0) navbarLayout = 'fixed';
|
||
noToolbar = smartSelect.parents('.page').hasClass('no-toolbar') ? 'no-toolbar' : '';
|
||
noNavbar = smartSelect.parents('.page').hasClass('no-navbar') ? 'no-navbar' : 'navbar-' + navbarLayout;
|
||
noTabbar = smartSelect.parents('.page').hasClass('no-tabbar') ? 'no-tabbar' : '';
|
||
}
|
||
else {
|
||
navbarLayout = 'fixed';
|
||
}
|
||
}
|
||
|
||
|
||
// Page Layout
|
||
var pageName = 'smart-select-' + inputName;
|
||
|
||
var useSearchbar = typeof smartSelect.data('searchbar') === 'undefined' ? app.params.smartSelectSearchbar : (smartSelect.data('searchbar') === 'true' ? true : false);
|
||
var searchbarPlaceholder, searchbarCancel;
|
||
|
||
if (useSearchbar) {
|
||
searchbarPlaceholder = smartSelect.data('searchbar-placeholder') || 'Search';
|
||
searchbarCancel = smartSelect.data('searchbar-cancel') || 'Cancel';
|
||
}
|
||
|
||
var searchbarHTML = '<form class="searchbar searchbar-init" data-search-list=".smart-select-list-' + id + '" data-search-in=".item-title">' +
|
||
'<div class="searchbar-input">' +
|
||
'<input type="search" placeholder="' + searchbarPlaceholder + '">' +
|
||
'<a href="#" class="searchbar-clear"></a>' +
|
||
'</div>' +
|
||
(material ? '' : '<a href="#" class="searchbar-cancel">' + searchbarCancel + '</a>') +
|
||
'</form>' +
|
||
'<div class="searchbar-overlay"></div>';
|
||
|
||
var pageHTML =
|
||
(openIn !== 'picker' && navbarLayout === 'through' ? navbarHTML : '') +
|
||
'<div class="pages">' +
|
||
' <div data-page="' + pageName + '" data-select-name="' + selectName + '" class="page smart-select-page ' + noNavbar + ' ' + noToolbar + ' ' + noTabbar + '">' +
|
||
(openIn !== 'picker' && navbarLayout === 'fixed' ? navbarHTML : '') +
|
||
(useSearchbar ? searchbarHTML : '') +
|
||
' <div class="page-content">' +
|
||
(openIn !== 'picker' && navbarLayout === 'static' ? navbarHTML : '') +
|
||
' <div class="list-block ' + (virtualList ? 'virtual-list' : '') + ' smart-select-list-' + id + ' ' + (formTheme ? 'theme-' + formTheme : '') + '">' +
|
||
' <ul>' +
|
||
(virtualList ? '' : inputsHTML) +
|
||
' </ul>' +
|
||
' </div>' +
|
||
' </div>' +
|
||
' </div>' +
|
||
'</div>';
|
||
|
||
// Define popup and picker
|
||
var popup, picker;
|
||
|
||
// Scroll SS Picker To Input
|
||
function scrollToInput() {
|
||
var pageContent = smartSelect.parents('.page-content');
|
||
if (pageContent.length === 0) return;
|
||
var paddingTop = parseInt(pageContent.css('padding-top'), 10),
|
||
paddingBottom = parseInt(pageContent.css('padding-bottom'), 10),
|
||
pageHeight = pageContent[0].offsetHeight - paddingTop - picker.height(),
|
||
pageScrollHeight = pageContent[0].scrollHeight - paddingTop - picker.height(),
|
||
newPaddingBottom;
|
||
var inputTop = smartSelect.offset().top - paddingTop + smartSelect[0].offsetHeight;
|
||
if (inputTop > pageHeight) {
|
||
var scrollTop = pageContent.scrollTop() + inputTop - pageHeight;
|
||
if (scrollTop + pageHeight > pageScrollHeight) {
|
||
newPaddingBottom = scrollTop + pageHeight - pageScrollHeight + paddingBottom;
|
||
if (pageHeight === pageScrollHeight) {
|
||
newPaddingBottom = picker.height();
|
||
}
|
||
pageContent.css({'padding-bottom': (newPaddingBottom) + 'px'});
|
||
}
|
||
pageContent.scrollTop(scrollTop, 300);
|
||
}
|
||
}
|
||
// Close SS Picker on HTML Click
|
||
function closeOnHTMLClick(e) {
|
||
var close = true;
|
||
if (e.target === smartSelect[0] || $(e.target).parents(smartSelect[0]).length > 0) {
|
||
close = false;
|
||
}
|
||
if ($(e.target).parents('.picker-modal').length > 0) {
|
||
close = false;
|
||
}
|
||
if (close) {
|
||
app.closeModal('.smart-select-picker.modal-in');
|
||
}
|
||
}
|
||
|
||
// Check max length
|
||
function checkMaxLength(container) {
|
||
if (select.selectedOptions.length >= maxLength) {
|
||
container.find('input[type="checkbox"]').each(function () {
|
||
if (!this.checked) {
|
||
$(this).parents('li').addClass('disabled');
|
||
}
|
||
else {
|
||
$(this).parents('li').removeClass('disabled');
|
||
}
|
||
});
|
||
}
|
||
else {
|
||
container.find('.disabled').removeClass('disabled');
|
||
}
|
||
}
|
||
// Event Listeners on new page
|
||
function handleInputs(container) {
|
||
container = $(container);
|
||
if (virtualList) {
|
||
var virtualListInstance = app.virtualList(container.find('.virtual-list'), {
|
||
items: values,
|
||
template: smartSelectItemTemplate,
|
||
height: virtualListHeight || undefined,
|
||
searchByItem: function (query, index, item) {
|
||
if (item.text.toLowerCase().indexOf(query.trim().toLowerCase()) >=0 ) return true;
|
||
return false;
|
||
}
|
||
});
|
||
container.once(openIn === 'popup' || openIn === 'picker' ? 'closed': 'pageBeforeRemove', function () {
|
||
if (virtualListInstance && virtualListInstance.destroy) virtualListInstance.destroy();
|
||
});
|
||
}
|
||
if (maxLength) {
|
||
checkMaxLength(container);
|
||
}
|
||
if (backOnSelect) {
|
||
container.find('input[type="radio"][name="' + inputName + '"]:checked').parents('label').once('click', function () {
|
||
if (openIn === 'popup') app.closeModal(popup);
|
||
else if (openIn === 'picker') app.closeModal(picker);
|
||
else view.router.back();
|
||
});
|
||
}
|
||
container.on('change', 'input[name="' + inputName + '"]', function () {
|
||
var input = this;
|
||
var value = input.value;
|
||
var optionText = [];
|
||
if (input.type === 'checkbox') {
|
||
var values = [];
|
||
for (var i = 0; i < select.options.length; i++) {
|
||
var option = select.options[i];
|
||
if (option.value === value) {
|
||
option.selected = input.checked;
|
||
}
|
||
if (option.selected) {
|
||
optionText.push(option.textContent.trim());
|
||
}
|
||
}
|
||
if (maxLength) {
|
||
checkMaxLength(container);
|
||
}
|
||
}
|
||
else {
|
||
optionText = [smartSelect.find('option[value="' + value + '"]').text()];
|
||
select.value = value;
|
||
}
|
||
|
||
$select.trigger('change');
|
||
smartSelect.find('.item-after').text(optionText.join(', '));
|
||
if (backOnSelect && inputType === 'radio') {
|
||
if (openIn === 'popup') app.closeModal(popup);
|
||
else if (openIn === 'picker') app.closeModal(picker);
|
||
else view.router.back();
|
||
}
|
||
});
|
||
}
|
||
function pageInit(e) {
|
||
var page = e.detail.page;
|
||
if (page.name === pageName) {
|
||
handleInputs(page.container);
|
||
}
|
||
}
|
||
if (openIn === 'popup') {
|
||
if (reLayout) {
|
||
popup = $('.popup.smart-select-popup .view');
|
||
popup.html(pageHTML);
|
||
}
|
||
else {
|
||
popup = app.popup(
|
||
'<div class="popup smart-select-popup smart-select-popup-' + inputName + '">' +
|
||
'<div class="view navbar-fixed">' +
|
||
pageHTML +
|
||
'</div>' +
|
||
'</div>'
|
||
);
|
||
popup = $(popup);
|
||
}
|
||
app.initPage(popup.find('.page'));
|
||
handleInputs(popup);
|
||
}
|
||
else if (openIn === 'picker') {
|
||
if (reLayout) {
|
||
picker = $('.picker-modal.smart-select-picker .view');
|
||
picker.html(pageHTML);
|
||
}
|
||
else {
|
||
picker = app.pickerModal(
|
||
'<div class="picker-modal smart-select-picker smart-select-picker-' + inputName + '"' + (pickerHeight ? ' style="height:' + pickerHeight + '"' : '') + '>' +
|
||
toolbarHTML +
|
||
'<div class="picker-modal-inner">' +
|
||
'<div class="view">' +
|
||
pageHTML +
|
||
'</div>' +
|
||
'</div>' +
|
||
'</div>'
|
||
);
|
||
picker = $(picker);
|
||
|
||
// Scroll To Input
|
||
scrollToInput();
|
||
|
||
// Close On Click
|
||
$('html').on('click', closeOnHTMLClick);
|
||
|
||
// On Close
|
||
picker.once('close', function () {
|
||
// Reset linked picker
|
||
smartSelect[0].f7SmartSelectPicker = undefined;
|
||
|
||
// Detach html click
|
||
$('html').off('click', closeOnHTMLClick);
|
||
|
||
// Restore page padding bottom
|
||
smartSelect.parents('.page-content').css({paddingBottom: ''});
|
||
});
|
||
|
||
// Link Picker
|
||
smartSelect[0].f7SmartSelectPicker = picker[0];
|
||
}
|
||
|
||
// Init Page
|
||
app.initPage(picker.find('.page'));
|
||
|
||
// Attach events
|
||
handleInputs(picker);
|
||
}
|
||
else {
|
||
$(document).once('pageInit', '.smart-select-page', pageInit);
|
||
view.router.load({
|
||
content: pageHTML,
|
||
reload: reLayout ? true : undefined
|
||
});
|
||
}
|
||
};
|
||
|
||
|
||
/*===============================================================================
|
||
************ Virtual List ************
|
||
===============================================================================*/
|
||
var VirtualList = function (listBlock, params) {
|
||
var defaults = {
|
||
cols: 1,
|
||
height: app.params.material ? 48 : 44,
|
||
cache: true,
|
||
dynamicHeightBufferSize: 1,
|
||
showFilteredItemsOnly: false
|
||
};
|
||
params = params || {};
|
||
for (var def in defaults) {
|
||
if (typeof params[def] === 'undefined') {
|
||
params[def] = defaults[def];
|
||
}
|
||
}
|
||
|
||
// Preparation
|
||
var vl = this;
|
||
vl.listBlock = $(listBlock);
|
||
vl.params = params;
|
||
vl.items = vl.params.items;
|
||
if (vl.params.showFilteredItemsOnly) {
|
||
vl.filteredItems = [];
|
||
}
|
||
if (vl.params.template) {
|
||
if (typeof vl.params.template === 'string') vl.template = t7.compile(vl.params.template);
|
||
else if (typeof vl.params.template === 'function') vl.template = vl.params.template;
|
||
}
|
||
vl.pageContent = vl.listBlock.parents('.page-content');
|
||
|
||
// Bad scroll
|
||
var updatableScroll;
|
||
if (typeof vl.params.updatableScroll !== 'undefined') {
|
||
updatableScroll = vl.params.updatableScroll;
|
||
}
|
||
else {
|
||
updatableScroll = true;
|
||
if (app.device.ios && app.device.osVersion.split('.')[0] < 8) {
|
||
updatableScroll = false;
|
||
}
|
||
}
|
||
|
||
// Append <ul>
|
||
vl.ul = vl.params.ul ? $(vl.params.ul) : vl.listBlock.children('ul');
|
||
if (vl.ul.length === 0) {
|
||
vl.listBlock.append('<ul></ul>');
|
||
vl.ul = vl.listBlock.children('ul');
|
||
}
|
||
|
||
// DOM cached items
|
||
vl.domCache = {};
|
||
vl.displayDomCache = {};
|
||
|
||
// Temporary DOM Element
|
||
vl.tempDomElement = document.createElement('ul');
|
||
|
||
// Last repain position
|
||
vl.lastRepaintY = null;
|
||
|
||
// Fragment
|
||
vl.fragment = document.createDocumentFragment();
|
||
|
||
// Filter
|
||
vl.filterItems = function (indexes, resetScrollTop) {
|
||
vl.filteredItems = [];
|
||
var firstIndex = indexes[0];
|
||
var lastIndex = indexes[indexes.length - 1];
|
||
for (var i = 0; i < indexes.length; i++) {
|
||
vl.filteredItems.push(vl.items[indexes[i]]);
|
||
}
|
||
if (typeof resetScrollTop === 'undefined') resetScrollTop = true;
|
||
if (resetScrollTop) {
|
||
vl.pageContent[0].scrollTop = 0;
|
||
}
|
||
vl.update();
|
||
};
|
||
vl.resetFilter = function () {
|
||
if (vl.params.showFilteredItemsOnly) {
|
||
vl.filteredItems = [];
|
||
}
|
||
else {
|
||
vl.filteredItems = null;
|
||
delete vl.filteredItems;
|
||
}
|
||
vl.update();
|
||
};
|
||
|
||
var pageHeight, rowsPerScreen, rowsBefore, rowsAfter, rowsToRender, maxBufferHeight = 0, listHeight;
|
||
var dynamicHeight = typeof vl.params.height === 'function';
|
||
|
||
// Set list size
|
||
vl.setListSize = function () {
|
||
var items = vl.filteredItems || vl.items;
|
||
pageHeight = vl.pageContent[0].offsetHeight;
|
||
if (dynamicHeight) {
|
||
listHeight = 0;
|
||
vl.heights = [];
|
||
for (var i = 0; i < items.length; i++) {
|
||
var itemHeight = vl.params.height(items[i]);
|
||
listHeight += itemHeight;
|
||
vl.heights.push(itemHeight);
|
||
}
|
||
}
|
||
else {
|
||
listHeight = Math.ceil(items.length / vl.params.cols) * vl.params.height;
|
||
rowsPerScreen = Math.ceil(pageHeight / vl.params.height);
|
||
rowsBefore = vl.params.rowsBefore || rowsPerScreen * 2;
|
||
rowsAfter = vl.params.rowsAfter || rowsPerScreen;
|
||
rowsToRender = (rowsPerScreen + rowsBefore + rowsAfter);
|
||
maxBufferHeight = rowsBefore / 2 * vl.params.height;
|
||
}
|
||
|
||
if (updatableScroll) {
|
||
vl.ul.css({height: listHeight + 'px'});
|
||
}
|
||
};
|
||
|
||
// Render items
|
||
vl.render = function (force, forceScrollTop) {
|
||
if (force) vl.lastRepaintY = null;
|
||
|
||
var scrollTop = -(vl.listBlock[0].getBoundingClientRect().top - vl.pageContent[0].getBoundingClientRect().top);
|
||
|
||
if (typeof forceScrollTop !== 'undefined') scrollTop = forceScrollTop;
|
||
|
||
if (vl.lastRepaintY === null || Math.abs(scrollTop - vl.lastRepaintY) > maxBufferHeight || (!updatableScroll && (vl.pageContent[0].scrollTop + pageHeight >= vl.pageContent[0].scrollHeight))) {
|
||
vl.lastRepaintY = scrollTop;
|
||
}
|
||
else {
|
||
return;
|
||
}
|
||
|
||
var items = vl.filteredItems || vl.items,
|
||
fromIndex, toIndex, heightBeforeFirstItem = 0, heightBeforeLastItem = 0;
|
||
if (dynamicHeight) {
|
||
var itemTop = 0, j, itemHeight;
|
||
maxBufferHeight = pageHeight;
|
||
|
||
for (j = 0; j < vl.heights.length; j++) {
|
||
itemHeight = vl.heights[j];
|
||
if (typeof fromIndex === 'undefined') {
|
||
if (itemTop + itemHeight >= scrollTop - pageHeight * 2 * vl.params.dynamicHeightBufferSize) fromIndex = j;
|
||
else heightBeforeFirstItem += itemHeight;
|
||
}
|
||
|
||
if (typeof toIndex === 'undefined') {
|
||
if (itemTop + itemHeight >= scrollTop + pageHeight * 2 * vl.params.dynamicHeightBufferSize || j === vl.heights.length - 1) toIndex = j + 1;
|
||
heightBeforeLastItem += itemHeight;
|
||
}
|
||
itemTop += itemHeight;
|
||
}
|
||
toIndex = Math.min(toIndex, items.length);
|
||
}
|
||
else {
|
||
fromIndex = (parseInt(scrollTop / vl.params.height) - rowsBefore) * vl.params.cols;
|
||
if (fromIndex < 0) {
|
||
fromIndex = 0;
|
||
}
|
||
toIndex = Math.min(fromIndex + rowsToRender * vl.params.cols, items.length);
|
||
}
|
||
|
||
var topPosition;
|
||
vl.reachEnd = false;
|
||
for (var i = fromIndex; i < toIndex; i++) {
|
||
var item, index;
|
||
// Define real item index
|
||
index = vl.items.indexOf(items[i]);
|
||
|
||
if (i === fromIndex) vl.currentFromIndex = index;
|
||
if (i === toIndex - 1) vl.currentToIndex = index;
|
||
if (index === vl.items.length - 1) vl.reachEnd = true;
|
||
|
||
// Find items
|
||
if (vl.domCache[index]) {
|
||
item = vl.domCache[index];
|
||
}
|
||
else {
|
||
if (vl.template) {
|
||
vl.tempDomElement.innerHTML = vl.template(items[i], {index: index}).trim();
|
||
}
|
||
else if (vl.params.renderItem) {
|
||
vl.tempDomElement.innerHTML = vl.params.renderItem(index, items[i]).trim();
|
||
}
|
||
else {
|
||
vl.tempDomElement.innerHTML = items[i].trim();
|
||
}
|
||
item = vl.tempDomElement.childNodes[0];
|
||
if (vl.params.cache) vl.domCache[index] = item;
|
||
}
|
||
item.f7VirtualListIndex = index;
|
||
|
||
// Set item top position
|
||
if (i === fromIndex) {
|
||
if (dynamicHeight) {
|
||
topPosition = heightBeforeFirstItem;
|
||
}
|
||
else {
|
||
topPosition = (i * vl.params.height / vl.params.cols);
|
||
}
|
||
}
|
||
item.style.top = topPosition + 'px';
|
||
|
||
// Before item insert
|
||
if (vl.params.onItemBeforeInsert) vl.params.onItemBeforeInsert(vl, item);
|
||
|
||
// Append item to fragment
|
||
vl.fragment.appendChild(item);
|
||
|
||
|
||
}
|
||
|
||
// Update list height with not updatable scroll
|
||
if (!updatableScroll) {
|
||
if (dynamicHeight) {
|
||
vl.ul[0].style.height = heightBeforeLastItem + 'px';
|
||
}
|
||
else {
|
||
vl.ul[0].style.height = i * vl.params.height / vl.params.cols + 'px';
|
||
}
|
||
}
|
||
|
||
|
||
// Update list html
|
||
if (vl.params.onBeforeClear) vl.params.onBeforeClear(vl, vl.fragment);
|
||
vl.ul[0].innerHTML = '';
|
||
|
||
if (vl.params.onItemsBeforeInsert) vl.params.onItemsBeforeInsert(vl, vl.fragment);
|
||
vl.ul[0].appendChild(vl.fragment);
|
||
if (vl.params.onItemsAfterInsert) vl.params.onItemsAfterInsert(vl, vl.fragment);
|
||
|
||
if (typeof forceScrollTop !== 'undefined' && force) {
|
||
vl.pageContent.scrollTop(forceScrollTop, 0);
|
||
}
|
||
};
|
||
|
||
vl.scrollToItem = function (index) {
|
||
if (index > vl.items.length) return false;
|
||
|
||
var itemTop = 0, listTop;
|
||
if (dynamicHeight) {
|
||
for (var i = 0; i < index; i++) {
|
||
itemTop += vl.heights[i];
|
||
}
|
||
}
|
||
else {
|
||
itemTop = index * vl.params.height;
|
||
}
|
||
listTop = vl.listBlock[0].offsetTop;
|
||
vl.render(true, listTop + itemTop - parseInt(vl.pageContent.css('padding-top'), 10));
|
||
return true;
|
||
};
|
||
|
||
// Handle scroll event
|
||
vl.handleScroll = function (e) {
|
||
vl.render();
|
||
};
|
||
// Handle resize event
|
||
vl._isVisible = function (el) {
|
||
return !!( el.offsetWidth || el.offsetHeight || el.getClientRects().length );
|
||
};
|
||
vl.handleResize = function (e) {
|
||
if (vl._isVisible(vl.listBlock[0])) {
|
||
vl.setListSize();
|
||
vl.render(true);
|
||
}
|
||
};
|
||
|
||
vl.attachEvents = function (detach) {
|
||
var action = detach ? 'off' : 'on';
|
||
vl.pageContent[action]('scroll', vl.handleScroll);
|
||
vl.listBlock.parents('.tab').eq(0)[action]('show', vl.handleResize);
|
||
$(window)[action]('resize', vl.handleResize);
|
||
};
|
||
|
||
// Init Virtual List
|
||
vl.init = function () {
|
||
vl.attachEvents();
|
||
vl.setListSize();
|
||
vl.render();
|
||
};
|
||
|
||
// Append
|
||
vl.appendItems = function (items) {
|
||
for (var i = 0; i < items.length; i++) {
|
||
vl.items.push(items[i]);
|
||
}
|
||
vl.update();
|
||
};
|
||
vl.appendItem = function (item) {
|
||
vl.appendItems([item]);
|
||
};
|
||
// Replace
|
||
vl.replaceAllItems = function (items) {
|
||
vl.items = items;
|
||
delete vl.filteredItems;
|
||
vl.domCache = {};
|
||
vl.update();
|
||
};
|
||
vl.replaceItem = function (index, item) {
|
||
vl.items[index] = item;
|
||
if (vl.params.cache) delete vl.domCache[index];
|
||
vl.update();
|
||
};
|
||
// Prepend
|
||
vl.prependItems = function (items) {
|
||
for (var i = items.length - 1; i >= 0; i--) {
|
||
vl.items.unshift(items[i]);
|
||
}
|
||
if (vl.params.cache) {
|
||
var newCache = {};
|
||
for (var cached in vl.domCache) {
|
||
newCache[parseInt(cached, 10) + items.length] = vl.domCache[cached];
|
||
}
|
||
vl.domCache = newCache;
|
||
}
|
||
vl.update();
|
||
};
|
||
vl.prependItem = function (item) {
|
||
vl.prependItems([item]);
|
||
};
|
||
|
||
// Move
|
||
vl.moveItem = function (oldIndex, newIndex) {
|
||
if (oldIndex === newIndex) return;
|
||
// remove item from array
|
||
var item = vl.items.splice(oldIndex, 1)[0];
|
||
if (newIndex >= vl.items.length) {
|
||
// Add item to the end
|
||
vl.items.push(item);
|
||
newIndex = vl.items.length - 1;
|
||
}
|
||
else {
|
||
// Add item to new index
|
||
vl.items.splice(newIndex, 0, item);
|
||
}
|
||
// Update cache
|
||
if (vl.params.cache) {
|
||
var newCache = {};
|
||
for (var cached in vl.domCache) {
|
||
var cachedIndex = parseInt(cached, 10);
|
||
var leftIndex = oldIndex < newIndex ? oldIndex : newIndex;
|
||
var rightIndex = oldIndex < newIndex ? newIndex : oldIndex;
|
||
var indexShift = oldIndex < newIndex ? -1 : 1;
|
||
if (cachedIndex < leftIndex || cachedIndex > rightIndex) newCache[cachedIndex] = vl.domCache[cachedIndex];
|
||
if (cachedIndex === leftIndex) newCache[rightIndex] = vl.domCache[cachedIndex];
|
||
if (cachedIndex > leftIndex && cachedIndex <= rightIndex) newCache[cachedIndex + indexShift] = vl.domCache[cachedIndex];
|
||
}
|
||
vl.domCache = newCache;
|
||
}
|
||
vl.update();
|
||
};
|
||
// Insert before
|
||
vl.insertItemBefore = function (index, item) {
|
||
if (index === 0) {
|
||
vl.prependItem(item);
|
||
return;
|
||
}
|
||
if (index >= vl.items.length) {
|
||
vl.appendItem(item);
|
||
return;
|
||
}
|
||
vl.items.splice(index, 0, item);
|
||
// Update cache
|
||
if (vl.params.cache) {
|
||
var newCache = {};
|
||
for (var cached in vl.domCache) {
|
||
var cachedIndex = parseInt(cached, 10);
|
||
if (cachedIndex >= index) {
|
||
newCache[cachedIndex + 1] = vl.domCache[cachedIndex];
|
||
}
|
||
}
|
||
vl.domCache = newCache;
|
||
}
|
||
vl.update();
|
||
};
|
||
// Delete
|
||
vl.deleteItems = function (indexes) {
|
||
var prevIndex, indexShift = 0;
|
||
for (var i = 0; i < indexes.length; i++) {
|
||
var index = indexes[i];
|
||
if (typeof prevIndex !== 'undefined') {
|
||
if (index > prevIndex) {
|
||
indexShift = -i;
|
||
}
|
||
}
|
||
index = index + indexShift;
|
||
prevIndex = indexes[i];
|
||
// Delete item
|
||
var deletedItem = vl.items.splice(index, 1)[0];
|
||
|
||
// Delete from filtered
|
||
if (vl.filteredItems && vl.filteredItems.indexOf(deletedItem) >= 0) {
|
||
vl.filteredItems.splice(vl.filteredItems.indexOf(deletedItem), 1);
|
||
}
|
||
// Update cache
|
||
if (vl.params.cache) {
|
||
var newCache = {};
|
||
for (var cached in vl.domCache) {
|
||
var cachedIndex = parseInt(cached, 10);
|
||
if (cachedIndex === index) {
|
||
delete vl.domCache[index];
|
||
}
|
||
else if (parseInt(cached, 10) > index) {
|
||
newCache[cachedIndex - 1] = vl.domCache[cached];
|
||
}
|
||
else {
|
||
newCache[cachedIndex] = vl.domCache[cached];
|
||
}
|
||
}
|
||
vl.domCache = newCache;
|
||
}
|
||
}
|
||
vl.update();
|
||
};
|
||
vl.deleteAllItems = function () {
|
||
vl.items = [];
|
||
delete vl.filteredItems;
|
||
if (vl.params.cache) vl.domCache = {};
|
||
vl.update();
|
||
};
|
||
vl.deleteItem = function (index) {
|
||
vl.deleteItems([index]);
|
||
};
|
||
|
||
// Clear cache
|
||
vl.clearCache = function () {
|
||
vl.domCache = {};
|
||
};
|
||
|
||
// Update Virtual List
|
||
vl.update = function () {
|
||
vl.setListSize();
|
||
vl.render(true);
|
||
};
|
||
|
||
// Destroy
|
||
vl.destroy = function () {
|
||
vl.attachEvents(true);
|
||
delete vl.items;
|
||
delete vl.domCache;
|
||
};
|
||
|
||
// Init Virtual List
|
||
vl.init();
|
||
|
||
// Store vl in container
|
||
vl.listBlock[0].f7VirtualList = vl;
|
||
return vl;
|
||
};
|
||
|
||
// App Method
|
||
app.virtualList = function (listBlock, params) {
|
||
return new VirtualList(listBlock, params);
|
||
};
|
||
|
||
app.reinitVirtualList = function (pageContainer) {
|
||
var page = $(pageContainer);
|
||
var vlists = page.find('.virtual-list');
|
||
if (vlists.length === 0) return;
|
||
for (var i = 0; i < vlists.length; i++) {
|
||
var vlistInstance = vlists[i].f7VirtualList;
|
||
if (vlistInstance) {
|
||
vlistInstance.update();
|
||
}
|
||
}
|
||
};
|
||
|
||
/*======================================================
|
||
************ Pull To Refresh ************
|
||
======================================================*/
|
||
app.initPullToRefresh = function (pageContainer) {
|
||
var eventsTarget = $(pageContainer);
|
||
if (!eventsTarget.hasClass('pull-to-refresh-content')) {
|
||
eventsTarget = eventsTarget.find('.pull-to-refresh-content');
|
||
}
|
||
if (!eventsTarget || eventsTarget.length === 0) return;
|
||
|
||
var touchId, isTouched, isMoved, touchesStart = {}, isScrolling, touchesDiff, touchStartTime, container, refresh = false, useTranslate = false, startTranslate = 0, translate, scrollTop, wasScrolled, layer, triggerDistance, dynamicTriggerDistance, pullStarted;
|
||
var page = eventsTarget.hasClass('page') ? eventsTarget : eventsTarget.parents('.page');
|
||
var hasNavbar = false;
|
||
if (page.find('.navbar').length > 0 || page.parents('.navbar-fixed, .navbar-through').length > 0 || page.hasClass('navbar-fixed') || page.hasClass('navbar-through')) hasNavbar = true;
|
||
if (page.hasClass('no-navbar')) hasNavbar = false;
|
||
if (!hasNavbar) eventsTarget.addClass('pull-to-refresh-no-navbar');
|
||
|
||
container = eventsTarget;
|
||
|
||
// Define trigger distance
|
||
if (container.attr('data-ptr-distance')) {
|
||
dynamicTriggerDistance = true;
|
||
}
|
||
else {
|
||
triggerDistance = 44;
|
||
}
|
||
|
||
function handleTouchStart(e) {
|
||
if (isTouched) {
|
||
if (app.device.os === 'android') {
|
||
if ('targetTouches' in e && e.targetTouches.length > 1) return;
|
||
}
|
||
else return;
|
||
}
|
||
|
||
/*jshint validthis:true */
|
||
container = $(this);
|
||
if (container.hasClass('refreshing')) {
|
||
return;
|
||
}
|
||
|
||
isMoved = false;
|
||
pullStarted = false;
|
||
isTouched = true;
|
||
isScrolling = undefined;
|
||
wasScrolled = undefined;
|
||
if (e.type === 'touchstart') touchId = e.targetTouches[0].identifier;
|
||
touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
|
||
touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
|
||
touchStartTime = (new Date()).getTime();
|
||
|
||
}
|
||
|
||
function handleTouchMove(e) {
|
||
if (!isTouched) return;
|
||
var pageX, pageY, touch;
|
||
if (e.type === 'touchmove') {
|
||
if (touchId && e.touches) {
|
||
for (var i = 0; i < e.touches.length; i++) {
|
||
if (e.touches[i].identifier === touchId) {
|
||
touch = e.touches[i];
|
||
}
|
||
}
|
||
}
|
||
if (!touch) touch = e.targetTouches[0];
|
||
pageX = touch.pageX;
|
||
pageY = touch.pageY;
|
||
}
|
||
else {
|
||
pageX = e.pageX;
|
||
pageY = e.pageY;
|
||
}
|
||
if (!pageX || !pageY) return;
|
||
|
||
|
||
if (typeof isScrolling === 'undefined') {
|
||
isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x));
|
||
}
|
||
if (!isScrolling) {
|
||
isTouched = false;
|
||
return;
|
||
}
|
||
|
||
scrollTop = container[0].scrollTop;
|
||
if (typeof wasScrolled === 'undefined' && scrollTop !== 0) wasScrolled = true;
|
||
|
||
if (!isMoved) {
|
||
/*jshint validthis:true */
|
||
container.removeClass('transitioning');
|
||
if (scrollTop > container[0].offsetHeight) {
|
||
isTouched = false;
|
||
return;
|
||
}
|
||
if (dynamicTriggerDistance) {
|
||
triggerDistance = container.attr('data-ptr-distance');
|
||
if (triggerDistance.indexOf('%') >= 0) triggerDistance = container[0].offsetHeight * parseInt(triggerDistance, 10) / 100;
|
||
}
|
||
startTranslate = container.hasClass('refreshing') ? triggerDistance : 0;
|
||
if (container[0].scrollHeight === container[0].offsetHeight || app.device.os !== 'ios') {
|
||
useTranslate = true;
|
||
}
|
||
else {
|
||
useTranslate = false;
|
||
}
|
||
}
|
||
isMoved = true;
|
||
touchesDiff = pageY - touchesStart.y;
|
||
|
||
if (touchesDiff > 0 && scrollTop <= 0 || scrollTop < 0) {
|
||
// iOS 8 fix
|
||
if (app.device.os === 'ios' && parseInt(app.device.osVersion.split('.')[0], 10) > 7 && scrollTop === 0 && !wasScrolled) useTranslate = true;
|
||
|
||
if (useTranslate) {
|
||
e.preventDefault();
|
||
translate = (Math.pow(touchesDiff, 0.85) + startTranslate);
|
||
container.transform('translate3d(0,' + translate + 'px,0)');
|
||
}
|
||
if ((useTranslate && Math.pow(touchesDiff, 0.85) > triggerDistance) || (!useTranslate && touchesDiff >= triggerDistance * 2)) {
|
||
refresh = true;
|
||
container.addClass('pull-up').removeClass('pull-down');
|
||
}
|
||
else {
|
||
refresh = false;
|
||
container.removeClass('pull-up').addClass('pull-down');
|
||
}
|
||
if (!pullStarted) {
|
||
container.trigger('pullstart');
|
||
pullStarted = true;
|
||
}
|
||
container.trigger('pullmove', {
|
||
event: e,
|
||
scrollTop: scrollTop,
|
||
translate: translate,
|
||
touchesDiff: touchesDiff
|
||
});
|
||
}
|
||
else {
|
||
pullStarted = false;
|
||
container.removeClass('pull-up pull-down');
|
||
refresh = false;
|
||
return;
|
||
}
|
||
}
|
||
function handleTouchEnd(e) {
|
||
if (e.type === 'touchend' && e.changedTouches && e.changedTouches.length > 0 && touchId) {
|
||
if (e.changedTouches[0].identifier !== touchId) return;
|
||
}
|
||
if (!isTouched || !isMoved) {
|
||
isTouched = false;
|
||
isMoved = false;
|
||
return;
|
||
}
|
||
if (translate) {
|
||
container.addClass('transitioning');
|
||
translate = 0;
|
||
}
|
||
container.transform('');
|
||
if (refresh) {
|
||
container.addClass('refreshing');
|
||
container.trigger('refresh', {
|
||
done: function () {
|
||
app.pullToRefreshDone(container);
|
||
}
|
||
});
|
||
}
|
||
else {
|
||
container.removeClass('pull-down');
|
||
}
|
||
isTouched = false;
|
||
isMoved = false;
|
||
if (pullStarted) container.trigger('pullend');
|
||
}
|
||
|
||
// Attach Events
|
||
var passiveListener = app.touchEvents.start === 'touchstart' && app.support.passiveListener ? {passive: true, capture: false} : false;
|
||
eventsTarget.on(app.touchEvents.start, handleTouchStart, passiveListener);
|
||
eventsTarget.on(app.touchEvents.move, handleTouchMove);
|
||
eventsTarget.on(app.touchEvents.end, handleTouchEnd, passiveListener);
|
||
|
||
// Detach Events on page remove
|
||
if (page.length === 0) return;
|
||
function destroyPullToRefresh() {
|
||
eventsTarget.off(app.touchEvents.start, handleTouchStart);
|
||
eventsTarget.off(app.touchEvents.move, handleTouchMove);
|
||
eventsTarget.off(app.touchEvents.end, handleTouchEnd);
|
||
}
|
||
eventsTarget[0].f7DestroyPullToRefresh = destroyPullToRefresh;
|
||
function detachEvents() {
|
||
destroyPullToRefresh();
|
||
page.off('pageBeforeRemove', detachEvents);
|
||
}
|
||
page.on('pageBeforeRemove', detachEvents);
|
||
|
||
};
|
||
|
||
app.pullToRefreshDone = function (container) {
|
||
container = $(container);
|
||
if (container.length === 0) container = $('.pull-to-refresh-content.refreshing');
|
||
container.removeClass('refreshing').addClass('transitioning');
|
||
container.transitionEnd(function () {
|
||
container.removeClass('transitioning pull-up pull-down');
|
||
container.trigger('refreshdone');
|
||
});
|
||
};
|
||
app.pullToRefreshTrigger = function (container) {
|
||
container = $(container);
|
||
if (container.length === 0) container = $('.pull-to-refresh-content');
|
||
if (container.hasClass('refreshing')) return;
|
||
container.addClass('transitioning refreshing');
|
||
container.trigger('refresh', {
|
||
done: function () {
|
||
app.pullToRefreshDone(container);
|
||
}
|
||
});
|
||
};
|
||
|
||
app.destroyPullToRefresh = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var pullToRefreshContent = pageContainer.hasClass('pull-to-refresh-content') ? pageContainer : pageContainer.find('.pull-to-refresh-content');
|
||
if (pullToRefreshContent.length === 0) return;
|
||
if (pullToRefreshContent[0].f7DestroyPullToRefresh) pullToRefreshContent[0].f7DestroyPullToRefresh();
|
||
};
|
||
|
||
|
||
/* ===============================================================================
|
||
************ Infinite Scroll ************
|
||
=============================================================================== */
|
||
function handleInfiniteScroll() {
|
||
/*jshint validthis:true */
|
||
var inf = $(this);
|
||
var scrollTop = inf[0].scrollTop;
|
||
var scrollHeight = inf[0].scrollHeight;
|
||
var height = inf[0].offsetHeight;
|
||
var distance = inf[0].getAttribute('data-distance');
|
||
var virtualListContainer = inf.find('.virtual-list');
|
||
var virtualList;
|
||
var onTop = inf.hasClass('infinite-scroll-top');
|
||
if (!distance) distance = 50;
|
||
if (typeof distance === 'string' && distance.indexOf('%') >= 0) {
|
||
distance = parseInt(distance, 10) / 100 * height;
|
||
}
|
||
if (distance > height) distance = height;
|
||
if (onTop) {
|
||
if (scrollTop < distance) {
|
||
inf.trigger('infinite');
|
||
}
|
||
}
|
||
else {
|
||
if (scrollTop + height >= scrollHeight - distance) {
|
||
if (virtualListContainer.length > 0) {
|
||
virtualList = virtualListContainer[0].f7VirtualList;
|
||
if (virtualList && !virtualList.reachEnd) return;
|
||
}
|
||
inf.trigger('infinite');
|
||
}
|
||
}
|
||
|
||
}
|
||
app.attachInfiniteScroll = function (infiniteContent) {
|
||
$(infiniteContent).on('scroll', handleInfiniteScroll);
|
||
};
|
||
app.detachInfiniteScroll = function (infiniteContent) {
|
||
$(infiniteContent).off('scroll', handleInfiniteScroll);
|
||
};
|
||
|
||
app.initPageInfiniteScroll = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var infiniteContent = pageContainer.find('.infinite-scroll');
|
||
if (infiniteContent.length === 0) return;
|
||
app.attachInfiniteScroll(infiniteContent);
|
||
function detachEvents() {
|
||
app.detachInfiniteScroll(infiniteContent);
|
||
pageContainer.off('pageBeforeRemove', detachEvents);
|
||
}
|
||
pageContainer.on('pageBeforeRemove', detachEvents);
|
||
};
|
||
|
||
/*=============================================================
|
||
************ Hide/show Toolbar/Navbar on scroll ************
|
||
=============================================================*/
|
||
app.initPageScrollToolbars = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var scrollContent = pageContainer.find('.page-content');
|
||
if (scrollContent.length === 0) return;
|
||
var hideNavbar = (app.params.hideNavbarOnPageScroll || scrollContent.hasClass('hide-navbar-on-scroll') || scrollContent.hasClass('hide-bars-on-scroll')) && !(scrollContent.hasClass('keep-navbar-on-scroll') || scrollContent.hasClass('keep-bars-on-scroll'));
|
||
var hideToolbar = (app.params.hideToolbarOnPageScroll || scrollContent.hasClass('hide-toolbar-on-scroll') || scrollContent.hasClass('hide-bars-on-scroll')) && !(scrollContent.hasClass('keep-toolbar-on-scroll') || scrollContent.hasClass('keep-bars-on-scroll'));
|
||
var hideTabbar = (app.params.hideTabbarOnPageScroll || scrollContent.hasClass('hide-tabbar-on-scroll')) && !(scrollContent.hasClass('keep-tabbar-on-scroll'));
|
||
|
||
if (!(hideNavbar || hideToolbar || hideTabbar)) return;
|
||
|
||
var viewContainer = scrollContent.parents('.' + app.params.viewClass);
|
||
if (viewContainer.length === 0) return;
|
||
|
||
var navbar = viewContainer.find('.navbar'),
|
||
toolbar = viewContainer.find('.toolbar'),
|
||
tabbar;
|
||
if (hideTabbar) {
|
||
tabbar = viewContainer.find('.tabbar');
|
||
if (tabbar.length === 0) tabbar = viewContainer.parents('.' + app.params.viewsClass).find('.tabbar');
|
||
}
|
||
|
||
var hasNavbar = navbar.length > 0,
|
||
hasToolbar = toolbar.length > 0,
|
||
hasTabbar = tabbar && tabbar.length > 0;
|
||
|
||
var previousScroll, currentScroll;
|
||
previousScroll = currentScroll = scrollContent[0].scrollTop;
|
||
|
||
var scrollHeight, offsetHeight, reachEnd, action, navbarHidden, toolbarHidden, tabbarHidden;
|
||
|
||
var toolbarHeight = (hasToolbar && hideToolbar) ? toolbar[0].offsetHeight : 0;
|
||
var tabbarHeight = (hasTabbar && hideTabbar) ? tabbar[0].offsetHeight : 0;
|
||
var bottomBarHeight = tabbarHeight || toolbarHeight;
|
||
|
||
function handleScroll(e) {
|
||
if (pageContainer.hasClass('page-on-left')) return;
|
||
currentScroll = scrollContent[0].scrollTop;
|
||
scrollHeight = scrollContent[0].scrollHeight;
|
||
offsetHeight = scrollContent[0].offsetHeight;
|
||
reachEnd = currentScroll + offsetHeight >= scrollHeight - bottomBarHeight;
|
||
navbarHidden = navbar.hasClass('navbar-hidden');
|
||
toolbarHidden = toolbar.hasClass('toolbar-hidden');
|
||
tabbarHidden = tabbar && tabbar.hasClass('toolbar-hidden');
|
||
|
||
if (reachEnd) {
|
||
if (app.params.showBarsOnPageScrollEnd) {
|
||
action = 'show';
|
||
}
|
||
}
|
||
else if (previousScroll > currentScroll) {
|
||
if (app.params.showBarsOnPageScrollTop || currentScroll <= 44) {
|
||
action = 'show';
|
||
}
|
||
else {
|
||
action = 'hide';
|
||
}
|
||
}
|
||
else {
|
||
if (currentScroll > 44) {
|
||
action = 'hide';
|
||
}
|
||
else {
|
||
action = 'show';
|
||
}
|
||
}
|
||
|
||
if (action === 'show') {
|
||
if (hasNavbar && hideNavbar && navbarHidden) {
|
||
app.showNavbar(navbar);
|
||
pageContainer.removeClass('no-navbar-by-scroll');
|
||
navbarHidden = false;
|
||
}
|
||
if (hasToolbar && hideToolbar && toolbarHidden) {
|
||
app.showToolbar(toolbar);
|
||
pageContainer.removeClass('no-toolbar-by-scroll');
|
||
toolbarHidden = false;
|
||
}
|
||
if (hasTabbar && hideTabbar && tabbarHidden) {
|
||
app.showToolbar(tabbar);
|
||
pageContainer.removeClass('no-tabbar-by-scroll');
|
||
tabbarHidden = false;
|
||
}
|
||
}
|
||
else {
|
||
if (hasNavbar && hideNavbar && !navbarHidden) {
|
||
app.hideNavbar(navbar);
|
||
pageContainer.addClass('no-navbar-by-scroll');
|
||
navbarHidden = true;
|
||
}
|
||
if (hasToolbar && hideToolbar && !toolbarHidden) {
|
||
app.hideToolbar(toolbar);
|
||
pageContainer.addClass('no-toolbar-by-scroll');
|
||
toolbarHidden = true;
|
||
}
|
||
if (hasTabbar && hideTabbar && !tabbarHidden) {
|
||
app.hideToolbar(tabbar);
|
||
pageContainer.addClass('no-tabbar-by-scroll');
|
||
tabbarHidden = true;
|
||
}
|
||
}
|
||
|
||
previousScroll = currentScroll;
|
||
}
|
||
scrollContent.on('scroll', handleScroll);
|
||
scrollContent[0].f7ScrollToolbarsHandler = handleScroll;
|
||
};
|
||
app.destroyScrollToolbars = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var scrollContent = pageContainer.find('.page-content');
|
||
if (scrollContent.length === 0) return;
|
||
var handler = scrollContent[0].f7ScrollToolbarsHandler;
|
||
if (!handler) return;
|
||
scrollContent.off('scroll', scrollContent[0].f7ScrollToolbarsHandler);
|
||
};
|
||
|
||
/*======================================================
|
||
************ Material Tabbar ************
|
||
======================================================*/
|
||
app.materialTabbarSetHighlight = function (tabbar, activeLink) {
|
||
tabbar = $(tabbar);
|
||
activeLink = activeLink || tabbar.find('.tab-link.active');
|
||
|
||
var tabLinkWidth, highlightTranslate;
|
||
if (tabbar.hasClass('tabbar-scrollable')) {
|
||
tabLinkWidth = activeLink[0].offsetWidth + 'px';
|
||
highlightTranslate = (app.rtl ? - activeLink[0].offsetLeft: activeLink[0].offsetLeft) + 'px';
|
||
}
|
||
else {
|
||
tabLinkWidth = 1 / tabbar.find('.tab-link').length * 100 + '%';
|
||
highlightTranslate = (app.rtl ? - activeLink.index(): activeLink.index()) * 100 + '%';
|
||
}
|
||
|
||
tabbar.find('.tab-link-highlight')
|
||
.css({width: tabLinkWidth})
|
||
.transform('translate3d(' + highlightTranslate + ',0,0)');
|
||
};
|
||
app.initPageMaterialTabbar = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var tabbar = $(pageContainer).find('.tabbar');
|
||
|
||
function tabbarSetHighlight() {
|
||
app.materialTabbarSetHighlight(tabbar);
|
||
}
|
||
if (tabbar.length > 0) {
|
||
if (tabbar.find('.tab-link-highlight').length === 0) {
|
||
tabbar.find('.toolbar-inner').append('<span class="tab-link-highlight"></span>');
|
||
}
|
||
|
||
tabbarSetHighlight();
|
||
$(window).on('resize', tabbarSetHighlight);
|
||
pageContainer.once('pageBeforeRemove', function () {
|
||
$(window).off('resize', tabbarSetHighlight);
|
||
});
|
||
}
|
||
};
|
||
|
||
/* ===============================================================================
|
||
************ Tabs ************
|
||
=============================================================================== */
|
||
app.showTab = function (tab, tabLink, force) {
|
||
var newTab = $(tab);
|
||
if (arguments.length === 2) {
|
||
if (typeof tabLink === 'boolean') {
|
||
force = tabLink;
|
||
}
|
||
}
|
||
if (newTab.length === 0) return false;
|
||
if (newTab.hasClass('active')) {
|
||
if (force) newTab.trigger('show');
|
||
return false;
|
||
}
|
||
var tabs = newTab.parent('.tabs');
|
||
if (tabs.length === 0) return false;
|
||
|
||
// Return swipeouts in hidden tabs
|
||
app.allowSwipeout = true;
|
||
|
||
// Animated tabs
|
||
var isAnimatedTabs = tabs.parent().hasClass('tabs-animated-wrap');
|
||
if (isAnimatedTabs) {
|
||
var tabTranslate = (app.rtl ? newTab.index() : -newTab.index()) * 100;
|
||
tabs.transform('translate3d(' + tabTranslate + '%,0,0)');
|
||
}
|
||
|
||
// Swipeable tabs
|
||
var isSwipeableTabs = tabs.parent().hasClass('tabs-swipeable-wrap'), swiper;
|
||
if (isSwipeableTabs) {
|
||
swiper = tabs.parent()[0].swiper;
|
||
if (swiper.activeIndex !== newTab.index()) swiper.slideTo(newTab.index(), undefined, false);
|
||
}
|
||
|
||
// Remove active class from old tabs
|
||
var oldTab = tabs.children('.tab.active').removeClass('active').trigger('hide');
|
||
// Add active class to new tab
|
||
newTab.addClass('active');
|
||
// Trigger 'show' event on new tab
|
||
newTab.trigger('show');
|
||
|
||
// Update navbars in new tab
|
||
if (!isAnimatedTabs && !isSwipeableTabs && newTab.find('.navbar').length > 0) {
|
||
// Find tab's view
|
||
var viewContainer;
|
||
if (newTab.hasClass(app.params.viewClass)) viewContainer = newTab[0];
|
||
else viewContainer = newTab.parents('.' + app.params.viewClass)[0];
|
||
app.sizeNavbars(viewContainer);
|
||
}
|
||
|
||
// Find related link for new tab
|
||
if (tabLink) tabLink = $(tabLink);
|
||
else {
|
||
// Search by id
|
||
if (typeof tab === 'string') tabLink = $('.tab-link[href="' + tab + '"]');
|
||
else tabLink = $('.tab-link[href="#' + newTab.attr('id') + '"]');
|
||
// Search by data-tab
|
||
if (!tabLink || tabLink && tabLink.length === 0) {
|
||
$('[data-tab]').each(function () {
|
||
if (newTab.is($(this).attr('data-tab'))) tabLink = $(this);
|
||
});
|
||
}
|
||
}
|
||
if (tabLink.length === 0) return;
|
||
|
||
// Find related link for old tab
|
||
var oldTabLink;
|
||
if (oldTab && oldTab.length > 0) {
|
||
// Search by id
|
||
var oldTabId = oldTab.attr('id');
|
||
if (oldTabId) oldTabLink = $('.tab-link[href="#' + oldTabId + '"]');
|
||
// Search by data-tab
|
||
if (!oldTabLink || oldTabLink && oldTabLink.length === 0) {
|
||
$('[data-tab]').each(function () {
|
||
if (oldTab.is($(this).attr('data-tab'))) oldTabLink = $(this);
|
||
});
|
||
}
|
||
}
|
||
|
||
// Update links' classes
|
||
if (tabLink && tabLink.length > 0) {
|
||
tabLink.addClass('active');
|
||
// Material Highlight
|
||
if (app.params.material) {
|
||
var tabbar = tabLink.parents('.tabbar');
|
||
if (tabbar.length > 0) {
|
||
if (tabbar.find('.tab-link-highlight').length === 0) {
|
||
tabbar.find('.toolbar-inner').append('<span class="tab-link-highlight"></span>');
|
||
}
|
||
app.materialTabbarSetHighlight(tabbar, tabLink);
|
||
}
|
||
}
|
||
}
|
||
if (oldTabLink && oldTabLink.length > 0) oldTabLink.removeClass('active');
|
||
|
||
return true;
|
||
};
|
||
|
||
/*===============================================================================
|
||
************ Accordion ************
|
||
===============================================================================*/
|
||
app.accordionToggle = function (item) {
|
||
item = $(item);
|
||
if (item.length === 0) return;
|
||
if (item.hasClass('accordion-item-expanded')) app.accordionClose(item);
|
||
else app.accordionOpen(item);
|
||
};
|
||
app.accordionOpen = function (item) {
|
||
item = $(item);
|
||
var list = item.parents('.accordion-list').eq(0);
|
||
var content = item.children('.accordion-item-content');
|
||
if (content.length === 0) content = item.find('.accordion-item-content');
|
||
var expandedItem = list.length > 0 && item.parent().children('.accordion-item-expanded');
|
||
if (expandedItem.length > 0) {
|
||
app.accordionClose(expandedItem);
|
||
}
|
||
content.css('height', content[0].scrollHeight + 'px').transitionEnd(function () {
|
||
if (item.hasClass('accordion-item-expanded')) {
|
||
content.transition(0);
|
||
content.css('height', 'auto');
|
||
var clientLeft = content[0].clientLeft;
|
||
content.transition('');
|
||
item.trigger('opened');
|
||
}
|
||
else {
|
||
content.css('height', '');
|
||
item.trigger('closed');
|
||
}
|
||
});
|
||
item.trigger('open');
|
||
item.addClass('accordion-item-expanded');
|
||
};
|
||
app.accordionClose = function (item) {
|
||
item = $(item);
|
||
var content = item.children('.accordion-item-content');
|
||
if (content.length === 0) content = item.find('.accordion-item-content');
|
||
item.removeClass('accordion-item-expanded');
|
||
content.transition(0);
|
||
content.css('height', content[0].scrollHeight + 'px');
|
||
// Relayout
|
||
var clientLeft = content[0].clientLeft;
|
||
// Close
|
||
content.transition('');
|
||
content.css('height', '').transitionEnd(function () {
|
||
if (item.hasClass('accordion-item-expanded')) {
|
||
content.transition(0);
|
||
content.css('height', 'auto');
|
||
var clientLeft = content[0].clientLeft;
|
||
content.transition('');
|
||
item.trigger('opened');
|
||
}
|
||
else {
|
||
content.css('height', '');
|
||
item.trigger('closed');
|
||
}
|
||
});
|
||
item.trigger('close');
|
||
};
|
||
|
||
/*===============================================================================
|
||
************ Fast Clicks ************
|
||
************ Inspired by https://github.com/ftlabs/fastclick ************
|
||
===============================================================================*/
|
||
app.initFastClicks = function () {
|
||
if (app.params.activeState) {
|
||
$('html').addClass('watch-active-state');
|
||
}
|
||
if (app.device.ios && app.device.webView) {
|
||
// Strange hack required for iOS 8 webview to work on inputs
|
||
window.addEventListener('touchstart', function () {});
|
||
}
|
||
|
||
var touchStartX, touchStartY, touchStartTime, targetElement, trackClick, activeSelection, scrollParent, lastClickTime, isMoved, tapHoldFired, tapHoldTimeout;
|
||
var activableElement, activeTimeout, needsFastClick, needsFastClickTimeOut;
|
||
var rippleWave, rippleTarget, rippleTransform, rippleTimeout;
|
||
function findActivableElement(el) {
|
||
var target = $(el);
|
||
var parents = target.parents(app.params.activeStateElements);
|
||
var activable;
|
||
if (target.is(app.params.activeStateElements)) {
|
||
activable = target;
|
||
}
|
||
if (parents.length > 0) {
|
||
activable = activable ? activable.add(parents) : parents;
|
||
}
|
||
return activable ? activable : target;
|
||
}
|
||
function isInsideScrollableView(el) {
|
||
var pageContent = el.parents('.page-content, .panel');
|
||
|
||
if (pageContent.length === 0) {
|
||
return false;
|
||
}
|
||
|
||
// This event handler covers the "tap to stop scrolling".
|
||
if (pageContent.prop('scrollHandlerSet') !== 'yes') {
|
||
pageContent.on('scroll', function() {
|
||
clearTimeout(activeTimeout);
|
||
clearTimeout(rippleTimeout);
|
||
});
|
||
pageContent.prop('scrollHandlerSet', 'yes');
|
||
}
|
||
|
||
return true;
|
||
}
|
||
function addActive() {
|
||
if (!activableElement) return;
|
||
activableElement.addClass('active-state');
|
||
}
|
||
function removeActive(el) {
|
||
if (!activableElement) return;
|
||
activableElement.removeClass('active-state');
|
||
activableElement = null;
|
||
}
|
||
function isFormElement(el) {
|
||
var nodes = ('input select textarea label').split(' ');
|
||
if (el.nodeName && nodes.indexOf(el.nodeName.toLowerCase()) >= 0) return true;
|
||
return false;
|
||
}
|
||
function androidNeedsBlur(el) {
|
||
var noBlur = ('button input textarea select').split(' ');
|
||
if (document.activeElement && el !== document.activeElement && document.activeElement !== document.body) {
|
||
if (noBlur.indexOf(el.nodeName.toLowerCase()) >= 0) {
|
||
return false;
|
||
}
|
||
else {
|
||
return true;
|
||
}
|
||
}
|
||
else {
|
||
return false;
|
||
}
|
||
}
|
||
function targetNeedsFastClick(el) {
|
||
var $el = $(el);
|
||
if (el.nodeName.toLowerCase() === 'input' && el.type === 'file') return false;
|
||
if (el.nodeName.toLowerCase() === 'select' && app.device.android) return false;
|
||
if ($el.hasClass('no-fastclick') || $el.parents('.no-fastclick').length > 0) return false;
|
||
if (app.params.fastClicksExclude && $el.is(app.params.fastClicksExclude)) return false;
|
||
return true;
|
||
}
|
||
function targetNeedsFocus(el) {
|
||
if (document.activeElement === el) {
|
||
return false;
|
||
}
|
||
var tag = el.nodeName.toLowerCase();
|
||
var skipInputs = ('button checkbox file image radio submit').split(' ');
|
||
if (el.disabled || el.readOnly) return false;
|
||
if (tag === 'textarea') return true;
|
||
if (tag === 'select') {
|
||
if (app.device.android) return false;
|
||
else return true;
|
||
}
|
||
if (tag === 'input' && skipInputs.indexOf(el.type) < 0) return true;
|
||
}
|
||
function targetNeedsPrevent(el) {
|
||
el = $(el);
|
||
var prevent = true;
|
||
if (el.is('label') || el.parents('label').length > 0) {
|
||
if (app.device.android) {
|
||
prevent = false;
|
||
}
|
||
else if (app.device.ios && el.is('input')) {
|
||
prevent = true;
|
||
}
|
||
else prevent = false;
|
||
}
|
||
return prevent;
|
||
}
|
||
|
||
// Mouse Handlers
|
||
function handleMouseDown (e) {
|
||
findActivableElement(e.target).addClass('active-state');
|
||
if ('which' in e && e.which === 3) {
|
||
setTimeout(function () {
|
||
$('.active-state').removeClass('active-state');
|
||
}, 0);
|
||
}
|
||
if (app.params.material && app.params.materialRipple) {
|
||
touchStartX = e.pageX;
|
||
touchStartY = e.pageY;
|
||
rippleTouchStart(e.target, e.pageX, e.pageY);
|
||
}
|
||
}
|
||
function handleMouseMove (e) {
|
||
$('.active-state').removeClass('active-state');
|
||
if (app.params.material && app.params.materialRipple) {
|
||
rippleTouchMove();
|
||
}
|
||
}
|
||
function handleMouseUp (e) {
|
||
$('.active-state').removeClass('active-state');
|
||
if (app.params.material && app.params.materialRipple) {
|
||
rippleTouchEnd();
|
||
}
|
||
}
|
||
|
||
// Material Touch Ripple Effect
|
||
function findRippleElement(el) {
|
||
var needsRipple = app.params.materialRippleElements;
|
||
var $el = $(el);
|
||
if ($el.is(needsRipple)) {
|
||
if ($el.hasClass('no-ripple')) {
|
||
return false;
|
||
}
|
||
return $el;
|
||
}
|
||
else if ($el.parents(needsRipple).length > 0) {
|
||
var rippleParent = $el.parents(needsRipple).eq(0);
|
||
if (rippleParent.hasClass('no-ripple')) {
|
||
return false;
|
||
}
|
||
return rippleParent;
|
||
}
|
||
else return false;
|
||
}
|
||
function createRipple(x, y, el) {
|
||
var box = el[0].getBoundingClientRect();
|
||
var center = {
|
||
x: x - box.left,
|
||
y: y - box.top
|
||
},
|
||
height = box.height,
|
||
width = box.width;
|
||
var diameter = Math.max(Math.pow((Math.pow(height, 2) + Math.pow(width, 2)), 0.5), 48);
|
||
|
||
rippleWave = $(
|
||
'<div class="ripple-wave" style="width: ' + diameter + 'px; height: '+diameter+'px; margin-top:-'+diameter/2+'px; margin-left:-'+diameter/2+'px; left:'+center.x+'px; top:'+center.y+'px;"></div>'
|
||
);
|
||
el.prepend(rippleWave);
|
||
var clientLeft = rippleWave[0].clientLeft;
|
||
rippleTransform = 'translate3d('+(-center.x + width/2)+'px, '+(-center.y + height/2)+'px, 0) scale(1)';
|
||
rippleWave.transform(rippleTransform);
|
||
}
|
||
|
||
function removeRipple() {
|
||
if (!rippleWave) return;
|
||
var toRemove = rippleWave;
|
||
|
||
var removeTimeout = setTimeout(function () {
|
||
toRemove.remove();
|
||
}, 400);
|
||
|
||
rippleWave
|
||
.addClass('ripple-wave-fill')
|
||
.transform(rippleTransform.replace('scale(1)', 'scale(1.01)'))
|
||
.transitionEnd(function () {
|
||
clearTimeout(removeTimeout);
|
||
|
||
var rippleWave = $(this)
|
||
.addClass('ripple-wave-out')
|
||
.transform(rippleTransform.replace('scale(1)', 'scale(1.01)'));
|
||
|
||
removeTimeout = setTimeout(function () {
|
||
rippleWave.remove();
|
||
}, 700);
|
||
|
||
setTimeout(function () {
|
||
rippleWave.transitionEnd(function(){
|
||
clearTimeout(removeTimeout);
|
||
$(this).remove();
|
||
});
|
||
}, 0);
|
||
});
|
||
|
||
rippleWave = rippleTarget = undefined;
|
||
}
|
||
|
||
function rippleTouchStart (el, x, y) {
|
||
rippleTarget = findRippleElement(el);
|
||
if (!rippleTarget || rippleTarget.length === 0) {
|
||
rippleTarget = undefined;
|
||
return;
|
||
}
|
||
if (!isInsideScrollableView(rippleTarget)) {
|
||
createRipple(touchStartX, touchStartY, rippleTarget);
|
||
}
|
||
else {
|
||
rippleTimeout = setTimeout(function () {
|
||
createRipple(touchStartX, touchStartY, rippleTarget);
|
||
}, 80);
|
||
}
|
||
}
|
||
function rippleTouchMove() {
|
||
clearTimeout(rippleTimeout);
|
||
removeRipple();
|
||
}
|
||
function rippleTouchEnd() {
|
||
if (rippleWave) {
|
||
removeRipple();
|
||
}
|
||
else if (rippleTarget && !isMoved) {
|
||
clearTimeout(rippleTimeout);
|
||
createRipple(touchStartX, touchStartY, rippleTarget);
|
||
setTimeout(removeRipple, 0);
|
||
}
|
||
else {
|
||
removeRipple();
|
||
}
|
||
}
|
||
|
||
// Send Click
|
||
function sendClick(e) {
|
||
var touch = e.changedTouches[0];
|
||
var evt = document.createEvent('MouseEvents');
|
||
var eventType = 'click';
|
||
if (app.device.android && targetElement.nodeName.toLowerCase() === 'select') {
|
||
eventType = 'mousedown';
|
||
}
|
||
evt.initMouseEvent(eventType, true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
|
||
evt.forwardedTouchEvent = true;
|
||
targetElement.dispatchEvent(evt);
|
||
}
|
||
|
||
// Touch Handlers
|
||
function handleTouchStart(e) {
|
||
isMoved = false;
|
||
tapHoldFired = false;
|
||
if (e.targetTouches.length > 1) {
|
||
if (activableElement) removeActive();
|
||
return true;
|
||
}
|
||
if (e.touches.length > 1 && activableElement) {
|
||
removeActive();
|
||
}
|
||
if (app.params.tapHold) {
|
||
if (tapHoldTimeout) clearTimeout(tapHoldTimeout);
|
||
tapHoldTimeout = setTimeout(function () {
|
||
if (e && e.touches && e.touches.length > 1) return;
|
||
tapHoldFired = true;
|
||
e.preventDefault();
|
||
$(e.target).trigger('taphold');
|
||
}, app.params.tapHoldDelay);
|
||
}
|
||
if (needsFastClickTimeOut) clearTimeout(needsFastClickTimeOut);
|
||
needsFastClick = targetNeedsFastClick(e.target);
|
||
|
||
if (!needsFastClick) {
|
||
trackClick = false;
|
||
return true;
|
||
}
|
||
if (app.device.ios || (app.device.android && 'getSelection' in window)) {
|
||
var selection = window.getSelection();
|
||
if (selection.rangeCount && selection.focusNode !== document.body && (!selection.isCollapsed || document.activeElement === selection.focusNode)) {
|
||
activeSelection = true;
|
||
return true;
|
||
}
|
||
else {
|
||
activeSelection = false;
|
||
}
|
||
}
|
||
if (app.device.android) {
|
||
if (androidNeedsBlur(e.target)) {
|
||
document.activeElement.blur();
|
||
}
|
||
}
|
||
|
||
trackClick = true;
|
||
targetElement = e.target;
|
||
touchStartTime = (new Date()).getTime();
|
||
touchStartX = e.targetTouches[0].pageX;
|
||
touchStartY = e.targetTouches[0].pageY;
|
||
|
||
// Detect scroll parent
|
||
if (app.device.ios) {
|
||
scrollParent = undefined;
|
||
$(targetElement).parents().each(function () {
|
||
var parent = this;
|
||
if (parent.scrollHeight > parent.offsetHeight && !scrollParent) {
|
||
scrollParent = parent;
|
||
scrollParent.f7ScrollTop = scrollParent.scrollTop;
|
||
}
|
||
});
|
||
}
|
||
if ((e.timeStamp - lastClickTime) < app.params.fastClicksDelayBetweenClicks) {
|
||
e.preventDefault();
|
||
}
|
||
|
||
if (app.params.activeState) {
|
||
activableElement = findActivableElement(targetElement);
|
||
// If it's inside a scrollable view, we don't trigger active-state yet,
|
||
// because it can be a scroll instead. Based on the link:
|
||
// http://labnote.beedesk.com/click-scroll-and-pseudo-active-on-mobile-webk
|
||
if (!isInsideScrollableView(activableElement)) {
|
||
addActive();
|
||
} else {
|
||
activeTimeout = setTimeout(addActive, 80);
|
||
}
|
||
}
|
||
if (app.params.material && app.params.materialRipple) {
|
||
rippleTouchStart(targetElement, touchStartX, touchStartY);
|
||
}
|
||
}
|
||
function handleTouchMove(e) {
|
||
if (!trackClick) return;
|
||
var _isMoved = false;
|
||
var distance = app.params.fastClicksDistanceThreshold;
|
||
if (distance) {
|
||
var pageX = e.targetTouches[0].pageX;
|
||
var pageY = e.targetTouches[0].pageY;
|
||
if (Math.abs(pageX - touchStartX) > distance || Math.abs(pageY - touchStartY) > distance) {
|
||
_isMoved = true;
|
||
}
|
||
}
|
||
else {
|
||
_isMoved = true;
|
||
}
|
||
if (_isMoved) {
|
||
trackClick = false;
|
||
targetElement = null;
|
||
isMoved = true;
|
||
if (app.params.tapHold) {
|
||
clearTimeout(tapHoldTimeout);
|
||
}
|
||
if (app.params.activeState) {
|
||
clearTimeout(activeTimeout);
|
||
removeActive();
|
||
}
|
||
if (app.params.material && app.params.materialRipple) {
|
||
rippleTouchMove();
|
||
}
|
||
}
|
||
}
|
||
function handleTouchEnd(e) {
|
||
clearTimeout(activeTimeout);
|
||
clearTimeout(tapHoldTimeout);
|
||
|
||
if (!trackClick) {
|
||
if (!activeSelection && needsFastClick) {
|
||
if (!(app.device.android && !e.cancelable)) {
|
||
e.preventDefault();
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
if (document.activeElement === e.target) {
|
||
if (app.params.activeState) removeActive();
|
||
if (app.params.material && app.params.materialRipple) {
|
||
rippleTouchEnd();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
if (!activeSelection) {
|
||
e.preventDefault();
|
||
}
|
||
|
||
if ((e.timeStamp - lastClickTime) < app.params.fastClicksDelayBetweenClicks) {
|
||
setTimeout(removeActive, 0);
|
||
return true;
|
||
}
|
||
|
||
lastClickTime = e.timeStamp;
|
||
|
||
trackClick = false;
|
||
|
||
if (app.device.ios && scrollParent) {
|
||
if (scrollParent.scrollTop !== scrollParent.f7ScrollTop) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// Add active-state here because, in a very fast tap, the timeout didn't
|
||
// have the chance to execute. Removing active-state in a timeout gives
|
||
// the chance to the animation execute.
|
||
if (app.params.activeState) {
|
||
addActive();
|
||
setTimeout(removeActive, 0);
|
||
}
|
||
// Remove Ripple
|
||
if (app.params.material && app.params.materialRipple) {
|
||
rippleTouchEnd();
|
||
}
|
||
|
||
// Trigger focus when required
|
||
if (targetNeedsFocus(targetElement)) {
|
||
if (app.device.ios && app.device.webView) {
|
||
if ((event.timeStamp - touchStartTime) > 159) {
|
||
targetElement = null;
|
||
return false;
|
||
}
|
||
targetElement.focus();
|
||
return false;
|
||
}
|
||
else {
|
||
targetElement.focus();
|
||
}
|
||
}
|
||
|
||
// Blur active elements
|
||
if (document.activeElement && targetElement !== document.activeElement && document.activeElement !== document.body && targetElement.nodeName.toLowerCase() !== 'label') {
|
||
document.activeElement.blur();
|
||
}
|
||
|
||
// Send click
|
||
e.preventDefault();
|
||
sendClick(e);
|
||
return false;
|
||
}
|
||
function handleTouchCancel(e) {
|
||
trackClick = false;
|
||
targetElement = null;
|
||
|
||
// Remove Active State
|
||
clearTimeout(activeTimeout);
|
||
clearTimeout(tapHoldTimeout);
|
||
if (app.params.activeState) {
|
||
removeActive();
|
||
}
|
||
|
||
// Remove Ripple
|
||
if (app.params.material && app.params.materialRipple) {
|
||
rippleTouchEnd();
|
||
}
|
||
}
|
||
|
||
function handleClick(e) {
|
||
var allowClick = false;
|
||
|
||
if (trackClick) {
|
||
targetElement = null;
|
||
trackClick = false;
|
||
return true;
|
||
}
|
||
if (e.target.type === 'submit' && e.detail === 0) {
|
||
return true;
|
||
}
|
||
if (!targetElement) {
|
||
if (!isFormElement(e.target)) {
|
||
allowClick = true;
|
||
}
|
||
}
|
||
if (!needsFastClick) {
|
||
allowClick = true;
|
||
}
|
||
if (document.activeElement === targetElement) {
|
||
allowClick = true;
|
||
}
|
||
if (e.forwardedTouchEvent) {
|
||
allowClick = true;
|
||
}
|
||
if (!e.cancelable) {
|
||
allowClick = true;
|
||
}
|
||
if (app.params.tapHold && app.params.tapHoldPreventClicks && tapHoldFired) {
|
||
allowClick = false;
|
||
}
|
||
if (!allowClick) {
|
||
e.stopImmediatePropagation();
|
||
e.stopPropagation();
|
||
if (targetElement) {
|
||
if (targetNeedsPrevent(targetElement) || isMoved) {
|
||
e.preventDefault();
|
||
}
|
||
}
|
||
else {
|
||
e.preventDefault();
|
||
}
|
||
targetElement = null;
|
||
}
|
||
needsFastClickTimeOut = setTimeout(function () {
|
||
needsFastClick = false;
|
||
}, (app.device.ios || app.device.androidChrome ? 100 : 400));
|
||
|
||
if (app.params.tapHold) {
|
||
tapHoldTimeout = setTimeout(function () {
|
||
tapHoldFired = false;
|
||
}, (app.device.ios || app.device.androidChrome ? 100 : 400));
|
||
}
|
||
|
||
return allowClick;
|
||
}
|
||
if (app.support.touch) {
|
||
document.addEventListener('click', handleClick, true);
|
||
|
||
document.addEventListener('touchstart', handleTouchStart);
|
||
document.addEventListener('touchmove', handleTouchMove);
|
||
document.addEventListener('touchend', handleTouchEnd);
|
||
document.addEventListener('touchcancel', handleTouchCancel);
|
||
}
|
||
else {
|
||
if (app.params.activeState) {
|
||
document.addEventListener('mousedown', handleMouseDown);
|
||
document.addEventListener('mousemove', handleMouseMove);
|
||
document.addEventListener('mouseup', handleMouseUp);
|
||
}
|
||
}
|
||
if (app.params.material && app.params.materialRipple) {
|
||
document.addEventListener('contextmenu', function (e) {
|
||
if (activableElement) removeActive();
|
||
rippleTouchEnd();
|
||
});
|
||
}
|
||
|
||
};
|
||
|
||
|
||
/*===============================================================================
|
||
************ Handle clicks and make them fast (on tap); ************
|
||
===============================================================================*/
|
||
app.initClickEvents = function () {
|
||
function handleScrollTop(e) {
|
||
/*jshint validthis:true */
|
||
var clicked = $(this);
|
||
var target = $(e.target);
|
||
var isLink = clicked[0].nodeName.toLowerCase() === 'a' ||
|
||
clicked.parents('a').length > 0 ||
|
||
target[0].nodeName.toLowerCase() === 'a' ||
|
||
target.parents('a').length > 0;
|
||
|
||
if (isLink) return;
|
||
var pageContent, page;
|
||
if (app.params.scrollTopOnNavbarClick && clicked.is('.navbar .center')) {
|
||
// Find active page
|
||
var navbar = clicked.parents('.navbar');
|
||
|
||
// Static Layout
|
||
pageContent = navbar.parents('.page-content');
|
||
|
||
if (pageContent.length === 0) {
|
||
// Fixed Layout
|
||
if (navbar.parents('.page').length > 0) {
|
||
pageContent = navbar.parents('.page').find('.page-content');
|
||
}
|
||
// Through Layout
|
||
if (pageContent.length === 0) {
|
||
if (navbar.nextAll('.pages').length > 0) {
|
||
pageContent = navbar.nextAll('.pages').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (app.params.scrollTopOnStatusbarClick && clicked.is('.statusbar-overlay')) {
|
||
if ($('.popup.modal-in').length > 0) {
|
||
// Check for opened popup
|
||
pageContent = $('.popup.modal-in').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');
|
||
}
|
||
else if ($('.panel.active').length > 0) {
|
||
// Check for opened panel
|
||
pageContent = $('.panel.active').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');
|
||
}
|
||
else if ($('.views > .view.active').length > 0) {
|
||
// View in tab bar app layout
|
||
pageContent = $('.views > .view.active').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');
|
||
}
|
||
else {
|
||
// Usual case
|
||
pageContent = $('.views').find('.page:not(.page-on-left):not(.page-on-right):not(.cached)').find('.page-content');
|
||
}
|
||
}
|
||
|
||
if (pageContent && pageContent.length > 0) {
|
||
// Check for tab
|
||
if (pageContent.hasClass('tab')) {
|
||
pageContent = pageContent.parent('.tabs').children('.page-content.active');
|
||
}
|
||
if (pageContent.length > 0) pageContent.scrollTop(0, 300);
|
||
}
|
||
}
|
||
function handleClicks(e) {
|
||
/*jshint validthis:true */
|
||
var clicked = $(this);
|
||
var url = clicked.attr('href');
|
||
var isLink = clicked[0].nodeName.toLowerCase() === 'a';
|
||
|
||
// Check if link is external
|
||
if (isLink) {
|
||
if (clicked.is(app.params.externalLinks) || (url && url.indexOf('javascript:') >= 0)) {
|
||
if(url && clicked.attr('target') === '_system') {
|
||
e.preventDefault();
|
||
window.open(url, '_system');
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
|
||
// Collect Clicked data- attributes
|
||
var clickedData = clicked.dataset();
|
||
|
||
// Smart Select
|
||
if (clicked.hasClass('smart-select')) {
|
||
if (app.smartSelectOpen) app.smartSelectOpen(clicked);
|
||
}
|
||
|
||
// Open Panel
|
||
if (clicked.hasClass('open-panel')) {
|
||
if ($('.panel').length === 1) {
|
||
if ($('.panel').hasClass('panel-left')) app.openPanel('left');
|
||
else app.openPanel('right');
|
||
}
|
||
else {
|
||
if (clickedData.panel === 'right') app.openPanel('right');
|
||
else app.openPanel('left');
|
||
}
|
||
}
|
||
// Close Panel
|
||
if (clicked.hasClass('close-panel')) {
|
||
app.closePanel();
|
||
}
|
||
|
||
if (clicked.hasClass('panel-overlay') && app.params.panelsCloseByOutside) {
|
||
app.closePanel();
|
||
}
|
||
// Popover
|
||
if (clicked.hasClass('open-popover')) {
|
||
var popover;
|
||
if (clickedData.popover) {
|
||
popover = clickedData.popover;
|
||
}
|
||
else popover = '.popover';
|
||
app.popover(popover, clicked);
|
||
}
|
||
if (clicked.hasClass('close-popover')) {
|
||
app.closeModal('.popover.modal-in');
|
||
}
|
||
// Popup
|
||
var popup;
|
||
if (clicked.hasClass('open-popup')) {
|
||
if (clickedData.popup) {
|
||
popup = clickedData.popup;
|
||
}
|
||
else popup = '.popup';
|
||
app.popup(popup);
|
||
}
|
||
if (clicked.hasClass('close-popup')) {
|
||
if (clickedData.popup) {
|
||
popup = clickedData.popup;
|
||
}
|
||
else popup = '.popup.modal-in';
|
||
app.closeModal(popup);
|
||
}
|
||
// Login Screen
|
||
var loginScreen;
|
||
if (clicked.hasClass('open-login-screen')) {
|
||
if (clickedData.loginScreen) {
|
||
loginScreen = clickedData.loginScreen;
|
||
}
|
||
else loginScreen = '.login-screen';
|
||
app.loginScreen(loginScreen);
|
||
}
|
||
if (clicked.hasClass('close-login-screen')) {
|
||
app.closeModal('.login-screen.modal-in');
|
||
}
|
||
// Close Modal
|
||
if (clicked.hasClass('modal-overlay')) {
|
||
if ($('.modal.modal-in').length > 0 && app.params.modalCloseByOutside)
|
||
app.closeModal('.modal.modal-in');
|
||
if ($('.actions-modal.modal-in').length > 0 && app.params.actionsCloseByOutside)
|
||
app.closeModal('.actions-modal.modal-in');
|
||
|
||
if ($('.popover.modal-in').length > 0) app.closeModal('.popover.modal-in');
|
||
}
|
||
if (clicked.hasClass('popup-overlay')) {
|
||
if ($('.popup.modal-in').length > 0 && app.params.popupCloseByOutside)
|
||
app.closeModal('.popup.modal-in');
|
||
}
|
||
if (clicked.hasClass('picker-modal-overlay')) {
|
||
if ($('.picker-modal.modal-in').length > 0)
|
||
app.closeModal('.picker-modal.modal-in');
|
||
}
|
||
|
||
// Picker
|
||
if (clicked.hasClass('close-picker')) {
|
||
var pickerToClose = $('.picker-modal.modal-in');
|
||
if (pickerToClose.length > 0) {
|
||
app.closeModal(pickerToClose);
|
||
}
|
||
else {
|
||
pickerToClose = $('.popover.modal-in .picker-modal');
|
||
if (pickerToClose.length > 0) {
|
||
app.closeModal(pickerToClose.parents('.popover'));
|
||
}
|
||
}
|
||
}
|
||
if (clicked.hasClass('open-picker')) {
|
||
var pickerToOpen;
|
||
if (clickedData.picker) {
|
||
pickerToOpen = clickedData.picker;
|
||
}
|
||
else pickerToOpen = '.picker-modal';
|
||
app.pickerModal(pickerToOpen, clicked);
|
||
}
|
||
|
||
// Tabs
|
||
var isTabLink;
|
||
if (clicked.hasClass('tab-link')) {
|
||
isTabLink = true;
|
||
app.showTab(clickedData.tab || clicked.attr('href'), clicked);
|
||
}
|
||
// Swipeout Close
|
||
if (clicked.hasClass('swipeout-close')) {
|
||
app.swipeoutClose(clicked.parents('.swipeout-opened'));
|
||
}
|
||
// Swipeout Delete
|
||
if (clicked.hasClass('swipeout-delete')) {
|
||
if (clickedData.confirm) {
|
||
var text = clickedData.confirm;
|
||
var title = clickedData.confirmTitle;
|
||
if (title) {
|
||
app.confirm(text, title, function () {
|
||
app.swipeoutDelete(clicked.parents('.swipeout'));
|
||
}, function () {
|
||
if (clickedData.closeOnCancel) app.swipeoutClose(clicked.parents('.swipeout'));
|
||
});
|
||
}
|
||
else {
|
||
app.confirm(text, function () {
|
||
app.swipeoutDelete(clicked.parents('.swipeout'));
|
||
}, function () {
|
||
if (clickedData.closeOnCancel) app.swipeoutClose(clicked.parents('.swipeout'));
|
||
});
|
||
}
|
||
}
|
||
else {
|
||
app.swipeoutDelete(clicked.parents('.swipeout'));
|
||
}
|
||
|
||
}
|
||
// Sortable
|
||
if (clicked.hasClass('toggle-sortable')) {
|
||
app.sortableToggle(clickedData.sortable);
|
||
}
|
||
if (clicked.hasClass('open-sortable')) {
|
||
app.sortableOpen(clickedData.sortable);
|
||
}
|
||
if (clicked.hasClass('close-sortable')) {
|
||
app.sortableClose(clickedData.sortable);
|
||
}
|
||
// Accordion
|
||
if (clicked.hasClass('accordion-item-toggle') || (clicked.hasClass('item-link') && clicked.parent().hasClass('accordion-item'))) {
|
||
var accordionItem = clicked.parent('.accordion-item');
|
||
if (accordionItem.length === 0) accordionItem = clicked.parents('.accordion-item');
|
||
if (accordionItem.length === 0) accordionItem = clicked.parents('li');
|
||
app.accordionToggle(accordionItem);
|
||
}
|
||
|
||
// Speed Dial
|
||
if (clicked.hasClass('floating-button') && clicked.parent().hasClass('speed-dial')) {
|
||
clicked.parent().toggleClass('speed-dial-opened');
|
||
}
|
||
if (clicked.hasClass('close-speed-dial')) {
|
||
$('.speed-dial-opened').removeClass('speed-dial-opened');
|
||
}
|
||
|
||
// Load Page
|
||
if (app.params.ajaxLinks && !clicked.is(app.params.ajaxLinks) || !isLink || !app.params.router) {
|
||
return;
|
||
}
|
||
if (isLink) {
|
||
e.preventDefault();
|
||
}
|
||
|
||
var validUrl = url && url.length > 0 && url !== '#' && !isTabLink;
|
||
var template = clickedData.template;
|
||
if (validUrl || clicked.hasClass('back') || template) {
|
||
var view;
|
||
if (clickedData.view) {
|
||
view = $(clickedData.view)[0].f7View;
|
||
}
|
||
else {
|
||
view = clicked.parents('.' + app.params.viewClass)[0] && clicked.parents('.' + app.params.viewClass)[0].f7View;
|
||
if (view && view.params.linksView) {
|
||
if (typeof view.params.linksView === 'string') view = $(view.params.linksView)[0].f7View;
|
||
else if (view.params.linksView instanceof View) view = view.params.linksView;
|
||
}
|
||
}
|
||
if (!view) {
|
||
if (app.mainView) view = app.mainView;
|
||
}
|
||
if (!view) return;
|
||
|
||
var pageName;
|
||
if (!template) {
|
||
if (url && url.indexOf('#') === 0 && url !== '#') {
|
||
if (view.params.domCache) {
|
||
pageName = url.split('#')[1];
|
||
}
|
||
else return;
|
||
}
|
||
if (url === '#' && !clicked.hasClass('back')) return;
|
||
}
|
||
else {
|
||
url = undefined;
|
||
}
|
||
|
||
var animatePages;
|
||
if (typeof clickedData.animatePages !== 'undefined') {
|
||
animatePages = clickedData.animatePages;
|
||
}
|
||
else {
|
||
if (clicked.hasClass('with-animation')) animatePages = true;
|
||
if (clicked.hasClass('no-animation')) animatePages = false;
|
||
}
|
||
|
||
var options = {
|
||
animatePages: animatePages,
|
||
ignoreCache: clickedData.ignoreCache,
|
||
force: clickedData.force,
|
||
reload: clickedData.reload,
|
||
reloadPrevious: clickedData.reloadPrevious,
|
||
pageName: pageName,
|
||
pushState: clickedData.pushState,
|
||
url: url
|
||
};
|
||
|
||
if (app.params.template7Pages) {
|
||
options.contextName = clickedData.contextName;
|
||
var context = clickedData.context;
|
||
if (context) {
|
||
options.context = JSON.parse(context);
|
||
}
|
||
}
|
||
if (template && template in t7.templates) {
|
||
options.template = t7.templates[template];
|
||
}
|
||
|
||
if (clicked.hasClass('back')) view.router.back(options);
|
||
else view.router.load(options);
|
||
}
|
||
}
|
||
$(document).on('click', 'a, .open-panel, .close-panel, .panel-overlay, .modal-overlay, .popup-overlay, .swipeout-delete, .swipeout-close, .close-popup, .open-popup, .open-popover, .open-login-screen, .close-login-screen .smart-select, .toggle-sortable, .open-sortable, .close-sortable, .accordion-item-toggle, .close-picker, .picker-modal-overlay', handleClicks);
|
||
if (app.params.scrollTopOnNavbarClick || app.params.scrollTopOnStatusbarClick) {
|
||
$(document).on('click', '.statusbar-overlay, .navbar .center', handleScrollTop);
|
||
}
|
||
|
||
// Prevent scrolling on overlays
|
||
function preventScrolling(e) {
|
||
e.preventDefault();
|
||
}
|
||
if (app.support.touch && !app.device.android) {
|
||
$(document).on((app.params.fastClicks ? 'touchstart' : 'touchmove'), '.panel-overlay, .modal-overlay, .preloader-indicator-overlay, .popup-overlay, .searchbar-overlay', preventScrolling);
|
||
}
|
||
};
|
||
|
||
|
||
/*======================================================
|
||
************ App Resize Actions ************
|
||
======================================================*/
|
||
// Prevent iPad horizontal body scrolling when soft keyboard is opened
|
||
function _fixIpadBodyScrolLeft() {
|
||
if (app.device.ipad) {
|
||
document.body.scrollLeft = 0;
|
||
setTimeout(function () {
|
||
document.body.scrollLeft = 0;
|
||
}, 0);
|
||
}
|
||
}
|
||
app.initResize = function () {
|
||
$(window).on('resize', app.resize);
|
||
$(window).on('orientationchange', app.orientationchange);
|
||
};
|
||
app.resize = function () {
|
||
if (app.sizeNavbars) app.sizeNavbars();
|
||
_fixIpadBodyScrolLeft();
|
||
|
||
};
|
||
app.orientationchange = function () {
|
||
if (app.device && app.device.minimalUi) {
|
||
if (window.orientation === 90 || window.orientation === -90) document.body.scrollTop = 0;
|
||
}
|
||
_fixIpadBodyScrolLeft();
|
||
};
|
||
|
||
|
||
/*===============================================================================
|
||
************ Store and parse forms data ************
|
||
===============================================================================*/
|
||
app.formsData = {};
|
||
app.formStoreData = function (formId, formJSON) {
|
||
// Store form data in app.formsData
|
||
app.formsData[formId] = formJSON;
|
||
|
||
// Store form data in local storage also
|
||
app.ls['f7form-' + formId] = JSON.stringify(formJSON);
|
||
};
|
||
app.formDeleteData = function (formId) {
|
||
// Delete form data from app.formsData
|
||
if (app.formsData[formId]) {
|
||
app.formsData[formId] = '';
|
||
delete app.formsData[formId];
|
||
}
|
||
|
||
// Delete form data from local storage also
|
||
if (app.ls['f7form-' + formId]) {
|
||
app.ls['f7form-' + formId] = '';
|
||
app.ls.removeItem('f7form-' + formId);
|
||
}
|
||
};
|
||
app.formGetData = function (formId) {
|
||
// First of all check in local storage
|
||
if (app.ls['f7form-' + formId]) {
|
||
return JSON.parse(app.ls['f7form-' + formId]);
|
||
}
|
||
// Try to get it from formsData obj
|
||
else if (app.formsData[formId]) return app.formsData[formId];
|
||
};
|
||
app.formToData = function (form) {
|
||
form = $(form);
|
||
if (form.length !== 1) return false;
|
||
|
||
// Form data
|
||
var formData = {};
|
||
|
||
// Skip input types
|
||
var skipTypes = ['submit', 'image', 'button', 'file'];
|
||
var skipNames = [];
|
||
form.find('input, select, textarea').each(function () {
|
||
var input = $(this);
|
||
var name = input.attr('name');
|
||
var type = input.attr('type');
|
||
var tag = this.nodeName.toLowerCase();
|
||
if (skipTypes.indexOf(type) >= 0) return;
|
||
if (skipNames.indexOf(name) >= 0 || !name) return;
|
||
if (tag === 'select' && input.prop('multiple')) {
|
||
skipNames.push(name);
|
||
formData[name] = [];
|
||
form.find('select[name="' + name + '"] option').each(function () {
|
||
if (this.selected) formData[name].push(this.value);
|
||
});
|
||
}
|
||
else {
|
||
switch (type) {
|
||
case 'checkbox' :
|
||
skipNames.push(name);
|
||
formData[name] = [];
|
||
form.find('input[name="' + name + '"]').each(function () {
|
||
if (this.checked) formData[name].push(this.value);
|
||
});
|
||
break;
|
||
case 'radio' :
|
||
skipNames.push(name);
|
||
form.find('input[name="' + name + '"]').each(function () {
|
||
if (this.checked) formData[name] = this.value;
|
||
});
|
||
break;
|
||
default :
|
||
formData[name] = input.val();
|
||
break;
|
||
}
|
||
}
|
||
|
||
});
|
||
form.trigger('formToJSON formToData', {formData: formData});
|
||
|
||
return formData;
|
||
};
|
||
app.formToJSON = app.formToData;
|
||
app.formFromData = function (form, formData) {
|
||
form = $(form);
|
||
if (form.length !== 1) return false;
|
||
|
||
// Skip input types
|
||
var skipTypes = ['submit', 'image', 'button', 'file'];
|
||
var skipNames = [];
|
||
|
||
form.find('input, select, textarea').each(function () {
|
||
var input = $(this);
|
||
var name = input.attr('name');
|
||
var type = input.attr('type');
|
||
var tag = this.nodeName.toLowerCase();
|
||
if (!formData[name]) return;
|
||
if (skipTypes.indexOf(type) >= 0) return;
|
||
if (skipNames.indexOf(name) >= 0 || !name) return;
|
||
if (tag === 'select' && input.prop('multiple')) {
|
||
skipNames.push(name);
|
||
form.find('select[name="' + name + '"] option').each(function () {
|
||
if (formData[name].indexOf(this.value) >= 0) this.selected = true;
|
||
else this.selected = false;
|
||
});
|
||
}
|
||
else {
|
||
switch (type) {
|
||
case 'checkbox' :
|
||
skipNames.push(name);
|
||
form.find('input[name="' + name + '"]').each(function () {
|
||
if (formData[name].indexOf(this.value) >= 0) this.checked = true;
|
||
else this.checked = false;
|
||
});
|
||
break;
|
||
case 'radio' :
|
||
skipNames.push(name);
|
||
form.find('input[name="' + name + '"]').each(function () {
|
||
if (formData[name] === this.value) this.checked = true;
|
||
else this.checked = false;
|
||
});
|
||
break;
|
||
default :
|
||
input.val(formData[name]);
|
||
break;
|
||
}
|
||
}
|
||
if (tag === 'select' && input.parents('.smart-select').length > 0) {
|
||
input.trigger('change');
|
||
}
|
||
});
|
||
form.trigger('formFromJSON formFromData', {formData: formData});
|
||
};
|
||
app.formFromJSON = app.formFromData;
|
||
|
||
app.initFormsStorage = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var forms = pageContainer.find('form.store-data');
|
||
if (forms.length === 0) return;
|
||
|
||
// Parse forms data and fill form if there is such data
|
||
forms.each(function () {
|
||
var id = this.getAttribute('id');
|
||
if (!id) return;
|
||
var formData = app.formGetData(id);
|
||
if (formData) app.formFromData(this, formData);
|
||
});
|
||
// Update forms data on inputs change
|
||
function storeForm() {
|
||
/*jshint validthis:true */
|
||
var form = $(this);
|
||
var formId = form[0].id;
|
||
if (!formId) return;
|
||
var formJSON = app.formToData(form);
|
||
if (!formJSON) return;
|
||
app.formStoreData(formId, formJSON);
|
||
form.trigger('store', {data: formJSON});
|
||
}
|
||
forms.on('change submit', storeForm);
|
||
|
||
// Detach Listeners
|
||
function pageBeforeRemove() {
|
||
forms.off('change submit', storeForm);
|
||
pageContainer.off('pageBeforeRemove', pageBeforeRemove);
|
||
}
|
||
pageContainer.on('pageBeforeRemove', pageBeforeRemove);
|
||
};
|
||
|
||
/*===============================================================================
|
||
************ Ajax submit for forms ************
|
||
===============================================================================*/
|
||
// Ajax submit on forms
|
||
$(document).on('submit change', 'form.ajax-submit, form.ajax-submit-onchange', function (e) {
|
||
var form = $(this);
|
||
if (e.type === 'change' && !form.hasClass('ajax-submit-onchange')) return;
|
||
if (e.type === 'submit') e.preventDefault();
|
||
|
||
var method = (form.attr('method') || 'GET').toUpperCase();
|
||
var contentType = form.prop('enctype') || form.attr('enctype');
|
||
|
||
var url = form.attr('action');
|
||
if (!url) return;
|
||
|
||
var data;
|
||
if (method === 'POST') data = new FormData(form[0]);
|
||
else data = $.serializeObject(app.formToJSON(form[0]));
|
||
|
||
var xhr = $.ajax({
|
||
method: method,
|
||
url: url,
|
||
contentType: contentType,
|
||
data: data,
|
||
beforeSend: function (xhr) {
|
||
form.trigger('beforeSubmit', {data:data, xhr: xhr});
|
||
},
|
||
error: function (xhr) {
|
||
form.trigger('submitError', {data:data, xhr: xhr});
|
||
},
|
||
success: function (data) {
|
||
form.trigger('submitted', {data: data, xhr: xhr});
|
||
}
|
||
});
|
||
});
|
||
|
||
|
||
|
||
/*===============================================================================
|
||
************ Resizable textarea ************
|
||
===============================================================================*/
|
||
app.resizeTextarea = function (textarea) {
|
||
textarea = $(textarea);
|
||
if (!textarea.hasClass('resizable')) {
|
||
return;
|
||
}
|
||
textarea.css({'height': ''});
|
||
var height = textarea[0].offsetHeight;
|
||
var diff = height - textarea[0].clientHeight;
|
||
var scrollHeight = textarea[0].scrollHeight;
|
||
|
||
if (scrollHeight + diff > height) {
|
||
var newAreaHeight = scrollHeight + diff;
|
||
textarea.css('height', newAreaHeight + 'px');
|
||
}
|
||
};
|
||
app.resizableTextarea = function (textarea) {
|
||
textarea = $(textarea);
|
||
if (textarea.length === 0) return;
|
||
var textareaTimeout;
|
||
function handleTextarea() {
|
||
clearTimeout(textareaTimeout);
|
||
textareaTimeout = setTimeout(function () {
|
||
app.resizeTextarea(textarea);
|
||
}, 0);
|
||
}
|
||
textarea[0].f7DestroyResizableTextarea = function () {
|
||
textarea.off('change keydown keypress keyup paste cut', handleTextarea);
|
||
};
|
||
return textarea.on('change keydown keypress keyup paste cut', handleTextarea);
|
||
};
|
||
app.destroyResizableTextarea = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
if (pageContainer.length > 0 && pageContainer.is('textarea') && pageContainer[0].f7DestroyResizableTextarea) {
|
||
pageContainer[0].f7DestroyResizableTextarea();
|
||
}
|
||
else if (pageContainer.length > 0) {
|
||
pageContainer.find('textarea.resiable').each(function () {
|
||
var textarea = this;
|
||
if (textarea.f7DestroyResizableTextarea) {
|
||
textarea.f7DestroyResizableTextarea ();
|
||
}
|
||
});
|
||
}
|
||
};
|
||
app.initPageResizableTextarea = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var textareas = pageContainer.find('textarea.resizable');
|
||
textareas.each(function () {
|
||
app.resizableTextarea(this);
|
||
});
|
||
};
|
||
|
||
/*======================================================
|
||
************ Material Text Inputs ************
|
||
======================================================*/
|
||
app.initPageMaterialInputs = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var textareas = pageContainer.find('textarea.resizable');
|
||
pageContainer.find('.item-input').each(function () {
|
||
var itemInput = $(this);
|
||
var notInputs = ['checkbox', 'button', 'submit', 'range', 'radio', 'image'];
|
||
itemInput.find('input, select, textarea').each(function () {
|
||
var input = $(this);
|
||
if (notInputs.indexOf(input.attr('type')) < 0) {
|
||
itemInput.addClass('item-input-field');
|
||
if (input.val().trim() !== '') {
|
||
input.parents('.item-input, .input-field').add(input.parents('.item-inner')).addClass('not-empty-state');
|
||
}
|
||
}
|
||
});
|
||
if (itemInput.parents('.input-item, .inputs-list').length > 0) return;
|
||
itemInput.parents('.list-block').eq(0).addClass('inputs-list');
|
||
});
|
||
};
|
||
/*======================================================
|
||
************ Material Focus Inputs ************
|
||
======================================================*/
|
||
app.initMaterialWatchInputs = function () {
|
||
var notInputs = ['checkbox', 'button', 'submit', 'range', 'radio', 'image'];
|
||
function addFocusState(e) {
|
||
/*jshint validthis:true*/
|
||
var i = $(this);
|
||
var type = i.attr('type');
|
||
if (notInputs.indexOf(type) >= 0) return;
|
||
var els = i.add(i.parents('.item-input, .input-field')).add(i.parents('.item-inner').eq(0));
|
||
els.addClass('focus-state');
|
||
}
|
||
function removeFocusState(e) {
|
||
/*jshint validthis:true*/
|
||
var i = $(this), value = i.val();
|
||
var type = i.attr('type');
|
||
if (notInputs.indexOf(type) >= 0) return;
|
||
var els = i.add(i.parents('.item-input, .input-field')).add(i.parents('.item-inner').eq(0));
|
||
els.removeClass('focus-state');
|
||
if (value && value.trim() !== '') {
|
||
els.addClass('not-empty-state');
|
||
}
|
||
else {
|
||
els.removeClass('not-empty-state');
|
||
}
|
||
}
|
||
function watchChangeState(e) {
|
||
/*jshint validthis:true*/
|
||
var i = $(this), value = i.val();
|
||
var type = i.attr('type');
|
||
if (notInputs.indexOf(type) >= 0) return;
|
||
var els = i.add(i.parents('.item-input, .input-field')).add(i.parents('.item-inner').eq(0));
|
||
if (value && value.trim() !== '') {
|
||
els.addClass('not-empty-state');
|
||
}
|
||
else {
|
||
els.removeClass('not-empty-state');
|
||
}
|
||
}
|
||
$(document).on('change', '.item-input input, .item-input select, .item-input textarea, input, textarea, select', watchChangeState, true);
|
||
$(document).on('focus', '.item-input input, .item-input select, .item-input textarea, input, textarea, select', addFocusState, true);
|
||
$(document).on('blur', '.item-input input, .item-input select, .item-input textarea, input, textarea, select', removeFocusState, true);
|
||
};
|
||
|
||
/*======================================================
|
||
************ Handle Browser's History ************
|
||
======================================================*/
|
||
app.pushStateQueue = [];
|
||
app.pushStateClearQueue = function () {
|
||
if (app.pushStateQueue.length === 0) return;
|
||
var queue = app.pushStateQueue.pop();
|
||
var animatePages;
|
||
if (app.params.pushStateNoAnimation === true) animatePages = false;
|
||
if (queue.action === 'back') {
|
||
app.router.back(queue.view, {animatePages: animatePages});
|
||
}
|
||
if (queue.action === 'loadPage') {
|
||
app.router.load(queue.view, {url: queue.stateUrl, animatePages: animatePages, pushState: false});
|
||
}
|
||
if (queue.action === 'loadContent') {
|
||
app.router.load(queue.view, {content: queue.stateContent, animatePages: animatePages, pushState: false});
|
||
}
|
||
if (queue.action === 'loadPageName') {
|
||
app.router.load(queue.view, {pageName: queue.statePageName, url: queue.stateUrl, animatePages: animatePages, pushState: false});
|
||
}
|
||
};
|
||
|
||
app.initPushState = function () {
|
||
var blockPopstate = true;
|
||
$(window).on('load', function () {
|
||
setTimeout(function () {
|
||
blockPopstate = false;
|
||
}, 0);
|
||
});
|
||
|
||
if (document.readyState && document.readyState === 'complete') {
|
||
blockPopstate = false;
|
||
}
|
||
|
||
function handlePopState(e) {
|
||
if (blockPopstate) return;
|
||
var mainView = app.mainView;
|
||
if (!mainView) return;
|
||
var state = e.state;
|
||
if (!state) {
|
||
state = {
|
||
viewIndex: app.views.indexOf(mainView),
|
||
url : mainView.history[0]
|
||
};
|
||
}
|
||
if (state.viewIndex < 0) return;
|
||
var view = app.views[state.viewIndex];
|
||
var stateUrl = state && state.url || undefined;
|
||
var stateContent = state && state.content || undefined;
|
||
var statePageName = state && state.pageName || undefined;
|
||
var animatePages;
|
||
|
||
if (app.params.pushStateNoAnimation === true) animatePages = false;
|
||
|
||
if (stateUrl !== view.url) {
|
||
if (view.history.indexOf(stateUrl) >= 0) {
|
||
// Go Back
|
||
if (view.allowPageChange) {
|
||
app.router.back(view, {url:undefined, animatePages: animatePages, pushState: false, preloadOnly:false});
|
||
}
|
||
else {
|
||
app.pushStateQueue.push({
|
||
action: 'back',
|
||
view: view
|
||
});
|
||
}
|
||
}
|
||
else if (stateContent) {
|
||
// Load Page
|
||
if (view.allowPageChange) {
|
||
app.router.load(view, {content:stateContent, animatePages: animatePages, pushState: false});
|
||
}
|
||
else {
|
||
app.pushStateQueue.unshift({
|
||
action: 'loadContent',
|
||
stateContent: stateContent,
|
||
view: view
|
||
});
|
||
}
|
||
|
||
}
|
||
else if (statePageName) {
|
||
// Load Page by page name with Dom Cache
|
||
if (view.allowPageChange) {
|
||
app.router.load(view, {pageName:statePageName, url: stateUrl, animatePages: animatePages, pushState: false});
|
||
}
|
||
else {
|
||
app.pushStateQueue.unshift({
|
||
action: 'loadPageName',
|
||
statePageName: statePageName,
|
||
view: view
|
||
});
|
||
}
|
||
}
|
||
else {
|
||
// Load Page
|
||
if (view.allowPageChange) {
|
||
app.router.load(view, {url:stateUrl, animatePages: animatePages, pushState: false});
|
||
}
|
||
else {
|
||
app.pushStateQueue.unshift({
|
||
action: 'loadPage',
|
||
stateUrl: stateUrl,
|
||
view: view
|
||
});
|
||
}
|
||
}
|
||
}
|
||
}
|
||
$(window).on('popstate', handlePopState);
|
||
};
|
||
|
||
|
||
/*===========================
|
||
Framework7 Swiper Additions
|
||
===========================*/
|
||
app.swiper = function (container, params) {
|
||
return new Swiper(container, params);
|
||
};
|
||
app.initPageSwiper = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var swipers = pageContainer.find('.swiper-init, .tabs-swipeable-wrap');
|
||
if (swipers.length === 0) return;
|
||
function destroySwiperOnRemove(slider) {
|
||
function destroySwiper() {
|
||
slider.destroy();
|
||
pageContainer.off('pageBeforeRemove', destroySwiper);
|
||
}
|
||
pageContainer.on('pageBeforeRemove', destroySwiper);
|
||
}
|
||
swipers.each(function () {
|
||
var swiper = $(this), initialSlide;
|
||
var params;
|
||
if (swiper.hasClass('tabs-swipeable-wrap')) {
|
||
swiper.addClass('swiper-container').children('.tabs').addClass('swiper-wrapper').children('.tab').addClass('swiper-slide');
|
||
initialSlide = swiper.children('.tabs').children('.tab.active').index();
|
||
}
|
||
if (swiper.data('swiper')) {
|
||
params = JSON.parse(swiper.data('swiper'));
|
||
}
|
||
else {
|
||
params = swiper.dataset();
|
||
}
|
||
if (typeof params.initialSlide === 'undefined' && typeof initialSlide !== 'undefined') {
|
||
params.initialSlide = initialSlide;
|
||
}
|
||
if (swiper.hasClass('tabs-swipeable-wrap')) {
|
||
params.onSlideChangeStart = function (s) {
|
||
app.showTab(s.slides.eq(s.activeIndex));
|
||
};
|
||
}
|
||
var _slider = app.swiper(swiper[0], params);
|
||
destroySwiperOnRemove(_slider);
|
||
});
|
||
};
|
||
app.reinitPageSwiper = function (pageContainer) {
|
||
pageContainer = $(pageContainer);
|
||
var sliders = pageContainer.find('.swiper-init, .tabs-swipeable-wrap');
|
||
if (sliders.length === 0) return;
|
||
for (var i = 0; i < sliders.length; i++) {
|
||
var sliderInstance = sliders[0].swiper;
|
||
if (sliderInstance) {
|
||
sliderInstance.update(true);
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
/*======================================================
|
||
************ Photo Browser ************
|
||
======================================================*/
|
||
var PhotoBrowser = function (params) {
|
||
var pb = this, i;
|
||
|
||
var defaults = {
|
||
photos : [],
|
||
initialSlide: 0,
|
||
spaceBetween: 20,
|
||
speed: 300,
|
||
zoom: true,
|
||
zoomMax: 3,
|
||
zoomMin: 1,
|
||
exposition: true,
|
||
expositionHideCaptions: false,
|
||
type: 'standalone',
|
||
navbar: true,
|
||
toolbar: true,
|
||
theme: 'light',
|
||
swipeToClose: true,
|
||
backLinkText: 'Close',
|
||
ofText: 'of',
|
||
loop: false,
|
||
lazyLoading: false,
|
||
lazyLoadingInPrevNext: false,
|
||
lazyLoadingOnTransitionStart: false,
|
||
material: app.params.material,
|
||
materialPreloaderSvg: app.params.materialPreloaderSvg,
|
||
materialPreloaderHtml: app.params.materialPreloaderHtml,
|
||
/*
|
||
Callbacks:
|
||
onLazyImageLoad(pb, slide, img)
|
||
onLazyImageReady(pb, slide, img)
|
||
onOpen(pb)
|
||
onClose(pb)
|
||
onTransitionStart(swiper)
|
||
onTransitionEnd(swiper)
|
||
onSlideChangeStart(swiper)
|
||
onSlideChangeEnd(swiper)
|
||
onTap(swiper, e)
|
||
onClick(swiper, e)
|
||
onDoubleTap(swiper, e)
|
||
onSwipeToClose(pb)
|
||
*/
|
||
};
|
||
|
||
params = params || {};
|
||
if (!params.backLinkText && app.params.material) defaults.backLinkText = '';
|
||
for (var def in defaults) {
|
||
if (typeof params[def] === 'undefined') {
|
||
params[def] = defaults[def];
|
||
}
|
||
}
|
||
if (params.maxZoom) {
|
||
params.zoomMax = params.maxZoom;
|
||
}
|
||
if (params.minZoom) {
|
||
params.zoomMin = params.minZoom;
|
||
}
|
||
|
||
pb.params = params;
|
||
pb.params.iconsColorClass = pb.params.iconsColor ? 'color-' + pb.params.iconsColor : (pb.params.theme === 'dark' ? 'color-white' : '');
|
||
pb.params.preloaderColorClass = pb.params.theme === 'dark' ? 'preloader-white' : '';
|
||
|
||
// Templates
|
||
var photoTemplate = pb.params.photoTemplate ||
|
||
'<div class="photo-browser-slide swiper-slide">' +
|
||
'<span class="swiper-zoom-container">' +
|
||
'<img src="{{js "this.url || this"}}">' +
|
||
'</span>' +
|
||
'</div>';
|
||
var photoLazyTemplate = pb.params.lazyPhotoTemplate ||
|
||
'<div class="photo-browser-slide photo-browser-slide-lazy swiper-slide">' +
|
||
'<div class="preloader {{@root.preloaderColorClass}}">{{#if @root.material}}{{@root.materialPreloaderHtml}}{{/if}}</div>' +
|
||
'<span class="swiper-zoom-container">' +
|
||
'<img data-src="{{js "this.url || this"}}" class="swiper-lazy">' +
|
||
'</span>' +
|
||
'</div>';
|
||
var objectTemplate = pb.params.objectTemplate ||
|
||
'<div class="photo-browser-slide photo-browser-object-slide swiper-slide">{{js "this.html || this"}}</div>';
|
||
var captionTemplate = pb.params.captionTemplate ||
|
||
'<div class="photo-browser-caption" data-caption-index="{{@index}}">' +
|
||
'{{caption}}' +
|
||
'</div>';
|
||
var navbarTemplate = pb.params.navbarTemplate ||
|
||
'<div class="navbar">' +
|
||
'<div class="navbar-inner">' +
|
||
'<div class="left sliding">' +
|
||
'<a href="#" class="link ' + (params.type === 'popup' ? 'close-popup' : 'photo-browser-close-link')+ ' {{#unless backLinkText}}icon-only{{/unless}} {{js "this.type === \'page\' ? \'back\' : \'\'"}}">' +
|
||
'<i class="icon icon-back {{iconsColorClass}}"></i>' +
|
||
'{{#if backLinkText}}<span>{{backLinkText}}</span>{{/if}}' +
|
||
'</a>' +
|
||
'</div>' +
|
||
'<div class="center sliding">' +
|
||
'<span class="photo-browser-current"></span> ' +
|
||
'<span class="photo-browser-of">{{ofText}}</span> ' +
|
||
'<span class="photo-browser-total"></span>' +
|
||
'</div>' +
|
||
'<div class="right"></div>' +
|
||
'</div>' +
|
||
'</div>';
|
||
var toolbarTemplate = pb.params.toolbarTemplate ||
|
||
'<div class="toolbar tabbar">' +
|
||
'<div class="toolbar-inner">' +
|
||
'<a href="#" class="link photo-browser-prev">' +
|
||
'<i class="icon icon-prev {{iconsColorClass}}"></i>' +
|
||
'</a>' +
|
||
'<a href="#" class="link photo-browser-next">' +
|
||
'<i class="icon icon-next {{iconsColorClass}}"></i>' +
|
||
'</a>' +
|
||
'</div>' +
|
||
'</div>';
|
||
|
||
var htmlTemplate = t7.compile('<div class="photo-browser photo-browser-{{theme}}">' +
|
||
'<div class="view navbar-fixed toolbar-fixed">' +
|
||
'{{#unless material}}{{#if navbar}}' +
|
||
navbarTemplate +
|
||
'{{/if}}{{/unless}}' +
|
||
'<div class="page no-toolbar {{#unless navbar}}no-navbar{{/unless}} toolbar-fixed navbar-fixed" data-page="photo-browser-slides">' +
|
||
'{{#if material}}{{#if navbar}}' +
|
||
navbarTemplate +
|
||
'{{/if}}{{/if}}' +
|
||
'{{#if toolbar}}' +
|
||
toolbarTemplate +
|
||
'{{/if}}' +
|
||
'<div class="photo-browser-captions photo-browser-captions-{{js "this.captionsTheme || this.theme"}}">' +
|
||
'{{#each photos}}{{#if caption}}' +
|
||
captionTemplate +
|
||
'{{/if}}{{/each}}' +
|
||
'</div>' +
|
||
'<div class="photo-browser-swiper-container swiper-container">' +
|
||
'<div class="photo-browser-swiper-wrapper swiper-wrapper">' +
|
||
'{{#each photos}}' +
|
||
'{{#js_compare "this.html || ((typeof this === \'string\' || this instanceof String) && (this.indexOf(\'<\') >= 0 || this.indexOf(\'>\') >= 0))"}}' +
|
||
objectTemplate +
|
||
'{{else}}' +
|
||
'{{#if @root.lazyLoading}}' +
|
||
photoLazyTemplate +
|
||
'{{else}}' +
|
||
photoTemplate +
|
||
'{{/if}}' +
|
||
'{{/js_compare}}' +
|
||
'{{/each}}' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'</div>')(pb.params);
|
||
|
||
pb.activeIndex = pb.params.initialSlide;
|
||
pb.openIndex = pb.activeIndex;
|
||
pb.opened = false;
|
||
|
||
pb.open = function (index) {
|
||
if (typeof index === 'undefined') index = pb.activeIndex;
|
||
index = parseInt(index, 10);
|
||
if (pb.opened && pb.swiper) {
|
||
pb.swiper.slideTo(index);
|
||
return;
|
||
}
|
||
pb.opened = true;
|
||
pb.openIndex = index;
|
||
if (pb.params.type === 'standalone') {
|
||
app.root.append(htmlTemplate);
|
||
}
|
||
if (pb.params.type === 'popup') {
|
||
pb.popup = app.popup('<div class="popup photo-browser-popup">' + htmlTemplate + '</div>');
|
||
$(pb.popup).on('closed', pb.onPopupClose);
|
||
}
|
||
if (pb.params.type === 'page') {
|
||
$(document).on('pageBeforeInit', pb.onPageBeforeInit);
|
||
$(document).on('pageBeforeRemove', pb.onPageBeforeRemove);
|
||
if (!pb.params.view) pb.params.view = app.mainView;
|
||
pb.params.view.loadContent(htmlTemplate);
|
||
return;
|
||
}
|
||
pb.layout(pb.openIndex);
|
||
if (pb.params.onOpen) {
|
||
pb.params.onOpen(pb);
|
||
}
|
||
|
||
};
|
||
pb.close = function () {
|
||
pb.opened = false;
|
||
if (!pb.swiperContainer || pb.swiperContainer.length === 0) {
|
||
return;
|
||
}
|
||
if (pb.params.onClose) {
|
||
pb.params.onClose(pb);
|
||
}
|
||
// Detach events
|
||
pb.attachEvents(true);
|
||
// Delete from DOM
|
||
if (pb.params.type === 'standalone') {
|
||
pb.container.removeClass('photo-browser-in').addClass('photo-browser-out').animationEnd(function () {
|
||
pb.container.remove();
|
||
});
|
||
}
|
||
// Destroy slider
|
||
pb.swiper.destroy();
|
||
// Delete references
|
||
pb.swiper = pb.swiperContainer = pb.swiperWrapper = pb.slides = undefined; //gestureSlide = gestureImg = gestureImgWrap = undefined;
|
||
};
|
||
|
||
pb.onPopupClose = function (e) {
|
||
pb.close();
|
||
$(pb.popup).off('pageBeforeInit', pb.onPopupClose);
|
||
};
|
||
pb.onPageBeforeInit = function (e) {
|
||
if (e.detail.page.name === 'photo-browser-slides') {
|
||
pb.layout(pb.openIndex);
|
||
}
|
||
$(document).off('pageBeforeInit', pb.onPageBeforeInit);
|
||
};
|
||
pb.onPageBeforeRemove = function (e) {
|
||
if (e.detail.page.name === 'photo-browser-slides') {
|
||
pb.close();
|
||
}
|
||
$(document).off('pageBeforeRemove', pb.onPageBeforeRemove);
|
||
};
|
||
|
||
pb.onSliderTransitionStart = function (swiper) {
|
||
pb.activeIndex = swiper.activeIndex;
|
||
|
||
var current = swiper.activeIndex + 1;
|
||
var total = swiper.slides.length;
|
||
if (pb.params.loop) {
|
||
total = total - 2;
|
||
current = current - swiper.loopedSlides;
|
||
if (current < 1) current = total + current;
|
||
if (current > total) current = current - total;
|
||
}
|
||
pb.container.find('.photo-browser-current').text(current);
|
||
pb.container.find('.photo-browser-total').text(total);
|
||
|
||
$('.photo-browser-prev, .photo-browser-next').removeClass('photo-browser-link-inactive');
|
||
|
||
if (swiper.isBeginning && !pb.params.loop) {
|
||
$('.photo-browser-prev').addClass('photo-browser-link-inactive');
|
||
}
|
||
if (swiper.isEnd && !pb.params.loop) {
|
||
$('.photo-browser-next').addClass('photo-browser-link-inactive');
|
||
}
|
||
|
||
// Update captions
|
||
if (pb.captions.length > 0) {
|
||
pb.captionsContainer.find('.photo-browser-caption-active').removeClass('photo-browser-caption-active');
|
||
var captionIndex = pb.params.loop ? swiper.slides.eq(swiper.activeIndex).attr('data-swiper-slide-index') : pb.activeIndex;
|
||
pb.captionsContainer.find('[data-caption-index="' + captionIndex + '"]').addClass('photo-browser-caption-active');
|
||
}
|
||
|
||
|
||
// Stop Video
|
||
var previousSlideVideo = swiper.slides.eq(swiper.previousIndex).find('video');
|
||
if (previousSlideVideo.length > 0) {
|
||
if ('pause' in previousSlideVideo[0]) previousSlideVideo[0].pause();
|
||
}
|
||
// Callback
|
||
if (pb.params.onTransitionStart) pb.params.onTransitionStart(swiper);
|
||
};
|
||
pb.onSliderTransitionEnd = function (swiper) {
|
||
if (pb.params.onTransitionEnd) pb.params.onTransitionEnd(swiper);
|
||
};
|
||
|
||
pb.layout = function (index) {
|
||
if (pb.params.type === 'page') {
|
||
pb.container = $('.photo-browser-swiper-container').parents('.view');
|
||
}
|
||
else {
|
||
pb.container = $('.photo-browser');
|
||
}
|
||
if (pb.params.type === 'standalone') {
|
||
pb.container.addClass('photo-browser-in');
|
||
app.sizeNavbars(pb.container);
|
||
}
|
||
pb.swiperContainer = pb.container.find('.photo-browser-swiper-container');
|
||
pb.swiperWrapper = pb.container.find('.photo-browser-swiper-wrapper');
|
||
pb.slides = pb.container.find('.photo-browser-slide');
|
||
pb.captionsContainer = pb.container.find('.photo-browser-captions');
|
||
pb.captions = pb.container.find('.photo-browser-caption');
|
||
|
||
var sliderSettings = {
|
||
nextButton: pb.params.nextButton || '.photo-browser-next',
|
||
prevButton: pb.params.prevButton || '.photo-browser-prev',
|
||
indexButton: pb.params.indexButton,
|
||
initialSlide: index,
|
||
spaceBetween: pb.params.spaceBetween,
|
||
speed: pb.params.speed,
|
||
loop: pb.params.loop,
|
||
lazyLoading: pb.params.lazyLoading,
|
||
lazyLoadingInPrevNext: pb.params.lazyLoadingInPrevNext,
|
||
lazyLoadingOnTransitionStart: pb.params.lazyLoadingOnTransitionStart,
|
||
preloadImages: pb.params.lazyLoading ? false : true,
|
||
zoom: pb.params.zoom,
|
||
zoomMax: pb.params.zoomMax,
|
||
zoomMin: pb.params.zoomMin,
|
||
onTap: function (swiper, e) {
|
||
if (pb.params.onTap) pb.params.onTap(swiper, e);
|
||
},
|
||
onClick: function (swiper, e) {
|
||
if (pb.params.exposition) pb.toggleExposition();
|
||
if (pb.params.onClick) pb.params.onClick(swiper, e);
|
||
},
|
||
onDoubleTap: function (swiper, e) {
|
||
// pb.toggleZoom(e);
|
||
if (pb.params.onDoubleTap) pb.params.onDoubleTap(swiper, e);
|
||
},
|
||
onTransitionStart: function (swiper) {
|
||
pb.onSliderTransitionStart(swiper);
|
||
},
|
||
onTransitionEnd: function (swiper) {
|
||
pb.onSliderTransitionEnd(swiper);
|
||
},
|
||
onSlideChangeStart: pb.params.onSlideChangeStart,
|
||
onSlideChangeEnd: pb.params.onSlideChangeEnd,
|
||
onLazyImageLoad: function (swiper, slide, img) {
|
||
if (pb.params.onLazyImageLoad) pb.params.onLazyImageLoad(pb, slide, img);
|
||
},
|
||
onLazyImageReady: function (swiper, slide, img) {
|
||
$(slide).removeClass('photo-browser-slide-lazy');
|
||
if (pb.params.onLazyImageReady) pb.params.onLazyImageReady(pb, slide, img);
|
||
}
|
||
};
|
||
|
||
if (pb.params.swipeToClose && pb.params.type !== 'page') {
|
||
sliderSettings.onTouchStart = pb.swipeCloseTouchStart;
|
||
sliderSettings.onTouchMoveOpposite = pb.swipeCloseTouchMove;
|
||
sliderSettings.onTouchEnd = pb.swipeCloseTouchEnd;
|
||
}
|
||
|
||
pb.swiper = app.swiper(pb.swiperContainer, sliderSettings);
|
||
if (index === 0) {
|
||
pb.onSliderTransitionStart(pb.swiper);
|
||
}
|
||
pb.attachEvents();
|
||
};
|
||
pb.attachEvents = function (detach) {
|
||
var action = detach ? 'off' : 'on';
|
||
pb.container.find('.photo-browser-close-link')[action]('click', pb.close);
|
||
};
|
||
|
||
|
||
// Expose
|
||
pb.exposed = false;
|
||
pb.toggleExposition = function () {
|
||
if (pb.container) pb.container.toggleClass('photo-browser-exposed');
|
||
if (pb.params.expositionHideCaptions) pb.captionsContainer.toggleClass('photo-browser-captions-exposed');
|
||
pb.exposed = !pb.exposed;
|
||
};
|
||
pb.enableExposition = function () {
|
||
if (pb.container) pb.container.addClass('photo-browser-exposed');
|
||
if (pb.params.expositionHideCaptions) pb.captionsContainer.addClass('photo-browser-captions-exposed');
|
||
pb.exposed = true;
|
||
};
|
||
pb.disableExposition = function () {
|
||
if (pb.container) pb.container.removeClass('photo-browser-exposed');
|
||
if (pb.params.expositionHideCaptions) pb.captionsContainer.removeClass('photo-browser-captions-exposed');
|
||
pb.exposed = false;
|
||
};
|
||
|
||
// Swipe Up To Close
|
||
var swipeToCloseIsTouched = false;
|
||
var allowSwipeToClose = true;
|
||
var swipeToCloseDiff, swipeToCloseStart, swipeToCloseCurrent, swipeToCloseStarted = false, swipeToCloseActiveSlide, swipeToCloseTimeStart;
|
||
pb.swipeCloseTouchStart = function (swiper, e) {
|
||
if (!allowSwipeToClose) return;
|
||
swipeToCloseIsTouched = true;
|
||
};
|
||
pb.swipeCloseTouchMove = function (swiper, e) {
|
||
if (!swipeToCloseIsTouched) return;
|
||
if (!swipeToCloseStarted) {
|
||
swipeToCloseStarted = true;
|
||
swipeToCloseStart = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
swipeToCloseActiveSlide = pb.swiper.slides.eq(pb.swiper.activeIndex);
|
||
swipeToCloseTimeStart = (new Date()).getTime();
|
||
}
|
||
e.preventDefault();
|
||
swipeToCloseCurrent = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
swipeToCloseDiff = swipeToCloseStart - swipeToCloseCurrent;
|
||
var opacity = 1 - Math.abs(swipeToCloseDiff) / 300;
|
||
swipeToCloseActiveSlide.transform('translate3d(0,' + (-swipeToCloseDiff) + 'px,0)');
|
||
pb.swiper.container.css('opacity', opacity).transition(0);
|
||
};
|
||
pb.swipeCloseTouchEnd = function (swiper, e) {
|
||
swipeToCloseIsTouched = false;
|
||
if (!swipeToCloseStarted) {
|
||
swipeToCloseStarted = false;
|
||
return;
|
||
}
|
||
swipeToCloseStarted = false;
|
||
allowSwipeToClose = false;
|
||
var diff = Math.abs(swipeToCloseDiff);
|
||
var timeDiff = (new Date()).getTime() - swipeToCloseTimeStart;
|
||
if ((timeDiff < 300 && diff > 20) || (timeDiff >= 300 && diff > 100)) {
|
||
setTimeout(function () {
|
||
if (pb.params.type === 'standalone') {
|
||
pb.close();
|
||
}
|
||
if (pb.params.type === 'popup') {
|
||
app.closeModal(pb.popup);
|
||
}
|
||
if (pb.params.onSwipeToClose) {
|
||
pb.params.onSwipeToClose(pb);
|
||
}
|
||
allowSwipeToClose = true;
|
||
}, 0);
|
||
return;
|
||
}
|
||
if (diff !== 0) {
|
||
swipeToCloseActiveSlide.addClass('transitioning').transitionEnd(function () {
|
||
allowSwipeToClose = true;
|
||
swipeToCloseActiveSlide.removeClass('transitioning');
|
||
});
|
||
}
|
||
else {
|
||
allowSwipeToClose = true;
|
||
}
|
||
pb.swiper.container.css('opacity', '').transition('');
|
||
swipeToCloseActiveSlide.transform('');
|
||
};
|
||
|
||
return pb;
|
||
};
|
||
|
||
app.photoBrowser = function (params) {
|
||
return new PhotoBrowser(params);
|
||
};
|
||
|
||
|
||
/*===============================================================================
|
||
************ Autocomplete ************
|
||
===============================================================================*/
|
||
var Autocomplete = function (params) {
|
||
var a = this;
|
||
|
||
// Params
|
||
var defaults = {
|
||
// Standalone Options
|
||
/*
|
||
opener: undefined,
|
||
*/
|
||
popupCloseText: 'Close',
|
||
backText: 'Back',
|
||
searchbarPlaceholderText: 'Search...',
|
||
searchbarCancelText: 'Cancel',
|
||
openIn: 'page',
|
||
backOnSelect: false,
|
||
notFoundText: 'Nothing found',
|
||
/*
|
||
pageTitle: undefined,
|
||
*/
|
||
|
||
// Handle Data
|
||
/*
|
||
source: undefined,
|
||
limit: undefined,
|
||
*/
|
||
valueProperty: 'id',
|
||
textProperty: 'text',
|
||
|
||
// Dropdown Options
|
||
/*
|
||
dropdownPlaceholderText: 'Type anything...',
|
||
*/
|
||
updateInputValueOnSelect: true,
|
||
expandInput: false,
|
||
|
||
// Preloader
|
||
preloaderColor: false,
|
||
preloader: false,
|
||
|
||
// Templates
|
||
/*
|
||
itemTemplate: undefined,
|
||
navbarTemplate: undefined,
|
||
dropdownTemplate: undefined
|
||
dropdownItemTemplate: undefined,
|
||
dropdownPlaceholderTemplate: undefined
|
||
*/
|
||
|
||
// Color themes
|
||
/*
|
||
navbarTheme: undefined,
|
||
formTheme: undefined,
|
||
*/
|
||
|
||
// Callbacks
|
||
/*
|
||
onChange: function (a, value) - for not dropdown
|
||
onOpen: function (a)
|
||
onClose: function (a)
|
||
*/
|
||
};
|
||
|
||
params = params || {};
|
||
for (var def in defaults) {
|
||
if (typeof params[def] === 'undefined') {
|
||
params[def] = defaults[def];
|
||
}
|
||
}
|
||
a.params = params;
|
||
|
||
// Opener Link & View
|
||
if (a.params.opener) {
|
||
a.opener = $(a.params.opener);
|
||
}
|
||
var view = a.params.view;
|
||
if (!a.params.view && a.opener && a.opener.length) {
|
||
// Find related view
|
||
view = a.opener.parents('.' + app.params.viewClass);
|
||
if (view.length === 0) return;
|
||
view = view[0].f7View;
|
||
}
|
||
|
||
// Input
|
||
if (a.params.input) {
|
||
a.input = $(a.params.input);
|
||
if (a.input.length === 0 && a.params.openIn === 'dropdown') return;
|
||
}
|
||
|
||
// Array with selected items
|
||
a.value = a.params.value || [];
|
||
|
||
// ID & Inputs
|
||
a.id = (new Date()).getTime();
|
||
a.inputType = a.params.multiple ? 'checkbox' : 'radio';
|
||
a.inputName = a.inputType + '-' + a.id;
|
||
|
||
// Is Material
|
||
var material = app.params.material;
|
||
|
||
// Back On Select
|
||
var backOnSelect = a.params.backOnSelect;
|
||
|
||
if (a.params.openIn !== 'dropdown') {
|
||
// Item Template
|
||
a.itemTemplate = t7.compile(a.params.itemTemplate ||
|
||
'<li>' +
|
||
'<label class="label-{{inputType}} item-content">' +
|
||
'<input type="{{inputType}}" name="{{inputName}}" value="{{value}}" {{#if selected}}checked{{/if}}>' +
|
||
'{{#if material}}' +
|
||
'<div class="item-media">' +
|
||
'<i class="icon icon-form-{{inputType}}"></i>' +
|
||
'</div>' +
|
||
'<div class="item-inner">' +
|
||
'<div class="item-title">{{text}}</div>' +
|
||
'</div>' +
|
||
'{{else}}' +
|
||
'{{#if checkbox}}' +
|
||
'<div class="item-media">' +
|
||
'<i class="icon icon-form-checkbox"></i>' +
|
||
'</div>' +
|
||
'{{/if}}' +
|
||
'<div class="item-inner">' +
|
||
'<div class="item-title">{{text}}</div>' +
|
||
'</div>' +
|
||
'{{/if}}' +
|
||
'</label>' +
|
||
'</li>'
|
||
);
|
||
// Page Layout
|
||
var pageTitle = a.params.pageTitle || '';
|
||
if (!pageTitle && a.opener && a.opener.length) {
|
||
pageTitle = a.opener.find('.item-title').text();
|
||
}
|
||
var pageName = 'autocomplete-' + a.inputName;
|
||
|
||
var navbarTheme = a.params.navbarTheme,
|
||
formTheme = a.params.formTheme;
|
||
|
||
// Navbar HTML
|
||
var navbarHTML;
|
||
var noNavbar = '', noToolbar = '', navbarLayout;
|
||
|
||
a.navbarTemplate = t7.compile(a.params.navbarTemplate ||
|
||
'<div class="navbar {{#if navbarTheme}}theme-{{navbarTheme}}{{/if}}">' +
|
||
'<div class="navbar-inner">' +
|
||
'<div class="left sliding">' +
|
||
'{{#if material}}' +
|
||
'<a href="#" class="link {{#if inPopup}}close-popup{{else}}back{{/if}} icon-only"><i class="icon icon-back"></i></a>' +
|
||
'{{else}}' +
|
||
'<a href="#" class="link {{#if inPopup}}close-popup{{else}}back{{/if}}">' +
|
||
'<i class="icon icon-back"></i>' +
|
||
'{{#if inPopup}}' +
|
||
'<span>{{popupCloseText}}</span>' +
|
||
'{{else}}' +
|
||
'<span>{{backText}}</span>' +
|
||
'{{/if}}' +
|
||
'</a>' +
|
||
'{{/if}}' +
|
||
'</div>' +
|
||
'<div class="center sliding">{{pageTitle}}</div>' +
|
||
'{{#if preloader}}' +
|
||
'<div class="right">' +
|
||
'<div class="autocomplete-preloader preloader {{#if preloaderColor}}preloader-{{preloaderColor}}{{/if}}"></div>' +
|
||
'</div>' +
|
||
'{{/if}}' +
|
||
'</div>' +
|
||
'</div>'
|
||
);
|
||
navbarHTML = a.navbarTemplate({
|
||
pageTitle: pageTitle,
|
||
backText: a.params.backText,
|
||
popupCloseText: a.params.popupCloseText,
|
||
openIn: a.params.openIn,
|
||
navbarTheme: navbarTheme,
|
||
inPopup: a.params.openIn === 'popup',
|
||
inPage: a.params.openIn === 'page',
|
||
material: material,
|
||
preloader: a.params.preloader,
|
||
preloaderColor: a.params.preloaderColor,
|
||
});
|
||
|
||
// Determine navbar layout type - static/fixed/through
|
||
if (a.params.openIn === 'page') {
|
||
navbarLayout = 'static';
|
||
if (a.opener) {
|
||
if (a.opener.parents('.navbar-through').length > 0) navbarLayout = 'through';
|
||
if (a.opener.parents('.navbar-fixed').length > 0) navbarLayout = 'fixed';
|
||
noToolbar = a.opener.parents('.page').hasClass('no-toolbar') ? 'no-toolbar' : '';
|
||
noNavbar = a.opener.parents('.page').hasClass('no-navbar') ? 'no-navbar' : 'navbar-' + navbarLayout;
|
||
}
|
||
else if (view.container) {
|
||
if ($(view.container).hasClass('navbar-through') || $(view.container).find('.navbar-through').length > 0) navbarLayout = 'through';
|
||
if ($(view.container).hasClass('navbar-fixed') || $(view.container).find('.navbar-fixed').length > 0) navbarLayout = 'fixed';
|
||
noToolbar = $(view.activePage.container).hasClass('no-toolbar') ? 'no-toolbar' : '';
|
||
noNavbar = $(view.activePage.container).hasClass('no-navbar') ? 'no-navbar' : 'navbar-' + navbarLayout;
|
||
}
|
||
}
|
||
else {
|
||
navbarLayout = 'fixed';
|
||
}
|
||
var searchbarHTML =
|
||
'<form class="searchbar">' +
|
||
'<div class="searchbar-input">' +
|
||
'<input type="search" placeholder="' + a.params.searchbarPlaceholderText + '">' +
|
||
'<a href="#" class="searchbar-clear"></a>' +
|
||
'</div>' +
|
||
(material ? '' : '<a href="#" class="searchbar-cancel">' + a.params.searchbarCancelText + '</a>') +
|
||
'</form>' +
|
||
'<div class="searchbar-overlay"></div>';
|
||
var pageHTML =
|
||
(navbarLayout === 'through' ? navbarHTML : '') +
|
||
'<div class="pages">' +
|
||
'<div data-page="' + pageName + '" class="page autocomplete-page ' + noNavbar + ' ' + noToolbar + '">' +
|
||
(navbarLayout === 'fixed' ? navbarHTML : '') +
|
||
searchbarHTML +
|
||
'<div class="page-content">' +
|
||
(navbarLayout === 'static' ? navbarHTML : '') +
|
||
'<div class="list-block autocomplete-found autocomplete-list-' + a.id + ' ' + (formTheme ? 'theme-' + formTheme : '') + '">' +
|
||
'<ul></ul>' +
|
||
'</div>' +
|
||
'<div class="list-block autocomplete-not-found">' +
|
||
'<ul><li class="item-content"><div class="item-inner"><div class="item-title">' + a.params.notFoundText + '</div></div></li></ul>' +
|
||
'</div>' +
|
||
'<div class="list-block autocomplete-values">' +
|
||
'<ul></ul>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'</div>';
|
||
}
|
||
else {
|
||
a.dropdownItemTemplate = t7.compile(a.params.dropdownItemTemplate ||
|
||
'<li>' +
|
||
'<label class="{{#unless placeholder}}label-radio{{/unless}} item-content" data-value="{{value}}">' +
|
||
'<div class="item-inner">' +
|
||
'<div class="item-title">{{text}}</div>' +
|
||
'</div>' +
|
||
'</label>' +
|
||
'</li>'
|
||
);
|
||
a.dropdownPlaceholderTemplate = t7.compile(a.params.dropdownPlaceholderTemplate ||
|
||
'<li class="autocomplete-dropdown-placeholder">' +
|
||
'<div class="item-content">' +
|
||
'<div class="item-inner">' +
|
||
'<div class="item-title">{{text}}</div>' +
|
||
'</div>' +
|
||
'</label>' +
|
||
'</li>'
|
||
);
|
||
a.dropdownTemplate = t7.compile(a.params.dropdownTemplate ||
|
||
'<div class="autocomplete-dropdown">' +
|
||
'<div class="autocomplete-dropdown-inner">' +
|
||
'<div class="list-block">' +
|
||
'<ul></ul>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'{{#if preloader}}' +
|
||
'<div class="autocomplete-preloader preloader {{#if preloaderColor}}preloader-{{preloaderColor}}{{/if}}">{{#if material}}{{materialPreloaderHtml}}{{/if}}</div>' +
|
||
'{{/if}}' +
|
||
'</div>'
|
||
);
|
||
}
|
||
|
||
// Define popup
|
||
a.popup = undefined;
|
||
|
||
// Define Dropdown
|
||
a.dropdown = undefined;
|
||
|
||
// Handle Input Value Change
|
||
function handleInputValue (e) {
|
||
var query = a.input.val();
|
||
if (a.params.source) {
|
||
a.params.source(a, query, function (items) {
|
||
var itemsHTML = '';
|
||
var limit = a.params.limit ? Math.min(a.params.limit, items.length) : items.length;
|
||
a.items = items;
|
||
var i, j;
|
||
var regExp = new RegExp('('+query+')', 'i');
|
||
for (i = 0; i < limit; i++) {
|
||
var itemValue = typeof items[i] === 'object' ? items[i][a.params.valueProperty] : items[i];
|
||
itemsHTML += a.dropdownItemTemplate({
|
||
value: itemValue,
|
||
text: (typeof items[i] !== 'object' ? items[i] : items[i][a.params.textProperty]).replace(regExp, '<b>$1</b>')
|
||
});
|
||
}
|
||
if (itemsHTML === '' && query === '' && a.params.dropdownPlaceholderText) {
|
||
itemsHTML += a.dropdownPlaceholderTemplate({
|
||
text: a.params.dropdownPlaceholderText,
|
||
});
|
||
}
|
||
a.dropdown.find('ul').html(itemsHTML);
|
||
});
|
||
}
|
||
}
|
||
// Handle Drop Down Click
|
||
function handleDropdownClick (e) {
|
||
/*jshint validthis:true */
|
||
var clicked = $(this);
|
||
var clickedItem;
|
||
for (var i = 0; i < a.items.length; i++) {
|
||
var itemValue = typeof a.items[i] === 'object' ? a.items[i][a.params.valueProperty] : a.items[i];
|
||
var value = clicked.attr('data-value');
|
||
if (itemValue === value || itemValue * 1 === value * 1) {
|
||
clickedItem = a.items[i];
|
||
}
|
||
}
|
||
if (a.params.updateInputValueOnSelect) {
|
||
a.input.val(typeof clickedItem === 'object' ? clickedItem[a.params.textProperty] : clickedItem);
|
||
a.input.trigger('input change');
|
||
}
|
||
|
||
if (a.params.onChange) {
|
||
a.params.onChange(a, clickedItem);
|
||
}
|
||
|
||
a.close();
|
||
}
|
||
|
||
// Handle HTML Click to close Dropdown
|
||
function closeOnHTMLClick (e) {
|
||
var target = $(e.target);
|
||
if (!(target.is(a.input[0]) || a.dropdown && target.parents(a.dropdown[0]).length > 0)) {
|
||
a.close();
|
||
}
|
||
}
|
||
|
||
a.positionDropDown = function () {
|
||
var listBlock = a.input.parents('.list-block'),
|
||
pageContent = a.input.parents('.page-content'),
|
||
paddingTop = parseInt(pageContent.css('padding-top'), 10),
|
||
paddingBottom = parseInt(pageContent.css('padding-top'), 10),
|
||
// inputOffset = a.input.offset(),
|
||
listBlockOffsetLeft = listBlock.length > 0 ? listBlock.offset().left - listBlock.parent().offset().left : 0,
|
||
inputOffsetLeft = a.input.offset().left - (listBlock.length > 0 ? listBlock.offset().left : 0),
|
||
inputOffsetTop = a.input.offset().top - (pageContent.offset().top - pageContent[0].scrollTop),
|
||
maxHeight = pageContent[0].scrollHeight - paddingBottom - (inputOffsetTop + pageContent[0].scrollTop) - a.input[0].offsetHeight;
|
||
|
||
a.dropdown.css({
|
||
left: (listBlock.length > 0 ? listBlockOffsetLeft : inputOffsetLeft) + 'px',
|
||
top: inputOffsetTop + pageContent[0].scrollTop + a.input[0].offsetHeight + 'px',
|
||
width: (listBlock.length > 0 ? listBlock[0].offsetWidth : a.input[0].offsetWidth) + 'px'
|
||
});
|
||
a.dropdown.children('.autocomplete-dropdown-inner').css({
|
||
maxHeight: maxHeight + 'px',
|
||
paddingLeft: listBlock.length > 0 && !a.params.expandInput ? inputOffsetLeft - (material ? 16 : 15) + 'px' : ''
|
||
});
|
||
};
|
||
|
||
// Event Listeners on new page
|
||
a.pageInit = function (e) {
|
||
var page = e.detail.page;
|
||
a.page = $(page.container);
|
||
a.pageData = page;
|
||
if (page.name !== pageName) {
|
||
return;
|
||
}
|
||
var container = $(page.container);
|
||
// Init Search Bar
|
||
var searchbar = app.searchbar(container.find('.searchbar'), {
|
||
customSearch: true,
|
||
onSearch: function (searchbar, data) {
|
||
if (data.query.length === 0 && searchbar.active) {
|
||
searchbar.overlay.addClass('searchbar-overlay-active');
|
||
}
|
||
else {
|
||
searchbar.overlay.removeClass('searchbar-overlay-active');
|
||
}
|
||
|
||
var i, j, k;
|
||
|
||
if (a.params.source) {
|
||
a.params.source(a, data.query, function(items) {
|
||
var itemsHTML = '';
|
||
var limit = a.params.limit ? Math.min(a.params.limit, items.length) : items.length;
|
||
a.items = items;
|
||
for (i = 0; i < limit; i++) {
|
||
var selected = false;
|
||
var itemValue = typeof items[i] === 'object' ? items[i][a.params.valueProperty] : items[i];
|
||
for (j = 0; j < a.value.length; j++) {
|
||
var aValue = typeof a.value[j] === 'object' ? a.value[j][a.params.valueProperty] : a.value[j];
|
||
if (aValue === itemValue || aValue * 1 === itemValue * 1) selected = true;
|
||
}
|
||
itemsHTML += a.itemTemplate({
|
||
value: itemValue,
|
||
text: typeof items[i] !== 'object' ? items[i] : items[i][a.params.textProperty],
|
||
inputType: a.inputType,
|
||
id: a.id,
|
||
inputName: a.inputName,
|
||
selected: selected,
|
||
checkbox: a.inputType === 'checkbox',
|
||
material: material
|
||
});
|
||
}
|
||
container.find('.autocomplete-found ul').html(itemsHTML);
|
||
if (items.length === 0) {
|
||
if (data.query.length !== 0) {
|
||
container.find('.autocomplete-not-found').show();
|
||
container.find('.autocomplete-found, .autocomplete-values').hide();
|
||
}
|
||
else {
|
||
container.find('.autocomplete-values').show();
|
||
container.find('.autocomplete-found, .autocomplete-not-found').hide();
|
||
}
|
||
}
|
||
else {
|
||
container.find('.autocomplete-found').show();
|
||
container.find('.autocomplete-not-found, .autocomplete-values').hide();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
});
|
||
|
||
// Save searchbar instance
|
||
a.searchbar = searchbar;
|
||
|
||
// Update values
|
||
function updateValues() {
|
||
var valuesHTML = '';
|
||
var i;
|
||
for (i = 0; i < a.value.length; i++) {
|
||
|
||
valuesHTML += a.itemTemplate({
|
||
value: typeof a.value[i] === 'object' ? a.value[i][a.params.valueProperty] : a.value[i],
|
||
text: typeof a.value[i] === 'object' ? a.value[i][a.params.textProperty]: a.value[i],
|
||
inputType: a.inputType,
|
||
id: a.id,
|
||
inputName: a.inputName + '-checked',
|
||
checkbox: a.inputType === 'checkbox',
|
||
material: material,
|
||
selected: true
|
||
});
|
||
}
|
||
container.find('.autocomplete-values ul').html(valuesHTML);
|
||
}
|
||
|
||
// Handle Inputs
|
||
container.on('change', 'input[type="radio"], input[type="checkbox"]', function () {
|
||
var i;
|
||
var input = this;
|
||
var value = input.value;
|
||
var text = $(input).parents('li').find('.item-title').text();
|
||
var isValues = $(input).parents('.autocomplete-values').length > 0;
|
||
var item, itemValue, aValue;
|
||
if (isValues) {
|
||
if (a.inputType === 'checkbox' && !input.checked) {
|
||
for (i = 0; i < a.value.length; i++) {
|
||
aValue = typeof a.value[i] === 'string' ? a.value[i] : a.value[i][a.params.valueProperty];
|
||
if (aValue === value || aValue * 1 === value * 1) {
|
||
a.value.splice(i, 1);
|
||
}
|
||
}
|
||
updateValues();
|
||
if (a.params.onChange) a.params.onChange(a, a.value);
|
||
}
|
||
return;
|
||
}
|
||
|
||
// Find Related Item
|
||
for (i = 0; i < a.items.length; i++) {
|
||
itemValue = typeof a.items[i] === 'string' ? a.items[i] : a.items[i][a.params.valueProperty];
|
||
if (itemValue === value || itemValue * 1 === value * 1) item = a.items[i];
|
||
}
|
||
// Update Selected Value
|
||
if (a.inputType === 'radio') {
|
||
a.value = [item];
|
||
}
|
||
else {
|
||
if (input.checked) {
|
||
a.value.push(item);
|
||
}
|
||
else {
|
||
for (i = 0; i < a.value.length; i++) {
|
||
aValue = typeof a.value[i] === 'string' ? a.value[i] : a.value[i][a.params.valueProperty];
|
||
if (aValue === value || aValue * 1 === value * 1) {
|
||
a.value.splice(i, 1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Update Values Block
|
||
updateValues();
|
||
|
||
// On Select Callback
|
||
if ((a.inputType === 'radio' && input.checked || a.inputType === 'checkbox') && a.params.onChange ) {
|
||
a.params.onChange(a, a.value);
|
||
}
|
||
if (backOnSelect && a.inputType === 'radio') {
|
||
if (a.params.openIn === 'popup') app.closeModal(a.popup);
|
||
else view.router.back();
|
||
}
|
||
});
|
||
|
||
// Update Values On Page Init
|
||
updateValues();
|
||
|
||
if (a.params.onOpen) a.params.onOpen(a);
|
||
};
|
||
|
||
// Show Hide Preloader
|
||
a.showPreloader = function () {
|
||
if (a.params.openIn === 'dropdown') {
|
||
if (a.dropdown) a.dropdown.find('.autocomplete-preloader').addClass('autocomplete-preloader-visible');
|
||
}
|
||
else $('.autocomplete-preloader').addClass('autocomplete-preloader-visible');
|
||
};
|
||
|
||
a.hidePreloader = function () {
|
||
if (a.params.openIn === 'dropdown') {
|
||
if (a.dropdown) a.dropdown.find('.autocomplete-preloader').removeClass('autocomplete-preloader-visible');
|
||
}
|
||
else $('.autocomplete-preloader').removeClass('autocomplete-preloader-visible');
|
||
};
|
||
|
||
// Open Autocomplete Page/Popup
|
||
a.open = function () {
|
||
if (a.opened) return;
|
||
a.opened = true;
|
||
if (a.params.openIn === 'dropdown') {
|
||
if (!a.dropdown) {
|
||
a.dropdown = $(a.dropdownTemplate({
|
||
preloader: a.params.preloader,
|
||
preloaderColor: a.params.preloaderColor,
|
||
material: material,
|
||
materialPreloaderHtml: app.params.materialPreloaderHtml
|
||
}));
|
||
a.dropdown.on('click', 'label', handleDropdownClick);
|
||
|
||
}
|
||
var listBlock = a.input.parents('.list-block');
|
||
if (listBlock.length && a.input.parents('.item-content').length > 0 && a.params.expandInput) {
|
||
a.input.parents('.item-content').addClass('item-content-dropdown-expand');
|
||
}
|
||
a.positionDropDown();
|
||
a.input.parents('.page-content').append(a.dropdown);
|
||
a.dropdown.addClass('autocomplete-dropdown-in');
|
||
a.input.trigger('input');
|
||
$(window).on('resize', a.positionDropDown);
|
||
if (a.params.onOpen) a.params.onOpen(a);
|
||
}
|
||
else {
|
||
$(document).once('pageInit', '.autocomplete-page', a.pageInit);
|
||
if (a.params.openIn === 'popup') {
|
||
a.popup = app.popup(
|
||
'<div class="popup autocomplete-popup autocomplete-popup-' + a.inputName + '">' +
|
||
'<div class="view navbar-fixed">' +
|
||
pageHTML +
|
||
'</div>' +
|
||
'</div>'
|
||
);
|
||
a.popup = $(a.popup);
|
||
a.popup.once('closed', function () {
|
||
a.popup = undefined;
|
||
a.opened = false;
|
||
if (a.params.onClose) a.params.onClose(a);
|
||
});
|
||
}
|
||
else {
|
||
view.router.load({
|
||
content: pageHTML
|
||
});
|
||
$(document).once('pageBack', '.autocomplete-page', function () {
|
||
a.opened = false;
|
||
if (a.params.onClose) a.params.onClose(a);
|
||
});
|
||
}
|
||
}
|
||
};
|
||
a.close = function (e) {
|
||
if (!a.opened) return;
|
||
if (a.params.openIn === 'dropdown') {
|
||
if (e && e.type === 'blur' && a.dropdown.find('label.active-state').length > 0) return;
|
||
a.dropdown.removeClass('autocomplete-dropdown-in').remove();
|
||
a.input.parents('.item-content-dropdown-expand').removeClass('item-content-dropdown-expand');
|
||
a.opened = false;
|
||
$(window).off('resize', a.positionDropDown);
|
||
if (a.params.onClose) a.params.onClose(a);
|
||
}
|
||
if (a.params.openIn === 'popup') {
|
||
if (a.popup) app.closeModal(a.popup);
|
||
}
|
||
};
|
||
|
||
// Init Events
|
||
a.initEvents = function (detach) {
|
||
var method = detach ? 'off' : 'on';
|
||
if (a.params.openIn !== 'dropdown' && a.opener) {
|
||
a.opener[method]('click', a.open);
|
||
}
|
||
if (a.params.openIn === 'dropdown' && a.input) {
|
||
a.input[method]('focus', a.open);
|
||
a.input[method]('input', handleInputValue);
|
||
if (app.device.android) {
|
||
$('html')[method]('click', closeOnHTMLClick);
|
||
}
|
||
else {
|
||
a.input[method]('blur', a.close);
|
||
}
|
||
}
|
||
if (detach && a.dropdown) {
|
||
a.dropdown = null;
|
||
}
|
||
};
|
||
|
||
// Init/Destroy Methods
|
||
a.init = function () {
|
||
a.initEvents();
|
||
};
|
||
a.destroy = function () {
|
||
a.initEvents(true);
|
||
a = null;
|
||
};
|
||
|
||
// Init
|
||
a.init();
|
||
|
||
return a;
|
||
};
|
||
app.autocomplete = function (params) {
|
||
return new Autocomplete(params);
|
||
};
|
||
|
||
/*======================================================
|
||
************ Picker ************
|
||
======================================================*/
|
||
var Picker = function (params) {
|
||
var p = this;
|
||
var defaults = {
|
||
updateValuesOnMomentum: false,
|
||
updateValuesOnTouchmove: true,
|
||
rotateEffect: false,
|
||
momentumRatio: 7,
|
||
freeMode: false,
|
||
// Common settings
|
||
closeByOutsideClick: true,
|
||
scrollToInput: true,
|
||
inputReadOnly: true,
|
||
convertToPopover: true,
|
||
onlyInPopover: false,
|
||
toolbar: true,
|
||
toolbarCloseText: 'Done',
|
||
toolbarTemplate:
|
||
'<div class="toolbar">' +
|
||
'<div class="toolbar-inner">' +
|
||
'<div class="left"></div>' +
|
||
'<div class="right">' +
|
||
'<a href="#" class="link close-picker">{{closeText}}</a>' +
|
||
'</div>' +
|
||
'</div>' +
|
||
'</div>'
|
||
};
|
||
params = params || {};
|
||
for (var def in defaults) {
|
||
if (typeof params[def] === 'undefined') {
|
||
params[def] = defaults[def];
|
||
}
|
||
}
|
||
p.params = params;
|
||
p.cols = [];
|
||
p.initialized = false;
|
||
|
||
// Inline flag
|
||
p.inline = p.params.container ? true : false;
|
||
|
||
// 3D Transforms origin bug, only on safari
|
||
var originBug = app.device.ios || (navigator.userAgent.toLowerCase().indexOf('safari') >= 0 && navigator.userAgent.toLowerCase().indexOf('chrome') < 0) && !app.device.android;
|
||
|
||
// Should be converted to popover
|
||
function isPopover() {
|
||
var toPopover = false;
|
||
if (!p.params.convertToPopover && !p.params.onlyInPopover) return toPopover;
|
||
if (!p.inline && p.params.input) {
|
||
if (p.params.onlyInPopover) toPopover = true;
|
||
else {
|
||
if (app.device.ios) {
|
||
toPopover = app.device.ipad ? true : false;
|
||
}
|
||
else {
|
||
if ($(window).width() >= 768) toPopover = true;
|
||
}
|
||
}
|
||
}
|
||
return toPopover;
|
||
}
|
||
function inPopover() {
|
||
if (p.opened && p.container && p.container.length > 0 && p.container.parents('.popover').length > 0) return true;
|
||
else return false;
|
||
}
|
||
|
||
// Value
|
||
p.setValue = function (arrValues, transition) {
|
||
var valueIndex = 0;
|
||
if (p.cols.length === 0) {
|
||
p.value = arrValues;
|
||
p.updateValue(arrValues);
|
||
return;
|
||
}
|
||
for (var i = 0; i < p.cols.length; i++) {
|
||
if (p.cols[i] && !p.cols[i].divider) {
|
||
p.cols[i].setValue(arrValues[valueIndex], transition);
|
||
valueIndex++;
|
||
}
|
||
}
|
||
};
|
||
p.updateValue = function (forceValues) {
|
||
var newValue = forceValues || [];
|
||
var newDisplayValue = [];
|
||
for (var i = 0; i < p.cols.length; i++) {
|
||
if (!p.cols[i].divider) {
|
||
newValue.push(p.cols[i].value);
|
||
newDisplayValue.push(p.cols[i].displayValue);
|
||
}
|
||
}
|
||
if (newValue.indexOf(undefined) >= 0) {
|
||
return;
|
||
}
|
||
p.value = newValue;
|
||
p.displayValue = newDisplayValue;
|
||
if (p.params.onChange) {
|
||
p.params.onChange(p, p.value, p.displayValue);
|
||
}
|
||
if (p.input && p.input.length > 0) {
|
||
$(p.input).val(p.params.formatValue ? p.params.formatValue(p, p.value, p.displayValue) : p.value.join(' '));
|
||
$(p.input).trigger('change');
|
||
}
|
||
};
|
||
|
||
// Columns Handlers
|
||
p.initPickerCol = function (colElement, updateItems) {
|
||
var colContainer = $(colElement);
|
||
var colIndex = colContainer.index();
|
||
var col = p.cols[colIndex];
|
||
if (col.divider) return;
|
||
col.container = colContainer;
|
||
col.wrapper = col.container.find('.picker-items-col-wrapper');
|
||
col.items = col.wrapper.find('.picker-item');
|
||
|
||
var i, j;
|
||
var wrapperHeight, itemHeight, itemsHeight, minTranslate, maxTranslate;
|
||
col.replaceValues = function (values, displayValues) {
|
||
col.destroyEvents();
|
||
col.values = values;
|
||
col.displayValues = displayValues;
|
||
var newItemsHTML = p.columnHTML(col, true);
|
||
col.wrapper.html(newItemsHTML);
|
||
col.items = col.wrapper.find('.picker-item');
|
||
col.calcSize();
|
||
col.setValue(col.values[0], 0, true);
|
||
col.initEvents();
|
||
};
|
||
col.calcSize = function () {
|
||
if (p.params.rotateEffect) {
|
||
col.container.removeClass('picker-items-col-absolute');
|
||
if (!col.width) col.container.css({width:''});
|
||
}
|
||
var colWidth, colHeight;
|
||
colWidth = 0;
|
||
colHeight = col.container[0].offsetHeight;
|
||
wrapperHeight = col.wrapper[0].offsetHeight;
|
||
itemHeight = col.items[0].offsetHeight;
|
||
itemsHeight = itemHeight * col.items.length;
|
||
minTranslate = colHeight / 2 - itemsHeight + itemHeight / 2;
|
||
maxTranslate = colHeight / 2 - itemHeight / 2;
|
||
if (col.width) {
|
||
colWidth = col.width;
|
||
if (parseInt(colWidth, 10) === colWidth) colWidth = colWidth + 'px';
|
||
col.container.css({width: colWidth});
|
||
}
|
||
if (p.params.rotateEffect) {
|
||
if (!col.width) {
|
||
col.items.each(function () {
|
||
var item = $(this);
|
||
item.css({width:'auto'});
|
||
colWidth = Math.max(colWidth, item[0].offsetWidth);
|
||
item.css({width:''});
|
||
});
|
||
col.container.css({width: (colWidth + 2) + 'px'});
|
||
}
|
||
col.container.addClass('picker-items-col-absolute');
|
||
}
|
||
};
|
||
col.calcSize();
|
||
|
||
col.wrapper.transform('translate3d(0,' + maxTranslate + 'px,0)').transition(0);
|
||
|
||
|
||
var activeIndex = 0;
|
||
var animationFrameId;
|
||
|
||
// Set Value Function
|
||
col.setValue = function (newValue, transition, valueCallbacks) {
|
||
if (typeof transition === 'undefined') transition = '';
|
||
var newActiveIndex = col.wrapper.find('.picker-item[data-picker-value="' + newValue + '"]').index();
|
||
if(typeof newActiveIndex === 'undefined' || newActiveIndex === -1) {
|
||
return;
|
||
}
|
||
var newTranslate = -newActiveIndex * itemHeight + maxTranslate;
|
||
// Update wrapper
|
||
col.wrapper.transition(transition);
|
||
col.wrapper.transform('translate3d(0,' + (newTranslate) + 'px,0)');
|
||
|
||
// Watch items
|
||
if (p.params.updateValuesOnMomentum && col.activeIndex && col.activeIndex !== newActiveIndex ) {
|
||
$.cancelAnimationFrame(animationFrameId);
|
||
col.wrapper.transitionEnd(function(){
|
||
$.cancelAnimationFrame(animationFrameId);
|
||
});
|
||
updateDuringScroll();
|
||
}
|
||
|
||
// Update items
|
||
col.updateItems(newActiveIndex, newTranslate, transition, valueCallbacks);
|
||
};
|
||
|
||
col.updateItems = function (activeIndex, translate, transition, valueCallbacks) {
|
||
if (typeof translate === 'undefined') {
|
||
translate = $.getTranslate(col.wrapper[0], 'y');
|
||
}
|
||
if(typeof activeIndex === 'undefined') activeIndex = -Math.round((translate - maxTranslate)/itemHeight);
|
||
if (activeIndex < 0) activeIndex = 0;
|
||
if (activeIndex >= col.items.length) activeIndex = col.items.length - 1;
|
||
var previousActiveIndex = col.activeIndex;
|
||
col.activeIndex = activeIndex;
|
||
col.wrapper.find('.picker-selected').removeClass('picker-selected');
|
||
|
||
col.items.transition(transition);
|
||
|
||
var selectedItem = col.items.eq(activeIndex).addClass('picker-selected').transform('');
|
||
|
||
// Set 3D rotate effect
|
||
if (p.params.rotateEffect) {
|
||
var percentage = (translate - (Math.floor((translate - maxTranslate)/itemHeight) * itemHeight + maxTranslate)) / itemHeight;
|
||
|
||
col.items.each(function () {
|
||
var item = $(this);
|
||
var itemOffsetTop = item.index() * itemHeight;
|
||
var translateOffset = maxTranslate - translate;
|
||
var itemOffset = itemOffsetTop - translateOffset;
|
||
var percentage = itemOffset / itemHeight;
|
||
|
||
var itemsFit = Math.ceil(col.height / itemHeight / 2) + 1;
|
||
|
||
var angle = (-18*percentage);
|
||
if (angle > 180) angle = 180;
|
||
if (angle < -180) angle = -180;
|
||
// Far class
|
||
if (Math.abs(percentage) > itemsFit) item.addClass('picker-item-far');
|
||
else item.removeClass('picker-item-far');
|
||
// Set transform
|
||
item.transform('translate3d(0, ' + (-translate + maxTranslate) + 'px, ' + (originBug ? -110 : 0) + 'px) rotateX(' + angle + 'deg)');
|
||
});
|
||
}
|
||
|
||
if (valueCallbacks || typeof valueCallbacks === 'undefined') {
|
||
// Update values
|
||
col.value = selectedItem.attr('data-picker-value');
|
||
col.displayValue = col.displayValues ? col.displayValues[activeIndex] : col.value;
|
||
// On change callback
|
||
if (previousActiveIndex !== activeIndex) {
|
||
if (col.onChange) {
|
||
col.onChange(p, col.value, col.displayValue);
|
||
}
|
||
p.updateValue();
|
||
}
|
||
}
|
||
};
|
||
|
||
function updateDuringScroll() {
|
||
animationFrameId = $.requestAnimationFrame(function () {
|
||
col.updateItems(undefined, undefined, 0);
|
||
updateDuringScroll();
|
||
});
|
||
}
|
||
|
||
// Update items on init
|
||
if (updateItems) col.updateItems(0, maxTranslate, 0);
|
||
|
||
var allowItemClick = true;
|
||
var isTouched, isMoved, touchStartY, touchCurrentY, touchStartTime, touchEndTime, startTranslate, returnTo, currentTranslate, prevTranslate, velocityTranslate, velocityTime;
|
||
function handleTouchStart (e) {
|
||
if (isMoved || isTouched) return;
|
||
e.preventDefault();
|
||
isTouched = true;
|
||
touchStartY = touchCurrentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
|
||
touchStartTime = (new Date()).getTime();
|
||
|
||
allowItemClick = true;
|
||
startTranslate = currentTranslate = $.getTranslate(col.wrapper[0], 'y');
|
||
}
|
||
function handleTouchMove (e) {
|
||
if (!isTouched) return;
|
||
e.preventDefault();
|
||
allowItemClick = false;
|
||
touchCurrentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
if (!isMoved) {
|
||
// First move
|
||
$.cancelAnimationFrame(animationFrameId);
|
||
isMoved = true;
|
||
startTranslate = currentTranslate = $.getTranslate(col.wrapper[0], 'y');
|
||
col.wrapper.transition(0);
|
||
}
|
||
|
||
var diff = touchCurrentY - touchStartY;
|
||
currentTranslate = startTranslate + diff;
|
||
returnTo = undefined;
|
||
|
||
// Normalize translate
|
||
if (currentTranslate < minTranslate) {
|
||
currentTranslate = minTranslate - Math.pow(minTranslate - currentTranslate, 0.8);
|
||
returnTo = 'min';
|
||
}
|
||
if (currentTranslate > maxTranslate) {
|
||
currentTranslate = maxTranslate + Math.pow(currentTranslate - maxTranslate, 0.8);
|
||
returnTo = 'max';
|
||
}
|
||
// Transform wrapper
|
||
col.wrapper.transform('translate3d(0,' + currentTranslate + 'px,0)');
|
||
|
||
// Update items
|
||
col.updateItems(undefined, currentTranslate, 0, p.params.updateValuesOnTouchmove);
|
||
|
||
// Calc velocity
|
||
velocityTranslate = currentTranslate - prevTranslate || currentTranslate;
|
||
velocityTime = (new Date()).getTime();
|
||
prevTranslate = currentTranslate;
|
||
}
|
||
function handleTouchEnd (e) {
|
||
if (!isTouched || !isMoved) {
|
||
isTouched = isMoved = false;
|
||
return;
|
||
}
|
||
isTouched = isMoved = false;
|
||
col.wrapper.transition('');
|
||
if (returnTo) {
|
||
if (returnTo === 'min') {
|
||
col.wrapper.transform('translate3d(0,' + minTranslate + 'px,0)');
|
||
}
|
||
else col.wrapper.transform('translate3d(0,' + maxTranslate + 'px,0)');
|
||
}
|
||
touchEndTime = new Date().getTime();
|
||
var velocity, newTranslate;
|
||
if (touchEndTime - touchStartTime > 300) {
|
||
newTranslate = currentTranslate;
|
||
}
|
||
else {
|
||
velocity = Math.abs(velocityTranslate / (touchEndTime - velocityTime));
|
||
newTranslate = currentTranslate + velocityTranslate * p.params.momentumRatio;
|
||
}
|
||
|
||
newTranslate = Math.max(Math.min(newTranslate, maxTranslate), minTranslate);
|
||
|
||
// Active Index
|
||
var activeIndex = -Math.floor((newTranslate - maxTranslate)/itemHeight);
|
||
|
||
// Normalize translate
|
||
if (!p.params.freeMode) newTranslate = -activeIndex * itemHeight + maxTranslate;
|
||
|
||
// Transform wrapper
|
||
col.wrapper.transform('translate3d(0,' + (parseInt(newTranslate,10)) + 'px,0)');
|
||
|
||
// Update items
|
||
col.updateItems(activeIndex, newTranslate, '', true);
|
||
|
||
// Watch items
|
||
if (p.params.updateValuesOnMomentum) {
|
||
updateDuringScroll();
|
||
col.wrapper.transitionEnd(function(){
|
||
$.cancelAnimationFrame(animationFrameId);
|
||
});
|
||
}
|
||
|
||
// Allow click
|
||
setTimeout(function () {
|
||
allowItemClick = true;
|
||
}, 100);
|
||
}
|
||
|
||
function handleClick(e) {
|
||
if (!allowItemClick) return;
|
||
$.cancelAnimationFrame(animationFrameId);
|
||
/*jshint validthis:true */
|
||
var value = $(this).attr('data-picker-value');
|
||
col.setValue(value);
|
||
}
|
||
|
||
col.initEvents = function (detach) {
|
||
var method = detach ? 'off' : 'on';
|
||
col.container[method](app.touchEvents.start, handleTouchStart);
|
||
col.container[method](app.touchEvents.move, handleTouchMove);
|
||
col.container[method](app.touchEvents.end, handleTouchEnd);
|
||
col.items[method]('click', handleClick);
|
||
};
|
||
col.destroyEvents = function () {
|
||
col.initEvents(true);
|
||
};
|
||
|
||
col.container[0].f7DestroyPickerCol = function () {
|
||
col.destroyEvents();
|
||
};
|
||
|
||
col.initEvents();
|
||
|
||
};
|
||
p.destroyPickerCol = function (colContainer) {
|
||
colContainer = $(colContainer);
|
||
if ('f7DestroyPickerCol' in colContainer[0]) colContainer[0].f7DestroyPickerCol();
|
||
};
|
||
// Resize cols
|
||
function resizeCols() {
|
||
if (!p.opened) return;
|
||
for (var i = 0; i < p.cols.length; i++) {
|
||
if (!p.cols[i].divider) {
|
||
p.cols[i].calcSize();
|
||
p.cols[i].setValue(p.cols[i].value, 0, false);
|
||
}
|
||
}
|
||
}
|
||
$(window).on('resize', resizeCols);
|
||
|
||
// HTML Layout
|
||
p.columnHTML = function (col, onlyItems) {
|
||
var columnItemsHTML = '';
|
||
var columnHTML = '';
|
||
if (col.divider) {
|
||
columnHTML += '<div class="picker-items-col picker-items-col-divider ' + (col.textAlign ? 'picker-items-col-' + col.textAlign : '') + ' ' + (col.cssClass || '') + '">' + col.content + '</div>';
|
||
}
|
||
else {
|
||
for (var j = 0; j < col.values.length; j++) {
|
||
columnItemsHTML += '<div class="picker-item" data-picker-value="' + col.values[j] + '">' + (col.displayValues ? col.displayValues[j] : col.values[j]) + '</div>';
|
||
}
|
||
columnHTML += '<div class="picker-items-col ' + (col.textAlign ? 'picker-items-col-' + col.textAlign : '') + ' ' + (col.cssClass || '') + '"><div class="picker-items-col-wrapper">' + columnItemsHTML + '</div></div>';
|
||
}
|
||
return onlyItems ? columnItemsHTML : columnHTML;
|
||
};
|
||
p.layout = function () {
|
||
var pickerHTML = '';
|
||
var pickerClass = '';
|
||
var i;
|
||
p.cols = [];
|
||
var colsHTML = '';
|
||
for (i = 0; i < p.params.cols.length; i++) {
|
||
var col = p.params.cols[i];
|
||
colsHTML += p.columnHTML(p.params.cols[i]);
|
||
p.cols.push(col);
|
||
}
|
||
pickerClass = 'picker-modal picker-columns ' + (p.params.cssClass || '') + (p.params.rotateEffect ? ' picker-3d' : '');
|
||
pickerHTML =
|
||
'<div class="' + (pickerClass) + '">' +
|
||
(p.params.toolbar ? p.params.toolbarTemplate.replace(/{{closeText}}/g, p.params.toolbarCloseText) : '') +
|
||
'<div class="picker-modal-inner picker-items">' +
|
||
colsHTML +
|
||
'<div class="picker-center-highlight"></div>' +
|
||
'</div>' +
|
||
'</div>';
|
||
|
||
p.pickerHTML = pickerHTML;
|
||
};
|
||
|
||
// Input Events
|
||
function openOnInput(e) {
|
||
e.preventDefault();
|
||
if (p.opened) return;
|
||
p.open();
|
||
if (p.params.scrollToInput && !isPopover()) {
|
||
var pageContent = p.input.parents('.page-content');
|
||
if (pageContent.length === 0) return;
|
||
|
||
var paddingTop = parseInt(pageContent.css('padding-top'), 10),
|
||
paddingBottom = parseInt(pageContent.css('padding-bottom'), 10),
|
||
pageHeight = pageContent[0].offsetHeight - paddingTop - p.container.height(),
|
||
pageScrollHeight = pageContent[0].scrollHeight - paddingTop - p.container.height(),
|
||
newPaddingBottom;
|
||
var inputTop = p.input.offset().top - paddingTop + p.input[0].offsetHeight;
|
||
if (inputTop > pageHeight) {
|
||
var scrollTop = pageContent.scrollTop() + inputTop - pageHeight;
|
||
if (scrollTop + pageHeight > pageScrollHeight) {
|
||
newPaddingBottom = scrollTop + pageHeight - pageScrollHeight + paddingBottom;
|
||
if (pageHeight === pageScrollHeight) {
|
||
newPaddingBottom = p.container.height();
|
||
}
|
||
pageContent.css({'padding-bottom': (newPaddingBottom) + 'px'});
|
||
}
|
||
pageContent.scrollTop(scrollTop, 300);
|
||
}
|
||
}
|
||
}
|
||
function closeOnHTMLClick(e) {
|
||
if (inPopover()) return;
|
||
if (p.input && p.input.length > 0) {
|
||
if (e.target !== p.input[0] && $(e.target).parents('.picker-modal').length === 0) p.close();
|
||
}
|
||
else {
|
||
if ($(e.target).parents('.picker-modal').length === 0) p.close();
|
||
}
|
||
}
|
||
|
||
if (p.params.input) {
|
||
p.input = $(p.params.input);
|
||
if (p.input.length > 0) {
|
||
if (p.params.inputReadOnly) p.input.prop('readOnly', true);
|
||
if (!p.inline) {
|
||
p.input.on('click', openOnInput);
|
||
}
|
||
if (p.params.inputReadOnly) {
|
||
p.input.on('focus mousedown', function (e) {
|
||
e.preventDefault();
|
||
});
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
if (!p.inline && p.params.closeByOutsideClick) $('html').on('click', closeOnHTMLClick);
|
||
|
||
// Open
|
||
function onPickerClose() {
|
||
p.opened = false;
|
||
if (p.input && p.input.length > 0) {
|
||
p.input.parents('.page-content').css({'padding-bottom': ''});
|
||
if (app.params.material) p.input.trigger('blur');
|
||
}
|
||
if (p.params.onClose) p.params.onClose(p);
|
||
|
||
// Destroy events
|
||
p.container.find('.picker-items-col').each(function () {
|
||
p.destroyPickerCol(this);
|
||
});
|
||
}
|
||
|
||
p.opened = false;
|
||
p.open = function () {
|
||
var toPopover = isPopover();
|
||
|
||
if (!p.opened) {
|
||
|
||
// Layout
|
||
p.layout();
|
||
|
||
// Append
|
||
if (toPopover) {
|
||
p.pickerHTML = '<div class="popover popover-picker-columns"><div class="popover-inner">' + p.pickerHTML + '</div></div>';
|
||
p.popover = app.popover(p.pickerHTML, p.params.input, true);
|
||
p.container = $(p.popover).find('.picker-modal');
|
||
$(p.popover).on('close', function () {
|
||
onPickerClose();
|
||
});
|
||
}
|
||
else if (p.inline) {
|
||
p.container = $(p.pickerHTML);
|
||
p.container.addClass('picker-modal-inline');
|
||
$(p.params.container).append(p.container);
|
||
}
|
||
else {
|
||
p.container = $(app.pickerModal(p.pickerHTML));
|
||
$(p.container)
|
||
.on('close', function () {
|
||
onPickerClose();
|
||
});
|
||
}
|
||
|
||
// Store picker instance
|
||
p.container[0].f7Picker = p;
|
||
|
||
// Init Events
|
||
p.container.find('.picker-items-col').each(function () {
|
||
var updateItems = true;
|
||
if ((!p.initialized && p.params.value) || (p.initialized && p.value)) updateItems = false;
|
||
p.initPickerCol(this, updateItems);
|
||
});
|
||
|
||
// Set value
|
||
if (!p.initialized) {
|
||
if (p.value) p.setValue(p.value, 0);
|
||
else if (p.params.value) {
|
||
p.setValue(p.params.value, 0);
|
||
}
|
||
}
|
||
else {
|
||
if (p.value) p.setValue(p.value, 0);
|
||
}
|
||
|
||
// Material Focus
|
||
if (p.input && p.input.length > 0 && app.params.material) {
|
||
p.input.trigger('focus');
|
||
}
|
||
}
|
||
|
||
// Set flag
|
||
p.opened = true;
|
||
p.initialized = true;
|
||
|
||
if (p.params.onOpen) p.params.onOpen(p);
|
||
};
|
||
|
||
// Close
|
||
p.close = function () {
|
||
if (!p.opened || p.inline) return;
|
||
if (inPopover()) {
|
||
app.closeModal(p.popover);
|
||
return;
|
||
}
|
||
else {
|
||
app.closeModal(p.container);
|
||
return;
|
||
}
|
||
};
|
||
|
||
// Destroy
|
||
p.destroy = function () {
|
||
p.close();
|
||
if (p.params.input && p.input.length > 0) {
|
||
p.input.off('click focus', openOnInput);
|
||
}
|
||
$('html').off('click', closeOnHTMLClick);
|
||
$(window).off('resize', resizeCols);
|
||
};
|
||
|
||
if (p.inline) {
|
||
p.open();
|
||
}
|
||
else {
|
||
if (!p.initialized && p.params.value) p.setValue(p.params.value);
|
||
}
|
||
|
||
return p;
|
||
};
|
||
app.picker = function (params) {
|
||
return new Picker(params);
|
||
};
|
||
|
||
/*======================================================
|
||
************ Calendar ************
|
||
======================================================*/
|
||
var Calendar = function (params) {
|
||
var p = this;
|
||
var defaults = {
|
||
monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August' , 'September' , 'October', 'November', 'December'],
|
||
monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||
dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
|
||
dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
||
firstDay: 1, // First day of the week, Monday
|
||
weekendDays: [0, 6], // Sunday and Saturday
|
||
multiple: false,
|
||
rangePicker: false,
|
||
dateFormat: 'yyyy-mm-dd',
|
||
direction: 'horizontal', // or 'vertical'
|
||
minDate: null,
|
||
maxDate: null,
|
||
disabled: null, // dates range of disabled days
|
||
events: null, // dates range of days with events
|
||
rangesClasses: null, //array with custom classes date ranges
|
||
touchMove: true,
|
||
animate: true,
|
||
closeOnSelect: false,
|
||
monthPicker: true,
|
||
monthPickerTemplate:
|
||
'<div class="picker-calendar-month-picker">' +
|
||
'<a href="#" class="link icon-only picker-calendar-prev-month"><i class="icon icon-prev"></i></a>' +
|
||
'<span class="current-month-value"></span>' +
|
||
'<a href="#" class="link icon-only picker-calendar-next-month"><i class="icon icon-next"></i></a>' +
|
||
'</div>',
|
||
yearPicker: true,
|
||
yearPickerTemplate:
|
||
'<div class="picker-calendar-year-picker">' +
|
||
'<a href="#" class="link icon-only picker-calendar-prev-year"><i class="icon icon-prev"></i></a>' +
|
||
'<span class="current-year-value"></span>' +
|
||
'<a href="#" class="link icon-only picker-calendar-next-year"><i class="icon icon-next"></i></a>' +
|
||
'</div>',
|
||
weekHeader: true,
|
||
// Common settings
|
||
closeByOutsideClick: true,
|
||
scrollToInput: true,
|
||
inputReadOnly: true,
|
||
convertToPopover: true,
|
||
onlyInPopover: false,
|
||
toolbar: true,
|
||
toolbarCloseText: 'Done',
|
||
headerPlaceholder: 'Select date',
|
||
header: app.params.material,
|
||
footer: app.params.material,
|
||
toolbarTemplate:
|
||
'<div class="toolbar">' +
|
||
'<div class="toolbar-inner">' +
|
||
'{{monthPicker}}' +
|
||
'{{yearPicker}}' +
|
||
'</div>' +
|
||
'</div>',
|
||
headerTemplate:
|
||
'<div class="picker-header">' +
|
||
'<div class="picker-calendar-selected-date">{{placeholder}}</div>' +
|
||
'</div>',
|
||
footerTemplate:
|
||
'<div class="picker-footer">' +
|
||
'<a href="#" class="button close-picker">{{closeText}}</a>' +
|
||
'</div>',
|
||
|
||
/* Callbacks
|
||
onMonthAdd
|
||
onChange
|
||
onOpen
|
||
onClose
|
||
onDayClick
|
||
onMonthYearChangeStart
|
||
onMonthYearChangeEnd
|
||
*/
|
||
};
|
||
params = params || {};
|
||
for (var def in defaults) {
|
||
if (typeof params[def] === 'undefined') {
|
||
params[def] = defaults[def];
|
||
}
|
||
}
|
||
p.params = params;
|
||
p.initialized = false;
|
||
|
||
// Inline flag
|
||
p.inline = p.params.container ? true : false;
|
||
|
||
// Is horizontal
|
||
p.isH = p.params.direction === 'horizontal';
|
||
|
||
// RTL inverter
|
||
var inverter = p.isH ? (app.rtl ? -1 : 1) : 1;
|
||
|
||
// Animating flag
|
||
p.animating = false;
|
||
|
||
// Should be converted to popover
|
||
function isPopover() {
|
||
var toPopover = false;
|
||
if (!p.params.convertToPopover && !p.params.onlyInPopover) return toPopover;
|
||
if (!p.inline && p.params.input) {
|
||
if (p.params.onlyInPopover) toPopover = true;
|
||
else {
|
||
if (app.device.ios) {
|
||
toPopover = app.device.ipad ? true : false;
|
||
}
|
||
else {
|
||
if ($(window).width() >= 768) toPopover = true;
|
||
}
|
||
}
|
||
}
|
||
return toPopover;
|
||
}
|
||
function inPopover() {
|
||
if (p.opened && p.container && p.container.length > 0 && p.container.parents('.popover').length > 0) return true;
|
||
else return false;
|
||
}
|
||
|
||
// Format date
|
||
function formatDate(date) {
|
||
date = new Date(date);
|
||
var year = date.getFullYear();
|
||
var month = date.getMonth();
|
||
var month1 = month + 1;
|
||
var day = date.getDate();
|
||
var weekDay = date.getDay();
|
||
|
||
return p.params.dateFormat
|
||
.replace(/yyyy/g, year)
|
||
.replace(/yy/g, (year + '').substring(2))
|
||
.replace(/mm/g, month1 < 10 ? '0' + month1 : month1)
|
||
.replace(/m(\W+)/g, month1 + '$1')
|
||
.replace(/MM/g, p.params.monthNames[month])
|
||
.replace(/M(\W+)/g, p.params.monthNamesShort[month] + '$1')
|
||
.replace(/dd/g, day < 10 ? '0' + day : day)
|
||
.replace(/d(\W+)/g, day + '$1')
|
||
.replace(/DD/g, p.params.dayNames[weekDay])
|
||
.replace(/D(\W+)/g, p.params.dayNamesShort[weekDay] + '$1');
|
||
}
|
||
|
||
|
||
// Value
|
||
p.addValue = function (value) {
|
||
if (p.params.multiple) {
|
||
if (!p.value) p.value = [];
|
||
var inValuesIndex;
|
||
for (var i = 0; i < p.value.length; i++) {
|
||
if (new Date(value).getTime() === new Date(p.value[i]).getTime()) {
|
||
inValuesIndex = i;
|
||
}
|
||
}
|
||
if (typeof inValuesIndex === 'undefined') {
|
||
p.value.push(value);
|
||
}
|
||
else {
|
||
p.value.splice(inValuesIndex, 1);
|
||
}
|
||
p.updateValue();
|
||
}
|
||
else if (p.params.rangePicker) {
|
||
if (!p.value) p.value = [];
|
||
if (p.value.length === 2 || p.value.length === 0) {
|
||
p.value = [];
|
||
}
|
||
if (p.value[0] !== value) p.value.push(value);
|
||
else p.value = [];
|
||
p.value.sort(function (a,b) {
|
||
return a - b;
|
||
});
|
||
p.updateValue();
|
||
}
|
||
else {
|
||
p.value = [value];
|
||
p.updateValue();
|
||
}
|
||
};
|
||
p.setValue = function (arrValues) {
|
||
p.value = arrValues;
|
||
p.updateValue();
|
||
};
|
||
p.updateValue = function (onlyHeader) {
|
||
var i, inputValue;
|
||
if (p.container && p.container.length > 0) {
|
||
p.wrapper.find('.picker-calendar-day-selected').removeClass('picker-calendar-day-selected');
|
||
var valueDate;
|
||
if (p.params.rangePicker && p.value.length === 2) {
|
||
for (i = p.value[0]; i <= p.value[1]; i += 24*60*60*1000) {
|
||
valueDate = new Date(i);
|
||
p.wrapper.find('.picker-calendar-day[data-date="' + valueDate.getFullYear() + '-' + valueDate.getMonth() + '-' + valueDate.getDate() + '"]').addClass('picker-calendar-day-selected');
|
||
}
|
||
}
|
||
else {
|
||
for (i = 0; i < p.value.length; i++) {
|
||
valueDate = new Date(p.value[i]);
|
||
p.wrapper.find('.picker-calendar-day[data-date="' + valueDate.getFullYear() + '-' + valueDate.getMonth() + '-' + valueDate.getDate() + '"]').addClass('picker-calendar-day-selected');
|
||
}
|
||
}
|
||
}
|
||
|
||
if (p.params.onChange) {
|
||
p.params.onChange(p, p.value);
|
||
}
|
||
if ((p.input && p.input.length > 0) || (app.params.material && p.params.header)) {
|
||
if (p.params.formatValue) inputValue = p.params.formatValue(p, p.value);
|
||
else {
|
||
inputValue = [];
|
||
for (i = 0; i < p.value.length; i++) {
|
||
inputValue.push(formatDate(p.value[i]));
|
||
}
|
||
inputValue = inputValue.join(p.params.rangePicker ? ' - ' : ', ');
|
||
}
|
||
if (app.params.material && p.params.header && p.container && p.container.length > 0) {
|
||
p.container.find('.picker-calendar-selected-date').text(inputValue);
|
||
}
|
||
if (p.input && p.input.length > 0 && !onlyHeader) {
|
||
$(p.input).val(inputValue);
|
||
$(p.input).trigger('change');
|
||
}
|
||
|
||
}
|
||
};
|
||
|
||
// Columns Handlers
|
||
p.initCalendarEvents = function () {
|
||
var col;
|
||
var allowItemClick = true;
|
||
var isTouched, isMoved, touchStartX, touchStartY, touchCurrentX, touchCurrentY, touchStartTime, touchEndTime, startTranslate, currentTranslate, wrapperWidth, wrapperHeight, percentage, touchesDiff, isScrolling;
|
||
function handleTouchStart (e) {
|
||
if (isMoved || isTouched) return;
|
||
// e.preventDefault();
|
||
isTouched = true;
|
||
touchStartX = touchCurrentY = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
|
||
touchStartY = touchCurrentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
|
||
touchStartTime = (new Date()).getTime();
|
||
percentage = 0;
|
||
allowItemClick = true;
|
||
isScrolling = undefined;
|
||
startTranslate = currentTranslate = p.monthsTranslate;
|
||
}
|
||
function handleTouchMove (e) {
|
||
if (!isTouched) return;
|
||
|
||
touchCurrentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
|
||
touchCurrentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
if (typeof isScrolling === 'undefined') {
|
||
isScrolling = !!(isScrolling || Math.abs(touchCurrentY - touchStartY) > Math.abs(touchCurrentX - touchStartX));
|
||
}
|
||
if (p.isH && isScrolling) {
|
||
isTouched = false;
|
||
return;
|
||
}
|
||
e.preventDefault();
|
||
if (p.animating) {
|
||
isTouched = false;
|
||
return;
|
||
}
|
||
allowItemClick = false;
|
||
if (!isMoved) {
|
||
// First move
|
||
isMoved = true;
|
||
wrapperWidth = p.wrapper[0].offsetWidth;
|
||
wrapperHeight = p.wrapper[0].offsetHeight;
|
||
p.wrapper.transition(0);
|
||
}
|
||
|
||
touchesDiff = p.isH ? touchCurrentX - touchStartX : touchCurrentY - touchStartY;
|
||
percentage = touchesDiff/(p.isH ? wrapperWidth : wrapperHeight);
|
||
currentTranslate = (p.monthsTranslate * inverter + percentage) * 100;
|
||
|
||
// Transform wrapper
|
||
p.wrapper.transform('translate3d(' + (p.isH ? currentTranslate : 0) + '%, ' + (p.isH ? 0 : currentTranslate) + '%, 0)');
|
||
|
||
}
|
||
function handleTouchEnd (e) {
|
||
if (!isTouched || !isMoved) {
|
||
isTouched = isMoved = false;
|
||
return;
|
||
}
|
||
isTouched = isMoved = false;
|
||
|
||
touchEndTime = new Date().getTime();
|
||
if (touchEndTime - touchStartTime < 300) {
|
||
if (Math.abs(touchesDiff) < 10) {
|
||
p.resetMonth();
|
||
}
|
||
else if (touchesDiff >= 10) {
|
||
if (app.rtl) p.nextMonth();
|
||
else p.prevMonth();
|
||
}
|
||
else {
|
||
if (app.rtl) p.prevMonth();
|
||
else p.nextMonth();
|
||
}
|
||
}
|
||
else {
|
||
if (percentage <= -0.5) {
|
||
if (app.rtl) p.prevMonth();
|
||
else p.nextMonth();
|
||
}
|
||
else if (percentage >= 0.5) {
|
||
if (app.rtl) p.nextMonth();
|
||
else p.prevMonth();
|
||
}
|
||
else {
|
||
p.resetMonth();
|
||
}
|
||
}
|
||
|
||
// Allow click
|
||
setTimeout(function () {
|
||
allowItemClick = true;
|
||
}, 100);
|
||
}
|
||
|
||
function handleDayClick(e) {
|
||
if (!allowItemClick) return;
|
||
var day = $(e.target).parents('.picker-calendar-day');
|
||
if (day.length === 0 && $(e.target).hasClass('picker-calendar-day')) {
|
||
day = $(e.target);
|
||
}
|
||
if (day.length === 0) return;
|
||
if (day.hasClass('picker-calendar-day-selected') && !(p.params.multiple || p.params.rangePicker)) return;
|
||
if (day.hasClass('picker-calendar-day-disabled')) return;
|
||
if (!p.params.rangePicker) {
|
||
if (day.hasClass('picker-calendar-day-next')) p.nextMonth();
|
||
if (day.hasClass('picker-calendar-day-prev')) p.prevMonth();
|
||
}
|
||
var dateYear = day.attr('data-year');
|
||
var dateMonth = day.attr('data-month');
|
||
var dateDay = day.attr('data-day');
|
||
if (p.params.onDayClick) {
|
||
p.params.onDayClick(p, day[0], dateYear, dateMonth, dateDay);
|
||
}
|
||
p.addValue(new Date(dateYear, dateMonth, dateDay).getTime());
|
||
if (p.params.closeOnSelect) {
|
||
if (p.params.rangePicker && p.value.length === 2 || !p.params.rangePicker) p.close();
|
||
}
|
||
}
|
||
|
||
p.container.find('.picker-calendar-prev-month').on('click', p.prevMonth);
|
||
p.container.find('.picker-calendar-next-month').on('click', p.nextMonth);
|
||
p.container.find('.picker-calendar-prev-year').on('click', p.prevYear);
|
||
p.container.find('.picker-calendar-next-year').on('click', p.nextYear);
|
||
p.wrapper.on('click', handleDayClick);
|
||
var passiveListener = app.touchEvents.start === 'touchstart' && app.support.passiveListener ? {passive: true, capture: false} : false;
|
||
if (p.params.touchMove) {
|
||
p.wrapper.on(app.touchEvents.start, handleTouchStart, passiveListener);
|
||
p.wrapper.on(app.touchEvents.move, handleTouchMove);
|
||
p.wrapper.on(app.touchEvents.end, handleTouchEnd, passiveListener);
|
||
}
|
||
|
||
p.container[0].f7DestroyCalendarEvents = function () {
|
||
p.container.find('.picker-calendar-prev-month').off('click', p.prevMonth);
|
||
p.container.find('.picker-calendar-next-month').off('click', p.nextMonth);
|
||
p.container.find('.picker-calendar-prev-year').off('click', p.prevYear);
|
||
p.container.find('.picker-calendar-next-year').off('click', p.nextYear);
|
||
p.wrapper.off('click', handleDayClick);
|
||
if (p.params.touchMove) {
|
||
p.wrapper.off(app.touchEvents.start, handleTouchStart, passiveListener);
|
||
p.wrapper.off(app.touchEvents.move, handleTouchMove);
|
||
p.wrapper.off(app.touchEvents.end, handleTouchEnd, passiveListener);
|
||
}
|
||
};
|
||
|
||
|
||
};
|
||
p.destroyCalendarEvents = function (colContainer) {
|
||
if ('f7DestroyCalendarEvents' in p.container[0]) p.container[0].f7DestroyCalendarEvents();
|
||
};
|
||
|
||
// Scan Dates Range
|
||
p.dateInRange = function (dayDate, range) {
|
||
var match = false;
|
||
var i;
|
||
if (!range) return false;
|
||
if ($.isArray(range)) {
|
||
for (i = 0; i < range.length; i ++) {
|
||
if (range[i].from || range[i].to) {
|
||
if (range[i].from && range[i].to) {
|
||
if ((dayDate <= new Date(range[i].to).getTime()) && (dayDate >= new Date(range[i].from).getTime())) {
|
||
match = true;
|
||
}
|
||
}
|
||
else if (range[i].from) {
|
||
if (dayDate >= new Date(range[i].from).getTime()) {
|
||
match = true;
|
||
}
|
||
}
|
||
else if (range[i].to) {
|
||
if (dayDate <= new Date(range[i].to).getTime()) {
|
||
match = true;
|
||
}
|
||
}
|
||
} else if (dayDate === new Date(range[i]).getTime()) {
|
||
match = true;
|
||
}
|
||
}
|
||
}
|
||
else if (range.from || range.to) {
|
||
if (range.from && range.to) {
|
||
if ((dayDate <= new Date(range.to).getTime()) && (dayDate >= new Date(range.from).getTime())) {
|
||
match = true;
|
||
}
|
||
}
|
||
else if (range.from) {
|
||
if (dayDate >= new Date(range.from).getTime()) {
|
||
match = true;
|
||
}
|
||
}
|
||
else if (range.to) {
|
||
if (dayDate <= new Date(range.to).getTime()) {
|
||
match = true;
|
||
}
|
||
}
|
||
}
|
||
else if (typeof range === 'function') {
|
||
match = range(new Date(dayDate));
|
||
}
|
||
return match;
|
||
};
|
||
// Calendar Methods
|
||
p.daysInMonth = function (date) {
|
||
var d = new Date(date);
|
||
return new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
|
||
};
|
||
p.monthHTML = function (date, offset) {
|
||
date = new Date(date);
|
||
var year = date.getFullYear(),
|
||
month = date.getMonth(),
|
||
day = date.getDate();
|
||
if (offset === 'next') {
|
||
if (month === 11) date = new Date(year + 1, 0);
|
||
else date = new Date(year, month + 1, 1);
|
||
}
|
||
if (offset === 'prev') {
|
||
if (month === 0) date = new Date(year - 1, 11);
|
||
else date = new Date(year, month - 1, 1);
|
||
}
|
||
if (offset === 'next' || offset === 'prev') {
|
||
month = date.getMonth();
|
||
year = date.getFullYear();
|
||
}
|
||
var daysInPrevMonth = p.daysInMonth(new Date(date.getFullYear(), date.getMonth()).getTime() - 10 * 24 * 60 * 60 * 1000),
|
||
daysInMonth = p.daysInMonth(date),
|
||
firstDayOfMonthIndex = new Date(date.getFullYear(), date.getMonth()).getDay();
|
||
if (firstDayOfMonthIndex === 0) firstDayOfMonthIndex = 7;
|
||
|
||
var dayDate, currentValues = [], i, j, k,
|
||
rows = 6, cols = 7,
|
||
monthHTML = '',
|
||
dayIndex = 0 + (p.params.firstDay - 1),
|
||
today = new Date().setHours(0,0,0,0),
|
||
minDate = p.params.minDate ? new Date(p.params.minDate).getTime() : null,
|
||
maxDate = p.params.maxDate ? new Date(p.params.maxDate).getTime() : null,
|
||
disabled,
|
||
hasEvent;
|
||
|
||
if (p.value && p.value.length) {
|
||
for (i = 0; i < p.value.length; i++) {
|
||
currentValues.push(new Date(p.value[i]).setHours(0,0,0,0));
|
||
}
|
||
}
|
||
|
||
for (i = 1; i <= rows; i++) {
|
||
var rowHTML = '';
|
||
var row = i;
|
||
for (j = 1; j <= cols; j++) {
|
||
var col = j;
|
||
dayIndex ++;
|
||
var dayNumber = dayIndex - firstDayOfMonthIndex;
|
||
var weekDayIndex = (col - 1 + p.params.firstDay > 6) ? (col - 1 - 7 + p.params.firstDay) : (col - 1 + p.params.firstDay);
|
||
var addClass = '';
|
||
if (dayNumber < 0) {
|
||
dayNumber = daysInPrevMonth + dayNumber + 1;
|
||
addClass += ' picker-calendar-day-prev';
|
||
dayDate = new Date(month - 1 < 0 ? year - 1 : year, month - 1 < 0 ? 11 : month - 1, dayNumber).getTime();
|
||
}
|
||
else {
|
||
dayNumber = dayNumber + 1;
|
||
if (dayNumber > daysInMonth) {
|
||
dayNumber = dayNumber - daysInMonth;
|
||
addClass += ' picker-calendar-day-next';
|
||
dayDate = new Date(month + 1 > 11 ? year + 1 : year, month + 1 > 11 ? 0 : month + 1, dayNumber).getTime();
|
||
}
|
||
else {
|
||
dayDate = new Date(year, month, dayNumber).getTime();
|
||
}
|
||
}
|
||
// Today
|
||
if (dayDate === today) addClass += ' picker-calendar-day-today';
|
||
// Selected
|
||
if (p.params.rangePicker && currentValues.length === 2) {
|
||
if (dayDate >= currentValues[0] && dayDate <= currentValues[1]) addClass += ' picker-calendar-day-selected';
|
||
}
|
||
else {
|
||
if (currentValues.indexOf(dayDate) >= 0) addClass += ' picker-calendar-day-selected';
|
||
}
|
||
// Weekend
|
||
if (p.params.weekendDays.indexOf(weekDayIndex) >= 0) {
|
||
addClass += ' picker-calendar-day-weekend';
|
||
}
|
||
// Has Events
|
||
hasEvent = false;
|
||
if (p.params.events) {
|
||
if (p.dateInRange(dayDate, p.params.events)) {
|
||
hasEvent = true;
|
||
}
|
||
}
|
||
if (hasEvent) {
|
||
addClass += ' picker-calendar-day-has-events';
|
||
}
|
||
// Custom Ranges
|
||
if (p.params.rangesClasses) {
|
||
for (k = 0; k < p.params.rangesClasses.length; k++) {
|
||
if (p.dateInRange(dayDate, p.params.rangesClasses[k].range)) {
|
||
addClass += ' ' + p.params.rangesClasses[k].cssClass;
|
||
}
|
||
}
|
||
}
|
||
// Disabled
|
||
disabled = false;
|
||
if ((minDate && dayDate < minDate) || (maxDate && dayDate > maxDate)) {
|
||
disabled = true;
|
||
}
|
||
if (p.params.disabled) {
|
||
if (p.dateInRange(dayDate, p.params.disabled)) {
|
||
disabled = true;
|
||
}
|
||
}
|
||
if (disabled) {
|
||
addClass += ' picker-calendar-day-disabled';
|
||
}
|
||
|
||
|
||
dayDate = new Date(dayDate);
|
||
var dayYear = dayDate.getFullYear();
|
||
var dayMonth = dayDate.getMonth();
|
||
rowHTML += '<div data-year="' + dayYear + '" data-month="' + dayMonth + '" data-day="' + dayNumber + '" class="picker-calendar-day' + (addClass) + '" data-date="' + (dayYear + '-' + dayMonth + '-' + dayNumber) + '"><span>'+dayNumber+'</span></div>';
|
||
}
|
||
monthHTML += '<div class="picker-calendar-row">' + rowHTML + '</div>';
|
||
}
|
||
monthHTML = '<div class="picker-calendar-month" data-year="' + year + '" data-month="' + month + '">' + monthHTML + '</div>';
|
||
return monthHTML;
|
||
};
|
||
p.animating = false;
|
||
p.updateCurrentMonthYear = function (dir) {
|
||
if (typeof dir === 'undefined') {
|
||
p.currentMonth = parseInt(p.months.eq(1).attr('data-month'), 10);
|
||
p.currentYear = parseInt(p.months.eq(1).attr('data-year'), 10);
|
||
}
|
||
else {
|
||
p.currentMonth = parseInt(p.months.eq(dir === 'next' ? (p.months.length - 1) : 0).attr('data-month'), 10);
|
||
p.currentYear = parseInt(p.months.eq(dir === 'next' ? (p.months.length - 1) : 0).attr('data-year'), 10);
|
||
}
|
||
p.container.find('.current-month-value').text(p.params.monthNames[p.currentMonth]);
|
||
p.container.find('.current-year-value').text(p.currentYear);
|
||
|
||
};
|
||
p.onMonthChangeStart = function (dir) {
|
||
p.updateCurrentMonthYear(dir);
|
||
p.months.removeClass('picker-calendar-month-current picker-calendar-month-prev picker-calendar-month-next');
|
||
var currentIndex = dir === 'next' ? p.months.length - 1 : 0;
|
||
|
||
p.months.eq(currentIndex).addClass('picker-calendar-month-current');
|
||
p.months.eq(dir === 'next' ? currentIndex - 1 : currentIndex + 1).addClass(dir === 'next' ? 'picker-calendar-month-prev' : 'picker-calendar-month-next');
|
||
|
||
if (p.params.onMonthYearChangeStart) {
|
||
p.params.onMonthYearChangeStart(p, p.currentYear, p.currentMonth);
|
||
}
|
||
};
|
||
p.onMonthChangeEnd = function (dir, rebuildBoth) {
|
||
p.animating = false;
|
||
var nextMonthHTML, prevMonthHTML, newMonthHTML;
|
||
p.wrapper.find('.picker-calendar-month:not(.picker-calendar-month-prev):not(.picker-calendar-month-current):not(.picker-calendar-month-next)').remove();
|
||
|
||
if (typeof dir === 'undefined') {
|
||
dir = 'next';
|
||
rebuildBoth = true;
|
||
}
|
||
if (!rebuildBoth) {
|
||
newMonthHTML = p.monthHTML(new Date(p.currentYear, p.currentMonth), dir);
|
||
}
|
||
else {
|
||
p.wrapper.find('.picker-calendar-month-next, .picker-calendar-month-prev').remove();
|
||
prevMonthHTML = p.monthHTML(new Date(p.currentYear, p.currentMonth), 'prev');
|
||
nextMonthHTML = p.monthHTML(new Date(p.currentYear, p.currentMonth), 'next');
|
||
}
|
||
if (dir === 'next' || rebuildBoth) {
|
||
p.wrapper.append(newMonthHTML || nextMonthHTML);
|
||
}
|
||
if (dir === 'prev' || rebuildBoth) {
|
||
p.wrapper.prepend(newMonthHTML || prevMonthHTML);
|
||
}
|
||
p.months = p.wrapper.find('.picker-calendar-month');
|
||
p.setMonthsTranslate(p.monthsTranslate);
|
||
if (p.params.onMonthAdd) {
|
||
p.params.onMonthAdd(p, dir === 'next' ? p.months.eq(p.months.length - 1)[0] : p.months.eq(0)[0]);
|
||
}
|
||
if (p.params.onMonthYearChangeEnd) {
|
||
p.params.onMonthYearChangeEnd(p, p.currentYear, p.currentMonth);
|
||
}
|
||
};
|
||
p.setMonthsTranslate = function (translate) {
|
||
translate = translate || p.monthsTranslate || 0;
|
||
if (typeof p.monthsTranslate === 'undefined') p.monthsTranslate = translate;
|
||
p.months.removeClass('picker-calendar-month-current picker-calendar-month-prev picker-calendar-month-next');
|
||
var prevMonthTranslate = -(translate + 1) * 100 * inverter;
|
||
var currentMonthTranslate = -translate * 100 * inverter;
|
||
var nextMonthTranslate = -(translate - 1) * 100 * inverter;
|
||
p.months.eq(0).transform('translate3d(' + (p.isH ? prevMonthTranslate : 0) + '%, ' + (p.isH ? 0 : prevMonthTranslate) + '%, 0)').addClass('picker-calendar-month-prev');
|
||
p.months.eq(1).transform('translate3d(' + (p.isH ? currentMonthTranslate : 0) + '%, ' + (p.isH ? 0 : currentMonthTranslate) + '%, 0)').addClass('picker-calendar-month-current');
|
||
p.months.eq(2).transform('translate3d(' + (p.isH ? nextMonthTranslate : 0) + '%, ' + (p.isH ? 0 : nextMonthTranslate) + '%, 0)').addClass('picker-calendar-month-next');
|
||
};
|
||
p.nextMonth = function (transition) {
|
||
if (typeof transition === 'undefined' || typeof transition === 'object') {
|
||
transition = '';
|
||
if (!p.params.animate) transition = 0;
|
||
}
|
||
var nextMonth = parseInt(p.months.eq(p.months.length - 1).attr('data-month'), 10);
|
||
var nextYear = parseInt(p.months.eq(p.months.length - 1).attr('data-year'), 10);
|
||
var nextDate = new Date(nextYear, nextMonth);
|
||
var nextDateTime = nextDate.getTime();
|
||
var transitionEndCallback = p.animating ? false : true;
|
||
if (p.params.maxDate) {
|
||
if (nextDateTime > new Date(p.params.maxDate).getTime()) {
|
||
return p.resetMonth();
|
||
}
|
||
}
|
||
p.monthsTranslate --;
|
||
if (nextMonth === p.currentMonth) {
|
||
var nextMonthTranslate = -(p.monthsTranslate) * 100 * inverter;
|
||
var nextMonthHTML = $(p.monthHTML(nextDateTime, 'next')).transform('translate3d(' + (p.isH ? nextMonthTranslate : 0) + '%, ' + (p.isH ? 0 : nextMonthTranslate) + '%, 0)').addClass('picker-calendar-month-next');
|
||
p.wrapper.append(nextMonthHTML[0]);
|
||
p.months = p.wrapper.find('.picker-calendar-month');
|
||
if (p.params.onMonthAdd) {
|
||
p.params.onMonthAdd(p, p.months.eq(p.months.length - 1)[0]);
|
||
}
|
||
}
|
||
p.animating = true;
|
||
p.onMonthChangeStart('next');
|
||
var translate = (p.monthsTranslate * 100) * inverter;
|
||
|
||
p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? translate : 0) + '%, ' + (p.isH ? 0 : translate) + '%, 0)');
|
||
if (transitionEndCallback) {
|
||
p.wrapper.transitionEnd(function () {
|
||
p.onMonthChangeEnd('next');
|
||
});
|
||
}
|
||
if (!p.params.animate) {
|
||
p.onMonthChangeEnd('next');
|
||
}
|
||
};
|
||
p.prevMonth = function (transition) {
|
||
if (typeof transition === 'undefined' || typeof transition === 'object') {
|
||
transition = '';
|
||
if (!p.params.animate) transition = 0;
|
||
}
|
||
var prevMonth = parseInt(p.months.eq(0).attr('data-month'), 10);
|
||
var prevYear = parseInt(p.months.eq(0).attr('data-year'), 10);
|
||
var prevDate = new Date(prevYear, prevMonth + 1, -1);
|
||
var prevDateTime = prevDate.getTime();
|
||
var transitionEndCallback = p.animating ? false : true;
|
||
if (p.params.minDate) {
|
||
if (prevDateTime < new Date(p.params.minDate).getTime()) {
|
||
return p.resetMonth();
|
||
}
|
||
}
|
||
p.monthsTranslate ++;
|
||
if (prevMonth === p.currentMonth) {
|
||
var prevMonthTranslate = -(p.monthsTranslate) * 100 * inverter;
|
||
var prevMonthHTML = $(p.monthHTML(prevDateTime, 'prev')).transform('translate3d(' + (p.isH ? prevMonthTranslate : 0) + '%, ' + (p.isH ? 0 : prevMonthTranslate) + '%, 0)').addClass('picker-calendar-month-prev');
|
||
p.wrapper.prepend(prevMonthHTML[0]);
|
||
p.months = p.wrapper.find('.picker-calendar-month');
|
||
if (p.params.onMonthAdd) {
|
||
p.params.onMonthAdd(p, p.months.eq(0)[0]);
|
||
}
|
||
}
|
||
p.animating = true;
|
||
p.onMonthChangeStart('prev');
|
||
var translate = (p.monthsTranslate * 100) * inverter;
|
||
p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? translate : 0) + '%, ' + (p.isH ? 0 : translate) + '%, 0)');
|
||
if (transitionEndCallback) {
|
||
p.wrapper.transitionEnd(function () {
|
||
p.onMonthChangeEnd('prev');
|
||
});
|
||
}
|
||
if (!p.params.animate) {
|
||
p.onMonthChangeEnd('prev');
|
||
}
|
||
};
|
||
p.resetMonth = function (transition) {
|
||
if (typeof transition === 'undefined') transition = '';
|
||
var translate = (p.monthsTranslate * 100) * inverter;
|
||
p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? translate : 0) + '%, ' + (p.isH ? 0 : translate) + '%, 0)');
|
||
};
|
||
p.setYearMonth = function (year, month, transition) {
|
||
if (typeof year === 'undefined') year = p.currentYear;
|
||
if (typeof month === 'undefined') month = p.currentMonth;
|
||
if (typeof transition === 'undefined' || typeof transition === 'object') {
|
||
transition = '';
|
||
if (!p.params.animate) transition = 0;
|
||
}
|
||
var targetDate;
|
||
if (year < p.currentYear) {
|
||
targetDate = new Date(year, month + 1, -1).getTime();
|
||
}
|
||
else {
|
||
targetDate = new Date(year, month).getTime();
|
||
}
|
||
if (p.params.maxDate && targetDate > new Date(p.params.maxDate).getTime()) {
|
||
return false;
|
||
}
|
||
if (p.params.minDate && targetDate < new Date(p.params.minDate).getTime()) {
|
||
return false;
|
||
}
|
||
var currentDate = new Date(p.currentYear, p.currentMonth).getTime();
|
||
var dir = targetDate > currentDate ? 'next' : 'prev';
|
||
var newMonthHTML = p.monthHTML(new Date(year, month));
|
||
p.monthsTranslate = p.monthsTranslate || 0;
|
||
var prevTranslate = p.monthsTranslate;
|
||
var monthTranslate, wrapperTranslate;
|
||
var transitionEndCallback = p.animating ? false : true;
|
||
if (targetDate > currentDate) {
|
||
// To next
|
||
p.monthsTranslate --;
|
||
if (!p.animating) p.months.eq(p.months.length - 1).remove();
|
||
p.wrapper.append(newMonthHTML);
|
||
p.months = p.wrapper.find('.picker-calendar-month');
|
||
monthTranslate = -(prevTranslate - 1) * 100 * inverter;
|
||
p.months.eq(p.months.length - 1).transform('translate3d(' + (p.isH ? monthTranslate : 0) + '%, ' + (p.isH ? 0 : monthTranslate) + '%, 0)').addClass('picker-calendar-month-next');
|
||
}
|
||
else {
|
||
// To prev
|
||
p.monthsTranslate ++;
|
||
if (!p.animating) p.months.eq(0).remove();
|
||
p.wrapper.prepend(newMonthHTML);
|
||
p.months = p.wrapper.find('.picker-calendar-month');
|
||
monthTranslate = -(prevTranslate + 1) * 100 * inverter;
|
||
p.months.eq(0).transform('translate3d(' + (p.isH ? monthTranslate : 0) + '%, ' + (p.isH ? 0 : monthTranslate) + '%, 0)').addClass('picker-calendar-month-prev');
|
||
}
|
||
if (p.params.onMonthAdd) {
|
||
p.params.onMonthAdd(p, dir === 'next' ? p.months.eq(p.months.length - 1)[0] : p.months.eq(0)[0]);
|
||
}
|
||
p.animating = true;
|
||
p.onMonthChangeStart(dir);
|
||
wrapperTranslate = (p.monthsTranslate * 100) * inverter;
|
||
p.wrapper.transition(transition).transform('translate3d(' + (p.isH ? wrapperTranslate : 0) + '%, ' + (p.isH ? 0 : wrapperTranslate) + '%, 0)');
|
||
if (transitionEndCallback) {
|
||
p.wrapper.transitionEnd(function () {
|
||
p.onMonthChangeEnd(dir, true);
|
||
});
|
||
}
|
||
if (!p.params.animate) {
|
||
p.onMonthChangeEnd(dir);
|
||
}
|
||
};
|
||
p.nextYear = function () {
|
||
p.setYearMonth(p.currentYear + 1);
|
||
};
|
||
p.prevYear = function () {
|
||
p.setYearMonth(p.currentYear - 1);
|
||
};
|
||
|
||
|
||
// HTML Layout
|
||
p.layout = function () {
|
||
var pickerHTML = '';
|
||
var pickerClass = '';
|
||
var i;
|
||
|
||
var layoutDate = p.value && p.value.length ? p.value[0] : new Date().setHours(0,0,0,0);
|
||
var prevMonthHTML = p.monthHTML(layoutDate, 'prev');
|
||
var currentMonthHTML = p.monthHTML(layoutDate);
|
||
var nextMonthHTML = p.monthHTML(layoutDate, 'next');
|
||
var monthsHTML = '<div class="picker-calendar-months"><div class="picker-calendar-months-wrapper">' + (prevMonthHTML + currentMonthHTML + nextMonthHTML) + '</div></div>';
|
||
// Week days header
|
||
var weekHeaderHTML = '';
|
||
if (p.params.weekHeader) {
|
||
for (i = 0; i < 7; i++) {
|
||
var weekDayIndex = (i + p.params.firstDay > 6) ? (i - 7 + p.params.firstDay) : (i + p.params.firstDay);
|
||
var dayName = p.params.dayNamesShort[weekDayIndex];
|
||
weekHeaderHTML += '<div class="picker-calendar-week-day ' + ((p.params.weekendDays.indexOf(weekDayIndex) >= 0) ? 'picker-calendar-week-day-weekend' : '') + '"> ' + dayName + '</div>';
|
||
|
||
}
|
||
weekHeaderHTML = '<div class="picker-calendar-week-days">' + weekHeaderHTML + '</div>';
|
||
}
|
||
pickerClass = 'picker-modal picker-calendar' +
|
||
(p.params.rangePicker ? ' picker-calendar-range' : '') +
|
||
(p.params.cssClass ? ' ' + p.params.cssClass : '');
|
||
var toolbarHTML = p.params.toolbar ? p.params.toolbarTemplate.replace(/{{closeText}}/g, p.params.toolbarCloseText) : '';
|
||
if (p.params.toolbar) {
|
||
toolbarHTML = p.params.toolbarTemplate
|
||
.replace(/{{closeText}}/g, p.params.toolbarCloseText)
|
||
.replace(/{{monthPicker}}/g, (p.params.monthPicker ? p.params.monthPickerTemplate : ''))
|
||
.replace(/{{yearPicker}}/g, (p.params.yearPicker ? p.params.yearPickerTemplate : ''));
|
||
}
|
||
var headerHTML = p.params.header ? p.params.headerTemplate.replace(/{{closeText}}/g, p.params.toolbarCloseText).replace(/{{placeholder}}/g, p.params.headerPlaceholder) : '';
|
||
var footerHTML = p.params.footer ? p.params.footerTemplate.replace(/{{closeText}}/g, p.params.toolbarCloseText) : '';
|
||
|
||
pickerHTML =
|
||
'<div class="' + (pickerClass) + '">' +
|
||
headerHTML +
|
||
footerHTML +
|
||
toolbarHTML +
|
||
'<div class="picker-modal-inner">' +
|
||
weekHeaderHTML +
|
||
monthsHTML +
|
||
'</div>' +
|
||
'</div>';
|
||
|
||
|
||
p.pickerHTML = pickerHTML;
|
||
};
|
||
|
||
// Input Events
|
||
function openOnInput(e) {
|
||
e.preventDefault();
|
||
if (p.opened) return;
|
||
p.open();
|
||
if (p.params.scrollToInput && !isPopover() && !app.params.material) {
|
||
var pageContent = p.input.parents('.page-content');
|
||
if (pageContent.length === 0) return;
|
||
|
||
var paddingTop = parseInt(pageContent.css('padding-top'), 10),
|
||
paddingBottom = parseInt(pageContent.css('padding-bottom'), 10),
|
||
pageHeight = pageContent[0].offsetHeight - paddingTop - p.container.height(),
|
||
pageScrollHeight = pageContent[0].scrollHeight - paddingTop - p.container.height(),
|
||
newPaddingBottom;
|
||
|
||
var inputTop = p.input.offset().top - paddingTop + p.input[0].offsetHeight;
|
||
if (inputTop > pageHeight) {
|
||
var scrollTop = pageContent.scrollTop() + inputTop - pageHeight;
|
||
if (scrollTop + pageHeight > pageScrollHeight) {
|
||
newPaddingBottom = scrollTop + pageHeight - pageScrollHeight + paddingBottom;
|
||
if (pageHeight === pageScrollHeight) {
|
||
newPaddingBottom = p.container.height();
|
||
}
|
||
pageContent.css({'padding-bottom': (newPaddingBottom) + 'px'});
|
||
}
|
||
pageContent.scrollTop(scrollTop, 300);
|
||
}
|
||
}
|
||
}
|
||
function closeOnHTMLClick(e) {
|
||
if (inPopover()) return;
|
||
if (p.input && p.input.length > 0) {
|
||
if (e.target !== p.input[0] && $(e.target).parents('.picker-modal').length === 0) p.close();
|
||
}
|
||
else {
|
||
if ($(e.target).parents('.picker-modal').length === 0) p.close();
|
||
}
|
||
}
|
||
|
||
if (p.params.input) {
|
||
p.input = $(p.params.input);
|
||
if (p.input.length > 0) {
|
||
if (p.params.inputReadOnly) p.input.prop('readOnly', true);
|
||
if (!p.inline) {
|
||
p.input.on('click', openOnInput);
|
||
}
|
||
if (p.params.inputReadOnly) {
|
||
p.input.on('focus mousedown', function (e) {
|
||
e.preventDefault();
|
||
});
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
if (!p.inline && p.params.closeByOutsideClick) $('html').on('click', closeOnHTMLClick);
|
||
|
||
// Open
|
||
function onPickerClose() {
|
||
p.opened = false;
|
||
if (p.input && p.input.length > 0) {
|
||
p.input.parents('.page-content').css({'padding-bottom': ''});
|
||
if (app.params.material) p.input.trigger('blur');
|
||
}
|
||
if (p.params.onClose) p.params.onClose(p);
|
||
|
||
// Destroy events
|
||
p.destroyCalendarEvents();
|
||
}
|
||
|
||
p.opened = false;
|
||
p.open = function () {
|
||
var toPopover = isPopover();
|
||
var updateValue = false;
|
||
if (!p.opened) {
|
||
// Set date value
|
||
if (!p.value) {
|
||
if (p.params.value) {
|
||
p.value = p.params.value;
|
||
updateValue = true;
|
||
}
|
||
}
|
||
|
||
// Layout
|
||
p.layout();
|
||
|
||
// Append
|
||
if (toPopover) {
|
||
p.pickerHTML = '<div class="popover popover-picker-calendar"><div class="popover-inner">' + p.pickerHTML + '</div></div>';
|
||
p.popover = app.popover(p.pickerHTML, p.params.input, true);
|
||
p.container = $(p.popover).find('.picker-modal');
|
||
$(p.popover).on('close', function () {
|
||
onPickerClose();
|
||
});
|
||
}
|
||
else if (p.inline) {
|
||
p.container = $(p.pickerHTML);
|
||
p.container.addClass('picker-modal-inline');
|
||
$(p.params.container).append(p.container);
|
||
}
|
||
else {
|
||
p.container = $(app.pickerModal(p.pickerHTML));
|
||
$(p.container)
|
||
.on('close', function () {
|
||
onPickerClose();
|
||
});
|
||
}
|
||
|
||
// Store calendar instance
|
||
p.container[0].f7Calendar = p;
|
||
p.wrapper = p.container.find('.picker-calendar-months-wrapper');
|
||
|
||
// Months
|
||
p.months = p.wrapper.find('.picker-calendar-month');
|
||
|
||
// Update current month and year
|
||
p.updateCurrentMonthYear();
|
||
|
||
// Set initial translate
|
||
p.monthsTranslate = 0;
|
||
p.setMonthsTranslate();
|
||
|
||
// Init events
|
||
p.initCalendarEvents();
|
||
|
||
// Update input value
|
||
if (updateValue) p.updateValue();
|
||
else if (app.params.material && p.value) p.updateValue(true);
|
||
|
||
// Material Focus
|
||
if (p.input && p.input.length > 0 && app.params.material) {
|
||
p.input.trigger('focus');
|
||
}
|
||
|
||
}
|
||
|
||
// Set flag
|
||
p.opened = true;
|
||
p.initialized = true;
|
||
if (p.params.onMonthAdd) {
|
||
p.months.each(function () {
|
||
p.params.onMonthAdd(p, this);
|
||
});
|
||
}
|
||
if (p.params.onOpen) p.params.onOpen(p);
|
||
};
|
||
|
||
// Close
|
||
p.close = function () {
|
||
if (!p.opened || p.inline) return;
|
||
if (inPopover()) {
|
||
app.closeModal(p.popover);
|
||
return;
|
||
}
|
||
else {
|
||
app.closeModal(p.container);
|
||
return;
|
||
}
|
||
};
|
||
|
||
// Destroy
|
||
p.destroy = function () {
|
||
p.close();
|
||
if (p.params.input && p.input.length > 0) {
|
||
p.input.off('click focus', openOnInput);
|
||
}
|
||
$('html').off('click', closeOnHTMLClick);
|
||
};
|
||
|
||
if (p.inline) {
|
||
p.open();
|
||
}
|
||
else {
|
||
if (!p.initialized && p.params.value) p.setValue(p.params.value);
|
||
}
|
||
|
||
return p;
|
||
};
|
||
app.calendar = function (params) {
|
||
return new Calendar(params);
|
||
};
|
||
|
||
|
||
/*======================================================
|
||
************ Notifications ************
|
||
======================================================*/
|
||
var _tempNotificationElement;
|
||
app.addNotification = function (params) {
|
||
if (!params) return;
|
||
|
||
if (typeof params.media === 'undefined') params.media = app.params.notificationMedia;
|
||
if (typeof params.title === 'undefined') params.title = app.params.notificationTitle;
|
||
if (typeof params.subtitle === 'undefined') params.subtitle = app.params.notificationSubtitle;
|
||
if (typeof params.closeIcon === 'undefined') params.closeIcon = app.params.notificationCloseIcon;
|
||
if (typeof params.hold === 'undefined') params.hold = app.params.notificationHold;
|
||
if (typeof params.closeOnClick === 'undefined') params.closeOnClick = app.params.notificationCloseOnClick;
|
||
if (typeof params.button === 'undefined') params.button = app.params.notificationCloseButtonText && {
|
||
text: app.params.notificationCloseButtonText,
|
||
close: true
|
||
};
|
||
|
||
if (!_tempNotificationElement) _tempNotificationElement = document.createElement('div');
|
||
|
||
params.material = app.params.material;
|
||
|
||
var container = $('.notifications');
|
||
if (container.length === 0) {
|
||
app.root.append('<div class="notifications list-block' + (params.material ? '' : ' media-list') + '"><ul></ul></div>');
|
||
container = $('.notifications');
|
||
}
|
||
var list = container.children('ul');
|
||
|
||
var notificationTemplate = app.params.notificationTemplate ||
|
||
'{{#if custom}}' +
|
||
'<li>{{custom}}</li>' +
|
||
'{{else}}' +
|
||
'<li class="notification-item notification-hidden">' +
|
||
'<div class="item-content">' +
|
||
'{{#if material}}' +
|
||
'<div class="item-inner">' +
|
||
'<div class="item-title">{{js "this.message || this.title || this.subtitle"}}</div>' +
|
||
'{{#if ../button}}{{#button}}' +
|
||
'<div class="item-after">' +
|
||
'<a href="#" class="button {{#if color}}color-{{color}}{{/if}} {{#js_compare "this.close !== false"}}close-notification{{/js_compare}}">{{text}}</a>' +
|
||
'</div>' +
|
||
'{{/button}}{{/if}}' +
|
||
'</div>' +
|
||
'{{else}}' +
|
||
'{{#if media}}' +
|
||
'<div class="item-media">{{media}}</div>' +
|
||
'{{/if}}' +
|
||
'<div class="item-inner">' +
|
||
'<div class="item-title-row">' +
|
||
'{{#if title}}' +
|
||
'<div class="item-title">{{title}}</div>' +
|
||
'{{/if}}' +
|
||
'{{#if closeIcon}}' +
|
||
'<div class="item-after"><a href="#" class="close-notification"><span></span></a></div>' +
|
||
'{{/if}}' +
|
||
'</div>' +
|
||
'{{#if subtitle}}' +
|
||
'<div class="item-subtitle">{{subtitle}}</div>' +
|
||
'{{/if}}' +
|
||
'{{#if message}}' +
|
||
'<div class="item-text">{{message}}</div>' +
|
||
'</div>' +
|
||
'{{/if}}' +
|
||
'{{/if}}' +
|
||
'</div>' +
|
||
'</li>' +
|
||
'{{/if}}';
|
||
if (!app._compiledTemplates.notification) {
|
||
app._compiledTemplates.notification = t7.compile(notificationTemplate);
|
||
}
|
||
_tempNotificationElement.innerHTML = app._compiledTemplates.notification(params);
|
||
|
||
var item = $(_tempNotificationElement).children();
|
||
|
||
item.on('click', function (e) {
|
||
var close = false;
|
||
var target = $(e.target);
|
||
if (params.material && target.hasClass('button')) {
|
||
if (params.button && params.button.onClick) params.button.onClick.call(target[0], e, item[0]);
|
||
}
|
||
if (target.is('.close-notification') || $(e.target).parents('.close-notification').length > 0) {
|
||
close = true;
|
||
}
|
||
else {
|
||
if (params.onClick) params.onClick(e, item[0]);
|
||
if (params.closeOnClick) close = true;
|
||
}
|
||
if (close) app.closeNotification(item[0]);
|
||
});
|
||
if (params.onClose) {
|
||
item.data('f7NotificationOnClose', function () {
|
||
params.onClose(item[0]);
|
||
});
|
||
}
|
||
if (params.additionalClass) {
|
||
item.addClass(params.additionalClass);
|
||
}
|
||
if (params.hold) {
|
||
setTimeout(function () {
|
||
if (item.length > 0) app.closeNotification(item[0]);
|
||
}, params.hold);
|
||
}
|
||
|
||
if (!app.params.material) {
|
||
app.closeNotification(list.children('li.notification-item:last-child'));
|
||
}
|
||
list.append(item[0]);
|
||
container.show();
|
||
|
||
var itemHeight = item.outerHeight(), clientLeft;
|
||
if (params.material) {
|
||
container.transform('translate3d(0, '+itemHeight+'px, 0)');
|
||
container.transition(0);
|
||
|
||
clientLeft = item[0].clientLeft;
|
||
|
||
container.transform('translate3d(0, 0, 0)');
|
||
container.transition('');
|
||
}
|
||
else {
|
||
item.transform('translate3d(0,' + (-itemHeight) + 'px,0)');
|
||
item.transition(0);
|
||
|
||
clientLeft = item[0].clientLeft;
|
||
|
||
item.transition('');
|
||
item.transform('translate3d(0,0px,0)');
|
||
}
|
||
|
||
container.transform('translate3d(0, 0,0)');
|
||
item.removeClass('notification-hidden');
|
||
|
||
return item[0];
|
||
};
|
||
app.closeNotification = function (item) {
|
||
item = $(item);
|
||
if (item.length === 0) return;
|
||
if (item.hasClass('notification-item-removing')) return;
|
||
var container = $('.notifications');
|
||
|
||
var itemHeight = item.outerHeight();
|
||
item.css('height', itemHeight + 'px').transition(0).addClass('notification-item-removing');
|
||
var clientLeft = item[0].clientLeft;
|
||
|
||
item.css({
|
||
height: '0px',
|
||
marginBottom: '0px'
|
||
}).transition('');
|
||
|
||
if (item.data('f7NotificationOnClose')) item.data('f7NotificationOnClose')();
|
||
|
||
if (container.find('.notification-item:not(.notification-item-removing)').length === 0) {
|
||
container.transform('');
|
||
}
|
||
|
||
item.addClass('notification-hidden').transitionEnd(function () {
|
||
item.remove();
|
||
if (container.find('.notification-item').length === 0) {
|
||
container.hide();
|
||
}
|
||
});
|
||
};
|
||
|
||
/*===========================
|
||
Compile Template7 Templates On App Init
|
||
===========================*/
|
||
app.initTemplate7Templates = function () {
|
||
if (!window.Template7) return;
|
||
Template7.templates = Template7.templates || app.params.templates || {};
|
||
Template7.data = Template7.data || app.params.template7Data || {};
|
||
Template7.cache = Template7.cache || {};
|
||
|
||
app.templates = Template7.templates;
|
||
app.template7Data = Template7.data;
|
||
app.template7Cache = Template7.cache;
|
||
|
||
// Precompile templates on app init
|
||
if (!app.params.precompileTemplates) return;
|
||
$('script[type="text/template7"]').each(function () {
|
||
var id = $(this).attr('id');
|
||
if (!id) return;
|
||
Template7.templates[id] = Template7.compile($(this).html());
|
||
});
|
||
};
|
||
|
||
|
||
/*=======================================
|
||
************ Plugins API ************
|
||
=======================================*/
|
||
var _plugins = [];
|
||
app.initPlugins = function () {
|
||
// Initialize plugins
|
||
for (var plugin in app.plugins) {
|
||
var p = app.plugins[plugin](app, app.params[plugin]);
|
||
if (p) _plugins.push(p);
|
||
}
|
||
};
|
||
// Plugin Hooks
|
||
app.pluginHook = function (hook) {
|
||
for (var i = 0; i < _plugins.length; i++) {
|
||
if (_plugins[i].hooks && hook in _plugins[i].hooks) {
|
||
_plugins[i].hooks[hook](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
|
||
}
|
||
}
|
||
};
|
||
// Prevented by plugin
|
||
app.pluginPrevent = function (action) {
|
||
var prevent = false;
|
||
for (var i = 0; i < _plugins.length; i++) {
|
||
if (_plugins[i].prevents && action in _plugins[i].prevents) {
|
||
if (_plugins[i].prevents[action](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5])) prevent = true;
|
||
}
|
||
}
|
||
return prevent;
|
||
};
|
||
// Preprocess content by plugin
|
||
app.pluginProcess = function (process, data) {
|
||
var processed = data;
|
||
for (var i = 0; i < _plugins.length; i++) {
|
||
if (_plugins[i].preprocess && process in _plugins[i].preprocess) {
|
||
processed = _plugins[i].preprocess[process](data, arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
|
||
}
|
||
}
|
||
return processed;
|
||
};
|
||
|
||
|
||
|
||
/*======================================================
|
||
************ App Init ************
|
||
======================================================*/
|
||
app.init = function () {
|
||
// Compile Template7 templates on app load
|
||
if (app.initTemplate7Templates) app.initTemplate7Templates();
|
||
|
||
// Init Plugins
|
||
if (app.initPlugins) app.initPlugins();
|
||
|
||
// Init Device
|
||
if (app.getDeviceInfo) app.getDeviceInfo();
|
||
|
||
// Init Click events
|
||
if (app.initFastClicks && app.params.fastClicks) app.initFastClicks();
|
||
if (app.initClickEvents) app.initClickEvents();
|
||
|
||
// Init each page callbacks
|
||
$('.page:not(.cached)').each(function () {
|
||
app.initPageWithCallback(this);
|
||
});
|
||
|
||
// Init each navbar callbacks
|
||
$('.navbar:not(.cached)').each(function () {
|
||
app.initNavbarWithCallback(this);
|
||
});
|
||
|
||
// Init resize events
|
||
if (app.initResize) app.initResize();
|
||
|
||
// Init push state
|
||
if (app.initPushState && app.params.pushState) app.initPushState();
|
||
|
||
// Init Live Swipeouts events
|
||
if (app.initSwipeout && app.params.swipeout) app.initSwipeout();
|
||
|
||
// Init Live Sortable events
|
||
if (app.initSortable && app.params.sortable) app.initSortable();
|
||
|
||
// Init Live Swipe Panels
|
||
if (app.initSwipePanels && (app.params.swipePanel || app.params.swipePanelOnlyClose)) app.initSwipePanels();
|
||
|
||
// Init Material Inputs
|
||
if (app.params.material && app.initMaterialWatchInputs) app.initMaterialWatchInputs();
|
||
|
||
// App Init callback
|
||
if (app.params.onAppInit) app.params.onAppInit();
|
||
|
||
// Plugin app init hook
|
||
app.pluginHook('appInit');
|
||
};
|
||
if (app.params.init) app.init();
|
||
|
||
|
||
//Return instance
|
||
return app;
|
||
};
|
||
|
||
|
||
/*===========================
|
||
Dom7 Library
|
||
===========================*/
|
||
var Dom7 = (function () {
|
||
var Dom7 = function (arr) {
|
||
var _this = this, i = 0;
|
||
// Create array-like object
|
||
for (i = 0; i < arr.length; i++) {
|
||
_this[i] = arr[i];
|
||
}
|
||
_this.length = arr.length;
|
||
// Return collection with methods
|
||
return this;
|
||
};
|
||
var $ = function (selector, context) {
|
||
var arr = [], i = 0;
|
||
if (selector && !context) {
|
||
if (selector instanceof Dom7) {
|
||
return selector;
|
||
}
|
||
}
|
||
if (selector) {
|
||
// String
|
||
if (typeof selector === 'string') {
|
||
var els, tempParent, html;
|
||
selector = html = selector.trim();
|
||
if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {
|
||
var toCreate = 'div';
|
||
if (html.indexOf('<li') === 0) toCreate = 'ul';
|
||
if (html.indexOf('<tr') === 0) toCreate = 'tbody';
|
||
if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) toCreate = 'tr';
|
||
if (html.indexOf('<tbody') === 0) toCreate = 'table';
|
||
if (html.indexOf('<option') === 0) toCreate = 'select';
|
||
tempParent = document.createElement(toCreate);
|
||
tempParent.innerHTML = html;
|
||
for (i = 0; i < tempParent.childNodes.length; i++) {
|
||
arr.push(tempParent.childNodes[i]);
|
||
}
|
||
}
|
||
else {
|
||
if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {
|
||
// Pure ID selector
|
||
els = [document.getElementById(selector.split('#')[1])];
|
||
}
|
||
else {
|
||
// Other selectors
|
||
els = (context || document).querySelectorAll(selector);
|
||
}
|
||
for (i = 0; i < els.length; i++) {
|
||
if (els[i]) arr.push(els[i]);
|
||
}
|
||
}
|
||
}
|
||
// Node/element
|
||
else if (selector.nodeType || selector === window || selector === document) {
|
||
arr.push(selector);
|
||
}
|
||
//Array of elements or instance of Dom
|
||
else if (selector.length > 0 && selector[0].nodeType) {
|
||
for (i = 0; i < selector.length; i++) {
|
||
arr.push(selector[i]);
|
||
}
|
||
}
|
||
}
|
||
return new Dom7(arr);
|
||
};
|
||
|
||
Dom7.prototype = {
|
||
// Classes and attriutes
|
||
addClass: function (className) {
|
||
if (typeof className === 'undefined') {
|
||
return this;
|
||
}
|
||
var classes = className.split(' ');
|
||
for (var i = 0; i < classes.length; i++) {
|
||
for (var j = 0; j < this.length; j++) {
|
||
if (typeof this[j].classList !== 'undefined') this[j].classList.add(classes[i]);
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
removeClass: function (className) {
|
||
var classes = className.split(' ');
|
||
for (var i = 0; i < classes.length; i++) {
|
||
for (var j = 0; j < this.length; j++) {
|
||
if (typeof this[j].classList !== 'undefined') this[j].classList.remove(classes[i]);
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
hasClass: function (className) {
|
||
if (!this[0]) return false;
|
||
else return this[0].classList.contains(className);
|
||
},
|
||
toggleClass: function (className) {
|
||
var classes = className.split(' ');
|
||
for (var i = 0; i < classes.length; i++) {
|
||
for (var j = 0; j < this.length; j++) {
|
||
if (typeof this[j].classList !== 'undefined') this[j].classList.toggle(classes[i]);
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
attr: function (attrs, value) {
|
||
if (arguments.length === 1 && typeof attrs === 'string') {
|
||
// Get attr
|
||
if (this[0]) return this[0].getAttribute(attrs);
|
||
else return undefined;
|
||
}
|
||
else {
|
||
// Set attrs
|
||
for (var i = 0; i < this.length; i++) {
|
||
if (arguments.length === 2) {
|
||
// String
|
||
this[i].setAttribute(attrs, value);
|
||
}
|
||
else {
|
||
// Object
|
||
for (var attrName in attrs) {
|
||
this[i][attrName] = attrs[attrName];
|
||
this[i].setAttribute(attrName, attrs[attrName]);
|
||
}
|
||
}
|
||
}
|
||
return this;
|
||
}
|
||
},
|
||
removeAttr: function (attr) {
|
||
for (var i = 0; i < this.length; i++) {
|
||
this[i].removeAttribute(attr);
|
||
}
|
||
return this;
|
||
},
|
||
prop: function (props, value) {
|
||
if (arguments.length === 1 && typeof props === 'string') {
|
||
// Get prop
|
||
if (this[0]) return this[0][props];
|
||
else return undefined;
|
||
}
|
||
else {
|
||
// Set props
|
||
for (var i = 0; i < this.length; i++) {
|
||
if (arguments.length === 2) {
|
||
// String
|
||
this[i][props] = value;
|
||
}
|
||
else {
|
||
// Object
|
||
for (var propName in props) {
|
||
this[i][propName] = props[propName];
|
||
}
|
||
}
|
||
}
|
||
return this;
|
||
}
|
||
},
|
||
data: function (key, value) {
|
||
if (typeof value === 'undefined') {
|
||
// Get value
|
||
if (this[0]) {
|
||
if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) {
|
||
return this[0].dom7ElementDataStorage[key];
|
||
}
|
||
else {
|
||
var dataKey = this[0].getAttribute('data-' + key);
|
||
if (dataKey) {
|
||
return dataKey;
|
||
}
|
||
else return undefined;
|
||
}
|
||
}
|
||
else return undefined;
|
||
}
|
||
else {
|
||
// Set value
|
||
for (var i = 0; i < this.length; i++) {
|
||
var el = this[i];
|
||
if (!el.dom7ElementDataStorage) el.dom7ElementDataStorage = {};
|
||
el.dom7ElementDataStorage[key] = value;
|
||
}
|
||
return this;
|
||
}
|
||
},
|
||
removeData: function(key) {
|
||
for (var i = 0; i < this.length; i++) {
|
||
var el = this[i];
|
||
if (el.dom7ElementDataStorage && el.dom7ElementDataStorage[key]) {
|
||
el.dom7ElementDataStorage[key] = null;
|
||
delete el.dom7ElementDataStorage[key];
|
||
}
|
||
}
|
||
},
|
||
dataset: function () {
|
||
var el = this[0];
|
||
if (el) {
|
||
var dataset = {};
|
||
if (el.dataset) {
|
||
for (var dataKey in el.dataset) {
|
||
dataset[dataKey] = el.dataset[dataKey];
|
||
}
|
||
}
|
||
else {
|
||
for (var i = 0; i < el.attributes.length; i++) {
|
||
var attr = el.attributes[i];
|
||
if (attr.name.indexOf('data-') >= 0) {
|
||
dataset[$.toCamelCase(attr.name.split('data-')[1])] = attr.value;
|
||
}
|
||
}
|
||
}
|
||
for (var key in dataset) {
|
||
if (dataset[key] === 'false') dataset[key] = false;
|
||
else if (dataset[key] === 'true') dataset[key] = true;
|
||
else if (parseFloat(dataset[key]) === dataset[key] * 1) dataset[key] = dataset[key] * 1;
|
||
}
|
||
return dataset;
|
||
}
|
||
else return undefined;
|
||
},
|
||
val: function (value) {
|
||
if (typeof value === 'undefined') {
|
||
if (this[0]) return this[0].value;
|
||
else return undefined;
|
||
}
|
||
else {
|
||
for (var i = 0; i < this.length; i++) {
|
||
this[i].value = value;
|
||
}
|
||
return this;
|
||
}
|
||
},
|
||
// Transforms
|
||
transform : function (transform) {
|
||
for (var i = 0; i < this.length; i++) {
|
||
var elStyle = this[i].style;
|
||
elStyle.webkitTransform = elStyle.MsTransform = elStyle.msTransform = elStyle.MozTransform = elStyle.OTransform = elStyle.transform = transform;
|
||
}
|
||
return this;
|
||
},
|
||
transition: function (duration) {
|
||
if (typeof duration !== 'string') {
|
||
duration = duration + 'ms';
|
||
}
|
||
for (var i = 0; i < this.length; i++) {
|
||
var elStyle = this[i].style;
|
||
elStyle.webkitTransitionDuration = elStyle.MsTransitionDuration = elStyle.msTransitionDuration = elStyle.MozTransitionDuration = elStyle.OTransitionDuration = elStyle.transitionDuration = duration;
|
||
}
|
||
return this;
|
||
},
|
||
//Events
|
||
on: function (eventName, targetSelector, listener, capture) {
|
||
function handleLiveEvent(e) {
|
||
var target = e.target;
|
||
if ($(target).is(targetSelector)) listener.call(target, e);
|
||
else {
|
||
var parents = $(target).parents();
|
||
for (var k = 0; k < parents.length; k++) {
|
||
if ($(parents[k]).is(targetSelector)) listener.call(parents[k], e);
|
||
}
|
||
}
|
||
}
|
||
var events = eventName.split(' ');
|
||
var i, j;
|
||
for (i = 0; i < this.length; i++) {
|
||
if (typeof targetSelector === 'function' || targetSelector === false) {
|
||
// Usual events
|
||
if (typeof targetSelector === 'function') {
|
||
listener = arguments[1];
|
||
capture = arguments[2] || false;
|
||
}
|
||
for (j = 0; j < events.length; j++) {
|
||
this[i].addEventListener(events[j], listener, capture);
|
||
}
|
||
}
|
||
else {
|
||
//Live events
|
||
for (j = 0; j < events.length; j++) {
|
||
if (!this[i].dom7LiveListeners) this[i].dom7LiveListeners = [];
|
||
this[i].dom7LiveListeners.push({listener: listener, liveListener: handleLiveEvent});
|
||
this[i].addEventListener(events[j], handleLiveEvent, capture);
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
off: function (eventName, targetSelector, listener, capture) {
|
||
var events = eventName.split(' ');
|
||
for (var i = 0; i < events.length; i++) {
|
||
for (var j = 0; j < this.length; j++) {
|
||
if (typeof targetSelector === 'function' || targetSelector === false) {
|
||
// Usual events
|
||
if (typeof targetSelector === 'function') {
|
||
listener = arguments[1];
|
||
capture = arguments[2] || false;
|
||
}
|
||
this[j].removeEventListener(events[i], listener, capture);
|
||
}
|
||
else {
|
||
// Live event
|
||
if (this[j].dom7LiveListeners) {
|
||
for (var k = 0; k < this[j].dom7LiveListeners.length; k++) {
|
||
if (this[j].dom7LiveListeners[k].listener === listener) {
|
||
this[j].removeEventListener(events[i], this[j].dom7LiveListeners[k].liveListener, capture);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
once: function (eventName, targetSelector, listener, capture) {
|
||
var dom = this;
|
||
if (typeof targetSelector === 'function') {
|
||
listener = arguments[1];
|
||
capture = arguments[2];
|
||
targetSelector = false;
|
||
}
|
||
function proxy(e) {
|
||
listener.call(e.target, e);
|
||
dom.off(eventName, targetSelector, proxy, capture);
|
||
}
|
||
return dom.on(eventName, targetSelector, proxy, capture);
|
||
},
|
||
trigger: function (eventName, eventData) {
|
||
var events = eventName.split(' ');
|
||
for (var i = 0; i < events.length; i++) {
|
||
for (var j = 0; j < this.length; j++) {
|
||
var evt;
|
||
try {
|
||
evt = new CustomEvent(events[i], {detail: eventData, bubbles: true, cancelable: true});
|
||
}
|
||
catch (e) {
|
||
evt = document.createEvent('Event');
|
||
evt.initEvent(events[i], true, true);
|
||
evt.detail = eventData;
|
||
}
|
||
this[j].dispatchEvent(evt);
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
transitionEnd: function (callback) {
|
||
var events = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'],
|
||
i, j, dom = this;
|
||
function fireCallBack(e) {
|
||
/*jshint validthis:true */
|
||
if (e.target !== this) return;
|
||
callback.call(this, e);
|
||
for (i = 0; i < events.length; i++) {
|
||
dom.off(events[i], fireCallBack);
|
||
}
|
||
}
|
||
if (callback) {
|
||
for (i = 0; i < events.length; i++) {
|
||
dom.on(events[i], fireCallBack);
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
animationEnd: function (callback) {
|
||
var events = ['webkitAnimationEnd', 'OAnimationEnd', 'MSAnimationEnd', 'animationend'],
|
||
i, j, dom = this;
|
||
function fireCallBack(e) {
|
||
callback(e);
|
||
for (i = 0; i < events.length; i++) {
|
||
dom.off(events[i], fireCallBack);
|
||
}
|
||
}
|
||
if (callback) {
|
||
for (i = 0; i < events.length; i++) {
|
||
dom.on(events[i], fireCallBack);
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
// Sizing/Styles
|
||
width: function () {
|
||
if (this[0] === window) {
|
||
return window.innerWidth;
|
||
}
|
||
else {
|
||
if (this.length > 0) {
|
||
return parseFloat(this.css('width'));
|
||
}
|
||
else {
|
||
return null;
|
||
}
|
||
}
|
||
},
|
||
outerWidth: function (includeMargins) {
|
||
if (this.length > 0) {
|
||
if (includeMargins) {
|
||
var styles = this.styles();
|
||
return this[0].offsetWidth + parseFloat(styles.getPropertyValue('margin-right')) + parseFloat(styles.getPropertyValue('margin-left'));
|
||
}
|
||
else
|
||
return this[0].offsetWidth;
|
||
}
|
||
else return null;
|
||
},
|
||
height: function () {
|
||
if (this[0] === window) {
|
||
return window.innerHeight;
|
||
}
|
||
else {
|
||
if (this.length > 0) {
|
||
return parseFloat(this.css('height'));
|
||
}
|
||
else {
|
||
return null;
|
||
}
|
||
}
|
||
},
|
||
outerHeight: function (includeMargins) {
|
||
if (this.length > 0) {
|
||
if (includeMargins) {
|
||
var styles = this.styles();
|
||
return this[0].offsetHeight + parseFloat(styles.getPropertyValue('margin-top')) + parseFloat(styles.getPropertyValue('margin-bottom'));
|
||
}
|
||
else
|
||
return this[0].offsetHeight;
|
||
}
|
||
else return null;
|
||
},
|
||
offset: function () {
|
||
if (this.length > 0) {
|
||
var el = this[0];
|
||
var box = el.getBoundingClientRect();
|
||
var body = document.body;
|
||
var clientTop = el.clientTop || body.clientTop || 0;
|
||
var clientLeft = el.clientLeft || body.clientLeft || 0;
|
||
var scrollTop = window.pageYOffset || el.scrollTop;
|
||
var scrollLeft = window.pageXOffset || el.scrollLeft;
|
||
return {
|
||
top: box.top + scrollTop - clientTop,
|
||
left: box.left + scrollLeft - clientLeft
|
||
};
|
||
}
|
||
else {
|
||
return null;
|
||
}
|
||
},
|
||
hide: function () {
|
||
for (var i = 0; i < this.length; i++) {
|
||
this[i].style.display = 'none';
|
||
}
|
||
return this;
|
||
},
|
||
show: function () {
|
||
for (var i = 0; i < this.length; i++) {
|
||
this[i].style.display = 'block';
|
||
}
|
||
return this;
|
||
},
|
||
styles: function () {
|
||
var i, styles;
|
||
if (this[0]) return window.getComputedStyle(this[0], null);
|
||
else return undefined;
|
||
},
|
||
css: function (props, value) {
|
||
var i;
|
||
if (arguments.length === 1) {
|
||
if (typeof props === 'string') {
|
||
if (this[0]) return window.getComputedStyle(this[0], null).getPropertyValue(props);
|
||
}
|
||
else {
|
||
for (i = 0; i < this.length; i++) {
|
||
for (var prop in props) {
|
||
this[i].style[prop] = props[prop];
|
||
}
|
||
}
|
||
return this;
|
||
}
|
||
}
|
||
if (arguments.length === 2 && typeof props === 'string') {
|
||
for (i = 0; i < this.length; i++) {
|
||
this[i].style[props] = value;
|
||
}
|
||
return this;
|
||
}
|
||
return this;
|
||
},
|
||
|
||
//Dom manipulation
|
||
each: function (callback) {
|
||
for (var i = 0; i < this.length; i++) {
|
||
callback.call(this[i], i, this[i]);
|
||
}
|
||
return this;
|
||
},
|
||
filter: function (callback) {
|
||
var matchedItems = [];
|
||
var dom = this;
|
||
for (var i = 0; i < dom.length; i++) {
|
||
if (callback.call(dom[i], i, dom[i])) matchedItems.push(dom[i]);
|
||
}
|
||
return new Dom7(matchedItems);
|
||
},
|
||
html: function (html) {
|
||
if (typeof html === 'undefined') {
|
||
return this[0] ? this[0].innerHTML : undefined;
|
||
}
|
||
else {
|
||
for (var i = 0; i < this.length; i++) {
|
||
this[i].innerHTML = html;
|
||
}
|
||
return this;
|
||
}
|
||
},
|
||
text: function (text) {
|
||
if (typeof text === 'undefined') {
|
||
if (this[0]) {
|
||
return this[0].textContent.trim();
|
||
}
|
||
else return null;
|
||
}
|
||
else {
|
||
for (var i = 0; i < this.length; i++) {
|
||
this[i].textContent = text;
|
||
}
|
||
return this;
|
||
}
|
||
},
|
||
is: function (selector) {
|
||
if (!this[0] || typeof selector === 'undefined') return false;
|
||
var compareWith, i;
|
||
if (typeof selector === 'string') {
|
||
var el = this[0];
|
||
if (el === document) return selector === document;
|
||
if (el === window) return selector === window;
|
||
|
||
if (el.matches) return el.matches(selector);
|
||
else if (el.webkitMatchesSelector) return el.webkitMatchesSelector(selector);
|
||
else if (el.mozMatchesSelector) return el.mozMatchesSelector(selector);
|
||
else if (el.msMatchesSelector) return el.msMatchesSelector(selector);
|
||
else {
|
||
compareWith = $(selector);
|
||
for (i = 0; i < compareWith.length; i++) {
|
||
if (compareWith[i] === this[0]) return true;
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
else if (selector === document) return this[0] === document;
|
||
else if (selector === window) return this[0] === window;
|
||
else {
|
||
if (selector.nodeType || selector instanceof Dom7) {
|
||
compareWith = selector.nodeType ? [selector] : selector;
|
||
for (i = 0; i < compareWith.length; i++) {
|
||
if (compareWith[i] === this[0]) return true;
|
||
}
|
||
return false;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
},
|
||
indexOf: function (el) {
|
||
for (var i = 0; i < this.length; i++) {
|
||
if (this[i] === el) return i;
|
||
}
|
||
},
|
||
index: function () {
|
||
if (this[0]) {
|
||
var child = this[0];
|
||
var i = 0;
|
||
while ((child = child.previousSibling) !== null) {
|
||
if (child.nodeType === 1) i++;
|
||
}
|
||
return i;
|
||
}
|
||
else return undefined;
|
||
},
|
||
eq: function (index) {
|
||
if (typeof index === 'undefined') return this;
|
||
var length = this.length;
|
||
var returnIndex;
|
||
if (index > length - 1) {
|
||
return new Dom7([]);
|
||
}
|
||
if (index < 0) {
|
||
returnIndex = length + index;
|
||
if (returnIndex < 0) return new Dom7([]);
|
||
else return new Dom7([this[returnIndex]]);
|
||
}
|
||
return new Dom7([this[index]]);
|
||
},
|
||
append: function (newChild) {
|
||
var i, j;
|
||
for (i = 0; i < this.length; i++) {
|
||
if (typeof newChild === 'string') {
|
||
var tempDiv = document.createElement('div');
|
||
tempDiv.innerHTML = newChild;
|
||
while (tempDiv.firstChild) {
|
||
this[i].appendChild(tempDiv.firstChild);
|
||
}
|
||
}
|
||
else if (newChild instanceof Dom7) {
|
||
for (j = 0; j < newChild.length; j++) {
|
||
this[i].appendChild(newChild[j]);
|
||
}
|
||
}
|
||
else {
|
||
this[i].appendChild(newChild);
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
appendTo: function (parent) {
|
||
$(parent).append(this);
|
||
return this;
|
||
},
|
||
prepend: function (newChild) {
|
||
var i, j;
|
||
for (i = 0; i < this.length; i++) {
|
||
if (typeof newChild === 'string') {
|
||
var tempDiv = document.createElement('div');
|
||
tempDiv.innerHTML = newChild;
|
||
for (j = tempDiv.childNodes.length - 1; j >= 0; j--) {
|
||
this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);
|
||
}
|
||
// this[i].insertAdjacentHTML('afterbegin', newChild);
|
||
}
|
||
else if (newChild instanceof Dom7) {
|
||
for (j = 0; j < newChild.length; j++) {
|
||
this[i].insertBefore(newChild[j], this[i].childNodes[0]);
|
||
}
|
||
}
|
||
else {
|
||
this[i].insertBefore(newChild, this[i].childNodes[0]);
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
prependTo: function (parent) {
|
||
$(parent).prepend(this);
|
||
return this;
|
||
},
|
||
insertBefore: function (selector) {
|
||
var before = $(selector);
|
||
for (var i = 0; i < this.length; i++) {
|
||
if (before.length === 1) {
|
||
before[0].parentNode.insertBefore(this[i], before[0]);
|
||
}
|
||
else if (before.length > 1) {
|
||
for (var j = 0; j < before.length; j++) {
|
||
before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);
|
||
}
|
||
}
|
||
}
|
||
},
|
||
insertAfter: function (selector) {
|
||
var after = $(selector);
|
||
for (var i = 0; i < this.length; i++) {
|
||
if (after.length === 1) {
|
||
after[0].parentNode.insertBefore(this[i], after[0].nextSibling);
|
||
}
|
||
else if (after.length > 1) {
|
||
for (var j = 0; j < after.length; j++) {
|
||
after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);
|
||
}
|
||
}
|
||
}
|
||
},
|
||
next: function (selector) {
|
||
if (this.length > 0) {
|
||
if (selector) {
|
||
if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) return new Dom7([this[0].nextElementSibling]);
|
||
else return new Dom7([]);
|
||
}
|
||
else {
|
||
if (this[0].nextElementSibling) return new Dom7([this[0].nextElementSibling]);
|
||
else return new Dom7([]);
|
||
}
|
||
}
|
||
else return new Dom7([]);
|
||
},
|
||
nextAll: function (selector) {
|
||
var nextEls = [];
|
||
var el = this[0];
|
||
if (!el) return new Dom7([]);
|
||
while (el.nextElementSibling) {
|
||
var next = el.nextElementSibling;
|
||
if (selector) {
|
||
if($(next).is(selector)) nextEls.push(next);
|
||
}
|
||
else nextEls.push(next);
|
||
el = next;
|
||
}
|
||
return new Dom7(nextEls);
|
||
},
|
||
prev: function (selector) {
|
||
if (this.length > 0) {
|
||
if (selector) {
|
||
if (this[0].previousElementSibling && $(this[0].previousElementSibling).is(selector)) return new Dom7([this[0].previousElementSibling]);
|
||
else return new Dom7([]);
|
||
}
|
||
else {
|
||
if (this[0].previousElementSibling) return new Dom7([this[0].previousElementSibling]);
|
||
else return new Dom7([]);
|
||
}
|
||
}
|
||
else return new Dom7([]);
|
||
},
|
||
prevAll: function (selector) {
|
||
var prevEls = [];
|
||
var el = this[0];
|
||
if (!el) return new Dom7([]);
|
||
while (el.previousElementSibling) {
|
||
var prev = el.previousElementSibling;
|
||
if (selector) {
|
||
if($(prev).is(selector)) prevEls.push(prev);
|
||
}
|
||
else prevEls.push(prev);
|
||
el = prev;
|
||
}
|
||
return new Dom7(prevEls);
|
||
},
|
||
siblings: function (selector) {
|
||
return this.nextAll(selector).add(this.prevAll(selector));
|
||
},
|
||
parent: function (selector) {
|
||
var parents = [];
|
||
for (var i = 0; i < this.length; i++) {
|
||
if (this[i].parentNode !== null) {
|
||
if (selector) {
|
||
if ($(this[i].parentNode).is(selector)) parents.push(this[i].parentNode);
|
||
}
|
||
else {
|
||
parents.push(this[i].parentNode);
|
||
}
|
||
}
|
||
}
|
||
return $($.unique(parents));
|
||
},
|
||
parents: function (selector) {
|
||
var parents = [];
|
||
for (var i = 0; i < this.length; i++) {
|
||
var parent = this[i].parentNode;
|
||
while (parent) {
|
||
if (selector) {
|
||
if ($(parent).is(selector)) parents.push(parent);
|
||
}
|
||
else {
|
||
parents.push(parent);
|
||
}
|
||
parent = parent.parentNode;
|
||
}
|
||
}
|
||
return $($.unique(parents));
|
||
},
|
||
closest: function (selector) {
|
||
var closest = this;
|
||
if (typeof selector === 'undefined') {
|
||
return new Dom7([]);
|
||
}
|
||
if (!closest.is(selector)) {
|
||
closest = closest.parents(selector).eq(0);
|
||
}
|
||
return closest;
|
||
},
|
||
find : function (selector) {
|
||
var foundElements = [];
|
||
for (var i = 0; i < this.length; i++) {
|
||
var found = this[i].querySelectorAll(selector);
|
||
for (var j = 0; j < found.length; j++) {
|
||
foundElements.push(found[j]);
|
||
}
|
||
}
|
||
return new Dom7(foundElements);
|
||
},
|
||
children: function (selector) {
|
||
var children = [];
|
||
for (var i = 0; i < this.length; i++) {
|
||
var childNodes = this[i].childNodes;
|
||
|
||
for (var j = 0; j < childNodes.length; j++) {
|
||
if (!selector) {
|
||
if (childNodes[j].nodeType === 1) children.push(childNodes[j]);
|
||
}
|
||
else {
|
||
if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) children.push(childNodes[j]);
|
||
}
|
||
}
|
||
}
|
||
return new Dom7($.unique(children));
|
||
},
|
||
remove: function () {
|
||
for (var i = 0; i < this.length; i++) {
|
||
if (this[i].parentNode) this[i].parentNode.removeChild(this[i]);
|
||
}
|
||
return this;
|
||
},
|
||
detach: function () {
|
||
return this.remove();
|
||
},
|
||
add: function () {
|
||
var dom = this;
|
||
var i, j;
|
||
for (i = 0; i < arguments.length; i++) {
|
||
var toAdd = $(arguments[i]);
|
||
for (j = 0; j < toAdd.length; j++) {
|
||
dom[dom.length] = toAdd[j];
|
||
dom.length++;
|
||
}
|
||
}
|
||
return dom;
|
||
},
|
||
empty: function () {
|
||
for (var i = 0; i < this.length; i++) {
|
||
var el = this[i];
|
||
if (el.nodeType === 1) {
|
||
for (var j = 0; j < el.childNodes.length; j++) {
|
||
if (el.childNodes[j].parentNode) el.childNodes[j].parentNode.removeChild(el.childNodes[j]);
|
||
}
|
||
el.textContent = '';
|
||
}
|
||
}
|
||
return this;
|
||
}
|
||
};
|
||
|
||
// Shortcuts
|
||
(function () {
|
||
var shortcuts = ('click blur focus focusin focusout keyup keydown keypress submit change mousedown mousemove mouseup mouseenter mouseleave mouseout mouseover touchstart touchend touchmove resize scroll').split(' ');
|
||
var notTrigger = ('resize scroll').split(' ');
|
||
function createMethod(name) {
|
||
Dom7.prototype[name] = function (targetSelector, listener, capture) {
|
||
var i;
|
||
if (typeof targetSelector === 'undefined') {
|
||
for (i = 0; i < this.length; i++) {
|
||
if (notTrigger.indexOf(name) < 0) {
|
||
if (name in this[i]) this[i][name]();
|
||
else {
|
||
$(this[i]).trigger(name);
|
||
}
|
||
}
|
||
}
|
||
return this;
|
||
}
|
||
else {
|
||
return this.on(name, targetSelector, listener, capture);
|
||
}
|
||
};
|
||
}
|
||
for (var i = 0; i < shortcuts.length; i++) {
|
||
createMethod(shortcuts[i]);
|
||
}
|
||
})();
|
||
|
||
|
||
// Global Ajax Setup
|
||
var globalAjaxOptions = {};
|
||
$.ajaxSetup = function (options) {
|
||
if (options.type) options.method = options.type;
|
||
$.each(options, function (optionName, optionValue) {
|
||
globalAjaxOptions[optionName] = optionValue;
|
||
});
|
||
};
|
||
|
||
// Ajax
|
||
var _jsonpRequests = 0;
|
||
$.ajax = function (options) {
|
||
var defaults = {
|
||
method: 'GET',
|
||
data: false,
|
||
async: true,
|
||
cache: true,
|
||
user: '',
|
||
password: '',
|
||
headers: {},
|
||
xhrFields: {},
|
||
statusCode: {},
|
||
processData: true,
|
||
dataType: 'text',
|
||
contentType: 'application/x-www-form-urlencoded',
|
||
timeout: 0
|
||
};
|
||
var callbacks = ['beforeSend', 'error', 'complete', 'success', 'statusCode'];
|
||
|
||
|
||
//For jQuery guys
|
||
if (options.type) options.method = options.type;
|
||
|
||
// Merge global and defaults
|
||
$.each(globalAjaxOptions, function (globalOptionName, globalOptionValue) {
|
||
if (callbacks.indexOf(globalOptionName) < 0) defaults[globalOptionName] = globalOptionValue;
|
||
});
|
||
|
||
// Function to run XHR callbacks and events
|
||
function fireAjaxCallback (eventName, eventData, callbackName) {
|
||
var a = arguments;
|
||
if (eventName) $(document).trigger(eventName, eventData);
|
||
if (callbackName) {
|
||
// Global callback
|
||
if (callbackName in globalAjaxOptions) globalAjaxOptions[callbackName](a[3], a[4], a[5], a[6]);
|
||
// Options callback
|
||
if (options[callbackName]) options[callbackName](a[3], a[4], a[5], a[6]);
|
||
}
|
||
}
|
||
|
||
// Merge options and defaults
|
||
$.each(defaults, function (prop, defaultValue) {
|
||
if (!(prop in options)) options[prop] = defaultValue;
|
||
});
|
||
|
||
// Default URL
|
||
if (!options.url) {
|
||
options.url = window.location.toString();
|
||
}
|
||
// Parameters Prefix
|
||
var paramsPrefix = options.url.indexOf('?') >= 0 ? '&' : '?';
|
||
|
||
// UC method
|
||
var _method = options.method.toUpperCase();
|
||
// Data to modify GET URL
|
||
if ((_method === 'GET' || _method === 'HEAD' || _method === 'OPTIONS' || _method === 'DELETE') && options.data) {
|
||
var stringData;
|
||
if (typeof options.data === 'string') {
|
||
// Should be key=value string
|
||
if (options.data.indexOf('?') >= 0) stringData = options.data.split('?')[1];
|
||
else stringData = options.data;
|
||
}
|
||
else {
|
||
// Should be key=value object
|
||
stringData = $.serializeObject(options.data);
|
||
}
|
||
if (stringData.length) {
|
||
options.url += paramsPrefix + stringData;
|
||
if (paramsPrefix === '?') paramsPrefix = '&';
|
||
}
|
||
}
|
||
// JSONP
|
||
if (options.dataType === 'json' && options.url.indexOf('callback=') >= 0) {
|
||
|
||
var callbackName = 'f7jsonp_' + Date.now() + (_jsonpRequests++);
|
||
var abortTimeout;
|
||
var callbackSplit = options.url.split('callback=');
|
||
var requestUrl = callbackSplit[0] + 'callback=' + callbackName;
|
||
if (callbackSplit[1].indexOf('&') >= 0) {
|
||
var addVars = callbackSplit[1].split('&').filter(function (el) { return el.indexOf('=') > 0; }).join('&');
|
||
if (addVars.length > 0) requestUrl += '&' + addVars;
|
||
}
|
||
|
||
// Create script
|
||
var script = document.createElement('script');
|
||
script.type = 'text/javascript';
|
||
script.onerror = function() {
|
||
clearTimeout(abortTimeout);
|
||
fireAjaxCallback(undefined, undefined, 'error', null, 'scripterror');
|
||
};
|
||
script.src = requestUrl;
|
||
|
||
// Handler
|
||
window[callbackName] = function (data) {
|
||
clearTimeout(abortTimeout);
|
||
fireAjaxCallback(undefined, undefined, 'success', data);
|
||
script.parentNode.removeChild(script);
|
||
script = null;
|
||
delete window[callbackName];
|
||
};
|
||
document.querySelector('head').appendChild(script);
|
||
|
||
if (options.timeout > 0) {
|
||
abortTimeout = setTimeout(function () {
|
||
script.parentNode.removeChild(script);
|
||
script = null;
|
||
fireAjaxCallback(undefined, undefined, 'error', null, 'timeout');
|
||
}, options.timeout);
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
// Cache for GET/HEAD requests
|
||
if (_method === 'GET' || _method === 'HEAD' || _method === 'OPTIONS' || _method === 'DELETE') {
|
||
if (options.cache === false) {
|
||
options.url += (paramsPrefix + '_nocache=' + Date.now());
|
||
}
|
||
}
|
||
|
||
// Create XHR
|
||
var xhr = new XMLHttpRequest();
|
||
|
||
// Save Request URL
|
||
xhr.requestUrl = options.url;
|
||
xhr.requestParameters = options;
|
||
|
||
// Open XHR
|
||
xhr.open(_method, options.url, options.async, options.user, options.password);
|
||
|
||
// Create POST Data
|
||
var postData = null;
|
||
|
||
if ((_method === 'POST' || _method === 'PUT' || _method === 'PATCH') && options.data) {
|
||
if (options.processData) {
|
||
var postDataInstances = [ArrayBuffer, Blob, Document, FormData];
|
||
// Post Data
|
||
if (postDataInstances.indexOf(options.data.constructor) >= 0) {
|
||
postData = options.data;
|
||
}
|
||
else {
|
||
// POST Headers
|
||
var boundary = '---------------------------' + Date.now().toString(16);
|
||
|
||
if (options.contentType === 'multipart\/form-data') {
|
||
xhr.setRequestHeader('Content-Type', 'multipart\/form-data; boundary=' + boundary);
|
||
}
|
||
else {
|
||
xhr.setRequestHeader('Content-Type', options.contentType);
|
||
}
|
||
postData = '';
|
||
var _data = $.serializeObject(options.data);
|
||
if (options.contentType === 'multipart\/form-data') {
|
||
boundary = '---------------------------' + Date.now().toString(16);
|
||
_data = _data.split('&');
|
||
var _newData = [];
|
||
for (var i = 0; i < _data.length; i++) {
|
||
_newData.push('Content-Disposition: form-data; name="' + _data[i].split('=')[0] + '"\r\n\r\n' + _data[i].split('=')[1] + '\r\n');
|
||
}
|
||
postData = '--' + boundary + '\r\n' + _newData.join('--' + boundary + '\r\n') + '--' + boundary + '--\r\n';
|
||
}
|
||
else {
|
||
postData = options.contentType === 'application/x-www-form-urlencoded' ? _data : _data.replace(/&/g, '\r\n');
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
postData = options.data;
|
||
}
|
||
|
||
}
|
||
|
||
// Additional headers
|
||
if (options.headers) {
|
||
$.each(options.headers, function (headerName, headerCallback) {
|
||
xhr.setRequestHeader(headerName, headerCallback);
|
||
});
|
||
}
|
||
|
||
// Check for crossDomain
|
||
if (typeof options.crossDomain === 'undefined') {
|
||
options.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(options.url) && RegExp.$2 !== window.location.host;
|
||
}
|
||
|
||
if (!options.crossDomain) {
|
||
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
||
}
|
||
|
||
if (options.xhrFields) {
|
||
$.each(options.xhrFields, function (fieldName, fieldValue) {
|
||
xhr[fieldName] = fieldValue;
|
||
});
|
||
}
|
||
|
||
var xhrTimeout;
|
||
// Handle XHR
|
||
xhr.onload = function (e) {
|
||
if (xhrTimeout) clearTimeout(xhrTimeout);
|
||
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {
|
||
var responseData;
|
||
if (options.dataType === 'json') {
|
||
try {
|
||
responseData = JSON.parse(xhr.responseText);
|
||
fireAjaxCallback('ajaxSuccess', {xhr: xhr}, 'success', responseData, xhr.status, xhr);
|
||
}
|
||
catch (err) {
|
||
fireAjaxCallback('ajaxError', {xhr: xhr, parseerror: true}, 'error', xhr, 'parseerror');
|
||
}
|
||
}
|
||
else {
|
||
responseData = xhr.responseType === 'text' || xhr.responseType === '' ? xhr.responseText : xhr.response;
|
||
fireAjaxCallback('ajaxSuccess', {xhr: xhr}, 'success', responseData, xhr.status, xhr);
|
||
}
|
||
}
|
||
else {
|
||
fireAjaxCallback('ajaxError', {xhr: xhr}, 'error', xhr, xhr.status);
|
||
}
|
||
if (options.statusCode) {
|
||
if (globalAjaxOptions.statusCode && globalAjaxOptions.statusCode[xhr.status]) globalAjaxOptions.statusCode[xhr.status](xhr);
|
||
if (options.statusCode[xhr.status]) options.statusCode[xhr.status](xhr);
|
||
}
|
||
fireAjaxCallback('ajaxComplete', {xhr: xhr}, 'complete', xhr, xhr.status);
|
||
};
|
||
|
||
xhr.onerror = function (e) {
|
||
if (xhrTimeout) clearTimeout(xhrTimeout);
|
||
fireAjaxCallback('ajaxError', {xhr: xhr}, 'error', xhr, xhr.status);
|
||
};
|
||
|
||
// Ajax start callback
|
||
fireAjaxCallback('ajaxStart', {xhr: xhr}, 'start', xhr);
|
||
fireAjaxCallback(undefined, undefined, 'beforeSend', xhr);
|
||
|
||
// Timeout
|
||
if (options.timeout > 0) {
|
||
xhr.onabort = function () {
|
||
if (xhrTimeout) clearTimeout(xhrTimeout);
|
||
};
|
||
xhrTimeout = setTimeout(function () {
|
||
xhr.abort();
|
||
fireAjaxCallback('ajaxError', {xhr: xhr, timeout: true}, 'error', xhr, 'timeout');
|
||
fireAjaxCallback('ajaxComplete', {xhr: xhr, timeout: true}, 'complete', xhr, 'timeout');
|
||
}, options.timeout);
|
||
}
|
||
|
||
// Send XHR
|
||
xhr.send(postData);
|
||
|
||
// Return XHR object
|
||
return xhr;
|
||
};
|
||
// Shrotcuts
|
||
(function () {
|
||
var methods = ('get post getJSON').split(' ');
|
||
function createMethod(method) {
|
||
$[method] = function (url, data, success, error) {
|
||
return $.ajax({
|
||
url: url,
|
||
method: method === 'post' ? 'POST' : 'GET',
|
||
data: typeof data === 'function' ? undefined : data,
|
||
success: typeof data === 'function' ? data : success,
|
||
error: typeof data === 'function' ? success : error,
|
||
dataType: method === 'getJSON' ? 'json' : undefined
|
||
});
|
||
};
|
||
}
|
||
for (var i = 0; i < methods.length; i++) {
|
||
createMethod(methods[i]);
|
||
}
|
||
})();
|
||
|
||
|
||
// DOM Library Utilites
|
||
$.parseUrlQuery = function (url) {
|
||
var url = url || location.href;
|
||
var query = {}, i, params, param;
|
||
|
||
if (typeof url === 'string' && url.length) {
|
||
url = (url.indexOf('#') > -1) ? url.split('#')[0] : url;
|
||
if (url.indexOf('?') > -1) url = url.split('?')[1];
|
||
else return query;
|
||
|
||
params = url.split('&');
|
||
for (i = 0; i < params.length; i ++) {
|
||
param = params[i].split('=');
|
||
query[param[0]] = param[1];
|
||
}
|
||
}
|
||
return query;
|
||
};
|
||
$.isArray = function (arr) {
|
||
if (Object.prototype.toString.apply(arr) === '[object Array]') return true;
|
||
else return false;
|
||
};
|
||
$.each = function (obj, callback) {
|
||
if (typeof obj !== 'object') return;
|
||
if (!callback) return;
|
||
var i, prop;
|
||
if ($.isArray(obj) || obj instanceof Dom7) {
|
||
// Array
|
||
for (i = 0; i < obj.length; i++) {
|
||
callback(i, obj[i]);
|
||
}
|
||
}
|
||
else {
|
||
// Object
|
||
for (prop in obj) {
|
||
if (obj.hasOwnProperty(prop)) {
|
||
callback(prop, obj[prop]);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
$.unique = function (arr) {
|
||
var unique = [];
|
||
for (var i = 0; i < arr.length; i++) {
|
||
if (unique.indexOf(arr[i]) === -1) unique.push(arr[i]);
|
||
}
|
||
return unique;
|
||
};
|
||
$.serializeObject = $.param = function (obj, parents) {
|
||
if (typeof obj === 'string') return obj;
|
||
var resultArray = [];
|
||
var separator = '&';
|
||
parents = parents || [];
|
||
var newParents;
|
||
function var_name(name) {
|
||
if (parents.length > 0) {
|
||
var _parents = '';
|
||
for (var j = 0; j < parents.length; j++) {
|
||
if (j === 0) _parents += parents[j];
|
||
else _parents += '[' + encodeURIComponent(parents[j]) + ']';
|
||
}
|
||
return _parents + '[' + encodeURIComponent(name) + ']';
|
||
}
|
||
else {
|
||
return encodeURIComponent(name);
|
||
}
|
||
}
|
||
function var_value(value) {
|
||
return encodeURIComponent(value);
|
||
}
|
||
for (var prop in obj) {
|
||
if (obj.hasOwnProperty(prop)) {
|
||
var toPush;
|
||
if ($.isArray(obj[prop])) {
|
||
toPush = [];
|
||
for (var i = 0; i < obj[prop].length; i ++) {
|
||
if (!$.isArray(obj[prop][i]) && typeof obj[prop][i] === 'object') {
|
||
newParents = parents.slice();
|
||
newParents.push(prop);
|
||
newParents.push(i + '');
|
||
toPush.push($.serializeObject(obj[prop][i], newParents));
|
||
}
|
||
else {
|
||
toPush.push(var_name(prop) + '[]=' + var_value(obj[prop][i]));
|
||
}
|
||
|
||
}
|
||
if (toPush.length > 0) resultArray.push(toPush.join(separator));
|
||
}
|
||
else if (obj[prop] === null) {
|
||
resultArray.push(var_name(prop) + '=');
|
||
}
|
||
else if (typeof obj[prop] === 'object') {
|
||
// Object, convert to named array
|
||
newParents = parents.slice();
|
||
newParents.push(prop);
|
||
toPush = $.serializeObject(obj[prop], newParents);
|
||
if (toPush !== '') resultArray.push(toPush);
|
||
}
|
||
else if (typeof obj[prop] !== 'undefined' && obj[prop] !== '') {
|
||
// Should be string or plain value
|
||
resultArray.push(var_name(prop) + '=' + var_value(obj[prop]));
|
||
}
|
||
}
|
||
}
|
||
return resultArray.join(separator);
|
||
};
|
||
$.toCamelCase = function (string) {
|
||
return string.toLowerCase().replace(/-(.)/g, function(match, group1) {
|
||
return group1.toUpperCase();
|
||
});
|
||
};
|
||
$.dataset = function (el) {
|
||
return $(el).dataset();
|
||
};
|
||
$.getTranslate = function (el, axis) {
|
||
var matrix, curTransform, curStyle, transformMatrix;
|
||
|
||
// automatic axis detection
|
||
if (typeof axis === 'undefined') {
|
||
axis = 'x';
|
||
}
|
||
|
||
curStyle = window.getComputedStyle(el, null);
|
||
if (window.WebKitCSSMatrix) {
|
||
curTransform = curStyle.transform || curStyle.webkitTransform;
|
||
if (curTransform.split(',').length > 6) {
|
||
curTransform = curTransform.split(', ').map(function(a){
|
||
return a.replace(',','.');
|
||
}).join(', ');
|
||
}
|
||
// Some old versions of Webkit choke when 'none' is passed; pass
|
||
// empty string instead in this case
|
||
transformMatrix = new WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
|
||
}
|
||
else {
|
||
transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
|
||
matrix = transformMatrix.toString().split(',');
|
||
}
|
||
|
||
if (axis === 'x') {
|
||
//Latest Chrome and webkits Fix
|
||
if (window.WebKitCSSMatrix)
|
||
curTransform = transformMatrix.m41;
|
||
//Crazy IE10 Matrix
|
||
else if (matrix.length === 16)
|
||
curTransform = parseFloat(matrix[12]);
|
||
//Normal Browsers
|
||
else
|
||
curTransform = parseFloat(matrix[4]);
|
||
}
|
||
if (axis === 'y') {
|
||
//Latest Chrome and webkits Fix
|
||
if (window.WebKitCSSMatrix)
|
||
curTransform = transformMatrix.m42;
|
||
//Crazy IE10 Matrix
|
||
else if (matrix.length === 16)
|
||
curTransform = parseFloat(matrix[13]);
|
||
//Normal Browsers
|
||
else
|
||
curTransform = parseFloat(matrix[5]);
|
||
}
|
||
|
||
return curTransform || 0;
|
||
};
|
||
|
||
$.requestAnimationFrame = function (callback) {
|
||
if (window.requestAnimationFrame) return window.requestAnimationFrame(callback);
|
||
else if (window.webkitRequestAnimationFrame) return window.webkitRequestAnimationFrame(callback);
|
||
else if (window.mozRequestAnimationFrame) return window.mozRequestAnimationFrame(callback);
|
||
else {
|
||
return window.setTimeout(callback, 1000 / 60);
|
||
}
|
||
};
|
||
$.cancelAnimationFrame = function (id) {
|
||
if (window.cancelAnimationFrame) return window.cancelAnimationFrame(id);
|
||
else if (window.webkitCancelAnimationFrame) return window.webkitCancelAnimationFrame(id);
|
||
else if (window.mozCancelAnimationFrame) return window.mozCancelAnimationFrame(id);
|
||
else {
|
||
return window.clearTimeout(id);
|
||
}
|
||
};
|
||
$.supportTouch = !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
|
||
|
||
// Remove Diacritics
|
||
var defaultDiacriticsRemovalap = [
|
||
{base:'A', letters:'\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F'},
|
||
{base:'AA',letters:'\uA732'},
|
||
{base:'AE',letters:'\u00C6\u01FC\u01E2'},
|
||
{base:'AO',letters:'\uA734'},
|
||
{base:'AU',letters:'\uA736'},
|
||
{base:'AV',letters:'\uA738\uA73A'},
|
||
{base:'AY',letters:'\uA73C'},
|
||
{base:'B', letters:'\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181'},
|
||
{base:'C', letters:'\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E'},
|
||
{base:'D', letters:'\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779'},
|
||
{base:'DZ',letters:'\u01F1\u01C4'},
|
||
{base:'Dz',letters:'\u01F2\u01C5'},
|
||
{base:'E', letters:'\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E'},
|
||
{base:'F', letters:'\u0046\u24BB\uFF26\u1E1E\u0191\uA77B'},
|
||
{base:'G', letters:'\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E'},
|
||
{base:'H', letters:'\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D'},
|
||
{base:'I', letters:'\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197'},
|
||
{base:'J', letters:'\u004A\u24BF\uFF2A\u0134\u0248'},
|
||
{base:'K', letters:'\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2'},
|
||
{base:'L', letters:'\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780'},
|
||
{base:'LJ',letters:'\u01C7'},
|
||
{base:'Lj',letters:'\u01C8'},
|
||
{base:'M', letters:'\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C'},
|
||
{base:'N', letters:'\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4'},
|
||
{base:'NJ',letters:'\u01CA'},
|
||
{base:'Nj',letters:'\u01CB'},
|
||
{base:'O', letters:'\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C'},
|
||
{base:'OI',letters:'\u01A2'},
|
||
{base:'OO',letters:'\uA74E'},
|
||
{base:'OU',letters:'\u0222'},
|
||
{base:'OE',letters:'\u008C\u0152'},
|
||
{base:'oe',letters:'\u009C\u0153'},
|
||
{base:'P', letters:'\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754'},
|
||
{base:'Q', letters:'\u0051\u24C6\uFF31\uA756\uA758\u024A'},
|
||
{base:'R', letters:'\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782'},
|
||
{base:'S', letters:'\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784'},
|
||
{base:'T', letters:'\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786'},
|
||
{base:'TZ',letters:'\uA728'},
|
||
{base:'U', letters:'\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244'},
|
||
{base:'V', letters:'\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245'},
|
||
{base:'VY',letters:'\uA760'},
|
||
{base:'W', letters:'\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72'},
|
||
{base:'X', letters:'\u0058\u24CD\uFF38\u1E8A\u1E8C'},
|
||
{base:'Y', letters:'\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE'},
|
||
{base:'Z', letters:'\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762'},
|
||
{base:'a', letters:'\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250'},
|
||
{base:'aa',letters:'\uA733'},
|
||
{base:'ae',letters:'\u00E6\u01FD\u01E3'},
|
||
{base:'ao',letters:'\uA735'},
|
||
{base:'au',letters:'\uA737'},
|
||
{base:'av',letters:'\uA739\uA73B'},
|
||
{base:'ay',letters:'\uA73D'},
|
||
{base:'b', letters:'\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253'},
|
||
{base:'c', letters:'\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184'},
|
||
{base:'d', letters:'\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A'},
|
||
{base:'dz',letters:'\u01F3\u01C6'},
|
||
{base:'e', letters:'\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD'},
|
||
{base:'f', letters:'\u0066\u24D5\uFF46\u1E1F\u0192\uA77C'},
|
||
{base:'g', letters:'\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F'},
|
||
{base:'h', letters:'\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265'},
|
||
{base:'hv',letters:'\u0195'},
|
||
{base:'i', letters:'\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131'},
|
||
{base:'j', letters:'\u006A\u24D9\uFF4A\u0135\u01F0\u0249'},
|
||
{base:'k', letters:'\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3'},
|
||
{base:'l', letters:'\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747'},
|
||
{base:'lj',letters:'\u01C9'},
|
||
{base:'m', letters:'\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F'},
|
||
{base:'n', letters:'\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5'},
|
||
{base:'nj',letters:'\u01CC'},
|
||
{base:'o', letters:'\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275'},
|
||
{base:'oi',letters:'\u01A3'},
|
||
{base:'ou',letters:'\u0223'},
|
||
{base:'oo',letters:'\uA74F'},
|
||
{base:'p',letters:'\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755'},
|
||
{base:'q',letters:'\u0071\u24E0\uFF51\u024B\uA757\uA759'},
|
||
{base:'r',letters:'\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783'},
|
||
{base:'s',letters:'\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B'},
|
||
{base:'t',letters:'\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787'},
|
||
{base:'tz',letters:'\uA729'},
|
||
{base:'u',letters: '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289'},
|
||
{base:'v',letters:'\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C'},
|
||
{base:'vy',letters:'\uA761'},
|
||
{base:'w',letters:'\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73'},
|
||
{base:'x',letters:'\u0078\u24E7\uFF58\u1E8B\u1E8D'},
|
||
{base:'y',letters:'\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF'},
|
||
{base:'z',letters:'\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763'}
|
||
];
|
||
|
||
var diacriticsMap = {};
|
||
for (var i=0; i < defaultDiacriticsRemovalap.length; i++){
|
||
var letters = defaultDiacriticsRemovalap[i].letters;
|
||
for (var j=0; j < letters.length ; j++){
|
||
diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base;
|
||
}
|
||
}
|
||
|
||
$.removeDiacritics = function (str) {
|
||
return str.replace(/[^\u0000-\u007E]/g, function(a){
|
||
return diacriticsMap[a] || a;
|
||
});
|
||
};
|
||
// Link to prototype
|
||
$.fn = Dom7.prototype;
|
||
|
||
// Plugins
|
||
$.fn.scrollTo = function (left, top, duration, easing, callback) {
|
||
if (arguments.length === 4 && typeof easing === 'function') {
|
||
callback = easing;
|
||
easing = undefined;
|
||
}
|
||
return this.each(function () {
|
||
var el = this;
|
||
var currentTop, currentLeft, maxTop, maxLeft, newTop, newLeft, scrollTop, scrollLeft;
|
||
var animateTop = top > 0 || top === 0;
|
||
var animateLeft = left > 0 || left === 0;
|
||
if (typeof easing === 'undefined') {
|
||
easing = 'swing';
|
||
}
|
||
if (animateTop) {
|
||
currentTop = el.scrollTop;
|
||
if (!duration) {
|
||
el.scrollTop = top;
|
||
}
|
||
}
|
||
if (animateLeft) {
|
||
currentLeft = el.scrollLeft;
|
||
if (!duration) {
|
||
el.scrollLeft = left;
|
||
}
|
||
}
|
||
if (!duration) return;
|
||
if (animateTop) {
|
||
maxTop = el.scrollHeight - el.offsetHeight;
|
||
newTop = Math.max(Math.min(top, maxTop), 0);
|
||
}
|
||
if (animateLeft) {
|
||
maxLeft = el.scrollWidth - el.offsetWidth;
|
||
newLeft = Math.max(Math.min(left, maxLeft), 0);
|
||
}
|
||
var startTime = null;
|
||
if (animateTop && newTop === currentTop) animateTop = false;
|
||
if (animateLeft && newLeft === currentLeft) animateLeft = false;
|
||
function render(time) {
|
||
if (time === undefined) {
|
||
time = new Date().getTime();
|
||
}
|
||
if (startTime === null) {
|
||
startTime = time;
|
||
}
|
||
var doneLeft, doneTop, done;
|
||
var progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
|
||
var easeProgress = easing === 'linear' ? progress : (0.5 - Math.cos( progress * Math.PI ) / 2);
|
||
if (animateTop) scrollTop = currentTop + (easeProgress * (newTop - currentTop));
|
||
if (animateLeft) scrollLeft = currentLeft + (easeProgress * (newLeft - currentLeft));
|
||
if (animateTop && newTop > currentTop && scrollTop >= newTop) {
|
||
el.scrollTop = newTop;
|
||
done = true;
|
||
}
|
||
if (animateTop && newTop < currentTop && scrollTop <= newTop) {
|
||
el.scrollTop = newTop;
|
||
done = true;
|
||
}
|
||
|
||
if (animateLeft && newLeft > currentLeft && scrollLeft >= newLeft) {
|
||
el.scrollLeft = newLeft;
|
||
done = true;
|
||
}
|
||
if (animateLeft && newLeft < currentLeft && scrollLeft <= newLeft) {
|
||
el.scrollLeft = newLeft;
|
||
done = true;
|
||
}
|
||
|
||
if (done) {
|
||
if (callback) callback();
|
||
return;
|
||
}
|
||
if (animateTop) el.scrollTop = scrollTop;
|
||
if (animateLeft) el.scrollLeft = scrollLeft;
|
||
$.requestAnimationFrame(render);
|
||
}
|
||
$.requestAnimationFrame(render);
|
||
});
|
||
};
|
||
$.fn.scrollTop = function (top, duration, easing, callback) {
|
||
if (arguments.length === 3 && typeof easing === 'function') {
|
||
callback = easing;
|
||
easing = undefined;
|
||
}
|
||
var dom = this;
|
||
if (typeof top === 'undefined') {
|
||
if (dom.length > 0) return dom[0].scrollTop;
|
||
else return null;
|
||
}
|
||
return dom.scrollTo(undefined, top, duration, easing, callback);
|
||
};
|
||
$.fn.scrollLeft = function (left, duration, easing, callback) {
|
||
if (arguments.length === 3 && typeof easing === 'function') {
|
||
callback = easing;
|
||
easing = undefined;
|
||
}
|
||
var dom = this;
|
||
if (typeof left === 'undefined') {
|
||
if (dom.length > 0) return dom[0].scrollLeft;
|
||
else return null;
|
||
}
|
||
return dom.scrollTo(left, undefined, duration, easing, callback);
|
||
};
|
||
|
||
return $;
|
||
})();
|
||
|
||
// Export Dom7 to Framework7
|
||
Framework7.$ = Dom7;
|
||
|
||
// Export to local scope
|
||
var $ = Dom7;
|
||
|
||
// Export to Window
|
||
window.Dom7 = Dom7;
|
||
|
||
|
||
/*========================
|
||
Animate7 Animate Engine
|
||
==========================*/
|
||
var Animate7 = function (elements, props, params) {
|
||
props = props || {};
|
||
params = params || {};
|
||
var defaults = {
|
||
duration: 300,
|
||
easing: 'swing', // or 'linear'
|
||
/* Callbacks
|
||
begin(elements)
|
||
complete(elements)
|
||
progress(elements, complete, remaining, start, tweenValue)
|
||
*/
|
||
};
|
||
|
||
for (var def in defaults) {
|
||
if (typeof params[def] === 'undefined') {
|
||
params[def] = defaults[def];
|
||
}
|
||
}
|
||
|
||
var a = this;
|
||
a.params = params;
|
||
a.props = props;
|
||
a.elements = $(elements);
|
||
if (a.elements.length === 0) {
|
||
return a;
|
||
}
|
||
|
||
a.easingProgress = function (easing, progress) {
|
||
if (easing === 'swing') {
|
||
return 0.5 - Math.cos( progress * Math.PI ) / 2;
|
||
}
|
||
if (typeof easing === 'function') {
|
||
return easing(progress);
|
||
}
|
||
return progress;
|
||
};
|
||
|
||
a.stop = function () {
|
||
if (a.frameId) {
|
||
$.cancelAnimationFrame(a.frameId);
|
||
}
|
||
a.animating = false;
|
||
a.elements.each(function (index, el) {
|
||
delete el.animate7Instance;
|
||
});
|
||
a.que = [];
|
||
};
|
||
a.done = function (complete) {
|
||
a.animating = false;
|
||
a.elements.each(function (index, el) {
|
||
delete el.animate7Instance;
|
||
});
|
||
if (complete) complete(elements);
|
||
if (a.que.length > 0) {
|
||
var que = a.que.shift();
|
||
a.animate(que[0], que[1]);
|
||
}
|
||
};
|
||
a.animating = false;
|
||
a.que = [];
|
||
a.animate = function (props, params) {
|
||
if (a.animating) {
|
||
a.que.push([props, params]);
|
||
return a;
|
||
}
|
||
a.params = params;
|
||
|
||
var _elements = [];
|
||
|
||
// Define & Cache Initials & Units
|
||
a.elements.each(function (index, el) {
|
||
var initialFullValue, initialValue, unit, finalValue, finalFullValue;
|
||
|
||
_elements[index] = {
|
||
_container: el
|
||
};
|
||
|
||
for (var prop in props) {
|
||
initialFullValue = window.getComputedStyle(el, null).getPropertyValue(prop).replace(',', '.');
|
||
initialValue = parseFloat(initialFullValue);
|
||
unit = initialFullValue.replace(initialValue, '');
|
||
finalValue = props[prop];
|
||
finalFullValue = props[prop] + unit;
|
||
_elements[index][prop] = {
|
||
initialFullValue: initialFullValue,
|
||
initialValue: initialValue,
|
||
unit: unit,
|
||
finalValue: finalValue,
|
||
finalFullValue: finalFullValue,
|
||
currentValue: initialValue
|
||
};
|
||
|
||
}
|
||
});
|
||
|
||
var startTime = null,
|
||
time,
|
||
elementsDone = 0,
|
||
propsDone = 0,
|
||
done,
|
||
began = false;
|
||
|
||
a.animating = true;
|
||
|
||
function render() {
|
||
time = new Date().getTime();
|
||
var progress, easeProgress, el;
|
||
if (!began) {
|
||
began = true;
|
||
if (params.begin) params.begin(elements);
|
||
}
|
||
if (startTime === null) {
|
||
startTime = time;
|
||
}
|
||
if (params.progress) {
|
||
params.progress(
|
||
a.elements,
|
||
Math.max(Math.min((time - startTime) / params.duration, 1), 0),
|
||
((startTime + params.duration) - time < 0 ? 0 : (startTime + params.duration) - time),
|
||
startTime
|
||
);
|
||
}
|
||
|
||
for (var i = 0; i < _elements.length; i++) {
|
||
if (done) continue;
|
||
el = _elements[i];
|
||
if (el.done) continue;
|
||
|
||
for (var prop in props) {
|
||
progress = Math.max(Math.min((time - startTime) / params.duration, 1), 0);
|
||
easeProgress = a.easingProgress(params.easing, progress);
|
||
|
||
el[prop].currentValue = el[prop].initialValue + easeProgress * (el[prop].finalValue - el[prop].initialValue);
|
||
|
||
if (el[prop].finalValue > el[prop].initialValue && el[prop].currentValue >= el[prop].finalValue || el[prop].finalValue < el[prop].initialValue && el[prop].currentValue <= el[prop].finalValue) {
|
||
el._container.style[prop] = el[prop].finalValue + el[prop].unit;
|
||
propsDone ++;
|
||
if (propsDone === Object.keys(props).length) {
|
||
el.done = true;
|
||
elementsDone++;
|
||
}
|
||
if (elementsDone === _elements.length) {
|
||
done = true;
|
||
}
|
||
}
|
||
if (done) {
|
||
a.done(params.complete);
|
||
return a;
|
||
}
|
||
el._container.style[prop] = el[prop].currentValue + el[prop].unit;
|
||
}
|
||
}
|
||
|
||
// Then call
|
||
a.frameId = $.requestAnimationFrame(render);
|
||
}
|
||
a.frameId = $.requestAnimationFrame(render);
|
||
return a;
|
||
};
|
||
var foundInstance;
|
||
for (var i = 0; i < a.elements.length; i++) {
|
||
if (a.elements[i].animate7Instance) {
|
||
foundInstance = a.elements[i].animate7Instance;
|
||
}
|
||
else a.elements[i].animate7Instance = a;
|
||
}
|
||
if (foundInstance) {
|
||
return foundInstance.animate(props, params);
|
||
}
|
||
else a.animate(props, params);
|
||
return a;
|
||
};
|
||
window.Animate7 = function (elements, props, params){
|
||
return new Animate7(elements, props, params);
|
||
};
|
||
Dom7.fn.animate = function (props, params) {
|
||
new Animate7(this, props, params);
|
||
return this;
|
||
};
|
||
|
||
/*===========================
|
||
Features Support Detection
|
||
===========================*/
|
||
Framework7.prototype.support = (function () {
|
||
var support = {
|
||
touch: !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch),
|
||
passiveListener: (function () {
|
||
var supportsPassive = false;
|
||
try {
|
||
var opts = Object.defineProperty({}, 'passive', {
|
||
get: function() {
|
||
supportsPassive = true;
|
||
}
|
||
});
|
||
window.addEventListener('testPassiveListener', null, opts);
|
||
} catch (e) {}
|
||
return supportsPassive;
|
||
})()
|
||
};
|
||
|
||
// Export object
|
||
return support;
|
||
})();
|
||
|
||
|
||
/*===========================
|
||
Device/OS Detection
|
||
===========================*/
|
||
Framework7.prototype.device = (function () {
|
||
var device = {};
|
||
var ua = navigator.userAgent;
|
||
var $ = Dom7;
|
||
|
||
var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
|
||
var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
|
||
var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
|
||
var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
|
||
|
||
device.ios = device.android = device.iphone = device.ipad = device.androidChrome = false;
|
||
|
||
// Android
|
||
if (android) {
|
||
device.os = 'android';
|
||
device.osVersion = android[2];
|
||
device.android = true;
|
||
device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0;
|
||
}
|
||
if (ipad || iphone || ipod) {
|
||
device.os = 'ios';
|
||
device.ios = true;
|
||
}
|
||
// iOS
|
||
if (iphone && !ipod) {
|
||
device.osVersion = iphone[2].replace(/_/g, '.');
|
||
device.iphone = true;
|
||
}
|
||
if (ipad) {
|
||
device.osVersion = ipad[2].replace(/_/g, '.');
|
||
device.ipad = true;
|
||
}
|
||
if (ipod) {
|
||
device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
|
||
device.iphone = true;
|
||
}
|
||
// iOS 8+ changed UA
|
||
if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) {
|
||
if (device.osVersion.split('.')[0] === '10') {
|
||
device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0];
|
||
}
|
||
}
|
||
|
||
// Webview
|
||
device.webView = (iphone || ipad || ipod) && ua.match(/.*AppleWebKit(?!.*Safari)/i);
|
||
|
||
// Minimal UI
|
||
if (device.os && device.os === 'ios') {
|
||
var osVersionArr = device.osVersion.split('.');
|
||
device.minimalUi = !device.webView &&
|
||
(ipod || iphone) &&
|
||
(osVersionArr[0] * 1 === 7 ? osVersionArr[1] * 1 >= 1 : osVersionArr[0] * 1 > 7) &&
|
||
$('meta[name="viewport"]').length > 0 && $('meta[name="viewport"]').attr('content').indexOf('minimal-ui') >= 0;
|
||
}
|
||
|
||
// Check for status bar and fullscreen app mode
|
||
var windowWidth = $(window).width();
|
||
var windowHeight = $(window).height();
|
||
device.statusBar = false;
|
||
if (device.webView && (windowWidth * windowHeight === screen.width * screen.height)) {
|
||
device.statusBar = true;
|
||
}
|
||
else {
|
||
device.statusBar = false;
|
||
}
|
||
|
||
// Classes
|
||
var classNames = [];
|
||
|
||
// Pixel Ratio
|
||
device.pixelRatio = window.devicePixelRatio || 1;
|
||
classNames.push('pixel-ratio-' + Math.floor(device.pixelRatio));
|
||
if (device.pixelRatio >= 2) {
|
||
classNames.push('retina');
|
||
}
|
||
|
||
// OS classes
|
||
if (device.os) {
|
||
classNames.push(device.os, device.os + '-' + device.osVersion.split('.')[0], device.os + '-' + device.osVersion.replace(/\./g, '-'));
|
||
if (device.os === 'ios') {
|
||
var major = parseInt(device.osVersion.split('.')[0], 10);
|
||
for (var i = major - 1; i >= 6; i--) {
|
||
classNames.push('ios-gt-' + i);
|
||
}
|
||
}
|
||
|
||
}
|
||
// Status bar classes
|
||
if (device.statusBar) {
|
||
classNames.push('with-statusbar-overlay');
|
||
}
|
||
else {
|
||
$('html').removeClass('with-statusbar-overlay');
|
||
}
|
||
|
||
// Add html classes
|
||
if (classNames.length > 0) $('html').addClass(classNames.join(' '));
|
||
|
||
// Export object
|
||
return device;
|
||
})();
|
||
|
||
|
||
/*===========================
|
||
Plugins prototype
|
||
===========================*/
|
||
Framework7.prototype.plugins = {};
|
||
|
||
|
||
/*===========================
|
||
Template7 Template engine
|
||
===========================*/
|
||
window.Template7 = (function () {
|
||
'use strict';
|
||
function isArray(arr) {
|
||
return Object.prototype.toString.apply(arr) === '[object Array]';
|
||
}
|
||
function isObject(obj) {
|
||
return obj instanceof Object;
|
||
}
|
||
function isFunction(func) {
|
||
return typeof func === 'function';
|
||
}
|
||
function _escape(string) {
|
||
return typeof window !== 'undefined' && window.escape ? window.escape(string) : string
|
||
.replace(/&/g, '&')
|
||
.replace(/</g, '<')
|
||
.replace(/>/g, '>')
|
||
.replace(/"/g, '"');
|
||
}
|
||
var cache = {};
|
||
var quoteSingleRexExp = new RegExp('\'', 'g');
|
||
var quoteDoubleRexExp = new RegExp('"', 'g');
|
||
function helperToSlices(string) {
|
||
var helperParts = string.replace(/[{}#}]/g, '').split(' ');
|
||
var slices = [];
|
||
var shiftIndex, i, j;
|
||
for (i = 0; i < helperParts.length; i++) {
|
||
var part = helperParts[i];
|
||
var blockQuoteRegExp, openingQuote;
|
||
if (i === 0) slices.push(part);
|
||
else {
|
||
if (part.indexOf('"') === 0 || part.indexOf('\'') === 0) {
|
||
blockQuoteRegExp = part.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp;
|
||
openingQuote = part.indexOf('"') === 0 ? '"' : '\'';
|
||
// Plain String
|
||
if (part.match(blockQuoteRegExp).length === 2) {
|
||
// One word string
|
||
slices.push(part);
|
||
}
|
||
else {
|
||
// Find closed Index
|
||
shiftIndex = 0;
|
||
for (j = i + 1; j < helperParts.length; j++) {
|
||
part += ' ' + helperParts[j];
|
||
if (helperParts[j].indexOf(openingQuote) >= 0) {
|
||
shiftIndex = j;
|
||
slices.push(part);
|
||
break;
|
||
}
|
||
}
|
||
if (shiftIndex) i = shiftIndex;
|
||
}
|
||
}
|
||
else {
|
||
if (part.indexOf('=') > 0) {
|
||
// Hash
|
||
var hashParts = part.split('=');
|
||
var hashName = hashParts[0];
|
||
var hashContent = hashParts[1];
|
||
if (hashContent.match(blockQuoteRegExp).length !== 2) {
|
||
shiftIndex = 0;
|
||
for (j = i + 1; j < helperParts.length; j++) {
|
||
hashContent += ' ' + helperParts[j];
|
||
if (helperParts[j].indexOf(openingQuote) >= 0) {
|
||
shiftIndex = j;
|
||
break;
|
||
}
|
||
}
|
||
if (shiftIndex) i = shiftIndex;
|
||
}
|
||
var hash = [hashName, hashContent.replace(blockQuoteRegExp,'')];
|
||
slices.push(hash);
|
||
}
|
||
else {
|
||
// Plain variable
|
||
slices.push(part);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return slices;
|
||
}
|
||
function stringToBlocks(string) {
|
||
var blocks = [], i, j, k;
|
||
if (!string) return [];
|
||
var _blocks = string.split(/({{[^{^}]*}})/);
|
||
for (i = 0; i < _blocks.length; i++) {
|
||
var block = _blocks[i];
|
||
if (block === '') continue;
|
||
if (block.indexOf('{{') < 0) {
|
||
blocks.push({
|
||
type: 'plain',
|
||
content: block
|
||
});
|
||
}
|
||
else {
|
||
if (block.indexOf('{/') >= 0) {
|
||
continue;
|
||
}
|
||
if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) {
|
||
// Simple variable
|
||
blocks.push({
|
||
type: 'variable',
|
||
contextName: block.replace(/[{}]/g, '')
|
||
});
|
||
continue;
|
||
}
|
||
// Helpers
|
||
var helperSlices = helperToSlices(block);
|
||
var helperName = helperSlices[0];
|
||
var isPartial = helperName === '>';
|
||
var helperContext = [];
|
||
var helperHash = {};
|
||
for (j = 1; j < helperSlices.length; j++) {
|
||
var slice = helperSlices[j];
|
||
if (isArray(slice)) {
|
||
// Hash
|
||
helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1];
|
||
}
|
||
else {
|
||
helperContext.push(slice);
|
||
}
|
||
}
|
||
|
||
if (block.indexOf('{#') >= 0) {
|
||
// Condition/Helper
|
||
var helperStartIndex = i;
|
||
var helperContent = '';
|
||
var elseContent = '';
|
||
var toSkip = 0;
|
||
var shiftIndex;
|
||
var foundClosed = false, foundElse = false, foundClosedElse = false, depth = 0;
|
||
for (j = i + 1; j < _blocks.length; j++) {
|
||
if (_blocks[j].indexOf('{{#') >= 0) {
|
||
depth ++;
|
||
}
|
||
if (_blocks[j].indexOf('{{/') >= 0) {
|
||
depth --;
|
||
}
|
||
if (_blocks[j].indexOf('{{#' + helperName) >= 0) {
|
||
helperContent += _blocks[j];
|
||
if (foundElse) elseContent += _blocks[j];
|
||
toSkip ++;
|
||
}
|
||
else if (_blocks[j].indexOf('{{/' + helperName) >= 0) {
|
||
if (toSkip > 0) {
|
||
toSkip--;
|
||
helperContent += _blocks[j];
|
||
if (foundElse) elseContent += _blocks[j];
|
||
}
|
||
else {
|
||
shiftIndex = j;
|
||
foundClosed = true;
|
||
break;
|
||
}
|
||
}
|
||
else if (_blocks[j].indexOf('else') >= 0 && depth === 0) {
|
||
foundElse = true;
|
||
}
|
||
else {
|
||
if (!foundElse) helperContent += _blocks[j];
|
||
if (foundElse) elseContent += _blocks[j];
|
||
}
|
||
|
||
}
|
||
if (foundClosed) {
|
||
if (shiftIndex) i = shiftIndex;
|
||
blocks.push({
|
||
type: 'helper',
|
||
helperName: helperName,
|
||
contextName: helperContext,
|
||
content: helperContent,
|
||
inverseContent: elseContent,
|
||
hash: helperHash
|
||
});
|
||
}
|
||
}
|
||
else if (block.indexOf(' ') > 0) {
|
||
if (isPartial) {
|
||
helperName = '_partial';
|
||
if (helperContext[0]) helperContext[0] = '"' + helperContext[0].replace(/"|'/g, '') + '"';
|
||
}
|
||
blocks.push({
|
||
type: 'helper',
|
||
helperName: helperName,
|
||
contextName: helperContext,
|
||
hash: helperHash
|
||
});
|
||
}
|
||
}
|
||
}
|
||
return blocks;
|
||
}
|
||
var Template7 = function (template, options) {
|
||
var t = this;
|
||
t.template = template;
|
||
|
||
function getCompileFn(block, depth) {
|
||
if (block.content) return compile(block.content, depth);
|
||
else return function () {return ''; };
|
||
}
|
||
function getCompileInverse(block, depth) {
|
||
if (block.inverseContent) return compile(block.inverseContent, depth);
|
||
else return function () {return ''; };
|
||
}
|
||
function getCompileVar(name, ctx) {
|
||
var variable, parts, levelsUp = 0, initialCtx = ctx;
|
||
if (name.indexOf('../') === 0) {
|
||
levelsUp = name.split('../').length - 1;
|
||
var newDepth = ctx.split('_')[1] - levelsUp;
|
||
ctx = 'ctx_' + (newDepth >= 1 ? newDepth : 1);
|
||
parts = name.split('../')[levelsUp].split('.');
|
||
}
|
||
else if (name.indexOf('@global') === 0) {
|
||
ctx = 'Template7.global';
|
||
parts = name.split('@global.')[1].split('.');
|
||
}
|
||
else if (name.indexOf('@root') === 0) {
|
||
ctx = 'root';
|
||
parts = name.split('@root.')[1].split('.');
|
||
}
|
||
else {
|
||
parts = name.split('.');
|
||
}
|
||
variable = ctx;
|
||
for (var i = 0; i < parts.length; i++) {
|
||
var part = parts[i];
|
||
if (part.indexOf('@') === 0) {
|
||
if (i > 0) {
|
||
variable += '[(data && data.' + part.replace('@', '') + ')]';
|
||
}
|
||
else {
|
||
variable = '(data && data.' + name.replace('@', '') + ')';
|
||
}
|
||
}
|
||
else {
|
||
if (isFinite(part)) {
|
||
variable += '[' + part + ']';
|
||
}
|
||
else {
|
||
if (part === 'this' || part.indexOf('this.') >= 0 || part.indexOf('this[') >= 0 || part.indexOf('this(') >= 0) {
|
||
variable = part.replace('this', ctx);
|
||
}
|
||
else {
|
||
variable += '.' + part;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return variable;
|
||
}
|
||
function getCompiledArguments(contextArray, ctx) {
|
||
var arr = [];
|
||
for (var i = 0; i < contextArray.length; i++) {
|
||
if (/^['"]/.test(contextArray[i])) arr.push(contextArray[i]);
|
||
else if (/^(true|false|\d+)$/.test(contextArray[i])) arr.push(contextArray[i]);
|
||
else {
|
||
arr.push(getCompileVar(contextArray[i], ctx));
|
||
}
|
||
}
|
||
|
||
return arr.join(', ');
|
||
}
|
||
function compile(template, depth) {
|
||
depth = depth || 1;
|
||
template = template || t.template;
|
||
if (typeof template !== 'string') {
|
||
throw new Error('Template7: Template must be a string');
|
||
}
|
||
var blocks = stringToBlocks(template);
|
||
if (blocks.length === 0) {
|
||
return function () { return ''; };
|
||
}
|
||
var ctx = 'ctx_' + depth;
|
||
var resultString = '';
|
||
if (depth === 1) {
|
||
resultString += '(function (' + ctx + ', data, root) {\n';
|
||
}
|
||
else {
|
||
resultString += '(function (' + ctx + ', data) {\n';
|
||
}
|
||
if (depth === 1) {
|
||
resultString += 'function isArray(arr){return Object.prototype.toString.apply(arr) === \'[object Array]\';}\n';
|
||
resultString += 'function isFunction(func){return (typeof func === \'function\');}\n';
|
||
resultString += 'function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n';
|
||
resultString += 'root = root || ctx_1 || {};\n';
|
||
}
|
||
resultString += 'var r = \'\';\n';
|
||
var i, j, context;
|
||
for (i = 0; i < blocks.length; i++) {
|
||
var block = blocks[i];
|
||
// Plain block
|
||
if (block.type === 'plain') {
|
||
resultString += 'r +=\'' + (block.content).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'') + '\';';
|
||
continue;
|
||
}
|
||
var variable, compiledArguments;
|
||
// Variable block
|
||
if (block.type === 'variable') {
|
||
variable = getCompileVar(block.contextName, ctx);
|
||
resultString += 'r += c(' + variable + ', ' + ctx + ');';
|
||
}
|
||
// Helpers block
|
||
if (block.type === 'helper') {
|
||
if (block.helperName in t.helpers) {
|
||
compiledArguments = getCompiledArguments(block.contextName, ctx);
|
||
|
||
resultString += 'r += (Template7.helpers.' + block.helperName + ').call(' + ctx + ', ' + (compiledArguments && (compiledArguments + ', ')) +'{hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth + 1) + ', inverse: ' + getCompileInverse(block, depth + 1) + ', root: root});';
|
||
|
||
}
|
||
else {
|
||
if (block.contextName.length > 0) {
|
||
throw new Error('Template7: Missing helper: "' + block.helperName + '"');
|
||
}
|
||
else {
|
||
variable = getCompileVar(block.helperName, ctx);
|
||
resultString += 'if (' + variable + ') {';
|
||
resultString += 'if (isArray(' + variable + ')) {';
|
||
resultString += 'r += (Template7.helpers.each).call(' + ctx + ', ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth+1) + ', inverse: ' + getCompileInverse(block, depth+1) + ', root: root});';
|
||
resultString += '}else {';
|
||
resultString += 'r += (Template7.helpers.with).call(' + ctx + ', ' + variable + ', {hash:' + JSON.stringify(block.hash) + ', data: data || {}, fn: ' + getCompileFn(block, depth+1) + ', inverse: ' + getCompileInverse(block, depth+1) + ', root: root});';
|
||
resultString += '}}';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
resultString += '\nreturn r;})';
|
||
return eval.call(window, resultString);
|
||
}
|
||
t.compile = function (template) {
|
||
if (!t.compiled) {
|
||
t.compiled = compile(template);
|
||
}
|
||
return t.compiled;
|
||
};
|
||
};
|
||
Template7.prototype = {
|
||
options: {},
|
||
partials: {},
|
||
helpers: {
|
||
'_partial' : function (partialName, options) {
|
||
var p = Template7.prototype.partials[partialName];
|
||
if (!p || (p && !p.template)) return '';
|
||
if (!p.compiled) {
|
||
p.compiled = new Template7(p.template).compile();
|
||
}
|
||
var ctx = this;
|
||
for (var hashName in options.hash) {
|
||
ctx[hashName] = options.hash[hashName];
|
||
}
|
||
return p.compiled(ctx, options.data, options.root);
|
||
},
|
||
'escape': function (context, options) {
|
||
if (typeof context !== 'string') {
|
||
throw new Error('Template7: Passed context to "escape" helper should be a string');
|
||
}
|
||
return _escape(context);
|
||
},
|
||
'if': function (context, options) {
|
||
if (isFunction(context)) { context = context.call(this); }
|
||
if (context) {
|
||
return options.fn(this, options.data);
|
||
}
|
||
else {
|
||
return options.inverse(this, options.data);
|
||
}
|
||
},
|
||
'unless': function (context, options) {
|
||
if (isFunction(context)) { context = context.call(this); }
|
||
if (!context) {
|
||
return options.fn(this, options.data);
|
||
}
|
||
else {
|
||
return options.inverse(this, options.data);
|
||
}
|
||
},
|
||
'each': function (context, options) {
|
||
var ret = '', i = 0;
|
||
if (isFunction(context)) { context = context.call(this); }
|
||
if (isArray(context)) {
|
||
if (options.hash.reverse) {
|
||
context = context.reverse();
|
||
}
|
||
for (i = 0; i < context.length; i++) {
|
||
ret += options.fn(context[i], {first: i === 0, last: i === context.length - 1, index: i});
|
||
}
|
||
if (options.hash.reverse) {
|
||
context = context.reverse();
|
||
}
|
||
}
|
||
else {
|
||
for (var key in context) {
|
||
i++;
|
||
ret += options.fn(context[key], {key: key});
|
||
}
|
||
}
|
||
if (i > 0) return ret;
|
||
else return options.inverse(this);
|
||
},
|
||
'with': function (context, options) {
|
||
if (isFunction(context)) { context = context.call(this); }
|
||
return options.fn(context);
|
||
},
|
||
'join': function (context, options) {
|
||
if (isFunction(context)) { context = context.call(this); }
|
||
return context.join(options.hash.delimiter || options.hash.delimeter);
|
||
},
|
||
'js': function (expression, options) {
|
||
var func;
|
||
if (expression.indexOf('return')>=0) {
|
||
func = '(function(){'+expression+'})';
|
||
}
|
||
else {
|
||
func = '(function(){return ('+expression+')})';
|
||
}
|
||
return eval.call(this, func).call(this);
|
||
},
|
||
'js_compare': function (expression, options) {
|
||
var func;
|
||
if (expression.indexOf('return')>=0) {
|
||
func = '(function(){'+expression+'})';
|
||
}
|
||
else {
|
||
func = '(function(){return ('+expression+')})';
|
||
}
|
||
var condition = eval.call(this, func).call(this);
|
||
if (condition) {
|
||
return options.fn(this, options.data);
|
||
}
|
||
else {
|
||
return options.inverse(this, options.data);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
var t7 = function (template, data) {
|
||
if (arguments.length === 2) {
|
||
var instance = new Template7(template);
|
||
var rendered = instance.compile()(data);
|
||
instance = null;
|
||
return (rendered);
|
||
}
|
||
else return new Template7(template);
|
||
};
|
||
t7.registerHelper = function (name, fn) {
|
||
Template7.prototype.helpers[name] = fn;
|
||
};
|
||
t7.unregisterHelper = function (name) {
|
||
Template7.prototype.helpers[name] = undefined;
|
||
delete Template7.prototype.helpers[name];
|
||
};
|
||
t7.registerPartial = function (name, template) {
|
||
Template7.prototype.partials[name] = {template: template};
|
||
};
|
||
t7.unregisterPartial = function (name, template) {
|
||
if (Template7.prototype.partials[name]) {
|
||
Template7.prototype.partials[name] = undefined;
|
||
delete Template7.prototype.partials[name];
|
||
}
|
||
};
|
||
t7.compile = function (template, options) {
|
||
var instance = new Template7(template, options);
|
||
return instance.compile();
|
||
};
|
||
|
||
t7.options = Template7.prototype.options;
|
||
t7.helpers = Template7.prototype.helpers;
|
||
t7.partials = Template7.prototype.partials;
|
||
return t7;
|
||
})();
|
||
|
||
/*===========================
|
||
Swiper
|
||
===========================*/
|
||
window.Swiper = function (container, params) {
|
||
if (!(this instanceof Swiper)) return new Swiper(container, params);
|
||
var defaults = {
|
||
direction: 'horizontal',
|
||
touchEventsTarget: 'container',
|
||
initialSlide: 0,
|
||
speed: 300,
|
||
// autoplay
|
||
autoplay: false,
|
||
autoplayDisableOnInteraction: true,
|
||
autoplayStopOnLast: false,
|
||
// To support iOS's swipe-to-go-back gesture (when being used in-app, with UIWebView).
|
||
iOSEdgeSwipeDetection: false,
|
||
iOSEdgeSwipeThreshold: 20,
|
||
// Free mode
|
||
freeMode: false,
|
||
freeModeMomentum: true,
|
||
freeModeMomentumRatio: 1,
|
||
freeModeMomentumBounce: true,
|
||
freeModeMomentumBounceRatio: 1,
|
||
freeModeMomentumVelocityRatio: 1,
|
||
freeModeSticky: false,
|
||
freeModeMinimumVelocity: 0.02,
|
||
// Autoheight
|
||
autoHeight: false,
|
||
// Set wrapper width
|
||
setWrapperSize: false,
|
||
// Virtual Translate
|
||
virtualTranslate: false,
|
||
// Effects
|
||
effect: 'slide', // 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
|
||
coverflow: {
|
||
rotate: 50,
|
||
stretch: 0,
|
||
depth: 100,
|
||
modifier: 1,
|
||
slideShadows : true
|
||
},
|
||
flip: {
|
||
slideShadows : true,
|
||
limitRotation: true
|
||
},
|
||
cube: {
|
||
slideShadows: true,
|
||
shadow: true,
|
||
shadowOffset: 20,
|
||
shadowScale: 0.94
|
||
},
|
||
fade: {
|
||
crossFade: false
|
||
},
|
||
// Parallax
|
||
parallax: false,
|
||
// Zoom
|
||
zoom: false,
|
||
zoomMax: 3,
|
||
zoomMin: 1,
|
||
zoomToggle: true,
|
||
// Scrollbar
|
||
scrollbar: null,
|
||
scrollbarHide: true,
|
||
scrollbarDraggable: false,
|
||
scrollbarSnapOnRelease: false,
|
||
// Keyboard Mousewheel
|
||
keyboardControl: false,
|
||
mousewheelControl: false,
|
||
mousewheelReleaseOnEdges: false,
|
||
mousewheelInvert: false,
|
||
mousewheelForceToAxis: false,
|
||
mousewheelSensitivity: 1,
|
||
mousewheelEventsTarged: 'container',
|
||
// Hash Navigation
|
||
hashnav: false,
|
||
hashnavWatchState: false,
|
||
// History
|
||
history: false,
|
||
// Commong Nav State
|
||
replaceState: false,
|
||
// Breakpoints
|
||
breakpoints: undefined,
|
||
// Slides grid
|
||
spaceBetween: 0,
|
||
slidesPerView: 1,
|
||
slidesPerColumn: 1,
|
||
slidesPerColumnFill: 'column',
|
||
slidesPerGroup: 1,
|
||
centeredSlides: false,
|
||
slidesOffsetBefore: 0, // in px
|
||
slidesOffsetAfter: 0, // in px
|
||
// Round length
|
||
roundLengths: false,
|
||
// Touches
|
||
touchRatio: 1,
|
||
touchAngle: 45,
|
||
simulateTouch: true,
|
||
shortSwipes: true,
|
||
longSwipes: true,
|
||
longSwipesRatio: 0.5,
|
||
longSwipesMs: 300,
|
||
followFinger: true,
|
||
onlyExternal: false,
|
||
threshold: 0,
|
||
touchMoveStopPropagation: true,
|
||
touchReleaseOnEdges: false,
|
||
// Unique Navigation Elements
|
||
uniqueNavElements: true,
|
||
// Pagination
|
||
pagination: null,
|
||
paginationElement: 'span',
|
||
paginationClickable: false,
|
||
paginationHide: false,
|
||
paginationBulletRender: null,
|
||
paginationProgressRender: null,
|
||
paginationFractionRender: null,
|
||
paginationCustomRender: null,
|
||
paginationType: 'bullets', // 'bullets' or 'progress' or 'fraction' or 'custom'
|
||
// Resistance
|
||
resistance: true,
|
||
resistanceRatio: 0.85,
|
||
// Next/prev buttons
|
||
nextButton: null,
|
||
prevButton: null,
|
||
// Progress
|
||
watchSlidesProgress: false,
|
||
watchSlidesVisibility: false,
|
||
// Cursor
|
||
grabCursor: false,
|
||
// Clicks
|
||
preventClicks: true,
|
||
preventClicksPropagation: true,
|
||
slideToClickedSlide: false,
|
||
// Lazy Loading
|
||
lazyLoading: false,
|
||
lazyLoadingInPrevNext: false,
|
||
lazyLoadingInPrevNextAmount: 1,
|
||
lazyLoadingOnTransitionStart: false,
|
||
// Images
|
||
preloadImages: true,
|
||
updateOnImagesReady: true,
|
||
// loop
|
||
loop: false,
|
||
loopAdditionalSlides: 0,
|
||
loopedSlides: null,
|
||
// Control
|
||
control: undefined,
|
||
controlInverse: false,
|
||
controlBy: 'slide', //or 'container'
|
||
normalizeSlideIndex: true,
|
||
// Swiping/no swiping
|
||
allowSwipeToPrev: true,
|
||
allowSwipeToNext: true,
|
||
swipeHandler: null, //'.swipe-handler',
|
||
noSwiping: true,
|
||
noSwipingClass: 'swiper-no-swiping',
|
||
// Passive Listeners
|
||
passiveListeners: true,
|
||
// NS
|
||
containerModifierClass: 'swiper-container-', // NEW
|
||
slideClass: 'swiper-slide',
|
||
slideActiveClass: 'swiper-slide-active',
|
||
slideDuplicateActiveClass: 'swiper-slide-duplicate-active',
|
||
slideVisibleClass: 'swiper-slide-visible',
|
||
slideDuplicateClass: 'swiper-slide-duplicate',
|
||
slideNextClass: 'swiper-slide-next',
|
||
slideDuplicateNextClass: 'swiper-slide-duplicate-next',
|
||
slidePrevClass: 'swiper-slide-prev',
|
||
slideDuplicatePrevClass: 'swiper-slide-duplicate-prev',
|
||
wrapperClass: 'swiper-wrapper',
|
||
bulletClass: 'swiper-pagination-bullet',
|
||
bulletActiveClass: 'swiper-pagination-bullet-active',
|
||
buttonDisabledClass: 'swiper-button-disabled',
|
||
paginationCurrentClass: 'swiper-pagination-current',
|
||
paginationTotalClass: 'swiper-pagination-total',
|
||
paginationHiddenClass: 'swiper-pagination-hidden',
|
||
paginationProgressbarClass: 'swiper-pagination-progressbar',
|
||
paginationClickableClass: 'swiper-pagination-clickable', // NEW
|
||
paginationModifierClass: 'swiper-pagination-', // NEW
|
||
lazyLoadingClass: 'swiper-lazy',
|
||
lazyStatusLoadingClass: 'swiper-lazy-loading',
|
||
lazyStatusLoadedClass: 'swiper-lazy-loaded',
|
||
lazyPreloaderClass: 'swiper-lazy-preloader',
|
||
notificationClass: 'swiper-notification',
|
||
preloaderClass: 'preloader',
|
||
zoomContainerClass: 'swiper-zoom-container',
|
||
|
||
// Observer
|
||
observer: false,
|
||
observeParents: false,
|
||
// Accessibility
|
||
a11y: false,
|
||
prevSlideMessage: 'Previous slide',
|
||
nextSlideMessage: 'Next slide',
|
||
firstSlideMessage: 'This is the first slide',
|
||
lastSlideMessage: 'This is the last slide',
|
||
paginationBulletMessage: 'Go to slide {{index}}',
|
||
// Callbacks
|
||
runCallbacksOnInit: true
|
||
/*
|
||
Callbacks:
|
||
onInit: function (swiper)
|
||
onDestroy: function (swiper)
|
||
onClick: function (swiper, e)
|
||
onTap: function (swiper, e)
|
||
onDoubleTap: function (swiper, e)
|
||
onSliderMove: function (swiper, e)
|
||
onSlideChangeStart: function (swiper)
|
||
onSlideChangeEnd: function (swiper)
|
||
onTransitionStart: function (swiper)
|
||
onTransitionEnd: function (swiper)
|
||
onImagesReady: function (swiper)
|
||
onProgress: function (swiper, progress)
|
||
onTouchStart: function (swiper, e)
|
||
onTouchMove: function (swiper, e)
|
||
onTouchMoveOpposite: function (swiper, e)
|
||
onTouchEnd: function (swiper, e)
|
||
onReachBeginning: function (swiper)
|
||
onReachEnd: function (swiper)
|
||
onSetTransition: function (swiper, duration)
|
||
onSetTranslate: function (swiper, translate)
|
||
onAutoplayStart: function (swiper)
|
||
onAutoplayStop: function (swiper),
|
||
onLazyImageLoad: function (swiper, slide, image)
|
||
onLazyImageReady: function (swiper, slide, image)
|
||
*/
|
||
|
||
};
|
||
var initialVirtualTranslate = params && params.virtualTranslate;
|
||
|
||
params = params || {};
|
||
var originalParams = {};
|
||
for (var param in params) {
|
||
if (typeof params[param] === 'object' && params[param] !== null && !(params[param].nodeType || params[param] === window || params[param] === document || (typeof Dom7 !== 'undefined' && params[param] instanceof Dom7) || (typeof jQuery !== 'undefined' && params[param] instanceof jQuery))) {
|
||
originalParams[param] = {};
|
||
for (var deepParam in params[param]) {
|
||
originalParams[param][deepParam] = params[param][deepParam];
|
||
}
|
||
}
|
||
else {
|
||
originalParams[param] = params[param];
|
||
}
|
||
}
|
||
for (var def in defaults) {
|
||
if (typeof params[def] === 'undefined') {
|
||
params[def] = defaults[def];
|
||
}
|
||
else if (typeof params[def] === 'object') {
|
||
for (var deepDef in defaults[def]) {
|
||
if (typeof params[def][deepDef] === 'undefined') {
|
||
params[def][deepDef] = defaults[def][deepDef];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Swiper
|
||
var s = this;
|
||
|
||
// Params
|
||
s.params = params;
|
||
s.originalParams = originalParams;
|
||
|
||
// Classname
|
||
s.classNames = [];
|
||
/*=========================
|
||
Dom Library and plugins
|
||
===========================*/
|
||
if (typeof $ !== 'undefined' && typeof Dom7 !== 'undefined'){
|
||
$ = Dom7;
|
||
}
|
||
if (typeof $ === 'undefined') {
|
||
if (typeof Dom7 === 'undefined') {
|
||
$ = window.Dom7 || window.Zepto || window.jQuery;
|
||
}
|
||
else {
|
||
$ = Dom7;
|
||
}
|
||
if (!$) return;
|
||
}
|
||
// Export it to Swiper instance
|
||
s.$ = $;
|
||
|
||
/*=========================
|
||
Breakpoints
|
||
===========================*/
|
||
s.currentBreakpoint = undefined;
|
||
s.getActiveBreakpoint = function () {
|
||
//Get breakpoint for window width
|
||
if (!s.params.breakpoints) return false;
|
||
var breakpoint = false;
|
||
var points = [], point;
|
||
for ( point in s.params.breakpoints ) {
|
||
if (s.params.breakpoints.hasOwnProperty(point)) {
|
||
points.push(point);
|
||
}
|
||
}
|
||
points.sort(function (a, b) {
|
||
return parseInt(a, 10) > parseInt(b, 10);
|
||
});
|
||
for (var i = 0; i < points.length; i++) {
|
||
point = points[i];
|
||
if (point >= window.innerWidth && !breakpoint) {
|
||
breakpoint = point;
|
||
}
|
||
}
|
||
return breakpoint || 'max';
|
||
};
|
||
s.setBreakpoint = function () {
|
||
//Set breakpoint for window width and update parameters
|
||
var breakpoint = s.getActiveBreakpoint();
|
||
if (breakpoint && s.currentBreakpoint !== breakpoint) {
|
||
var breakPointsParams = breakpoint in s.params.breakpoints ? s.params.breakpoints[breakpoint] : s.originalParams;
|
||
var needsReLoop = s.params.loop && (breakPointsParams.slidesPerView !== s.params.slidesPerView);
|
||
for ( var param in breakPointsParams ) {
|
||
s.params[param] = breakPointsParams[param];
|
||
}
|
||
s.currentBreakpoint = breakpoint;
|
||
if(needsReLoop && s.destroyLoop) {
|
||
s.reLoop(true);
|
||
}
|
||
}
|
||
};
|
||
// Set breakpoint on load
|
||
if (s.params.breakpoints) {
|
||
s.setBreakpoint();
|
||
}
|
||
|
||
/*=========================
|
||
Preparation - Define Container, Wrapper and Pagination
|
||
===========================*/
|
||
s.container = $(container);
|
||
if (s.container.length === 0) return;
|
||
if (s.container.length > 1) {
|
||
var swipers = [];
|
||
s.container.each(function () {
|
||
var container = this;
|
||
swipers.push(new Swiper(this, params));
|
||
});
|
||
return swipers;
|
||
}
|
||
|
||
// Save instance in container HTML Element and in data
|
||
s.container[0].swiper = s;
|
||
s.container.data('swiper', s);
|
||
|
||
s.classNames.push(s.params.containerModifierClass + s.params.direction);
|
||
|
||
if (s.params.freeMode) {
|
||
s.classNames.push(s.params.containerModifierClass + 'free-mode');
|
||
}
|
||
if (!s.support.flexbox) {
|
||
s.classNames.push(s.params.containerModifierClass + 'no-flexbox');
|
||
s.params.slidesPerColumn = 1;
|
||
}
|
||
if (s.params.autoHeight) {
|
||
s.classNames.push(s.params.containerModifierClass + 'autoheight');
|
||
}
|
||
// Enable slides progress when required
|
||
if (s.params.parallax || s.params.watchSlidesVisibility) {
|
||
s.params.watchSlidesProgress = true;
|
||
}
|
||
// Max resistance when touchReleaseOnEdges
|
||
if (s.params.touchReleaseOnEdges) {
|
||
s.params.resistanceRatio = 0;
|
||
}
|
||
// Coverflow / 3D
|
||
if (['cube', 'coverflow', 'flip'].indexOf(s.params.effect) >= 0) {
|
||
if (s.support.transforms3d) {
|
||
s.params.watchSlidesProgress = true;
|
||
s.classNames.push(s.params.containerModifierClass + '3d');
|
||
}
|
||
else {
|
||
s.params.effect = 'slide';
|
||
}
|
||
}
|
||
if (s.params.effect !== 'slide') {
|
||
s.classNames.push(s.params.containerModifierClass + s.params.effect);
|
||
}
|
||
if (s.params.effect === 'cube') {
|
||
s.params.resistanceRatio = 0;
|
||
s.params.slidesPerView = 1;
|
||
s.params.slidesPerColumn = 1;
|
||
s.params.slidesPerGroup = 1;
|
||
s.params.centeredSlides = false;
|
||
s.params.spaceBetween = 0;
|
||
s.params.virtualTranslate = true;
|
||
s.params.setWrapperSize = false;
|
||
}
|
||
if (s.params.effect === 'fade' || s.params.effect === 'flip') {
|
||
s.params.slidesPerView = 1;
|
||
s.params.slidesPerColumn = 1;
|
||
s.params.slidesPerGroup = 1;
|
||
s.params.watchSlidesProgress = true;
|
||
s.params.spaceBetween = 0;
|
||
s.params.setWrapperSize = false;
|
||
if (typeof initialVirtualTranslate === 'undefined') {
|
||
s.params.virtualTranslate = true;
|
||
}
|
||
}
|
||
|
||
// Grab Cursor
|
||
if (s.params.grabCursor && s.support.touch) {
|
||
s.params.grabCursor = false;
|
||
}
|
||
|
||
// Wrapper
|
||
s.wrapper = s.container.children('.' + s.params.wrapperClass);
|
||
|
||
// Pagination
|
||
if (s.params.pagination) {
|
||
s.paginationContainer = $(s.params.pagination);
|
||
if (s.params.uniqueNavElements && typeof s.params.pagination === 'string' && s.paginationContainer.length > 1 && s.container.find(s.params.pagination).length === 1) {
|
||
s.paginationContainer = s.container.find(s.params.pagination);
|
||
}
|
||
|
||
if (s.params.paginationType === 'bullets' && s.params.paginationClickable) {
|
||
s.paginationContainer.addClass(s.params.paginationModifierClass + 'clickable');
|
||
}
|
||
else {
|
||
s.params.paginationClickable = false;
|
||
}
|
||
s.paginationContainer.addClass(s.params.paginationModifierClass + s.params.paginationType);
|
||
}
|
||
// Next/Prev Buttons
|
||
if (s.params.nextButton || s.params.prevButton) {
|
||
if (s.params.nextButton) {
|
||
s.nextButton = $(s.params.nextButton);
|
||
if (s.params.uniqueNavElements && typeof s.params.nextButton === 'string' && s.nextButton.length > 1 && s.container.find(s.params.nextButton).length === 1) {
|
||
s.nextButton = s.container.find(s.params.nextButton);
|
||
}
|
||
}
|
||
if (s.params.prevButton) {
|
||
s.prevButton = $(s.params.prevButton);
|
||
if (s.params.uniqueNavElements && typeof s.params.prevButton === 'string' && s.prevButton.length > 1 && s.container.find(s.params.prevButton).length === 1) {
|
||
s.prevButton = s.container.find(s.params.prevButton);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Is Horizontal
|
||
s.isHorizontal = function () {
|
||
return s.params.direction === 'horizontal';
|
||
};
|
||
// s.isH = isH;
|
||
|
||
// RTL
|
||
s.rtl = s.isHorizontal() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');
|
||
if (s.rtl) {
|
||
s.classNames.push(s.params.containerModifierClass + 'rtl');
|
||
}
|
||
|
||
// Wrong RTL support
|
||
if (s.rtl) {
|
||
s.wrongRTL = s.wrapper.css('display') === '-webkit-box';
|
||
}
|
||
|
||
// Columns
|
||
if (s.params.slidesPerColumn > 1) {
|
||
s.classNames.push(s.params.containerModifierClass + 'multirow');
|
||
}
|
||
|
||
// Check for Android
|
||
if (s.device.android) {
|
||
s.classNames.push(s.params.containerModifierClass + 'android');
|
||
}
|
||
|
||
// Add classes
|
||
s.container.addClass(s.classNames.join(' '));
|
||
|
||
// Translate
|
||
s.translate = 0;
|
||
|
||
// Progress
|
||
s.progress = 0;
|
||
|
||
// Velocity
|
||
s.velocity = 0;
|
||
|
||
/*=========================
|
||
Locks, unlocks
|
||
===========================*/
|
||
s.lockSwipeToNext = function () {
|
||
s.params.allowSwipeToNext = false;
|
||
if (s.params.allowSwipeToPrev === false && s.params.grabCursor) {
|
||
s.unsetGrabCursor();
|
||
}
|
||
};
|
||
s.lockSwipeToPrev = function () {
|
||
s.params.allowSwipeToPrev = false;
|
||
if (s.params.allowSwipeToNext === false && s.params.grabCursor) {
|
||
s.unsetGrabCursor();
|
||
}
|
||
};
|
||
s.lockSwipes = function () {
|
||
s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;
|
||
if (s.params.grabCursor) s.unsetGrabCursor();
|
||
};
|
||
s.unlockSwipeToNext = function () {
|
||
s.params.allowSwipeToNext = true;
|
||
if (s.params.allowSwipeToPrev === true && s.params.grabCursor) {
|
||
s.setGrabCursor();
|
||
}
|
||
};
|
||
s.unlockSwipeToPrev = function () {
|
||
s.params.allowSwipeToPrev = true;
|
||
if (s.params.allowSwipeToNext === true && s.params.grabCursor) {
|
||
s.setGrabCursor();
|
||
}
|
||
};
|
||
s.unlockSwipes = function () {
|
||
s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;
|
||
if (s.params.grabCursor) s.setGrabCursor();
|
||
};
|
||
|
||
/*=========================
|
||
Round helper
|
||
===========================*/
|
||
function round(a) {
|
||
return Math.floor(a);
|
||
}
|
||
/*=========================
|
||
Set grab cursor
|
||
===========================*/
|
||
s.setGrabCursor = function(moving) {
|
||
s.container[0].style.cursor = 'move';
|
||
s.container[0].style.cursor = moving ? '-webkit-grabbing' : '-webkit-grab';
|
||
s.container[0].style.cursor = moving ? '-moz-grabbin' : '-moz-grab';
|
||
s.container[0].style.cursor = moving ? 'grabbing': 'grab';
|
||
};
|
||
s.unsetGrabCursor = function () {
|
||
s.container[0].style.cursor = '';
|
||
};
|
||
if (s.params.grabCursor) {
|
||
s.setGrabCursor();
|
||
}
|
||
/*=========================
|
||
Update on Images Ready
|
||
===========================*/
|
||
s.imagesToLoad = [];
|
||
s.imagesLoaded = 0;
|
||
|
||
s.loadImage = function (imgElement, src, srcset, sizes, checkForComplete, callback) {
|
||
var image;
|
||
function onReady () {
|
||
if (callback) callback();
|
||
}
|
||
if (!imgElement.complete || !checkForComplete) {
|
||
if (src) {
|
||
image = new window.Image();
|
||
image.onload = onReady;
|
||
image.onerror = onReady;
|
||
if (sizes) {
|
||
image.sizes = sizes;
|
||
}
|
||
if (srcset) {
|
||
image.srcset = srcset;
|
||
}
|
||
if (src) {
|
||
image.src = src;
|
||
}
|
||
} else {
|
||
onReady();
|
||
}
|
||
|
||
} else {//image already loaded...
|
||
onReady();
|
||
}
|
||
};
|
||
s.preloadImages = function () {
|
||
s.imagesToLoad = s.container.find('img');
|
||
function _onReady() {
|
||
if (typeof s === 'undefined' || s === null) return;
|
||
if (s.imagesLoaded !== undefined) s.imagesLoaded++;
|
||
if (s.imagesLoaded === s.imagesToLoad.length) {
|
||
if (s.params.updateOnImagesReady) s.update();
|
||
s.emit('onImagesReady', s);
|
||
}
|
||
}
|
||
for (var i = 0; i < s.imagesToLoad.length; i++) {
|
||
s.loadImage(s.imagesToLoad[i], (s.imagesToLoad[i].currentSrc || s.imagesToLoad[i].getAttribute('src')), (s.imagesToLoad[i].srcset || s.imagesToLoad[i].getAttribute('srcset')), s.imagesToLoad[i].sizes || s.imagesToLoad[i].getAttribute('sizes'), true, _onReady);
|
||
}
|
||
};
|
||
|
||
/*=========================
|
||
Autoplay
|
||
===========================*/
|
||
s.autoplayTimeoutId = undefined;
|
||
s.autoplaying = false;
|
||
s.autoplayPaused = false;
|
||
function autoplay() {
|
||
var autoplayDelay = s.params.autoplay;
|
||
var activeSlide = s.slides.eq(s.activeIndex);
|
||
if (activeSlide.attr('data-swiper-autoplay')) {
|
||
autoplayDelay = activeSlide.attr('data-swiper-autoplay') || s.params.autoplay;
|
||
}
|
||
s.autoplayTimeoutId = setTimeout(function () {
|
||
if (s.params.loop) {
|
||
s.fixLoop();
|
||
s._slideNext();
|
||
s.emit('onAutoplay', s);
|
||
}
|
||
else {
|
||
if (!s.isEnd) {
|
||
s._slideNext();
|
||
s.emit('onAutoplay', s);
|
||
}
|
||
else {
|
||
if (!params.autoplayStopOnLast) {
|
||
s._slideTo(0);
|
||
s.emit('onAutoplay', s);
|
||
}
|
||
else {
|
||
s.stopAutoplay();
|
||
}
|
||
}
|
||
}
|
||
}, autoplayDelay);
|
||
}
|
||
s.startAutoplay = function () {
|
||
if (typeof s.autoplayTimeoutId !== 'undefined') return false;
|
||
if (!s.params.autoplay) return false;
|
||
if (s.autoplaying) return false;
|
||
s.autoplaying = true;
|
||
s.emit('onAutoplayStart', s);
|
||
autoplay();
|
||
};
|
||
s.stopAutoplay = function (internal) {
|
||
if (!s.autoplayTimeoutId) return;
|
||
if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
|
||
s.autoplaying = false;
|
||
s.autoplayTimeoutId = undefined;
|
||
s.emit('onAutoplayStop', s);
|
||
};
|
||
s.pauseAutoplay = function (speed) {
|
||
if (s.autoplayPaused) return;
|
||
if (s.autoplayTimeoutId) clearTimeout(s.autoplayTimeoutId);
|
||
s.autoplayPaused = true;
|
||
if (speed === 0) {
|
||
s.autoplayPaused = false;
|
||
autoplay();
|
||
}
|
||
else {
|
||
s.wrapper.transitionEnd(function () {
|
||
if (!s) return;
|
||
s.autoplayPaused = false;
|
||
if (!s.autoplaying) {
|
||
s.stopAutoplay();
|
||
}
|
||
else {
|
||
autoplay();
|
||
}
|
||
});
|
||
}
|
||
};
|
||
/*=========================
|
||
Min/Max Translate
|
||
===========================*/
|
||
s.minTranslate = function () {
|
||
return (-s.snapGrid[0]);
|
||
};
|
||
s.maxTranslate = function () {
|
||
return (-s.snapGrid[s.snapGrid.length - 1]);
|
||
};
|
||
/*=========================
|
||
Slider/slides sizes
|
||
===========================*/
|
||
s.updateAutoHeight = function () {
|
||
var activeSlides = [];
|
||
var newHeight = 0;
|
||
|
||
// Find slides currently in view
|
||
if(s.params.slidesPerView !== 'auto' && s.params.slidesPerView > 1) {
|
||
for (i = 0; i < Math.ceil(s.params.slidesPerView); i++) {
|
||
var index = s.activeIndex + i;
|
||
if(index > s.slides.length) break;
|
||
activeSlides.push(s.slides.eq(index)[0]);
|
||
}
|
||
} else {
|
||
activeSlides.push(s.slides.eq(s.activeIndex)[0]);
|
||
}
|
||
|
||
// Find new height from heighest slide in view
|
||
for (i = 0; i < activeSlides.length; i++) {
|
||
if (typeof activeSlides[i] !== 'undefined') {
|
||
var height = activeSlides[i].offsetHeight;
|
||
newHeight = height > newHeight ? height : newHeight;
|
||
}
|
||
}
|
||
|
||
// Update Height
|
||
if (newHeight) s.wrapper.css('height', newHeight + 'px');
|
||
};
|
||
s.updateContainerSize = function () {
|
||
var width, height;
|
||
if (typeof s.params.width !== 'undefined') {
|
||
width = s.params.width;
|
||
}
|
||
else {
|
||
width = s.container[0].clientWidth;
|
||
}
|
||
if (typeof s.params.height !== 'undefined') {
|
||
height = s.params.height;
|
||
}
|
||
else {
|
||
height = s.container[0].clientHeight;
|
||
}
|
||
if (width === 0 && s.isHorizontal() || height === 0 && !s.isHorizontal()) {
|
||
return;
|
||
}
|
||
|
||
//Subtract paddings
|
||
width = width - parseInt(s.container.css('padding-left'), 10) - parseInt(s.container.css('padding-right'), 10);
|
||
height = height - parseInt(s.container.css('padding-top'), 10) - parseInt(s.container.css('padding-bottom'), 10);
|
||
|
||
// Store values
|
||
s.width = width;
|
||
s.height = height;
|
||
s.size = s.isHorizontal() ? s.width : s.height;
|
||
};
|
||
|
||
s.updateSlidesSize = function () {
|
||
s.slides = s.wrapper.children('.' + s.params.slideClass);
|
||
s.snapGrid = [];
|
||
s.slidesGrid = [];
|
||
s.slidesSizesGrid = [];
|
||
|
||
var spaceBetween = s.params.spaceBetween,
|
||
slidePosition = -s.params.slidesOffsetBefore,
|
||
i,
|
||
prevSlideSize = 0,
|
||
index = 0;
|
||
if (typeof s.size === 'undefined') return;
|
||
if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
|
||
spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * s.size;
|
||
}
|
||
|
||
s.virtualSize = -spaceBetween;
|
||
// reset margins
|
||
if (s.rtl) s.slides.css({marginLeft: '', marginTop: ''});
|
||
else s.slides.css({marginRight: '', marginBottom: ''});
|
||
|
||
var slidesNumberEvenToRows;
|
||
if (s.params.slidesPerColumn > 1) {
|
||
if (Math.floor(s.slides.length / s.params.slidesPerColumn) === s.slides.length / s.params.slidesPerColumn) {
|
||
slidesNumberEvenToRows = s.slides.length;
|
||
}
|
||
else {
|
||
slidesNumberEvenToRows = Math.ceil(s.slides.length / s.params.slidesPerColumn) * s.params.slidesPerColumn;
|
||
}
|
||
if (s.params.slidesPerView !== 'auto' && s.params.slidesPerColumnFill === 'row') {
|
||
slidesNumberEvenToRows = Math.max(slidesNumberEvenToRows, s.params.slidesPerView * s.params.slidesPerColumn);
|
||
}
|
||
}
|
||
|
||
// Calc slides
|
||
var slideSize;
|
||
var slidesPerColumn = s.params.slidesPerColumn;
|
||
var slidesPerRow = slidesNumberEvenToRows / slidesPerColumn;
|
||
var numFullColumns = slidesPerRow - (s.params.slidesPerColumn * slidesPerRow - s.slides.length);
|
||
for (i = 0; i < s.slides.length; i++) {
|
||
slideSize = 0;
|
||
var slide = s.slides.eq(i);
|
||
if (s.params.slidesPerColumn > 1) {
|
||
// Set slides order
|
||
var newSlideOrderIndex;
|
||
var column, row;
|
||
if (s.params.slidesPerColumnFill === 'column') {
|
||
column = Math.floor(i / slidesPerColumn);
|
||
row = i - column * slidesPerColumn;
|
||
if (column > numFullColumns || (column === numFullColumns && row === slidesPerColumn-1)) {
|
||
if (++row >= slidesPerColumn) {
|
||
row = 0;
|
||
column++;
|
||
}
|
||
}
|
||
newSlideOrderIndex = column + row * slidesNumberEvenToRows / slidesPerColumn;
|
||
slide
|
||
.css({
|
||
'-webkit-box-ordinal-group': newSlideOrderIndex,
|
||
'-moz-box-ordinal-group': newSlideOrderIndex,
|
||
'-ms-flex-order': newSlideOrderIndex,
|
||
'-webkit-order': newSlideOrderIndex,
|
||
'order': newSlideOrderIndex
|
||
});
|
||
}
|
||
else {
|
||
row = Math.floor(i / slidesPerRow);
|
||
column = i - row * slidesPerRow;
|
||
}
|
||
slide
|
||
.css(
|
||
'margin-' + (s.isHorizontal() ? 'top' : 'left'),
|
||
(row !== 0 && s.params.spaceBetween) && (s.params.spaceBetween + 'px')
|
||
)
|
||
.attr('data-swiper-column', column)
|
||
.attr('data-swiper-row', row);
|
||
|
||
}
|
||
if (slide.css('display') === 'none') continue;
|
||
if (s.params.slidesPerView === 'auto') {
|
||
slideSize = s.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);
|
||
if (s.params.roundLengths) slideSize = round(slideSize);
|
||
}
|
||
else {
|
||
slideSize = (s.size - (s.params.slidesPerView - 1) * spaceBetween) / s.params.slidesPerView;
|
||
if (s.params.roundLengths) slideSize = round(slideSize);
|
||
|
||
if (s.isHorizontal()) {
|
||
s.slides[i].style.width = slideSize + 'px';
|
||
}
|
||
else {
|
||
s.slides[i].style.height = slideSize + 'px';
|
||
}
|
||
}
|
||
s.slides[i].swiperSlideSize = slideSize;
|
||
s.slidesSizesGrid.push(slideSize);
|
||
|
||
|
||
if (s.params.centeredSlides) {
|
||
slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
|
||
if (i === 0) slidePosition = slidePosition - s.size / 2 - spaceBetween;
|
||
if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
|
||
if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
|
||
s.slidesGrid.push(slidePosition);
|
||
}
|
||
else {
|
||
if ((index) % s.params.slidesPerGroup === 0) s.snapGrid.push(slidePosition);
|
||
s.slidesGrid.push(slidePosition);
|
||
slidePosition = slidePosition + slideSize + spaceBetween;
|
||
}
|
||
|
||
s.virtualSize += slideSize + spaceBetween;
|
||
|
||
prevSlideSize = slideSize;
|
||
|
||
index ++;
|
||
}
|
||
s.virtualSize = Math.max(s.virtualSize, s.size) + s.params.slidesOffsetAfter;
|
||
var newSlidesGrid;
|
||
|
||
if (
|
||
s.rtl && s.wrongRTL && (s.params.effect === 'slide' || s.params.effect === 'coverflow')) {
|
||
s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
|
||
}
|
||
if (!s.support.flexbox || s.params.setWrapperSize) {
|
||
if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
|
||
else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});
|
||
}
|
||
|
||
if (s.params.slidesPerColumn > 1) {
|
||
s.virtualSize = (slideSize + s.params.spaceBetween) * slidesNumberEvenToRows;
|
||
s.virtualSize = Math.ceil(s.virtualSize / s.params.slidesPerColumn) - s.params.spaceBetween;
|
||
if (s.isHorizontal()) s.wrapper.css({width: s.virtualSize + s.params.spaceBetween + 'px'});
|
||
else s.wrapper.css({height: s.virtualSize + s.params.spaceBetween + 'px'});
|
||
if (s.params.centeredSlides) {
|
||
newSlidesGrid = [];
|
||
for (i = 0; i < s.snapGrid.length; i++) {
|
||
if (s.snapGrid[i] < s.virtualSize + s.snapGrid[0]) newSlidesGrid.push(s.snapGrid[i]);
|
||
}
|
||
s.snapGrid = newSlidesGrid;
|
||
}
|
||
}
|
||
|
||
// Remove last grid elements depending on width
|
||
if (!s.params.centeredSlides) {
|
||
newSlidesGrid = [];
|
||
for (i = 0; i < s.snapGrid.length; i++) {
|
||
if (s.snapGrid[i] <= s.virtualSize - s.size) {
|
||
newSlidesGrid.push(s.snapGrid[i]);
|
||
}
|
||
}
|
||
s.snapGrid = newSlidesGrid;
|
||
if (Math.floor(s.virtualSize - s.size) - Math.floor(s.snapGrid[s.snapGrid.length - 1]) > 1) {
|
||
s.snapGrid.push(s.virtualSize - s.size);
|
||
}
|
||
}
|
||
if (s.snapGrid.length === 0) s.snapGrid = [0];
|
||
|
||
if (s.params.spaceBetween !== 0) {
|
||
if (s.isHorizontal()) {
|
||
if (s.rtl) s.slides.css({marginLeft: spaceBetween + 'px'});
|
||
else s.slides.css({marginRight: spaceBetween + 'px'});
|
||
}
|
||
else s.slides.css({marginBottom: spaceBetween + 'px'});
|
||
}
|
||
if (s.params.watchSlidesProgress) {
|
||
s.updateSlidesOffset();
|
||
}
|
||
};
|
||
s.updateSlidesOffset = function () {
|
||
for (var i = 0; i < s.slides.length; i++) {
|
||
s.slides[i].swiperSlideOffset = s.isHorizontal() ? s.slides[i].offsetLeft : s.slides[i].offsetTop;
|
||
}
|
||
};
|
||
|
||
/*=========================
|
||
Slider/slides progress
|
||
===========================*/
|
||
s.updateSlidesProgress = function (translate) {
|
||
if (typeof translate === 'undefined') {
|
||
translate = s.translate || 0;
|
||
}
|
||
if (s.slides.length === 0) return;
|
||
if (typeof s.slides[0].swiperSlideOffset === 'undefined') s.updateSlidesOffset();
|
||
|
||
var offsetCenter = -translate;
|
||
if (s.rtl) offsetCenter = translate;
|
||
|
||
// Visible Slides
|
||
s.slides.removeClass(s.params.slideVisibleClass);
|
||
for (var i = 0; i < s.slides.length; i++) {
|
||
var slide = s.slides[i];
|
||
var slideProgress = (offsetCenter + (s.params.centeredSlides ? s.minTranslate() : 0) - slide.swiperSlideOffset) / (slide.swiperSlideSize + s.params.spaceBetween);
|
||
if (s.params.watchSlidesVisibility) {
|
||
var slideBefore = -(offsetCenter - slide.swiperSlideOffset);
|
||
var slideAfter = slideBefore + s.slidesSizesGrid[i];
|
||
var isVisible =
|
||
(slideBefore >= 0 && slideBefore < s.size) ||
|
||
(slideAfter > 0 && slideAfter <= s.size) ||
|
||
(slideBefore <= 0 && slideAfter >= s.size);
|
||
if (isVisible) {
|
||
s.slides.eq(i).addClass(s.params.slideVisibleClass);
|
||
}
|
||
}
|
||
slide.progress = s.rtl ? -slideProgress : slideProgress;
|
||
}
|
||
};
|
||
s.updateProgress = function (translate) {
|
||
if (typeof translate === 'undefined') {
|
||
translate = s.translate || 0;
|
||
}
|
||
var translatesDiff = s.maxTranslate() - s.minTranslate();
|
||
var wasBeginning = s.isBeginning;
|
||
var wasEnd = s.isEnd;
|
||
if (translatesDiff === 0) {
|
||
s.progress = 0;
|
||
s.isBeginning = s.isEnd = true;
|
||
}
|
||
else {
|
||
s.progress = (translate - s.minTranslate()) / (translatesDiff);
|
||
s.isBeginning = s.progress <= 0;
|
||
s.isEnd = s.progress >= 1;
|
||
}
|
||
if (s.isBeginning && !wasBeginning) s.emit('onReachBeginning', s);
|
||
if (s.isEnd && !wasEnd) s.emit('onReachEnd', s);
|
||
|
||
if (s.params.watchSlidesProgress) s.updateSlidesProgress(translate);
|
||
s.emit('onProgress', s, s.progress);
|
||
};
|
||
s.updateActiveIndex = function () {
|
||
var translate = s.rtl ? s.translate : -s.translate;
|
||
var newActiveIndex, i, snapIndex;
|
||
for (i = 0; i < s.slidesGrid.length; i ++) {
|
||
if (typeof s.slidesGrid[i + 1] !== 'undefined') {
|
||
if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1] - (s.slidesGrid[i + 1] - s.slidesGrid[i]) / 2) {
|
||
newActiveIndex = i;
|
||
}
|
||
else if (translate >= s.slidesGrid[i] && translate < s.slidesGrid[i + 1]) {
|
||
newActiveIndex = i + 1;
|
||
}
|
||
}
|
||
else {
|
||
if (translate >= s.slidesGrid[i]) {
|
||
newActiveIndex = i;
|
||
}
|
||
}
|
||
}
|
||
// Normalize slideIndex
|
||
if(s.params.normalizeSlideIndex){
|
||
if (newActiveIndex < 0 || typeof newActiveIndex === 'undefined') newActiveIndex = 0;
|
||
}
|
||
// for (i = 0; i < s.slidesGrid.length; i++) {
|
||
// if (- translate >= s.slidesGrid[i]) {
|
||
// newActiveIndex = i;
|
||
// }
|
||
// }
|
||
snapIndex = Math.floor(newActiveIndex / s.params.slidesPerGroup);
|
||
if (snapIndex >= s.snapGrid.length) snapIndex = s.snapGrid.length - 1;
|
||
|
||
if (newActiveIndex === s.activeIndex) {
|
||
return;
|
||
}
|
||
s.snapIndex = snapIndex;
|
||
s.previousIndex = s.activeIndex;
|
||
s.activeIndex = newActiveIndex;
|
||
s.updateClasses();
|
||
s.updateRealIndex();
|
||
};
|
||
s.updateRealIndex = function(){
|
||
s.realIndex = s.slides.eq(s.activeIndex).attr('data-swiper-slide-index') || s.activeIndex;
|
||
};
|
||
|
||
/*=========================
|
||
Classes
|
||
===========================*/
|
||
s.updateClasses = function () {
|
||
s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass + ' ' + s.params.slideDuplicateActiveClass + ' ' + s.params.slideDuplicateNextClass + ' ' + s.params.slideDuplicatePrevClass);
|
||
var activeSlide = s.slides.eq(s.activeIndex);
|
||
// Active classes
|
||
activeSlide.addClass(s.params.slideActiveClass);
|
||
if (params.loop) {
|
||
// Duplicate to all looped slides
|
||
if (activeSlide.hasClass(s.params.slideDuplicateClass)) {
|
||
s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index="' + s.realIndex + '"]').addClass(s.params.slideDuplicateActiveClass);
|
||
}
|
||
else {
|
||
s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + s.realIndex + '"]').addClass(s.params.slideDuplicateActiveClass);
|
||
}
|
||
}
|
||
// Next Slide
|
||
var nextSlide = activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);
|
||
if (s.params.loop && nextSlide.length === 0) {
|
||
nextSlide = s.slides.eq(0);
|
||
nextSlide.addClass(s.params.slideNextClass);
|
||
}
|
||
// Prev Slide
|
||
var prevSlide = activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);
|
||
if (s.params.loop && prevSlide.length === 0) {
|
||
prevSlide = s.slides.eq(-1);
|
||
prevSlide.addClass(s.params.slidePrevClass);
|
||
}
|
||
if (params.loop) {
|
||
// Duplicate to all looped slides
|
||
if (nextSlide.hasClass(s.params.slideDuplicateClass)) {
|
||
s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index="' + nextSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicateNextClass);
|
||
}
|
||
else {
|
||
s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + nextSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicateNextClass);
|
||
}
|
||
if (prevSlide.hasClass(s.params.slideDuplicateClass)) {
|
||
s.wrapper.children('.' + s.params.slideClass + ':not(.' + s.params.slideDuplicateClass + ')[data-swiper-slide-index="' + prevSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicatePrevClass);
|
||
}
|
||
else {
|
||
s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + prevSlide.attr('data-swiper-slide-index') + '"]').addClass(s.params.slideDuplicatePrevClass);
|
||
}
|
||
}
|
||
|
||
// Pagination
|
||
if (s.paginationContainer && s.paginationContainer.length > 0) {
|
||
// Current/Total
|
||
var current,
|
||
total = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;
|
||
if (s.params.loop) {
|
||
current = Math.ceil((s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup);
|
||
if (current > s.slides.length - 1 - s.loopedSlides * 2) {
|
||
current = current - (s.slides.length - s.loopedSlides * 2);
|
||
}
|
||
if (current > total - 1) current = current - total;
|
||
if (current < 0 && s.params.paginationType !== 'bullets') current = total + current;
|
||
}
|
||
else {
|
||
if (typeof s.snapIndex !== 'undefined') {
|
||
current = s.snapIndex;
|
||
}
|
||
else {
|
||
current = s.activeIndex || 0;
|
||
}
|
||
}
|
||
// Types
|
||
if (s.params.paginationType === 'bullets' && s.bullets && s.bullets.length > 0) {
|
||
s.bullets.removeClass(s.params.bulletActiveClass);
|
||
if (s.paginationContainer.length > 1) {
|
||
s.bullets.each(function () {
|
||
if ($(this).index() === current) $(this).addClass(s.params.bulletActiveClass);
|
||
});
|
||
}
|
||
else {
|
||
s.bullets.eq(current).addClass(s.params.bulletActiveClass);
|
||
}
|
||
}
|
||
if (s.params.paginationType === 'fraction') {
|
||
s.paginationContainer.find('.' + s.params.paginationCurrentClass).text(current + 1);
|
||
s.paginationContainer.find('.' + s.params.paginationTotalClass).text(total);
|
||
}
|
||
if (s.params.paginationType === 'progress') {
|
||
var scale = (current + 1) / total,
|
||
scaleX = scale,
|
||
scaleY = 1;
|
||
if (!s.isHorizontal()) {
|
||
scaleY = scale;
|
||
scaleX = 1;
|
||
}
|
||
s.paginationContainer.find('.' + s.params.paginationProgressbarClass).transform('translate3d(0,0,0) scaleX(' + scaleX + ') scaleY(' + scaleY + ')').transition(s.params.speed);
|
||
}
|
||
if (s.params.paginationType === 'custom' && s.params.paginationCustomRender) {
|
||
s.paginationContainer.html(s.params.paginationCustomRender(s, current + 1, total));
|
||
s.emit('onPaginationRendered', s, s.paginationContainer[0]);
|
||
}
|
||
}
|
||
|
||
// Next/active buttons
|
||
if (!s.params.loop) {
|
||
if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {
|
||
if (s.isBeginning) {
|
||
s.prevButton.addClass(s.params.buttonDisabledClass);
|
||
if (s.params.a11y && s.a11y) s.a11y.disable(s.prevButton);
|
||
}
|
||
else {
|
||
s.prevButton.removeClass(s.params.buttonDisabledClass);
|
||
if (s.params.a11y && s.a11y) s.a11y.enable(s.prevButton);
|
||
}
|
||
}
|
||
if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {
|
||
if (s.isEnd) {
|
||
s.nextButton.addClass(s.params.buttonDisabledClass);
|
||
if (s.params.a11y && s.a11y) s.a11y.disable(s.nextButton);
|
||
}
|
||
else {
|
||
s.nextButton.removeClass(s.params.buttonDisabledClass);
|
||
if (s.params.a11y && s.a11y) s.a11y.enable(s.nextButton);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
/*=========================
|
||
Pagination
|
||
===========================*/
|
||
s.updatePagination = function () {
|
||
if (!s.params.pagination) return;
|
||
if (s.paginationContainer && s.paginationContainer.length > 0) {
|
||
var paginationHTML = '';
|
||
if (s.params.paginationType === 'bullets') {
|
||
var numberOfBullets = s.params.loop ? Math.ceil((s.slides.length - s.loopedSlides * 2) / s.params.slidesPerGroup) : s.snapGrid.length;
|
||
for (var i = 0; i < numberOfBullets; i++) {
|
||
if (s.params.paginationBulletRender) {
|
||
paginationHTML += s.params.paginationBulletRender(s, i, s.params.bulletClass);
|
||
}
|
||
else {
|
||
paginationHTML += '<' + s.params.paginationElement+' class="' + s.params.bulletClass + '"></' + s.params.paginationElement + '>';
|
||
}
|
||
}
|
||
s.paginationContainer.html(paginationHTML);
|
||
s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);
|
||
if (s.params.paginationClickable && s.params.a11y && s.a11y) {
|
||
s.a11y.initPagination();
|
||
}
|
||
}
|
||
if (s.params.paginationType === 'fraction') {
|
||
if (s.params.paginationFractionRender) {
|
||
paginationHTML = s.params.paginationFractionRender(s, s.params.paginationCurrentClass, s.params.paginationTotalClass);
|
||
}
|
||
else {
|
||
paginationHTML =
|
||
'<span class="' + s.params.paginationCurrentClass + '"></span>' +
|
||
' / ' +
|
||
'<span class="' + s.params.paginationTotalClass+'"></span>';
|
||
}
|
||
s.paginationContainer.html(paginationHTML);
|
||
}
|
||
if (s.params.paginationType === 'progress') {
|
||
if (s.params.paginationProgressRender) {
|
||
paginationHTML = s.params.paginationProgressRender(s, s.params.paginationProgressbarClass);
|
||
}
|
||
else {
|
||
paginationHTML = '<span class="' + s.params.paginationProgressbarClass + '"></span>';
|
||
}
|
||
s.paginationContainer.html(paginationHTML);
|
||
}
|
||
if (s.params.paginationType !== 'custom') {
|
||
s.emit('onPaginationRendered', s, s.paginationContainer[0]);
|
||
}
|
||
}
|
||
};
|
||
/*=========================
|
||
Common update method
|
||
===========================*/
|
||
s.update = function (updateTranslate) {
|
||
s.updateContainerSize();
|
||
s.updateSlidesSize();
|
||
s.updateProgress();
|
||
s.updatePagination();
|
||
s.updateClasses();
|
||
if (s.params.scrollbar && s.scrollbar) {
|
||
s.scrollbar.set();
|
||
}
|
||
function forceSetTranslate() {
|
||
var translate = s.rtl ? -s.translate : s.translate;
|
||
newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
|
||
s.setWrapperTranslate(newTranslate);
|
||
s.updateActiveIndex();
|
||
s.updateClasses();
|
||
}
|
||
if (updateTranslate) {
|
||
var translated, newTranslate;
|
||
if (s.controller && s.controller.spline) {
|
||
s.controller.spline = undefined;
|
||
}
|
||
if (s.params.freeMode) {
|
||
forceSetTranslate();
|
||
if (s.params.autoHeight) {
|
||
s.updateAutoHeight();
|
||
}
|
||
}
|
||
else {
|
||
if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {
|
||
translated = s.slideTo(s.slides.length - 1, 0, false, true);
|
||
}
|
||
else {
|
||
translated = s.slideTo(s.activeIndex, 0, false, true);
|
||
}
|
||
if (!translated) {
|
||
forceSetTranslate();
|
||
}
|
||
}
|
||
}
|
||
else if (s.params.autoHeight) {
|
||
s.updateAutoHeight();
|
||
}
|
||
};
|
||
|
||
/*=========================
|
||
Resize Handler
|
||
===========================*/
|
||
s.onResize = function (forceUpdatePagination) {
|
||
//Breakpoints
|
||
if (s.params.breakpoints) {
|
||
s.setBreakpoint();
|
||
}
|
||
|
||
// Disable locks on resize
|
||
var allowSwipeToPrev = s.params.allowSwipeToPrev;
|
||
var allowSwipeToNext = s.params.allowSwipeToNext;
|
||
s.params.allowSwipeToPrev = s.params.allowSwipeToNext = true;
|
||
|
||
s.updateContainerSize();
|
||
s.updateSlidesSize();
|
||
if (s.params.slidesPerView === 'auto' || s.params.freeMode || forceUpdatePagination) s.updatePagination();
|
||
if (s.params.scrollbar && s.scrollbar) {
|
||
s.scrollbar.set();
|
||
}
|
||
if (s.controller && s.controller.spline) {
|
||
s.controller.spline = undefined;
|
||
}
|
||
var slideChangedBySlideTo = false;
|
||
if (s.params.freeMode) {
|
||
var newTranslate = Math.min(Math.max(s.translate, s.maxTranslate()), s.minTranslate());
|
||
s.setWrapperTranslate(newTranslate);
|
||
s.updateActiveIndex();
|
||
s.updateClasses();
|
||
|
||
if (s.params.autoHeight) {
|
||
s.updateAutoHeight();
|
||
}
|
||
}
|
||
else {
|
||
s.updateClasses();
|
||
if ((s.params.slidesPerView === 'auto' || s.params.slidesPerView > 1) && s.isEnd && !s.params.centeredSlides) {
|
||
slideChangedBySlideTo = s.slideTo(s.slides.length - 1, 0, false, true);
|
||
}
|
||
else {
|
||
slideChangedBySlideTo = s.slideTo(s.activeIndex, 0, false, true);
|
||
}
|
||
}
|
||
if (s.params.lazyLoading && !slideChangedBySlideTo && s.lazy) {
|
||
s.lazy.load();
|
||
}
|
||
// Return locks after resize
|
||
s.params.allowSwipeToPrev = allowSwipeToPrev;
|
||
s.params.allowSwipeToNext = allowSwipeToNext;
|
||
};
|
||
|
||
/*=========================
|
||
Events
|
||
===========================*/
|
||
|
||
//Define Touch Events
|
||
s.touchEventsDesktop = {start: 'mousedown', move: 'mousemove', end: 'mouseup'};
|
||
if (window.navigator.pointerEnabled) s.touchEventsDesktop = {start: 'pointerdown', move: 'pointermove', end: 'pointerup'};
|
||
else if (window.navigator.msPointerEnabled) s.touchEventsDesktop = {start: 'MSPointerDown', move: 'MSPointerMove', end: 'MSPointerUp'};
|
||
s.touchEvents = {
|
||
start : s.support.touch || !s.params.simulateTouch ? 'touchstart' : s.touchEventsDesktop.start,
|
||
move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : s.touchEventsDesktop.move,
|
||
end : s.support.touch || !s.params.simulateTouch ? 'touchend' : s.touchEventsDesktop.end
|
||
};
|
||
|
||
|
||
// WP8 Touch Events Fix
|
||
if (window.navigator.pointerEnabled || window.navigator.msPointerEnabled) {
|
||
(s.params.touchEventsTarget === 'container' ? s.container : s.wrapper).addClass('swiper-wp8-' + s.params.direction);
|
||
}
|
||
|
||
// Attach/detach events
|
||
s.initEvents = function (detach) {
|
||
var actionDom = detach ? 'off' : 'on';
|
||
var action = detach ? 'removeEventListener' : 'addEventListener';
|
||
var touchEventsTarget = s.params.touchEventsTarget === 'container' ? s.container[0] : s.wrapper[0];
|
||
var target = s.support.touch ? touchEventsTarget : document;
|
||
|
||
var moveCapture = s.params.nested ? true : false;
|
||
|
||
//Touch Events
|
||
if (s.browser.ie) {
|
||
touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);
|
||
target[action](s.touchEvents.move, s.onTouchMove, moveCapture);
|
||
target[action](s.touchEvents.end, s.onTouchEnd, false);
|
||
}
|
||
else {
|
||
if (s.support.touch) {
|
||
var passiveListener = s.touchEvents.start === 'touchstart' && s.support.passiveListener && s.params.passiveListeners ? {passive: true, capture: false} : false;
|
||
touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, passiveListener);
|
||
touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);
|
||
touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, passiveListener);
|
||
}
|
||
if ((params.simulateTouch && !s.device.ios && !s.device.android) || (params.simulateTouch && !s.support.touch && s.device.ios)) {
|
||
touchEventsTarget[action]('mousedown', s.onTouchStart, false);
|
||
document[action]('mousemove', s.onTouchMove, moveCapture);
|
||
document[action]('mouseup', s.onTouchEnd, false);
|
||
}
|
||
}
|
||
window[action]('resize', s.onResize);
|
||
|
||
// Next, Prev, Index
|
||
if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {
|
||
s.nextButton[actionDom]('click', s.onClickNext);
|
||
if (s.params.a11y && s.a11y) s.nextButton[actionDom]('keydown', s.a11y.onEnterKey);
|
||
}
|
||
if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {
|
||
s.prevButton[actionDom]('click', s.onClickPrev);
|
||
if (s.params.a11y && s.a11y) s.prevButton[actionDom]('keydown', s.a11y.onEnterKey);
|
||
}
|
||
if (s.params.pagination && s.params.paginationClickable) {
|
||
s.paginationContainer[actionDom]('click', '.' + s.params.bulletClass, s.onClickIndex);
|
||
if (s.params.a11y && s.a11y) s.paginationContainer[actionDom]('keydown', '.' + s.params.bulletClass, s.a11y.onEnterKey);
|
||
}
|
||
|
||
// Prevent Links Clicks
|
||
if (s.params.preventClicks || s.params.preventClicksPropagation) touchEventsTarget[action]('click', s.preventClicks, true);
|
||
};
|
||
s.attachEvents = function () {
|
||
s.initEvents();
|
||
};
|
||
s.detachEvents = function () {
|
||
s.initEvents(true);
|
||
};
|
||
|
||
/*=========================
|
||
Handle Clicks
|
||
===========================*/
|
||
// Prevent Clicks
|
||
s.allowClick = true;
|
||
s.preventClicks = function (e) {
|
||
if (!s.allowClick) {
|
||
if (s.params.preventClicks) e.preventDefault();
|
||
if (s.params.preventClicksPropagation && s.animating) {
|
||
e.stopPropagation();
|
||
e.stopImmediatePropagation();
|
||
}
|
||
}
|
||
};
|
||
// Clicks
|
||
s.onClickNext = function (e) {
|
||
e.preventDefault();
|
||
if (s.isEnd && !s.params.loop) return;
|
||
s.slideNext();
|
||
};
|
||
s.onClickPrev = function (e) {
|
||
e.preventDefault();
|
||
if (s.isBeginning && !s.params.loop) return;
|
||
s.slidePrev();
|
||
};
|
||
s.onClickIndex = function (e) {
|
||
e.preventDefault();
|
||
var index = $(this).index() * s.params.slidesPerGroup;
|
||
if (s.params.loop) index = index + s.loopedSlides;
|
||
s.slideTo(index);
|
||
};
|
||
|
||
/*=========================
|
||
Handle Touches
|
||
===========================*/
|
||
function findElementInEvent(e, selector) {
|
||
var el = $(e.target);
|
||
if (!el.is(selector)) {
|
||
if (typeof selector === 'string') {
|
||
el = el.parents(selector);
|
||
}
|
||
else if (selector.nodeType) {
|
||
var found;
|
||
el.parents().each(function (index, _el) {
|
||
if (_el === selector) found = selector;
|
||
});
|
||
if (!found) return undefined;
|
||
else return selector;
|
||
}
|
||
}
|
||
if (el.length === 0) {
|
||
return undefined;
|
||
}
|
||
return el[0];
|
||
}
|
||
s.updateClickedSlide = function (e) {
|
||
var slide = findElementInEvent(e, '.' + s.params.slideClass);
|
||
var slideFound = false;
|
||
if (slide) {
|
||
for (var i = 0; i < s.slides.length; i++) {
|
||
if (s.slides[i] === slide) slideFound = true;
|
||
}
|
||
}
|
||
|
||
if (slide && slideFound) {
|
||
s.clickedSlide = slide;
|
||
s.clickedIndex = $(slide).index();
|
||
}
|
||
else {
|
||
s.clickedSlide = undefined;
|
||
s.clickedIndex = undefined;
|
||
return;
|
||
}
|
||
if (s.params.slideToClickedSlide && s.clickedIndex !== undefined && s.clickedIndex !== s.activeIndex) {
|
||
var slideToIndex = s.clickedIndex,
|
||
realIndex,
|
||
duplicatedSlides;
|
||
if (s.params.loop) {
|
||
if (s.animating) return;
|
||
realIndex = $(s.clickedSlide).attr('data-swiper-slide-index');
|
||
if (s.params.centeredSlides) {
|
||
if ((slideToIndex < s.loopedSlides - s.params.slidesPerView/2) || (slideToIndex > s.slides.length - s.loopedSlides + s.params.slidesPerView/2)) {
|
||
s.fixLoop();
|
||
slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]:not(.' + s.params.slideDuplicateClass + ')').eq(0).index();
|
||
setTimeout(function () {
|
||
s.slideTo(slideToIndex);
|
||
}, 0);
|
||
}
|
||
else {
|
||
s.slideTo(slideToIndex);
|
||
}
|
||
}
|
||
else {
|
||
if (slideToIndex > s.slides.length - s.params.slidesPerView) {
|
||
s.fixLoop();
|
||
slideToIndex = s.wrapper.children('.' + s.params.slideClass + '[data-swiper-slide-index="' + realIndex + '"]:not(.' + s.params.slideDuplicateClass + ')').eq(0).index();
|
||
setTimeout(function () {
|
||
s.slideTo(slideToIndex);
|
||
}, 0);
|
||
}
|
||
else {
|
||
s.slideTo(slideToIndex);
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
s.slideTo(slideToIndex);
|
||
}
|
||
}
|
||
};
|
||
|
||
var isTouched,
|
||
isMoved,
|
||
allowTouchCallbacks,
|
||
touchStartTime,
|
||
isScrolling,
|
||
currentTranslate,
|
||
startTranslate,
|
||
allowThresholdMove,
|
||
// Form elements to match
|
||
formElements = 'input, select, textarea, button, video',
|
||
// Last click time
|
||
lastClickTime = Date.now(), clickTimeout,
|
||
//Velocities
|
||
velocities = [],
|
||
allowMomentumBounce;
|
||
|
||
// Animating Flag
|
||
s.animating = false;
|
||
|
||
// Touches information
|
||
s.touches = {
|
||
startX: 0,
|
||
startY: 0,
|
||
currentX: 0,
|
||
currentY: 0,
|
||
diff: 0
|
||
};
|
||
|
||
// Touch handlers
|
||
var isTouchEvent, startMoving;
|
||
s.onTouchStart = function (e) {
|
||
if (e.originalEvent) e = e.originalEvent;
|
||
isTouchEvent = e.type === 'touchstart';
|
||
if (!isTouchEvent && 'which' in e && e.which === 3) return;
|
||
if (s.params.noSwiping && findElementInEvent(e, '.' + s.params.noSwipingClass)) {
|
||
s.allowClick = true;
|
||
return;
|
||
}
|
||
if (s.params.swipeHandler) {
|
||
if (!findElementInEvent(e, s.params.swipeHandler)) return;
|
||
}
|
||
|
||
var startX = s.touches.currentX = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
|
||
var startY = s.touches.currentY = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
|
||
|
||
// Do NOT start if iOS edge swipe is detected. Otherwise iOS app (UIWebView) cannot swipe-to-go-back anymore
|
||
if(s.device.ios && s.params.iOSEdgeSwipeDetection && startX <= s.params.iOSEdgeSwipeThreshold) {
|
||
return;
|
||
}
|
||
|
||
isTouched = true;
|
||
isMoved = false;
|
||
allowTouchCallbacks = true;
|
||
isScrolling = undefined;
|
||
startMoving = undefined;
|
||
s.touches.startX = startX;
|
||
s.touches.startY = startY;
|
||
touchStartTime = Date.now();
|
||
s.allowClick = true;
|
||
s.updateContainerSize();
|
||
s.swipeDirection = undefined;
|
||
if (s.params.threshold > 0) allowThresholdMove = false;
|
||
if (e.type !== 'touchstart') {
|
||
var preventDefault = true;
|
||
if ($(e.target).is(formElements)) preventDefault = false;
|
||
if (document.activeElement && $(document.activeElement).is(formElements)) {
|
||
document.activeElement.blur();
|
||
}
|
||
if (preventDefault) {
|
||
e.preventDefault();
|
||
}
|
||
}
|
||
s.emit('onTouchStart', s, e);
|
||
};
|
||
|
||
s.onTouchMove = function (e) {
|
||
if (e.originalEvent) e = e.originalEvent;
|
||
if (isTouchEvent && e.type === 'mousemove') return;
|
||
if (e.preventedByNestedSwiper) {
|
||
s.touches.startX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
|
||
s.touches.startY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
return;
|
||
}
|
||
if (s.params.onlyExternal) {
|
||
// isMoved = true;
|
||
s.allowClick = false;
|
||
if (isTouched) {
|
||
s.touches.startX = s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
|
||
s.touches.startY = s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
touchStartTime = Date.now();
|
||
}
|
||
return;
|
||
}
|
||
if (isTouchEvent && s.params.touchReleaseOnEdges && !s.params.loop) {
|
||
if (!s.isHorizontal()) {
|
||
// Vertical
|
||
if (
|
||
(s.touches.currentY < s.touches.startY && s.translate <= s.maxTranslate()) ||
|
||
(s.touches.currentY > s.touches.startY && s.translate >= s.minTranslate())
|
||
) {
|
||
return;
|
||
}
|
||
}
|
||
else {
|
||
if (
|
||
(s.touches.currentX < s.touches.startX && s.translate <= s.maxTranslate()) ||
|
||
(s.touches.currentX > s.touches.startX && s.translate >= s.minTranslate())
|
||
) {
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
if (isTouchEvent && document.activeElement) {
|
||
if (e.target === document.activeElement && $(e.target).is(formElements)) {
|
||
isMoved = true;
|
||
s.allowClick = false;
|
||
return;
|
||
}
|
||
}
|
||
if (allowTouchCallbacks) {
|
||
s.emit('onTouchMove', s, e);
|
||
}
|
||
if (e.targetTouches && e.targetTouches.length > 1) return;
|
||
|
||
s.touches.currentX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
|
||
s.touches.currentY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
|
||
if (typeof isScrolling === 'undefined') {
|
||
var touchAngle;
|
||
if (s.isHorizontal() && s.touches.currentY === s.touches.startY || !s.isHorizontal() && s.touches.currentX !== s.touches.startX) {
|
||
isScrolling = false;
|
||
}
|
||
else {
|
||
touchAngle = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;
|
||
isScrolling = s.isHorizontal() ? touchAngle > s.params.touchAngle : (90 - touchAngle > s.params.touchAngle);
|
||
}
|
||
}
|
||
if (isScrolling) {
|
||
s.emit('onTouchMoveOpposite', s, e);
|
||
}
|
||
if (typeof startMoving === 'undefined' && s.browser.ieTouch) {
|
||
if (s.touches.currentX !== s.touches.startX || s.touches.currentY !== s.touches.startY) {
|
||
startMoving = true;
|
||
}
|
||
}
|
||
if (!isTouched) return;
|
||
if (isScrolling) {
|
||
isTouched = false;
|
||
return;
|
||
}
|
||
if (!startMoving && s.browser.ieTouch) {
|
||
return;
|
||
}
|
||
s.allowClick = false;
|
||
s.emit('onSliderMove', s, e);
|
||
e.preventDefault();
|
||
if (s.params.touchMoveStopPropagation && !s.params.nested) {
|
||
e.stopPropagation();
|
||
}
|
||
|
||
if (!isMoved) {
|
||
if (params.loop) {
|
||
s.fixLoop();
|
||
}
|
||
startTranslate = s.getWrapperTranslate();
|
||
s.setWrapperTransition(0);
|
||
if (s.animating) {
|
||
s.wrapper.trigger('webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd');
|
||
}
|
||
if (s.params.autoplay && s.autoplaying) {
|
||
if (s.params.autoplayDisableOnInteraction) {
|
||
s.stopAutoplay();
|
||
}
|
||
else {
|
||
s.pauseAutoplay();
|
||
}
|
||
}
|
||
allowMomentumBounce = false;
|
||
//Grab Cursor
|
||
if (s.params.grabCursor && (s.params.allowSwipeToNext === true || s.params.allowSwipeToPrev === true)) {
|
||
s.setGrabCursor(true);
|
||
}
|
||
}
|
||
isMoved = true;
|
||
|
||
var diff = s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
|
||
|
||
diff = diff * s.params.touchRatio;
|
||
if (s.rtl) diff = -diff;
|
||
|
||
s.swipeDirection = diff > 0 ? 'prev' : 'next';
|
||
currentTranslate = diff + startTranslate;
|
||
|
||
var disableParentSwiper = true;
|
||
if ((diff > 0 && currentTranslate > s.minTranslate())) {
|
||
disableParentSwiper = false;
|
||
if (s.params.resistance) currentTranslate = s.minTranslate() - 1 + Math.pow(-s.minTranslate() + startTranslate + diff, s.params.resistanceRatio);
|
||
}
|
||
else if (diff < 0 && currentTranslate < s.maxTranslate()) {
|
||
disableParentSwiper = false;
|
||
if (s.params.resistance) currentTranslate = s.maxTranslate() + 1 - Math.pow(s.maxTranslate() - startTranslate - diff, s.params.resistanceRatio);
|
||
}
|
||
|
||
if (disableParentSwiper) {
|
||
e.preventedByNestedSwiper = true;
|
||
}
|
||
|
||
// Directions locks
|
||
if (!s.params.allowSwipeToNext && s.swipeDirection === 'next' && currentTranslate < startTranslate) {
|
||
currentTranslate = startTranslate;
|
||
}
|
||
if (!s.params.allowSwipeToPrev && s.swipeDirection === 'prev' && currentTranslate > startTranslate) {
|
||
currentTranslate = startTranslate;
|
||
}
|
||
|
||
|
||
// Threshold
|
||
if (s.params.threshold > 0) {
|
||
if (Math.abs(diff) > s.params.threshold || allowThresholdMove) {
|
||
if (!allowThresholdMove) {
|
||
allowThresholdMove = true;
|
||
s.touches.startX = s.touches.currentX;
|
||
s.touches.startY = s.touches.currentY;
|
||
currentTranslate = startTranslate;
|
||
s.touches.diff = s.isHorizontal() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
|
||
return;
|
||
}
|
||
}
|
||
else {
|
||
currentTranslate = startTranslate;
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (!s.params.followFinger) return;
|
||
|
||
// Update active index in free mode
|
||
if (s.params.freeMode || s.params.watchSlidesProgress) {
|
||
s.updateActiveIndex();
|
||
}
|
||
if (s.params.freeMode) {
|
||
//Velocity
|
||
if (velocities.length === 0) {
|
||
velocities.push({
|
||
position: s.touches[s.isHorizontal() ? 'startX' : 'startY'],
|
||
time: touchStartTime
|
||
});
|
||
}
|
||
velocities.push({
|
||
position: s.touches[s.isHorizontal() ? 'currentX' : 'currentY'],
|
||
time: (new window.Date()).getTime()
|
||
});
|
||
}
|
||
// Update progress
|
||
s.updateProgress(currentTranslate);
|
||
// Update translate
|
||
s.setWrapperTranslate(currentTranslate);
|
||
};
|
||
s.onTouchEnd = function (e) {
|
||
if (e.originalEvent) e = e.originalEvent;
|
||
if (allowTouchCallbacks) {
|
||
s.emit('onTouchEnd', s, e);
|
||
}
|
||
allowTouchCallbacks = false;
|
||
if (!isTouched) return;
|
||
//Return Grab Cursor
|
||
if (s.params.grabCursor && isMoved && isTouched && (s.params.allowSwipeToNext === true || s.params.allowSwipeToPrev === true)) {
|
||
s.setGrabCursor(false);
|
||
}
|
||
|
||
// Time diff
|
||
var touchEndTime = Date.now();
|
||
var timeDiff = touchEndTime - touchStartTime;
|
||
|
||
// Tap, doubleTap, Click
|
||
if (s.allowClick) {
|
||
s.updateClickedSlide(e);
|
||
s.emit('onTap', s, e);
|
||
if (timeDiff < 300 && (touchEndTime - lastClickTime) > 300) {
|
||
if (clickTimeout) clearTimeout(clickTimeout);
|
||
clickTimeout = setTimeout(function () {
|
||
if (!s) return;
|
||
if (s.params.paginationHide && s.paginationContainer.length > 0 && !$(e.target).hasClass(s.params.bulletClass)) {
|
||
s.paginationContainer.toggleClass(s.params.paginationHiddenClass);
|
||
}
|
||
s.emit('onClick', s, e);
|
||
}, 300);
|
||
|
||
}
|
||
if (timeDiff < 300 && (touchEndTime - lastClickTime) < 300) {
|
||
if (clickTimeout) clearTimeout(clickTimeout);
|
||
s.emit('onDoubleTap', s, e);
|
||
}
|
||
}
|
||
|
||
lastClickTime = Date.now();
|
||
setTimeout(function () {
|
||
if (s) s.allowClick = true;
|
||
}, 0);
|
||
|
||
if (!isTouched || !isMoved || !s.swipeDirection || s.touches.diff === 0 || currentTranslate === startTranslate) {
|
||
isTouched = isMoved = false;
|
||
return;
|
||
}
|
||
isTouched = isMoved = false;
|
||
|
||
var currentPos;
|
||
if (s.params.followFinger) {
|
||
currentPos = s.rtl ? s.translate : -s.translate;
|
||
}
|
||
else {
|
||
currentPos = -currentTranslate;
|
||
}
|
||
if (s.params.freeMode) {
|
||
if (currentPos < -s.minTranslate()) {
|
||
s.slideTo(s.activeIndex);
|
||
return;
|
||
}
|
||
else if (currentPos > -s.maxTranslate()) {
|
||
if (s.slides.length < s.snapGrid.length) {
|
||
s.slideTo(s.snapGrid.length - 1);
|
||
}
|
||
else {
|
||
s.slideTo(s.slides.length - 1);
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (s.params.freeModeMomentum) {
|
||
if (velocities.length > 1) {
|
||
var lastMoveEvent = velocities.pop(), velocityEvent = velocities.pop();
|
||
|
||
var distance = lastMoveEvent.position - velocityEvent.position;
|
||
var time = lastMoveEvent.time - velocityEvent.time;
|
||
s.velocity = distance / time;
|
||
s.velocity = s.velocity / 2;
|
||
if (Math.abs(s.velocity) < s.params.freeModeMinimumVelocity) {
|
||
s.velocity = 0;
|
||
}
|
||
// this implies that the user stopped moving a finger then released.
|
||
// There would be no events with distance zero, so the last event is stale.
|
||
if (time > 150 || (new window.Date().getTime() - lastMoveEvent.time) > 300) {
|
||
s.velocity = 0;
|
||
}
|
||
} else {
|
||
s.velocity = 0;
|
||
}
|
||
s.velocity = s.velocity * s.params.freeModeMomentumVelocityRatio;
|
||
|
||
velocities.length = 0;
|
||
var momentumDuration = 1000 * s.params.freeModeMomentumRatio;
|
||
var momentumDistance = s.velocity * momentumDuration;
|
||
|
||
var newPosition = s.translate + momentumDistance;
|
||
if (s.rtl) newPosition = - newPosition;
|
||
var doBounce = false;
|
||
var afterBouncePosition;
|
||
var bounceAmount = Math.abs(s.velocity) * 20 * s.params.freeModeMomentumBounceRatio;
|
||
if (newPosition < s.maxTranslate()) {
|
||
if (s.params.freeModeMomentumBounce) {
|
||
if (newPosition + s.maxTranslate() < -bounceAmount) {
|
||
newPosition = s.maxTranslate() - bounceAmount;
|
||
}
|
||
afterBouncePosition = s.maxTranslate();
|
||
doBounce = true;
|
||
allowMomentumBounce = true;
|
||
}
|
||
else {
|
||
newPosition = s.maxTranslate();
|
||
}
|
||
}
|
||
else if (newPosition > s.minTranslate()) {
|
||
if (s.params.freeModeMomentumBounce) {
|
||
if (newPosition - s.minTranslate() > bounceAmount) {
|
||
newPosition = s.minTranslate() + bounceAmount;
|
||
}
|
||
afterBouncePosition = s.minTranslate();
|
||
doBounce = true;
|
||
allowMomentumBounce = true;
|
||
}
|
||
else {
|
||
newPosition = s.minTranslate();
|
||
}
|
||
}
|
||
else if (s.params.freeModeSticky) {
|
||
var j = 0,
|
||
nextSlide;
|
||
for (j = 0; j < s.snapGrid.length; j += 1) {
|
||
if (s.snapGrid[j] > -newPosition) {
|
||
nextSlide = j;
|
||
break;
|
||
}
|
||
|
||
}
|
||
if (Math.abs(s.snapGrid[nextSlide] - newPosition) < Math.abs(s.snapGrid[nextSlide - 1] - newPosition) || s.swipeDirection === 'next') {
|
||
newPosition = s.snapGrid[nextSlide];
|
||
} else {
|
||
newPosition = s.snapGrid[nextSlide - 1];
|
||
}
|
||
if (!s.rtl) newPosition = - newPosition;
|
||
}
|
||
//Fix duration
|
||
if (s.velocity !== 0) {
|
||
if (s.rtl) {
|
||
momentumDuration = Math.abs((-newPosition - s.translate) / s.velocity);
|
||
}
|
||
else {
|
||
momentumDuration = Math.abs((newPosition - s.translate) / s.velocity);
|
||
}
|
||
}
|
||
else if (s.params.freeModeSticky) {
|
||
s.slideReset();
|
||
return;
|
||
}
|
||
|
||
if (s.params.freeModeMomentumBounce && doBounce) {
|
||
s.updateProgress(afterBouncePosition);
|
||
s.setWrapperTransition(momentumDuration);
|
||
s.setWrapperTranslate(newPosition);
|
||
s.onTransitionStart();
|
||
s.animating = true;
|
||
s.wrapper.transitionEnd(function () {
|
||
if (!s || !allowMomentumBounce) return;
|
||
s.emit('onMomentumBounce', s);
|
||
|
||
s.setWrapperTransition(s.params.speed);
|
||
s.setWrapperTranslate(afterBouncePosition);
|
||
s.wrapper.transitionEnd(function () {
|
||
if (!s) return;
|
||
s.onTransitionEnd();
|
||
});
|
||
});
|
||
} else if (s.velocity) {
|
||
s.updateProgress(newPosition);
|
||
s.setWrapperTransition(momentumDuration);
|
||
s.setWrapperTranslate(newPosition);
|
||
s.onTransitionStart();
|
||
if (!s.animating) {
|
||
s.animating = true;
|
||
s.wrapper.transitionEnd(function () {
|
||
if (!s) return;
|
||
s.onTransitionEnd();
|
||
});
|
||
}
|
||
|
||
} else {
|
||
s.updateProgress(newPosition);
|
||
}
|
||
|
||
s.updateActiveIndex();
|
||
}
|
||
if (!s.params.freeModeMomentum || timeDiff >= s.params.longSwipesMs) {
|
||
s.updateProgress();
|
||
s.updateActiveIndex();
|
||
}
|
||
return;
|
||
}
|
||
|
||
// Find current slide
|
||
var i, stopIndex = 0, groupSize = s.slidesSizesGrid[0];
|
||
for (i = 0; i < s.slidesGrid.length; i += s.params.slidesPerGroup) {
|
||
if (typeof s.slidesGrid[i + s.params.slidesPerGroup] !== 'undefined') {
|
||
if (currentPos >= s.slidesGrid[i] && currentPos < s.slidesGrid[i + s.params.slidesPerGroup]) {
|
||
stopIndex = i;
|
||
groupSize = s.slidesGrid[i + s.params.slidesPerGroup] - s.slidesGrid[i];
|
||
}
|
||
}
|
||
else {
|
||
if (currentPos >= s.slidesGrid[i]) {
|
||
stopIndex = i;
|
||
groupSize = s.slidesGrid[s.slidesGrid.length - 1] - s.slidesGrid[s.slidesGrid.length - 2];
|
||
}
|
||
}
|
||
}
|
||
|
||
// Find current slide size
|
||
var ratio = (currentPos - s.slidesGrid[stopIndex]) / groupSize;
|
||
|
||
if (timeDiff > s.params.longSwipesMs) {
|
||
// Long touches
|
||
if (!s.params.longSwipes) {
|
||
s.slideTo(s.activeIndex);
|
||
return;
|
||
}
|
||
if (s.swipeDirection === 'next') {
|
||
if (ratio >= s.params.longSwipesRatio) s.slideTo(stopIndex + s.params.slidesPerGroup);
|
||
else s.slideTo(stopIndex);
|
||
|
||
}
|
||
if (s.swipeDirection === 'prev') {
|
||
if (ratio > (1 - s.params.longSwipesRatio)) s.slideTo(stopIndex + s.params.slidesPerGroup);
|
||
else s.slideTo(stopIndex);
|
||
}
|
||
}
|
||
else {
|
||
// Short swipes
|
||
if (!s.params.shortSwipes) {
|
||
s.slideTo(s.activeIndex);
|
||
return;
|
||
}
|
||
if (s.swipeDirection === 'next') {
|
||
s.slideTo(stopIndex + s.params.slidesPerGroup);
|
||
|
||
}
|
||
if (s.swipeDirection === 'prev') {
|
||
s.slideTo(stopIndex);
|
||
}
|
||
}
|
||
};
|
||
/*=========================
|
||
Transitions
|
||
===========================*/
|
||
s._slideTo = function (slideIndex, speed) {
|
||
return s.slideTo(slideIndex, speed, true, true);
|
||
};
|
||
s.slideTo = function (slideIndex, speed, runCallbacks, internal) {
|
||
if (typeof runCallbacks === 'undefined') runCallbacks = true;
|
||
if (typeof slideIndex === 'undefined') slideIndex = 0;
|
||
if (slideIndex < 0) slideIndex = 0;
|
||
s.snapIndex = Math.floor(slideIndex / s.params.slidesPerGroup);
|
||
if (s.snapIndex >= s.snapGrid.length) s.snapIndex = s.snapGrid.length - 1;
|
||
|
||
var translate = - s.snapGrid[s.snapIndex];
|
||
// Stop autoplay
|
||
if (s.params.autoplay && s.autoplaying) {
|
||
if (internal || !s.params.autoplayDisableOnInteraction) {
|
||
s.pauseAutoplay(speed);
|
||
}
|
||
else {
|
||
s.stopAutoplay();
|
||
}
|
||
}
|
||
// Update progress
|
||
s.updateProgress(translate);
|
||
|
||
// Normalize slideIndex
|
||
if(s.params.normalizeSlideIndex){
|
||
for (var i = 0; i < s.slidesGrid.length; i++) {
|
||
if (- Math.floor(translate * 100) >= Math.floor(s.slidesGrid[i] * 100)) {
|
||
slideIndex = i;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Directions locks
|
||
if (!s.params.allowSwipeToNext && translate < s.translate && translate < s.minTranslate()) {
|
||
return false;
|
||
}
|
||
if (!s.params.allowSwipeToPrev && translate > s.translate && translate > s.maxTranslate()) {
|
||
if ((s.activeIndex || 0) !== slideIndex ) return false;
|
||
}
|
||
|
||
// Update Index
|
||
if (typeof speed === 'undefined') speed = s.params.speed;
|
||
s.previousIndex = s.activeIndex || 0;
|
||
s.activeIndex = slideIndex;
|
||
s.updateRealIndex();
|
||
if ((s.rtl && -translate === s.translate) || (!s.rtl && translate === s.translate)) {
|
||
// Update Height
|
||
if (s.params.autoHeight) {
|
||
s.updateAutoHeight();
|
||
}
|
||
s.updateClasses();
|
||
if (s.params.effect !== 'slide') {
|
||
s.setWrapperTranslate(translate);
|
||
}
|
||
return false;
|
||
}
|
||
s.updateClasses();
|
||
s.onTransitionStart(runCallbacks);
|
||
|
||
if (speed === 0 || s.browser.lteIE9) {
|
||
s.setWrapperTranslate(translate);
|
||
s.setWrapperTransition(0);
|
||
s.onTransitionEnd(runCallbacks);
|
||
}
|
||
else {
|
||
s.setWrapperTranslate(translate);
|
||
s.setWrapperTransition(speed);
|
||
if (!s.animating) {
|
||
s.animating = true;
|
||
s.wrapper.transitionEnd(function () {
|
||
if (!s) return;
|
||
s.onTransitionEnd(runCallbacks);
|
||
});
|
||
}
|
||
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
s.onTransitionStart = function (runCallbacks) {
|
||
if (typeof runCallbacks === 'undefined') runCallbacks = true;
|
||
if (s.params.autoHeight) {
|
||
s.updateAutoHeight();
|
||
}
|
||
if (s.lazy) s.lazy.onTransitionStart();
|
||
if (runCallbacks) {
|
||
s.emit('onTransitionStart', s);
|
||
if (s.activeIndex !== s.previousIndex) {
|
||
s.emit('onSlideChangeStart', s);
|
||
if (s.activeIndex > s.previousIndex) {
|
||
s.emit('onSlideNextStart', s);
|
||
}
|
||
else {
|
||
s.emit('onSlidePrevStart', s);
|
||
}
|
||
}
|
||
|
||
}
|
||
};
|
||
s.onTransitionEnd = function (runCallbacks) {
|
||
s.animating = false;
|
||
s.setWrapperTransition(0);
|
||
if (typeof runCallbacks === 'undefined') runCallbacks = true;
|
||
if (s.lazy) s.lazy.onTransitionEnd();
|
||
if (runCallbacks) {
|
||
s.emit('onTransitionEnd', s);
|
||
if (s.activeIndex !== s.previousIndex) {
|
||
s.emit('onSlideChangeEnd', s);
|
||
if (s.activeIndex > s.previousIndex) {
|
||
s.emit('onSlideNextEnd', s);
|
||
}
|
||
else {
|
||
s.emit('onSlidePrevEnd', s);
|
||
}
|
||
}
|
||
}
|
||
if (s.params.history && s.history) {
|
||
s.history.setHistory(s.params.history, s.activeIndex);
|
||
}
|
||
if (s.params.hashnav && s.hashnav) {
|
||
s.hashnav.setHash();
|
||
}
|
||
|
||
};
|
||
s.slideNext = function (runCallbacks, speed, internal) {
|
||
if (s.params.loop) {
|
||
if (s.animating) return false;
|
||
s.fixLoop();
|
||
var clientLeft = s.container[0].clientLeft;
|
||
return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
|
||
}
|
||
else return s.slideTo(s.activeIndex + s.params.slidesPerGroup, speed, runCallbacks, internal);
|
||
};
|
||
s._slideNext = function (speed) {
|
||
return s.slideNext(true, speed, true);
|
||
};
|
||
s.slidePrev = function (runCallbacks, speed, internal) {
|
||
if (s.params.loop) {
|
||
if (s.animating) return false;
|
||
s.fixLoop();
|
||
var clientLeft = s.container[0].clientLeft;
|
||
return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
|
||
}
|
||
else return s.slideTo(s.activeIndex - 1, speed, runCallbacks, internal);
|
||
};
|
||
s._slidePrev = function (speed) {
|
||
return s.slidePrev(true, speed, true);
|
||
};
|
||
s.slideReset = function (runCallbacks, speed, internal) {
|
||
return s.slideTo(s.activeIndex, speed, runCallbacks);
|
||
};
|
||
|
||
s.disableTouchControl = function () {
|
||
s.params.onlyExternal = true;
|
||
return true;
|
||
};
|
||
s.enableTouchControl = function () {
|
||
s.params.onlyExternal = false;
|
||
return true;
|
||
};
|
||
|
||
/*=========================
|
||
Translate/transition helpers
|
||
===========================*/
|
||
s.setWrapperTransition = function (duration, byController) {
|
||
s.wrapper.transition(duration);
|
||
if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
|
||
s.effects[s.params.effect].setTransition(duration);
|
||
}
|
||
if (s.params.parallax && s.parallax) {
|
||
s.parallax.setTransition(duration);
|
||
}
|
||
if (s.params.scrollbar && s.scrollbar) {
|
||
s.scrollbar.setTransition(duration);
|
||
}
|
||
if (s.params.control && s.controller) {
|
||
s.controller.setTransition(duration, byController);
|
||
}
|
||
s.emit('onSetTransition', s, duration);
|
||
};
|
||
s.setWrapperTranslate = function (translate, updateActiveIndex, byController) {
|
||
var x = 0, y = 0, z = 0;
|
||
if (s.isHorizontal()) {
|
||
x = s.rtl ? -translate : translate;
|
||
}
|
||
else {
|
||
y = translate;
|
||
}
|
||
|
||
if (s.params.roundLengths) {
|
||
x = round(x);
|
||
y = round(y);
|
||
}
|
||
|
||
if (!s.params.virtualTranslate) {
|
||
if (s.support.transforms3d) s.wrapper.transform('translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)');
|
||
else s.wrapper.transform('translate(' + x + 'px, ' + y + 'px)');
|
||
}
|
||
|
||
s.translate = s.isHorizontal() ? x : y;
|
||
|
||
// Check if we need to update progress
|
||
var progress;
|
||
var translatesDiff = s.maxTranslate() - s.minTranslate();
|
||
if (translatesDiff === 0) {
|
||
progress = 0;
|
||
}
|
||
else {
|
||
progress = (translate - s.minTranslate()) / (translatesDiff);
|
||
}
|
||
if (progress !== s.progress) {
|
||
s.updateProgress(translate);
|
||
}
|
||
|
||
if (updateActiveIndex) s.updateActiveIndex();
|
||
if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
|
||
s.effects[s.params.effect].setTranslate(s.translate);
|
||
}
|
||
if (s.params.parallax && s.parallax) {
|
||
s.parallax.setTranslate(s.translate);
|
||
}
|
||
if (s.params.scrollbar && s.scrollbar) {
|
||
s.scrollbar.setTranslate(s.translate);
|
||
}
|
||
if (s.params.control && s.controller) {
|
||
s.controller.setTranslate(s.translate, byController);
|
||
}
|
||
s.emit('onSetTranslate', s, s.translate);
|
||
};
|
||
|
||
s.getTranslate = function (el, axis) {
|
||
var matrix, curTransform, curStyle, transformMatrix;
|
||
|
||
// automatic axis detection
|
||
if (typeof axis === 'undefined') {
|
||
axis = 'x';
|
||
}
|
||
|
||
if (s.params.virtualTranslate) {
|
||
return s.rtl ? -s.translate : s.translate;
|
||
}
|
||
|
||
curStyle = window.getComputedStyle(el, null);
|
||
if (window.WebKitCSSMatrix) {
|
||
curTransform = curStyle.transform || curStyle.webkitTransform;
|
||
if (curTransform.split(',').length > 6) {
|
||
curTransform = curTransform.split(', ').map(function(a){
|
||
return a.replace(',','.');
|
||
}).join(', ');
|
||
}
|
||
// Some old versions of Webkit choke when 'none' is passed; pass
|
||
// empty string instead in this case
|
||
transformMatrix = new window.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
|
||
}
|
||
else {
|
||
transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
|
||
matrix = transformMatrix.toString().split(',');
|
||
}
|
||
|
||
if (axis === 'x') {
|
||
//Latest Chrome and webkits Fix
|
||
if (window.WebKitCSSMatrix)
|
||
curTransform = transformMatrix.m41;
|
||
//Crazy IE10 Matrix
|
||
else if (matrix.length === 16)
|
||
curTransform = parseFloat(matrix[12]);
|
||
//Normal Browsers
|
||
else
|
||
curTransform = parseFloat(matrix[4]);
|
||
}
|
||
if (axis === 'y') {
|
||
//Latest Chrome and webkits Fix
|
||
if (window.WebKitCSSMatrix)
|
||
curTransform = transformMatrix.m42;
|
||
//Crazy IE10 Matrix
|
||
else if (matrix.length === 16)
|
||
curTransform = parseFloat(matrix[13]);
|
||
//Normal Browsers
|
||
else
|
||
curTransform = parseFloat(matrix[5]);
|
||
}
|
||
if (s.rtl && curTransform) curTransform = -curTransform;
|
||
return curTransform || 0;
|
||
};
|
||
s.getWrapperTranslate = function (axis) {
|
||
if (typeof axis === 'undefined') {
|
||
axis = s.isHorizontal() ? 'x' : 'y';
|
||
}
|
||
return s.getTranslate(s.wrapper[0], axis);
|
||
};
|
||
|
||
/*=========================
|
||
Observer
|
||
===========================*/
|
||
s.observers = [];
|
||
function initObserver(target, options) {
|
||
options = options || {};
|
||
// create an observer instance
|
||
var ObserverFunc = window.MutationObserver || window.WebkitMutationObserver;
|
||
var observer = new ObserverFunc(function (mutations) {
|
||
mutations.forEach(function (mutation) {
|
||
s.onResize(true);
|
||
s.emit('onObserverUpdate', s, mutation);
|
||
});
|
||
});
|
||
|
||
observer.observe(target, {
|
||
attributes: typeof options.attributes === 'undefined' ? true : options.attributes,
|
||
childList: typeof options.childList === 'undefined' ? true : options.childList,
|
||
characterData: typeof options.characterData === 'undefined' ? true : options.characterData
|
||
});
|
||
|
||
s.observers.push(observer);
|
||
}
|
||
s.initObservers = function () {
|
||
if (s.params.observeParents) {
|
||
var containerParents = s.container.parents();
|
||
for (var i = 0; i < containerParents.length; i++) {
|
||
initObserver(containerParents[i]);
|
||
}
|
||
}
|
||
|
||
// Observe container
|
||
initObserver(s.container[0], {childList: false});
|
||
|
||
// Observe wrapper
|
||
initObserver(s.wrapper[0], {attributes: false});
|
||
};
|
||
s.disconnectObservers = function () {
|
||
for (var i = 0; i < s.observers.length; i++) {
|
||
s.observers[i].disconnect();
|
||
}
|
||
s.observers = [];
|
||
};
|
||
/*=========================
|
||
Loop
|
||
===========================*/
|
||
// Create looped slides
|
||
s.createLoop = function () {
|
||
// Remove duplicated slides
|
||
s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
|
||
|
||
var slides = s.wrapper.children('.' + s.params.slideClass);
|
||
|
||
if(s.params.slidesPerView === 'auto' && !s.params.loopedSlides) s.params.loopedSlides = slides.length;
|
||
|
||
s.loopedSlides = parseInt(s.params.loopedSlides || s.params.slidesPerView, 10);
|
||
s.loopedSlides = s.loopedSlides + s.params.loopAdditionalSlides;
|
||
if (s.loopedSlides > slides.length) {
|
||
s.loopedSlides = slides.length;
|
||
}
|
||
|
||
var prependSlides = [], appendSlides = [], i;
|
||
slides.each(function (index, el) {
|
||
var slide = $(this);
|
||
if (index < s.loopedSlides) appendSlides.push(el);
|
||
if (index < slides.length && index >= slides.length - s.loopedSlides) prependSlides.push(el);
|
||
slide.attr('data-swiper-slide-index', index);
|
||
});
|
||
for (i = 0; i < appendSlides.length; i++) {
|
||
s.wrapper.append($(appendSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
|
||
}
|
||
for (i = prependSlides.length - 1; i >= 0; i--) {
|
||
s.wrapper.prepend($(prependSlides[i].cloneNode(true)).addClass(s.params.slideDuplicateClass));
|
||
}
|
||
};
|
||
s.destroyLoop = function () {
|
||
s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
|
||
s.slides.removeAttr('data-swiper-slide-index');
|
||
};
|
||
s.reLoop = function (updatePosition) {
|
||
var oldIndex = s.activeIndex - s.loopedSlides;
|
||
s.destroyLoop();
|
||
s.createLoop();
|
||
s.updateSlidesSize();
|
||
if (updatePosition) {
|
||
s.slideTo(oldIndex + s.loopedSlides, 0, false);
|
||
}
|
||
|
||
};
|
||
s.fixLoop = function () {
|
||
var newIndex;
|
||
//Fix For Negative Oversliding
|
||
if (s.activeIndex < s.loopedSlides) {
|
||
newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;
|
||
newIndex = newIndex + s.loopedSlides;
|
||
s.slideTo(newIndex, 0, false, true);
|
||
}
|
||
//Fix For Positive Oversliding
|
||
else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {
|
||
newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;
|
||
newIndex = newIndex + s.loopedSlides;
|
||
s.slideTo(newIndex, 0, false, true);
|
||
}
|
||
};
|
||
/*=========================
|
||
Append/Prepend/Remove Slides
|
||
===========================*/
|
||
s.appendSlide = function (slides) {
|
||
if (s.params.loop) {
|
||
s.destroyLoop();
|
||
}
|
||
if (typeof slides === 'object' && slides.length) {
|
||
for (var i = 0; i < slides.length; i++) {
|
||
if (slides[i]) s.wrapper.append(slides[i]);
|
||
}
|
||
}
|
||
else {
|
||
s.wrapper.append(slides);
|
||
}
|
||
if (s.params.loop) {
|
||
s.createLoop();
|
||
}
|
||
if (!(s.params.observer && s.support.observer)) {
|
||
s.update(true);
|
||
}
|
||
};
|
||
s.prependSlide = function (slides) {
|
||
if (s.params.loop) {
|
||
s.destroyLoop();
|
||
}
|
||
var newActiveIndex = s.activeIndex + 1;
|
||
if (typeof slides === 'object' && slides.length) {
|
||
for (var i = 0; i < slides.length; i++) {
|
||
if (slides[i]) s.wrapper.prepend(slides[i]);
|
||
}
|
||
newActiveIndex = s.activeIndex + slides.length;
|
||
}
|
||
else {
|
||
s.wrapper.prepend(slides);
|
||
}
|
||
if (s.params.loop) {
|
||
s.createLoop();
|
||
}
|
||
if (!(s.params.observer && s.support.observer)) {
|
||
s.update(true);
|
||
}
|
||
s.slideTo(newActiveIndex, 0, false);
|
||
};
|
||
s.removeSlide = function (slidesIndexes) {
|
||
if (s.params.loop) {
|
||
s.destroyLoop();
|
||
s.slides = s.wrapper.children('.' + s.params.slideClass);
|
||
}
|
||
var newActiveIndex = s.activeIndex,
|
||
indexToRemove;
|
||
if (typeof slidesIndexes === 'object' && slidesIndexes.length) {
|
||
for (var i = 0; i < slidesIndexes.length; i++) {
|
||
indexToRemove = slidesIndexes[i];
|
||
if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
|
||
if (indexToRemove < newActiveIndex) newActiveIndex--;
|
||
}
|
||
newActiveIndex = Math.max(newActiveIndex, 0);
|
||
}
|
||
else {
|
||
indexToRemove = slidesIndexes;
|
||
if (s.slides[indexToRemove]) s.slides.eq(indexToRemove).remove();
|
||
if (indexToRemove < newActiveIndex) newActiveIndex--;
|
||
newActiveIndex = Math.max(newActiveIndex, 0);
|
||
}
|
||
|
||
if (s.params.loop) {
|
||
s.createLoop();
|
||
}
|
||
|
||
if (!(s.params.observer && s.support.observer)) {
|
||
s.update(true);
|
||
}
|
||
if (s.params.loop) {
|
||
s.slideTo(newActiveIndex + s.loopedSlides, 0, false);
|
||
}
|
||
else {
|
||
s.slideTo(newActiveIndex, 0, false);
|
||
}
|
||
|
||
};
|
||
s.removeAllSlides = function () {
|
||
var slidesIndexes = [];
|
||
for (var i = 0; i < s.slides.length; i++) {
|
||
slidesIndexes.push(i);
|
||
}
|
||
s.removeSlide(slidesIndexes);
|
||
};
|
||
|
||
|
||
/*=========================
|
||
Effects
|
||
===========================*/
|
||
s.effects = {
|
||
fade: {
|
||
setTranslate: function () {
|
||
for (var i = 0; i < s.slides.length; i++) {
|
||
var slide = s.slides.eq(i);
|
||
var offset = slide[0].swiperSlideOffset;
|
||
var tx = -offset;
|
||
if (!s.params.virtualTranslate) tx = tx - s.translate;
|
||
var ty = 0;
|
||
if (!s.isHorizontal()) {
|
||
ty = tx;
|
||
tx = 0;
|
||
}
|
||
var slideOpacity = s.params.fade.crossFade ?
|
||
Math.max(1 - Math.abs(slide[0].progress), 0) :
|
||
1 + Math.min(Math.max(slide[0].progress, -1), 0);
|
||
slide
|
||
.css({
|
||
opacity: slideOpacity
|
||
})
|
||
.transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px)');
|
||
|
||
}
|
||
|
||
},
|
||
setTransition: function (duration) {
|
||
s.slides.transition(duration);
|
||
if (s.params.virtualTranslate && duration !== 0) {
|
||
var eventTriggered = false;
|
||
s.slides.transitionEnd(function () {
|
||
if (eventTriggered) return;
|
||
if (!s) return;
|
||
eventTriggered = true;
|
||
s.animating = false;
|
||
var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];
|
||
for (var i = 0; i < triggerEvents.length; i++) {
|
||
s.wrapper.trigger(triggerEvents[i]);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
},
|
||
flip: {
|
||
setTranslate: function () {
|
||
for (var i = 0; i < s.slides.length; i++) {
|
||
var slide = s.slides.eq(i);
|
||
var progress = slide[0].progress;
|
||
if (s.params.flip.limitRotation) {
|
||
progress = Math.max(Math.min(slide[0].progress, 1), -1);
|
||
}
|
||
var offset = slide[0].swiperSlideOffset;
|
||
var rotate = -180 * progress,
|
||
rotateY = rotate,
|
||
rotateX = 0,
|
||
tx = -offset,
|
||
ty = 0;
|
||
if (!s.isHorizontal()) {
|
||
ty = tx;
|
||
tx = 0;
|
||
rotateX = -rotateY;
|
||
rotateY = 0;
|
||
}
|
||
else if (s.rtl) {
|
||
rotateY = -rotateY;
|
||
}
|
||
|
||
slide[0].style.zIndex = -Math.abs(Math.round(progress)) + s.slides.length;
|
||
|
||
if (s.params.flip.slideShadows) {
|
||
//Set shadows
|
||
var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
|
||
var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
|
||
if (shadowBefore.length === 0) {
|
||
shadowBefore = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '"></div>');
|
||
slide.append(shadowBefore);
|
||
}
|
||
if (shadowAfter.length === 0) {
|
||
shadowAfter = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '"></div>');
|
||
slide.append(shadowAfter);
|
||
}
|
||
if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
|
||
if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
|
||
}
|
||
|
||
slide
|
||
.transform('translate3d(' + tx + 'px, ' + ty + 'px, 0px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)');
|
||
}
|
||
},
|
||
setTransition: function (duration) {
|
||
s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
|
||
if (s.params.virtualTranslate && duration !== 0) {
|
||
var eventTriggered = false;
|
||
s.slides.eq(s.activeIndex).transitionEnd(function () {
|
||
if (eventTriggered) return;
|
||
if (!s) return;
|
||
if (!$(this).hasClass(s.params.slideActiveClass)) return;
|
||
eventTriggered = true;
|
||
s.animating = false;
|
||
var triggerEvents = ['webkitTransitionEnd', 'transitionend', 'oTransitionEnd', 'MSTransitionEnd', 'msTransitionEnd'];
|
||
for (var i = 0; i < triggerEvents.length; i++) {
|
||
s.wrapper.trigger(triggerEvents[i]);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
},
|
||
cube: {
|
||
setTranslate: function () {
|
||
var wrapperRotate = 0, cubeShadow;
|
||
if (s.params.cube.shadow) {
|
||
if (s.isHorizontal()) {
|
||
cubeShadow = s.wrapper.find('.swiper-cube-shadow');
|
||
if (cubeShadow.length === 0) {
|
||
cubeShadow = $('<div class="swiper-cube-shadow"></div>');
|
||
s.wrapper.append(cubeShadow);
|
||
}
|
||
cubeShadow.css({height: s.width + 'px'});
|
||
}
|
||
else {
|
||
cubeShadow = s.container.find('.swiper-cube-shadow');
|
||
if (cubeShadow.length === 0) {
|
||
cubeShadow = $('<div class="swiper-cube-shadow"></div>');
|
||
s.container.append(cubeShadow);
|
||
}
|
||
}
|
||
}
|
||
for (var i = 0; i < s.slides.length; i++) {
|
||
var slide = s.slides.eq(i);
|
||
var slideAngle = i * 90;
|
||
var round = Math.floor(slideAngle / 360);
|
||
if (s.rtl) {
|
||
slideAngle = -slideAngle;
|
||
round = Math.floor(-slideAngle / 360);
|
||
}
|
||
var progress = Math.max(Math.min(slide[0].progress, 1), -1);
|
||
var tx = 0, ty = 0, tz = 0;
|
||
if (i % 4 === 0) {
|
||
tx = - round * 4 * s.size;
|
||
tz = 0;
|
||
}
|
||
else if ((i - 1) % 4 === 0) {
|
||
tx = 0;
|
||
tz = - round * 4 * s.size;
|
||
}
|
||
else if ((i - 2) % 4 === 0) {
|
||
tx = s.size + round * 4 * s.size;
|
||
tz = s.size;
|
||
}
|
||
else if ((i - 3) % 4 === 0) {
|
||
tx = - s.size;
|
||
tz = 3 * s.size + s.size * 4 * round;
|
||
}
|
||
if (s.rtl) {
|
||
tx = -tx;
|
||
}
|
||
|
||
if (!s.isHorizontal()) {
|
||
ty = tx;
|
||
tx = 0;
|
||
}
|
||
|
||
var transform = 'rotateX(' + (s.isHorizontal() ? 0 : -slideAngle) + 'deg) rotateY(' + (s.isHorizontal() ? slideAngle : 0) + 'deg) translate3d(' + tx + 'px, ' + ty + 'px, ' + tz + 'px)';
|
||
if (progress <= 1 && progress > -1) {
|
||
wrapperRotate = i * 90 + progress * 90;
|
||
if (s.rtl) wrapperRotate = -i * 90 - progress * 90;
|
||
}
|
||
slide.transform(transform);
|
||
if (s.params.cube.slideShadows) {
|
||
//Set shadows
|
||
var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
|
||
var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
|
||
if (shadowBefore.length === 0) {
|
||
shadowBefore = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '"></div>');
|
||
slide.append(shadowBefore);
|
||
}
|
||
if (shadowAfter.length === 0) {
|
||
shadowAfter = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '"></div>');
|
||
slide.append(shadowAfter);
|
||
}
|
||
if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
|
||
if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
|
||
}
|
||
}
|
||
s.wrapper.css({
|
||
'-webkit-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
|
||
'-moz-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
|
||
'-ms-transform-origin': '50% 50% -' + (s.size / 2) + 'px',
|
||
'transform-origin': '50% 50% -' + (s.size / 2) + 'px'
|
||
});
|
||
|
||
if (s.params.cube.shadow) {
|
||
if (s.isHorizontal()) {
|
||
cubeShadow.transform('translate3d(0px, ' + (s.width / 2 + s.params.cube.shadowOffset) + 'px, ' + (-s.width / 2) + 'px) rotateX(90deg) rotateZ(0deg) scale(' + (s.params.cube.shadowScale) + ')');
|
||
}
|
||
else {
|
||
var shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
|
||
var multiplier = 1.5 - (Math.sin(shadowAngle * 2 * Math.PI / 360) / 2 + Math.cos(shadowAngle * 2 * Math.PI / 360) / 2);
|
||
var scale1 = s.params.cube.shadowScale,
|
||
scale2 = s.params.cube.shadowScale / multiplier,
|
||
offset = s.params.cube.shadowOffset;
|
||
cubeShadow.transform('scale3d(' + scale1 + ', 1, ' + scale2 + ') translate3d(0px, ' + (s.height / 2 + offset) + 'px, ' + (-s.height / 2 / scale2) + 'px) rotateX(-90deg)');
|
||
}
|
||
}
|
||
var zFactor = (s.isSafari || s.isUiWebView) ? (-s.size / 2) : 0;
|
||
s.wrapper.transform('translate3d(0px,0,' + zFactor + 'px) rotateX(' + (s.isHorizontal() ? 0 : wrapperRotate) + 'deg) rotateY(' + (s.isHorizontal() ? -wrapperRotate : 0) + 'deg)');
|
||
},
|
||
setTransition: function (duration) {
|
||
s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
|
||
if (s.params.cube.shadow && !s.isHorizontal()) {
|
||
s.container.find('.swiper-cube-shadow').transition(duration);
|
||
}
|
||
}
|
||
},
|
||
coverflow: {
|
||
setTranslate: function () {
|
||
var transform = s.translate;
|
||
var center = s.isHorizontal() ? -transform + s.width / 2 : -transform + s.height / 2;
|
||
var rotate = s.isHorizontal() ? s.params.coverflow.rotate: -s.params.coverflow.rotate;
|
||
var translate = s.params.coverflow.depth;
|
||
//Each slide offset from center
|
||
for (var i = 0, length = s.slides.length; i < length; i++) {
|
||
var slide = s.slides.eq(i);
|
||
var slideSize = s.slidesSizesGrid[i];
|
||
var slideOffset = slide[0].swiperSlideOffset;
|
||
var offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * s.params.coverflow.modifier;
|
||
|
||
var rotateY = s.isHorizontal() ? rotate * offsetMultiplier : 0;
|
||
var rotateX = s.isHorizontal() ? 0 : rotate * offsetMultiplier;
|
||
// var rotateZ = 0
|
||
var translateZ = -translate * Math.abs(offsetMultiplier);
|
||
|
||
var translateY = s.isHorizontal() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);
|
||
var translateX = s.isHorizontal() ? s.params.coverflow.stretch * (offsetMultiplier) : 0;
|
||
|
||
//Fix for ultra small values
|
||
if (Math.abs(translateX) < 0.001) translateX = 0;
|
||
if (Math.abs(translateY) < 0.001) translateY = 0;
|
||
if (Math.abs(translateZ) < 0.001) translateZ = 0;
|
||
if (Math.abs(rotateY) < 0.001) rotateY = 0;
|
||
if (Math.abs(rotateX) < 0.001) rotateX = 0;
|
||
|
||
var slideTransform = 'translate3d(' + translateX + 'px,' + translateY + 'px,' + translateZ + 'px) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)';
|
||
|
||
slide.transform(slideTransform);
|
||
slide[0].style.zIndex = -Math.abs(Math.round(offsetMultiplier)) + 1;
|
||
if (s.params.coverflow.slideShadows) {
|
||
//Set shadows
|
||
var shadowBefore = s.isHorizontal() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
|
||
var shadowAfter = s.isHorizontal() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
|
||
if (shadowBefore.length === 0) {
|
||
shadowBefore = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'left' : 'top') + '"></div>');
|
||
slide.append(shadowBefore);
|
||
}
|
||
if (shadowAfter.length === 0) {
|
||
shadowAfter = $('<div class="swiper-slide-shadow-' + (s.isHorizontal() ? 'right' : 'bottom') + '"></div>');
|
||
slide.append(shadowAfter);
|
||
}
|
||
if (shadowBefore.length) shadowBefore[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
|
||
if (shadowAfter.length) shadowAfter[0].style.opacity = (-offsetMultiplier) > 0 ? -offsetMultiplier : 0;
|
||
}
|
||
}
|
||
|
||
//Set correct perspective for IE10
|
||
if (s.browser.ie) {
|
||
var ws = s.wrapper[0].style;
|
||
ws.perspectiveOrigin = center + 'px 50%';
|
||
}
|
||
},
|
||
setTransition: function (duration) {
|
||
s.slides.transition(duration).find('.swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left').transition(duration);
|
||
}
|
||
}
|
||
};
|
||
|
||
/*=========================
|
||
Images Lazy Loading
|
||
===========================*/
|
||
s.lazy = {
|
||
initialImageLoaded: false,
|
||
loadImageInSlide: function (index, loadInDuplicate) {
|
||
if (typeof index === 'undefined') return;
|
||
if (typeof loadInDuplicate === 'undefined') loadInDuplicate = true;
|
||
if (s.slides.length === 0) return;
|
||
|
||
var slide = s.slides.eq(index);
|
||
var img = slide.find('.' + s.params.lazyLoadingClass + ':not(.' + s.params.lazyStatusLoadedClass + '):not(.' + s.params.lazyStatusLoadingClass + ')');
|
||
if (slide.hasClass(s.params.lazyLoadingClass) && !slide.hasClass(s.params.lazyStatusLoadedClass) && !slide.hasClass(s.params.lazyStatusLoadingClass)) {
|
||
img = img.add(slide[0]);
|
||
}
|
||
if (img.length === 0) return;
|
||
|
||
img.each(function () {
|
||
var _img = $(this);
|
||
_img.addClass(s.params.lazyStatusLoadingClass);
|
||
var background = _img.attr('data-background');
|
||
var src = _img.attr('data-src'),
|
||
srcset = _img.attr('data-srcset'),
|
||
sizes = _img.attr('data-sizes');
|
||
s.loadImage(_img[0], (src || background), srcset, sizes, false, function () {
|
||
if (background) {
|
||
_img.css('background-image', 'url("' + background + '")');
|
||
_img.removeAttr('data-background');
|
||
}
|
||
else {
|
||
if (srcset) {
|
||
_img.attr('srcset', srcset);
|
||
_img.removeAttr('data-srcset');
|
||
}
|
||
if (sizes) {
|
||
_img.attr('sizes', sizes);
|
||
_img.removeAttr('data-sizes');
|
||
}
|
||
if (src) {
|
||
_img.attr('src', src);
|
||
_img.removeAttr('data-src');
|
||
}
|
||
|
||
}
|
||
|
||
_img.addClass(s.params.lazyStatusLoadedClass).removeClass(s.params.lazyStatusLoadingClass);
|
||
slide.find('.' + s.params.lazyPreloaderClass + ', .' + s.params.preloaderClass).remove();
|
||
if (s.params.loop && loadInDuplicate) {
|
||
var slideOriginalIndex = slide.attr('data-swiper-slide-index');
|
||
if (slide.hasClass(s.params.slideDuplicateClass)) {
|
||
var originalSlide = s.wrapper.children('[data-swiper-slide-index="' + slideOriginalIndex + '"]:not(.' + s.params.slideDuplicateClass + ')');
|
||
s.lazy.loadImageInSlide(originalSlide.index(), false);
|
||
}
|
||
else {
|
||
var duplicatedSlide = s.wrapper.children('.' + s.params.slideDuplicateClass + '[data-swiper-slide-index="' + slideOriginalIndex + '"]');
|
||
s.lazy.loadImageInSlide(duplicatedSlide.index(), false);
|
||
}
|
||
}
|
||
s.emit('onLazyImageReady', s, slide[0], _img[0]);
|
||
});
|
||
|
||
s.emit('onLazyImageLoad', s, slide[0], _img[0]);
|
||
});
|
||
|
||
},
|
||
load: function () {
|
||
var i;
|
||
var slidesPerView = s.params.slidesPerView;
|
||
if (slidesPerView === 'auto') {
|
||
slidesPerView = 0;
|
||
}
|
||
if (!s.lazy.initialImageLoaded) s.lazy.initialImageLoaded = true;
|
||
if (s.params.watchSlidesVisibility) {
|
||
s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {
|
||
s.lazy.loadImageInSlide($(this).index());
|
||
});
|
||
}
|
||
else {
|
||
if (slidesPerView > 1) {
|
||
for (i = s.activeIndex; i < s.activeIndex + slidesPerView ; i++) {
|
||
if (s.slides[i]) s.lazy.loadImageInSlide(i);
|
||
}
|
||
}
|
||
else {
|
||
s.lazy.loadImageInSlide(s.activeIndex);
|
||
}
|
||
}
|
||
if (s.params.lazyLoadingInPrevNext) {
|
||
if (slidesPerView > 1 || (s.params.lazyLoadingInPrevNextAmount && s.params.lazyLoadingInPrevNextAmount > 1)) {
|
||
var amount = s.params.lazyLoadingInPrevNextAmount;
|
||
var spv = slidesPerView;
|
||
var maxIndex = Math.min(s.activeIndex + spv + Math.max(amount, spv), s.slides.length);
|
||
var minIndex = Math.max(s.activeIndex - Math.max(spv, amount), 0);
|
||
// Next Slides
|
||
for (i = s.activeIndex + slidesPerView; i < maxIndex; i++) {
|
||
if (s.slides[i]) s.lazy.loadImageInSlide(i);
|
||
}
|
||
// Prev Slides
|
||
for (i = minIndex; i < s.activeIndex ; i++) {
|
||
if (s.slides[i]) s.lazy.loadImageInSlide(i);
|
||
}
|
||
}
|
||
else {
|
||
var nextSlide = s.wrapper.children('.' + s.params.slideNextClass);
|
||
if (nextSlide.length > 0) s.lazy.loadImageInSlide(nextSlide.index());
|
||
|
||
var prevSlide = s.wrapper.children('.' + s.params.slidePrevClass);
|
||
if (prevSlide.length > 0) s.lazy.loadImageInSlide(prevSlide.index());
|
||
}
|
||
}
|
||
},
|
||
onTransitionStart: function () {
|
||
if (s.params.lazyLoading) {
|
||
if (s.params.lazyLoadingOnTransitionStart || (!s.params.lazyLoadingOnTransitionStart && !s.lazy.initialImageLoaded)) {
|
||
s.lazy.load();
|
||
}
|
||
}
|
||
},
|
||
onTransitionEnd: function () {
|
||
if (s.params.lazyLoading && !s.params.lazyLoadingOnTransitionStart) {
|
||
s.lazy.load();
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
/*=========================
|
||
Scrollbar
|
||
===========================*/
|
||
s.scrollbar = {
|
||
isTouched: false,
|
||
setDragPosition: function (e) {
|
||
var sb = s.scrollbar;
|
||
var x = 0, y = 0;
|
||
var translate;
|
||
var pointerPosition = s.isHorizontal() ?
|
||
((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :
|
||
((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;
|
||
var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;
|
||
var positionMin = -s.minTranslate() * sb.moveDivider;
|
||
var positionMax = -s.maxTranslate() * sb.moveDivider;
|
||
if (position < positionMin) {
|
||
position = positionMin;
|
||
}
|
||
else if (position > positionMax) {
|
||
position = positionMax;
|
||
}
|
||
position = -position / sb.moveDivider;
|
||
s.updateProgress(position);
|
||
s.setWrapperTranslate(position, true);
|
||
},
|
||
dragStart: function (e) {
|
||
var sb = s.scrollbar;
|
||
sb.isTouched = true;
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
|
||
sb.setDragPosition(e);
|
||
clearTimeout(sb.dragTimeout);
|
||
|
||
sb.track.transition(0);
|
||
if (s.params.scrollbarHide) {
|
||
sb.track.css('opacity', 1);
|
||
}
|
||
s.wrapper.transition(100);
|
||
sb.drag.transition(100);
|
||
s.emit('onScrollbarDragStart', s);
|
||
},
|
||
dragMove: function (e) {
|
||
var sb = s.scrollbar;
|
||
if (!sb.isTouched) return;
|
||
if (e.preventDefault) e.preventDefault();
|
||
else e.returnValue = false;
|
||
sb.setDragPosition(e);
|
||
s.wrapper.transition(0);
|
||
sb.track.transition(0);
|
||
sb.drag.transition(0);
|
||
s.emit('onScrollbarDragMove', s);
|
||
},
|
||
dragEnd: function (e) {
|
||
var sb = s.scrollbar;
|
||
if (!sb.isTouched) return;
|
||
sb.isTouched = false;
|
||
if (s.params.scrollbarHide) {
|
||
clearTimeout(sb.dragTimeout);
|
||
sb.dragTimeout = setTimeout(function () {
|
||
sb.track.css('opacity', 0);
|
||
sb.track.transition(400);
|
||
}, 1000);
|
||
|
||
}
|
||
s.emit('onScrollbarDragEnd', s);
|
||
if (s.params.scrollbarSnapOnRelease) {
|
||
s.slideReset();
|
||
}
|
||
},
|
||
draggableEvents: (function () {
|
||
if ((s.params.simulateTouch === false && !s.support.touch)) return s.touchEventsDesktop;
|
||
else return s.touchEvents;
|
||
})(),
|
||
enableDraggable: function () {
|
||
var sb = s.scrollbar;
|
||
var target = s.support.touch ? sb.track : document;
|
||
$(sb.track).on(sb.draggableEvents.start, sb.dragStart);
|
||
$(target).on(sb.draggableEvents.move, sb.dragMove);
|
||
$(target).on(sb.draggableEvents.end, sb.dragEnd);
|
||
},
|
||
disableDraggable: function () {
|
||
var sb = s.scrollbar;
|
||
var target = s.support.touch ? sb.track : document;
|
||
$(sb.track).off(s.draggableEvents.start, sb.dragStart);
|
||
$(target).off(s.draggableEvents.move, sb.dragMove);
|
||
$(target).off(s.draggableEvents.end, sb.dragEnd);
|
||
},
|
||
set: function () {
|
||
if (!s.params.scrollbar) return;
|
||
var sb = s.scrollbar;
|
||
sb.track = $(s.params.scrollbar);
|
||
if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {
|
||
sb.track = s.container.find(s.params.scrollbar);
|
||
}
|
||
sb.drag = sb.track.find('.swiper-scrollbar-drag');
|
||
if (sb.drag.length === 0) {
|
||
sb.drag = $('<div class="swiper-scrollbar-drag"></div>');
|
||
sb.track.append(sb.drag);
|
||
}
|
||
sb.drag[0].style.width = '';
|
||
sb.drag[0].style.height = '';
|
||
sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;
|
||
|
||
sb.divider = s.size / s.virtualSize;
|
||
sb.moveDivider = sb.divider * (sb.trackSize / s.size);
|
||
sb.dragSize = sb.trackSize * sb.divider;
|
||
|
||
if (s.isHorizontal()) {
|
||
sb.drag[0].style.width = sb.dragSize + 'px';
|
||
}
|
||
else {
|
||
sb.drag[0].style.height = sb.dragSize + 'px';
|
||
}
|
||
|
||
if (sb.divider >= 1) {
|
||
sb.track[0].style.display = 'none';
|
||
}
|
||
else {
|
||
sb.track[0].style.display = '';
|
||
}
|
||
if (s.params.scrollbarHide) {
|
||
sb.track[0].style.opacity = 0;
|
||
}
|
||
},
|
||
setTranslate: function () {
|
||
if (!s.params.scrollbar) return;
|
||
var diff;
|
||
var sb = s.scrollbar;
|
||
var translate = s.translate || 0;
|
||
var newPos;
|
||
|
||
var newSize = sb.dragSize;
|
||
newPos = (sb.trackSize - sb.dragSize) * s.progress;
|
||
if (s.rtl && s.isHorizontal()) {
|
||
newPos = -newPos;
|
||
if (newPos > 0) {
|
||
newSize = sb.dragSize - newPos;
|
||
newPos = 0;
|
||
}
|
||
else if (-newPos + sb.dragSize > sb.trackSize) {
|
||
newSize = sb.trackSize + newPos;
|
||
}
|
||
}
|
||
else {
|
||
if (newPos < 0) {
|
||
newSize = sb.dragSize + newPos;
|
||
newPos = 0;
|
||
}
|
||
else if (newPos + sb.dragSize > sb.trackSize) {
|
||
newSize = sb.trackSize - newPos;
|
||
}
|
||
}
|
||
if (s.isHorizontal()) {
|
||
if (s.support.transforms3d) {
|
||
sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');
|
||
}
|
||
else {
|
||
sb.drag.transform('translateX(' + (newPos) + 'px)');
|
||
}
|
||
sb.drag[0].style.width = newSize + 'px';
|
||
}
|
||
else {
|
||
if (s.support.transforms3d) {
|
||
sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');
|
||
}
|
||
else {
|
||
sb.drag.transform('translateY(' + (newPos) + 'px)');
|
||
}
|
||
sb.drag[0].style.height = newSize + 'px';
|
||
}
|
||
if (s.params.scrollbarHide) {
|
||
clearTimeout(sb.timeout);
|
||
sb.track[0].style.opacity = 1;
|
||
sb.timeout = setTimeout(function () {
|
||
sb.track[0].style.opacity = 0;
|
||
sb.track.transition(400);
|
||
}, 1000);
|
||
}
|
||
},
|
||
setTransition: function (duration) {
|
||
if (!s.params.scrollbar) return;
|
||
s.scrollbar.drag.transition(duration);
|
||
}
|
||
};
|
||
|
||
/*=========================
|
||
Controller
|
||
===========================*/
|
||
s.controller = {
|
||
LinearSpline: function (x, y) {
|
||
this.x = x;
|
||
this.y = y;
|
||
this.lastIndex = x.length - 1;
|
||
// Given an x value (x2), return the expected y2 value:
|
||
// (x1,y1) is the known point before given value,
|
||
// (x3,y3) is the known point after given value.
|
||
var i1, i3;
|
||
var l = this.x.length;
|
||
|
||
this.interpolate = function (x2) {
|
||
if (!x2) return 0;
|
||
|
||
// Get the indexes of x1 and x3 (the array indexes before and after given x2):
|
||
i3 = binarySearch(this.x, x2);
|
||
i1 = i3 - 1;
|
||
|
||
// We have our indexes i1 & i3, so we can calculate already:
|
||
// y2 := ((x2−x1) × (y3−y1)) ÷ (x3−x1) + y1
|
||
return ((x2 - this.x[i1]) * (this.y[i3] - this.y[i1])) / (this.x[i3] - this.x[i1]) + this.y[i1];
|
||
};
|
||
|
||
var binarySearch = (function() {
|
||
var maxIndex, minIndex, guess;
|
||
return function(array, val) {
|
||
minIndex = -1;
|
||
maxIndex = array.length;
|
||
while (maxIndex - minIndex > 1)
|
||
if (array[guess = maxIndex + minIndex >> 1] <= val) {
|
||
minIndex = guess;
|
||
} else {
|
||
maxIndex = guess;
|
||
}
|
||
return maxIndex;
|
||
};
|
||
})();
|
||
},
|
||
//xxx: for now i will just save one spline function to to
|
||
getInterpolateFunction: function(c){
|
||
if(!s.controller.spline) s.controller.spline = s.params.loop ?
|
||
new s.controller.LinearSpline(s.slidesGrid, c.slidesGrid) :
|
||
new s.controller.LinearSpline(s.snapGrid, c.snapGrid);
|
||
},
|
||
setTranslate: function (translate, byController) {
|
||
var controlled = s.params.control;
|
||
var multiplier, controlledTranslate;
|
||
function setControlledTranslate(c) {
|
||
// this will create an Interpolate function based on the snapGrids
|
||
// x is the Grid of the scrolled scroller and y will be the controlled scroller
|
||
// it makes sense to create this only once and recall it for the interpolation
|
||
// the function does a lot of value caching for performance
|
||
translate = c.rtl && c.params.direction === 'horizontal' ? -s.translate : s.translate;
|
||
if (s.params.controlBy === 'slide') {
|
||
s.controller.getInterpolateFunction(c);
|
||
// i am not sure why the values have to be multiplicated this way, tried to invert the snapGrid
|
||
// but it did not work out
|
||
controlledTranslate = -s.controller.spline.interpolate(-translate);
|
||
}
|
||
|
||
if(!controlledTranslate || s.params.controlBy === 'container'){
|
||
multiplier = (c.maxTranslate() - c.minTranslate()) / (s.maxTranslate() - s.minTranslate());
|
||
controlledTranslate = (translate - s.minTranslate()) * multiplier + c.minTranslate();
|
||
}
|
||
|
||
if (s.params.controlInverse) {
|
||
controlledTranslate = c.maxTranslate() - controlledTranslate;
|
||
}
|
||
c.updateProgress(controlledTranslate);
|
||
c.setWrapperTranslate(controlledTranslate, false, s);
|
||
c.updateActiveIndex();
|
||
}
|
||
if (s.isArray(controlled)) {
|
||
for (var i = 0; i < controlled.length; i++) {
|
||
if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
|
||
setControlledTranslate(controlled[i]);
|
||
}
|
||
}
|
||
}
|
||
else if (controlled instanceof Swiper && byController !== controlled) {
|
||
|
||
setControlledTranslate(controlled);
|
||
}
|
||
},
|
||
setTransition: function (duration, byController) {
|
||
var controlled = s.params.control;
|
||
var i;
|
||
function setControlledTransition(c) {
|
||
c.setWrapperTransition(duration, s);
|
||
if (duration !== 0) {
|
||
c.onTransitionStart();
|
||
c.wrapper.transitionEnd(function(){
|
||
if (!controlled) return;
|
||
if (c.params.loop && s.params.controlBy === 'slide') {
|
||
c.fixLoop();
|
||
}
|
||
c.onTransitionEnd();
|
||
|
||
});
|
||
}
|
||
}
|
||
if (s.isArray(controlled)) {
|
||
for (i = 0; i < controlled.length; i++) {
|
||
if (controlled[i] !== byController && controlled[i] instanceof Swiper) {
|
||
setControlledTransition(controlled[i]);
|
||
}
|
||
}
|
||
}
|
||
else if (controlled instanceof Swiper && byController !== controlled) {
|
||
setControlledTransition(controlled);
|
||
}
|
||
}
|
||
};
|
||
|
||
/*=========================
|
||
Parallax
|
||
===========================*/
|
||
function setParallaxTransform(el, progress) {
|
||
el = $(el);
|
||
var p, pX, pY;
|
||
var rtlFactor = s.rtl ? -1 : 1;
|
||
|
||
p = el.attr('data-swiper-parallax') || '0';
|
||
pX = el.attr('data-swiper-parallax-x');
|
||
pY = el.attr('data-swiper-parallax-y');
|
||
if (pX || pY) {
|
||
pX = pX || '0';
|
||
pY = pY || '0';
|
||
}
|
||
else {
|
||
if (s.isHorizontal()) {
|
||
pX = p;
|
||
pY = '0';
|
||
}
|
||
else {
|
||
pY = p;
|
||
pX = '0';
|
||
}
|
||
}
|
||
|
||
if ((pX).indexOf('%') >= 0) {
|
||
pX = parseInt(pX, 10) * progress * rtlFactor + '%';
|
||
}
|
||
else {
|
||
pX = pX * progress * rtlFactor + 'px' ;
|
||
}
|
||
if ((pY).indexOf('%') >= 0) {
|
||
pY = parseInt(pY, 10) * progress + '%';
|
||
}
|
||
else {
|
||
pY = pY * progress + 'px' ;
|
||
}
|
||
|
||
el.transform('translate3d(' + pX + ', ' + pY + ',0px)');
|
||
}
|
||
s.parallax = {
|
||
setTranslate: function () {
|
||
s.container.children('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
|
||
setParallaxTransform(this, s.progress);
|
||
|
||
});
|
||
s.slides.each(function () {
|
||
var slide = $(this);
|
||
slide.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function () {
|
||
var progress = Math.min(Math.max(slide[0].progress, -1), 1);
|
||
setParallaxTransform(this, progress);
|
||
});
|
||
});
|
||
},
|
||
setTransition: function (duration) {
|
||
if (typeof duration === 'undefined') duration = s.params.speed;
|
||
s.container.find('[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]').each(function(){
|
||
var el = $(this);
|
||
var parallaxDuration = parseInt(el.attr('data-swiper-parallax-duration'), 10) || duration;
|
||
if (duration === 0) parallaxDuration = 0;
|
||
el.transition(parallaxDuration);
|
||
});
|
||
}
|
||
};
|
||
|
||
|
||
/*=========================
|
||
Zoom
|
||
===========================*/
|
||
s.zoom = {
|
||
// "Global" Props
|
||
scale: 1,
|
||
currentScale: 1,
|
||
isScaling: false,
|
||
gesture: {
|
||
slide: undefined,
|
||
slideWidth: undefined,
|
||
slideHeight: undefined,
|
||
image: undefined,
|
||
imageWrap: undefined,
|
||
zoomMax: s.params.zoomMax
|
||
},
|
||
image: {
|
||
isTouched: undefined,
|
||
isMoved: undefined,
|
||
currentX: undefined,
|
||
currentY: undefined,
|
||
minX: undefined,
|
||
minY: undefined,
|
||
maxX: undefined,
|
||
maxY: undefined,
|
||
width: undefined,
|
||
height: undefined,
|
||
startX: undefined,
|
||
startY: undefined,
|
||
touchesStart: {},
|
||
touchesCurrent: {}
|
||
},
|
||
velocity: {
|
||
x: undefined,
|
||
y: undefined,
|
||
prevPositionX: undefined,
|
||
prevPositionY: undefined,
|
||
prevTime: undefined
|
||
},
|
||
// Calc Scale From Multi-touches
|
||
getDistanceBetweenTouches: function (e) {
|
||
if (e.targetTouches.length < 2) return 1;
|
||
var x1 = e.targetTouches[0].pageX,
|
||
y1 = e.targetTouches[0].pageY,
|
||
x2 = e.targetTouches[1].pageX,
|
||
y2 = e.targetTouches[1].pageY;
|
||
var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
|
||
return distance;
|
||
},
|
||
// Events
|
||
onGestureStart: function (e) {
|
||
var z = s.zoom;
|
||
if (!s.support.gestures) {
|
||
if (e.type !== 'touchstart' || e.type === 'touchstart' && e.targetTouches.length < 2) {
|
||
return;
|
||
}
|
||
z.gesture.scaleStart = z.getDistanceBetweenTouches(e);
|
||
}
|
||
if (!z.gesture.slide || !z.gesture.slide.length) {
|
||
z.gesture.slide = $(this);
|
||
if (z.gesture.slide.length === 0) z.gesture.slide = s.slides.eq(s.activeIndex);
|
||
z.gesture.image = z.gesture.slide.find('img, svg, canvas');
|
||
z.gesture.imageWrap = z.gesture.image.parent('.' + s.params.zoomContainerClass);
|
||
z.gesture.zoomMax = z.gesture.imageWrap.attr('data-swiper-zoom') || s.params.zoomMax ;
|
||
if (z.gesture.imageWrap.length === 0) {
|
||
z.gesture.image = undefined;
|
||
return;
|
||
}
|
||
}
|
||
z.gesture.image.transition(0);
|
||
z.isScaling = true;
|
||
},
|
||
onGestureChange: function (e) {
|
||
var z = s.zoom;
|
||
if (!s.support.gestures) {
|
||
if (e.type !== 'touchmove' || e.type === 'touchmove' && e.targetTouches.length < 2) {
|
||
return;
|
||
}
|
||
z.gesture.scaleMove = z.getDistanceBetweenTouches(e);
|
||
}
|
||
if (!z.gesture.image || z.gesture.image.length === 0) return;
|
||
if (s.support.gestures) {
|
||
z.scale = e.scale * z.currentScale;
|
||
}
|
||
else {
|
||
z.scale = (z.gesture.scaleMove / z.gesture.scaleStart) * z.currentScale;
|
||
}
|
||
if (z.scale > z.gesture.zoomMax) {
|
||
z.scale = z.gesture.zoomMax - 1 + Math.pow((z.scale - z.gesture.zoomMax + 1), 0.5);
|
||
}
|
||
if (z.scale < s.params.zoomMin) {
|
||
z.scale = s.params.zoomMin + 1 - Math.pow((s.params.zoomMin - z.scale + 1), 0.5);
|
||
}
|
||
z.gesture.image.transform('translate3d(0,0,0) scale(' + z.scale + ')');
|
||
},
|
||
onGestureEnd: function (e) {
|
||
var z = s.zoom;
|
||
if (!s.support.gestures) {
|
||
if (e.type !== 'touchend' || e.type === 'touchend' && e.changedTouches.length < 2) {
|
||
return;
|
||
}
|
||
}
|
||
if (!z.gesture.image || z.gesture.image.length === 0) return;
|
||
z.scale = Math.max(Math.min(z.scale, z.gesture.zoomMax), s.params.zoomMin);
|
||
z.gesture.image.transition(s.params.speed).transform('translate3d(0,0,0) scale(' + z.scale + ')');
|
||
z.currentScale = z.scale;
|
||
z.isScaling = false;
|
||
if (z.scale === 1) z.gesture.slide = undefined;
|
||
},
|
||
onTouchStart: function (s, e) {
|
||
var z = s.zoom;
|
||
if (!z.gesture.image || z.gesture.image.length === 0) return;
|
||
if (z.image.isTouched) return;
|
||
if (s.device.os === 'android') e.preventDefault();
|
||
z.image.isTouched = true;
|
||
z.image.touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
|
||
z.image.touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
|
||
},
|
||
onTouchMove: function (e) {
|
||
var z = s.zoom;
|
||
if (!z.gesture.image || z.gesture.image.length === 0) return;
|
||
s.allowClick = false;
|
||
if (!z.image.isTouched || !z.gesture.slide) return;
|
||
|
||
if (!z.image.isMoved) {
|
||
z.image.width = z.gesture.image[0].offsetWidth;
|
||
z.image.height = z.gesture.image[0].offsetHeight;
|
||
z.image.startX = s.getTranslate(z.gesture.imageWrap[0], 'x') || 0;
|
||
z.image.startY = s.getTranslate(z.gesture.imageWrap[0], 'y') || 0;
|
||
z.gesture.slideWidth = z.gesture.slide[0].offsetWidth;
|
||
z.gesture.slideHeight = z.gesture.slide[0].offsetHeight;
|
||
z.gesture.imageWrap.transition(0);
|
||
}
|
||
// Define if we need image drag
|
||
var scaledWidth = z.image.width * z.scale;
|
||
var scaledHeight = z.image.height * z.scale;
|
||
|
||
if (scaledWidth < z.gesture.slideWidth && scaledHeight < z.gesture.slideHeight) return;
|
||
|
||
z.image.minX = Math.min((z.gesture.slideWidth / 2 - scaledWidth / 2), 0);
|
||
z.image.maxX = -z.image.minX;
|
||
z.image.minY = Math.min((z.gesture.slideHeight / 2 - scaledHeight / 2), 0);
|
||
z.image.maxY = -z.image.minY;
|
||
|
||
z.image.touchesCurrent.x = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
|
||
z.image.touchesCurrent.y = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
|
||
|
||
if (!z.image.isMoved && !z.isScaling) {
|
||
if (s.isHorizontal() &&
|
||
(Math.floor(z.image.minX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x < z.image.touchesStart.x) ||
|
||
(Math.floor(z.image.maxX) === Math.floor(z.image.startX) && z.image.touchesCurrent.x > z.image.touchesStart.x)
|
||
) {
|
||
z.image.isTouched = false;
|
||
return;
|
||
}
|
||
else if (!s.isHorizontal() &&
|
||
(Math.floor(z.image.minY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y < z.image.touchesStart.y) ||
|
||
(Math.floor(z.image.maxY) === Math.floor(z.image.startY) && z.image.touchesCurrent.y > z.image.touchesStart.y)
|
||
) {
|
||
z.image.isTouched = false;
|
||
return;
|
||
}
|
||
}
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
|
||
z.image.isMoved = true;
|
||
z.image.currentX = z.image.touchesCurrent.x - z.image.touchesStart.x + z.image.startX;
|
||
z.image.currentY = z.image.touchesCurrent.y - z.image.touchesStart.y + z.image.startY;
|
||
|
||
if (z.image.currentX < z.image.minX) {
|
||
z.image.currentX = z.image.minX + 1 - Math.pow((z.image.minX - z.image.currentX + 1), 0.8);
|
||
}
|
||
if (z.image.currentX > z.image.maxX) {
|
||
z.image.currentX = z.image.maxX - 1 + Math.pow((z.image.currentX - z.image.maxX + 1), 0.8);
|
||
}
|
||
|
||
if (z.image.currentY < z.image.minY) {
|
||
z.image.currentY = z.image.minY + 1 - Math.pow((z.image.minY - z.image.currentY + 1), 0.8);
|
||
}
|
||
if (z.image.currentY > z.image.maxY) {
|
||
z.image.currentY = z.image.maxY - 1 + Math.pow((z.image.currentY - z.image.maxY + 1), 0.8);
|
||
}
|
||
|
||
//Velocity
|
||
if (!z.velocity.prevPositionX) z.velocity.prevPositionX = z.image.touchesCurrent.x;
|
||
if (!z.velocity.prevPositionY) z.velocity.prevPositionY = z.image.touchesCurrent.y;
|
||
if (!z.velocity.prevTime) z.velocity.prevTime = Date.now();
|
||
z.velocity.x = (z.image.touchesCurrent.x - z.velocity.prevPositionX) / (Date.now() - z.velocity.prevTime) / 2;
|
||
z.velocity.y = (z.image.touchesCurrent.y - z.velocity.prevPositionY) / (Date.now() - z.velocity.prevTime) / 2;
|
||
if (Math.abs(z.image.touchesCurrent.x - z.velocity.prevPositionX) < 2) z.velocity.x = 0;
|
||
if (Math.abs(z.image.touchesCurrent.y - z.velocity.prevPositionY) < 2) z.velocity.y = 0;
|
||
z.velocity.prevPositionX = z.image.touchesCurrent.x;
|
||
z.velocity.prevPositionY = z.image.touchesCurrent.y;
|
||
z.velocity.prevTime = Date.now();
|
||
|
||
z.gesture.imageWrap.transform('translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');
|
||
},
|
||
onTouchEnd: function (s, e) {
|
||
var z = s.zoom;
|
||
if (!z.gesture.image || z.gesture.image.length === 0) return;
|
||
if (!z.image.isTouched || !z.image.isMoved) {
|
||
z.image.isTouched = false;
|
||
z.image.isMoved = false;
|
||
return;
|
||
}
|
||
z.image.isTouched = false;
|
||
z.image.isMoved = false;
|
||
var momentumDurationX = 300;
|
||
var momentumDurationY = 300;
|
||
var momentumDistanceX = z.velocity.x * momentumDurationX;
|
||
var newPositionX = z.image.currentX + momentumDistanceX;
|
||
var momentumDistanceY = z.velocity.y * momentumDurationY;
|
||
var newPositionY = z.image.currentY + momentumDistanceY;
|
||
|
||
//Fix duration
|
||
if (z.velocity.x !== 0) momentumDurationX = Math.abs((newPositionX - z.image.currentX) / z.velocity.x);
|
||
if (z.velocity.y !== 0) momentumDurationY = Math.abs((newPositionY - z.image.currentY) / z.velocity.y);
|
||
var momentumDuration = Math.max(momentumDurationX, momentumDurationY);
|
||
|
||
z.image.currentX = newPositionX;
|
||
z.image.currentY = newPositionY;
|
||
|
||
// Define if we need image drag
|
||
var scaledWidth = z.image.width * z.scale;
|
||
var scaledHeight = z.image.height * z.scale;
|
||
z.image.minX = Math.min((z.gesture.slideWidth / 2 - scaledWidth / 2), 0);
|
||
z.image.maxX = -z.image.minX;
|
||
z.image.minY = Math.min((z.gesture.slideHeight / 2 - scaledHeight / 2), 0);
|
||
z.image.maxY = -z.image.minY;
|
||
z.image.currentX = Math.max(Math.min(z.image.currentX, z.image.maxX), z.image.minX);
|
||
z.image.currentY = Math.max(Math.min(z.image.currentY, z.image.maxY), z.image.minY);
|
||
|
||
z.gesture.imageWrap.transition(momentumDuration).transform('translate3d(' + z.image.currentX + 'px, ' + z.image.currentY + 'px,0)');
|
||
},
|
||
onTransitionEnd: function (s) {
|
||
var z = s.zoom;
|
||
if (z.gesture.slide && s.previousIndex !== s.activeIndex) {
|
||
z.gesture.image.transform('translate3d(0,0,0) scale(1)');
|
||
z.gesture.imageWrap.transform('translate3d(0,0,0)');
|
||
z.gesture.slide = z.gesture.image = z.gesture.imageWrap = undefined;
|
||
z.scale = z.currentScale = 1;
|
||
}
|
||
},
|
||
// Toggle Zoom
|
||
toggleZoom: function (s, e) {
|
||
var z = s.zoom;
|
||
if (!z.gesture.slide) {
|
||
z.gesture.slide = s.clickedSlide ? $(s.clickedSlide) : s.slides.eq(s.activeIndex);
|
||
z.gesture.image = z.gesture.slide.find('img, svg, canvas');
|
||
z.gesture.imageWrap = z.gesture.image.parent('.' + s.params.zoomContainerClass);
|
||
}
|
||
if (!z.gesture.image || z.gesture.image.length === 0) return;
|
||
|
||
var touchX, touchY, offsetX, offsetY, diffX, diffY, translateX, translateY, imageWidth, imageHeight, scaledWidth, scaledHeight, translateMinX, translateMinY, translateMaxX, translateMaxY, slideWidth, slideHeight;
|
||
|
||
if (typeof z.image.touchesStart.x === 'undefined' && e) {
|
||
touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX;
|
||
touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY;
|
||
}
|
||
else {
|
||
touchX = z.image.touchesStart.x;
|
||
touchY = z.image.touchesStart.y;
|
||
}
|
||
|
||
if (z.scale && z.scale !== 1) {
|
||
// Zoom Out
|
||
z.scale = z.currentScale = 1;
|
||
z.gesture.imageWrap.transition(300).transform('translate3d(0,0,0)');
|
||
z.gesture.image.transition(300).transform('translate3d(0,0,0) scale(1)');
|
||
z.gesture.slide = undefined;
|
||
}
|
||
else {
|
||
// Zoom In
|
||
z.scale = z.currentScale = z.gesture.imageWrap.attr('data-swiper-zoom') || s.params.zoomMax;
|
||
if (e) {
|
||
slideWidth = z.gesture.slide[0].offsetWidth;
|
||
slideHeight = z.gesture.slide[0].offsetHeight;
|
||
offsetX = z.gesture.slide.offset().left;
|
||
offsetY = z.gesture.slide.offset().top;
|
||
diffX = offsetX + slideWidth/2 - touchX;
|
||
diffY = offsetY + slideHeight/2 - touchY;
|
||
|
||
imageWidth = z.gesture.image[0].offsetWidth;
|
||
imageHeight = z.gesture.image[0].offsetHeight;
|
||
scaledWidth = imageWidth * z.scale;
|
||
scaledHeight = imageHeight * z.scale;
|
||
|
||
translateMinX = Math.min((slideWidth / 2 - scaledWidth / 2), 0);
|
||
translateMinY = Math.min((slideHeight / 2 - scaledHeight / 2), 0);
|
||
translateMaxX = -translateMinX;
|
||
translateMaxY = -translateMinY;
|
||
|
||
translateX = diffX * z.scale;
|
||
translateY = diffY * z.scale;
|
||
|
||
if (translateX < translateMinX) {
|
||
translateX = translateMinX;
|
||
}
|
||
if (translateX > translateMaxX) {
|
||
translateX = translateMaxX;
|
||
}
|
||
|
||
if (translateY < translateMinY) {
|
||
translateY = translateMinY;
|
||
}
|
||
if (translateY > translateMaxY) {
|
||
translateY = translateMaxY;
|
||
}
|
||
}
|
||
else {
|
||
translateX = 0;
|
||
translateY = 0;
|
||
}
|
||
z.gesture.imageWrap.transition(300).transform('translate3d(' + translateX + 'px, ' + translateY + 'px,0)');
|
||
z.gesture.image.transition(300).transform('translate3d(0,0,0) scale(' + z.scale + ')');
|
||
}
|
||
},
|
||
// Attach/Detach Events
|
||
attachEvents: function (detach) {
|
||
var action = detach ? 'off' : 'on';
|
||
|
||
if (s.params.zoom) {
|
||
var target = s.slides;
|
||
var passiveListener = s.touchEvents.start === 'touchstart' && s.support.passiveListener && s.params.passiveListeners ? {passive: true, capture: false} : false;
|
||
// Scale image
|
||
if (s.support.gestures) {
|
||
s.slides[action]('gesturestart', s.zoom.onGestureStart, passiveListener);
|
||
s.slides[action]('gesturechange', s.zoom.onGestureChange, passiveListener);
|
||
s.slides[action]('gestureend', s.zoom.onGestureEnd, passiveListener);
|
||
}
|
||
else if (s.touchEvents.start === 'touchstart') {
|
||
s.slides[action](s.touchEvents.start, s.zoom.onGestureStart, passiveListener);
|
||
s.slides[action](s.touchEvents.move, s.zoom.onGestureChange, passiveListener);
|
||
s.slides[action](s.touchEvents.end, s.zoom.onGestureEnd, passiveListener);
|
||
}
|
||
|
||
// Move image
|
||
s[action]('touchStart', s.zoom.onTouchStart);
|
||
s.slides.each(function (index, slide){
|
||
if ($(slide).find('.' + s.params.zoomContainerClass).length > 0) {
|
||
$(slide)[action](s.touchEvents.move, s.zoom.onTouchMove);
|
||
}
|
||
});
|
||
s[action]('touchEnd', s.zoom.onTouchEnd);
|
||
|
||
// Scale Out
|
||
s[action]('transitionEnd', s.zoom.onTransitionEnd);
|
||
if (s.params.zoomToggle) {
|
||
s.on('doubleTap', s.zoom.toggleZoom);
|
||
}
|
||
}
|
||
},
|
||
init: function () {
|
||
s.zoom.attachEvents();
|
||
},
|
||
destroy: function () {
|
||
s.zoom.attachEvents(true);
|
||
}
|
||
};
|
||
|
||
/*=========================
|
||
Plugins API. Collect all and init all plugins
|
||
===========================*/
|
||
s._plugins = [];
|
||
for (var plugin in s.plugins) {
|
||
var p = s.plugins[plugin](s, s.params[plugin]);
|
||
if (p) s._plugins.push(p);
|
||
}
|
||
// Method to call all plugins event/method
|
||
s.callPlugins = function (eventName) {
|
||
for (var i = 0; i < s._plugins.length; i++) {
|
||
if (eventName in s._plugins[i]) {
|
||
s._plugins[i][eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
|
||
}
|
||
}
|
||
};
|
||
|
||
/*=========================
|
||
Events/Callbacks/Plugins Emitter
|
||
===========================*/
|
||
function normalizeEventName (eventName) {
|
||
if (eventName.indexOf('on') !== 0) {
|
||
if (eventName[0] !== eventName[0].toUpperCase()) {
|
||
eventName = 'on' + eventName[0].toUpperCase() + eventName.substring(1);
|
||
}
|
||
else {
|
||
eventName = 'on' + eventName;
|
||
}
|
||
}
|
||
return eventName;
|
||
}
|
||
s.emitterEventListeners = {
|
||
|
||
};
|
||
s.emit = function (eventName) {
|
||
// Trigger callbacks
|
||
if (s.params[eventName]) {
|
||
s.params[eventName](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
|
||
}
|
||
var i;
|
||
// Trigger events
|
||
if (s.emitterEventListeners[eventName]) {
|
||
for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
|
||
s.emitterEventListeners[eventName][i](arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
|
||
}
|
||
}
|
||
// Trigger plugins
|
||
if (s.callPlugins) s.callPlugins(eventName, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
|
||
};
|
||
s.on = function (eventName, handler) {
|
||
eventName = normalizeEventName(eventName);
|
||
if (!s.emitterEventListeners[eventName]) s.emitterEventListeners[eventName] = [];
|
||
s.emitterEventListeners[eventName].push(handler);
|
||
return s;
|
||
};
|
||
s.off = function (eventName, handler) {
|
||
var i;
|
||
eventName = normalizeEventName(eventName);
|
||
if (typeof handler === 'undefined') {
|
||
// Remove all handlers for such event
|
||
s.emitterEventListeners[eventName] = [];
|
||
return s;
|
||
}
|
||
if (!s.emitterEventListeners[eventName] || s.emitterEventListeners[eventName].length === 0) return;
|
||
for (i = 0; i < s.emitterEventListeners[eventName].length; i++) {
|
||
if(s.emitterEventListeners[eventName][i] === handler) s.emitterEventListeners[eventName].splice(i, 1);
|
||
}
|
||
return s;
|
||
};
|
||
s.once = function (eventName, handler) {
|
||
eventName = normalizeEventName(eventName);
|
||
var _handler = function () {
|
||
handler(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
|
||
s.off(eventName, _handler);
|
||
};
|
||
s.on(eventName, _handler);
|
||
return s;
|
||
};
|
||
|
||
// Accessibility tools
|
||
s.a11y = {
|
||
makeFocusable: function ($el) {
|
||
$el.attr('tabIndex', '0');
|
||
return $el;
|
||
},
|
||
addRole: function ($el, role) {
|
||
$el.attr('role', role);
|
||
return $el;
|
||
},
|
||
|
||
addLabel: function ($el, label) {
|
||
$el.attr('aria-label', label);
|
||
return $el;
|
||
},
|
||
|
||
disable: function ($el) {
|
||
$el.attr('aria-disabled', true);
|
||
return $el;
|
||
},
|
||
|
||
enable: function ($el) {
|
||
$el.attr('aria-disabled', false);
|
||
return $el;
|
||
},
|
||
|
||
onEnterKey: function (event) {
|
||
if (event.keyCode !== 13) return;
|
||
if ($(event.target).is(s.params.nextButton)) {
|
||
s.onClickNext(event);
|
||
if (s.isEnd) {
|
||
s.a11y.notify(s.params.lastSlideMessage);
|
||
}
|
||
else {
|
||
s.a11y.notify(s.params.nextSlideMessage);
|
||
}
|
||
}
|
||
else if ($(event.target).is(s.params.prevButton)) {
|
||
s.onClickPrev(event);
|
||
if (s.isBeginning) {
|
||
s.a11y.notify(s.params.firstSlideMessage);
|
||
}
|
||
else {
|
||
s.a11y.notify(s.params.prevSlideMessage);
|
||
}
|
||
}
|
||
if ($(event.target).is('.' + s.params.bulletClass)) {
|
||
$(event.target)[0].click();
|
||
}
|
||
},
|
||
|
||
liveRegion: $('<span class="' + s.params.notificationClass + '" aria-live="assertive" aria-atomic="true"></span>'),
|
||
|
||
notify: function (message) {
|
||
var notification = s.a11y.liveRegion;
|
||
if (notification.length === 0) return;
|
||
notification.html('');
|
||
notification.html(message);
|
||
},
|
||
init: function () {
|
||
// Setup accessibility
|
||
if (s.params.nextButton && s.nextButton && s.nextButton.length > 0) {
|
||
s.a11y.makeFocusable(s.nextButton);
|
||
s.a11y.addRole(s.nextButton, 'button');
|
||
s.a11y.addLabel(s.nextButton, s.params.nextSlideMessage);
|
||
}
|
||
if (s.params.prevButton && s.prevButton && s.prevButton.length > 0) {
|
||
s.a11y.makeFocusable(s.prevButton);
|
||
s.a11y.addRole(s.prevButton, 'button');
|
||
s.a11y.addLabel(s.prevButton, s.params.prevSlideMessage);
|
||
}
|
||
|
||
$(s.container).append(s.a11y.liveRegion);
|
||
},
|
||
initPagination: function () {
|
||
if (s.params.pagination && s.params.paginationClickable && s.bullets && s.bullets.length) {
|
||
s.bullets.each(function () {
|
||
var bullet = $(this);
|
||
s.a11y.makeFocusable(bullet);
|
||
s.a11y.addRole(bullet, 'button');
|
||
s.a11y.addLabel(bullet, s.params.paginationBulletMessage.replace(/{{index}}/, bullet.index() + 1));
|
||
});
|
||
}
|
||
},
|
||
destroy: function () {
|
||
if (s.a11y.liveRegion && s.a11y.liveRegion.length > 0) s.a11y.liveRegion.remove();
|
||
}
|
||
};
|
||
|
||
|
||
/*=========================
|
||
Init/Destroy
|
||
===========================*/
|
||
s.init = function () {
|
||
if (s.params.loop) s.createLoop();
|
||
s.updateContainerSize();
|
||
s.updateSlidesSize();
|
||
s.updatePagination();
|
||
if (s.params.scrollbar && s.scrollbar) {
|
||
s.scrollbar.set();
|
||
if (s.params.scrollbarDraggable) {
|
||
s.scrollbar.enableDraggable();
|
||
}
|
||
}
|
||
if (s.params.effect !== 'slide' && s.effects[s.params.effect]) {
|
||
if (!s.params.loop) s.updateProgress();
|
||
s.effects[s.params.effect].setTranslate();
|
||
}
|
||
if (s.params.loop) {
|
||
s.slideTo(s.params.initialSlide + s.loopedSlides, 0, s.params.runCallbacksOnInit);
|
||
}
|
||
else {
|
||
s.slideTo(s.params.initialSlide, 0, s.params.runCallbacksOnInit);
|
||
if (s.params.initialSlide === 0) {
|
||
if (s.parallax && s.params.parallax) s.parallax.setTranslate();
|
||
if (s.lazy && s.params.lazyLoading) {
|
||
s.lazy.load();
|
||
s.lazy.initialImageLoaded = true;
|
||
}
|
||
}
|
||
}
|
||
s.attachEvents();
|
||
if (s.params.observer && s.support.observer) {
|
||
s.initObservers();
|
||
}
|
||
if (s.params.preloadImages && !s.params.lazyLoading) {
|
||
s.preloadImages();
|
||
}
|
||
if (s.params.zoom && s.zoom) {
|
||
s.zoom.init();
|
||
}
|
||
if (s.params.autoplay) {
|
||
s.startAutoplay();
|
||
}
|
||
if (s.params.keyboardControl) {
|
||
if (s.enableKeyboardControl) s.enableKeyboardControl();
|
||
}
|
||
if (s.params.mousewheelControl) {
|
||
if (s.enableMousewheelControl) s.enableMousewheelControl();
|
||
}
|
||
// Deprecated hashnavReplaceState changed to replaceState for use in hashnav and history
|
||
if (s.params.hashnavReplaceState) {
|
||
s.params.replaceState = s.params.hashnavReplaceState;
|
||
}
|
||
if (s.params.history) {
|
||
if (s.history) s.history.init();
|
||
}
|
||
if (s.params.hashnav) {
|
||
if (s.hashnav) s.hashnav.init();
|
||
}
|
||
if (s.params.a11y && s.a11y) s.a11y.init();
|
||
s.emit('onInit', s);
|
||
};
|
||
|
||
// Cleanup dynamic styles
|
||
s.cleanupStyles = function () {
|
||
// Container
|
||
s.container.removeClass(s.classNames.join(' ')).removeAttr('style');
|
||
|
||
// Wrapper
|
||
s.wrapper.removeAttr('style');
|
||
|
||
// Slides
|
||
if (s.slides && s.slides.length) {
|
||
s.slides
|
||
.removeClass([
|
||
s.params.slideVisibleClass,
|
||
s.params.slideActiveClass,
|
||
s.params.slideNextClass,
|
||
s.params.slidePrevClass
|
||
].join(' '))
|
||
.removeAttr('style')
|
||
.removeAttr('data-swiper-column')
|
||
.removeAttr('data-swiper-row');
|
||
}
|
||
|
||
// Pagination/Bullets
|
||
if (s.paginationContainer && s.paginationContainer.length) {
|
||
s.paginationContainer.removeClass(s.params.paginationHiddenClass);
|
||
}
|
||
if (s.bullets && s.bullets.length) {
|
||
s.bullets.removeClass(s.params.bulletActiveClass);
|
||
}
|
||
|
||
// Buttons
|
||
if (s.params.prevButton) $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);
|
||
if (s.params.nextButton) $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);
|
||
|
||
// Scrollbar
|
||
if (s.params.scrollbar && s.scrollbar) {
|
||
if (s.scrollbar.track && s.scrollbar.track.length) s.scrollbar.track.removeAttr('style');
|
||
if (s.scrollbar.drag && s.scrollbar.drag.length) s.scrollbar.drag.removeAttr('style');
|
||
}
|
||
};
|
||
|
||
// Destroy
|
||
s.destroy = function (deleteInstance, cleanupStyles) {
|
||
// Detach evebts
|
||
s.detachEvents();
|
||
// Stop autoplay
|
||
s.stopAutoplay();
|
||
// Disable draggable
|
||
if (s.params.scrollbar && s.scrollbar) {
|
||
if (s.params.scrollbarDraggable) {
|
||
s.scrollbar.disableDraggable();
|
||
}
|
||
}
|
||
// Destroy loop
|
||
if (s.params.loop) {
|
||
s.destroyLoop();
|
||
}
|
||
// Cleanup styles
|
||
if (cleanupStyles) {
|
||
s.cleanupStyles();
|
||
}
|
||
// Disconnect observer
|
||
s.disconnectObservers();
|
||
|
||
// Destroy zoom
|
||
if (s.params.zoom && s.zoom) {
|
||
s.zoom.destroy();
|
||
}
|
||
// Disable keyboard/mousewheel
|
||
if (s.params.keyboardControl) {
|
||
if (s.disableKeyboardControl) s.disableKeyboardControl();
|
||
}
|
||
if (s.params.mousewheelControl) {
|
||
if (s.disableMousewheelControl) s.disableMousewheelControl();
|
||
}
|
||
// Disable a11y
|
||
if (s.params.a11y && s.a11y) s.a11y.destroy();
|
||
// Delete history popstate
|
||
if (s.params.history && !s.params.replaceState) {
|
||
window.removeEventListener('popstate', s.history.setHistoryPopState);
|
||
}
|
||
if (s.params.hashnav && s.hashnav) {
|
||
s.hashnav.destroy();
|
||
}
|
||
// Destroy callback
|
||
s.emit('onDestroy');
|
||
// Delete instance
|
||
if (deleteInstance !== false) s = null;
|
||
};
|
||
|
||
s.init();
|
||
|
||
|
||
|
||
// Return swiper instance
|
||
return s;
|
||
};
|
||
|
||
/*==================================================
|
||
Prototype
|
||
====================================================*/
|
||
Swiper.prototype = {
|
||
isSafari: (function () {
|
||
var ua = navigator.userAgent.toLowerCase();
|
||
return (ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0 && ua.indexOf('android') < 0);
|
||
})(),
|
||
isUiWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),
|
||
isArray: function (arr) {
|
||
return Object.prototype.toString.apply(arr) === '[object Array]';
|
||
},
|
||
/*==================================================
|
||
Browser
|
||
====================================================*/
|
||
browser: {
|
||
ie: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
|
||
ieTouch: (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 1) || (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 1),
|
||
lteIE9: (function() {
|
||
// create temporary DIV
|
||
var div = document.createElement('div');
|
||
// add content to tmp DIV which is wrapped into the IE HTML conditional statement
|
||
div.innerHTML = '<!--[if lte IE 9]><i></i><![endif]-->';
|
||
// return true / false value based on what will browser render
|
||
return div.getElementsByTagName('i').length === 1;
|
||
})()
|
||
},
|
||
/*==================================================
|
||
Devices
|
||
====================================================*/
|
||
device: (function () {
|
||
var ua = navigator.userAgent;
|
||
var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
|
||
var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
|
||
var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
|
||
var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
|
||
return {
|
||
ios: ipad || iphone || ipod,
|
||
android: android
|
||
};
|
||
})(),
|
||
/*==================================================
|
||
Feature Detection
|
||
====================================================*/
|
||
support: {
|
||
touch : (window.Modernizr && Modernizr.touch === true) || (function () {
|
||
return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
|
||
})(),
|
||
|
||
transforms3d : (window.Modernizr && Modernizr.csstransforms3d === true) || (function () {
|
||
var div = document.createElement('div').style;
|
||
return ('webkitPerspective' in div || 'MozPerspective' in div || 'OPerspective' in div || 'MsPerspective' in div || 'perspective' in div);
|
||
})(),
|
||
|
||
flexbox: (function () {
|
||
var div = document.createElement('div').style;
|
||
var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');
|
||
for (var i = 0; i < styles.length; i++) {
|
||
if (styles[i] in div) return true;
|
||
}
|
||
})(),
|
||
|
||
observer: (function () {
|
||
return ('MutationObserver' in window || 'WebkitMutationObserver' in window);
|
||
})(),
|
||
|
||
passiveListener: (function () {
|
||
var supportsPassive = false;
|
||
try {
|
||
var opts = Object.defineProperty({}, 'passive', {
|
||
get: function() {
|
||
supportsPassive = true;
|
||
}
|
||
});
|
||
window.addEventListener('testPassiveListener', null, opts);
|
||
} catch (e) {}
|
||
return supportsPassive;
|
||
})(),
|
||
|
||
gestures: (function () {
|
||
return 'ongesturestart' in window;
|
||
})()
|
||
},
|
||
/*==================================================
|
||
Plugins
|
||
====================================================*/
|
||
plugins: {}
|
||
};
|
||
|
||
})();
|
||
|
||
//# sourceMappingURL=framework7.js.map
|