summaryrefslogtreecommitdiff
path: root/www/lib/ionic/js/ionic.bundle.js
diff options
context:
space:
mode:
authorpliablepixels <pliablepixels@gmail.com>2016-04-10 10:47:35 -0400
committerpliablepixels <pliablepixels@gmail.com>2016-04-10 10:47:35 -0400
commita29f9a676a6ea3bad56ede05cd1a1c82ffbbe8e9 (patch)
tree7e6e6bfb23390a64344fdfe2272a5da04c2dd97c /www/lib/ionic/js/ionic.bundle.js
parent42bc21f7d0b4acfeefa5f4c2708203be78f57778 (diff)
#219 - everything upgraded
Former-commit-id: 15f58d10df83feda8199a1b904433e625ef36b44
Diffstat (limited to 'www/lib/ionic/js/ionic.bundle.js')
-rw-r--r--www/lib/ionic/js/ionic.bundle.js5462
1 files changed, 5273 insertions, 189 deletions
diff --git a/www/lib/ionic/js/ionic.bundle.js b/www/lib/ionic/js/ionic.bundle.js
index 46b29505..75fbaecf 100644
--- a/www/lib/ionic/js/ionic.bundle.js
+++ b/www/lib/ionic/js/ionic.bundle.js
@@ -6,10 +6,10 @@
*/
/*!
- * Copyright 2014 Drifty Co.
+ * Copyright 2015 Drifty Co.
* http://drifty.com/
*
- * Ionic, v1.1.0
+ * Ionic, v1.2.4-nightly-1917
* A powerful HTML5 mobile app framework.
* http://ionicframework.com/
*
@@ -25,7 +25,7 @@
// build processes may have already created an ionic obj
window.ionic = window.ionic || {};
window.ionic.views = {};
-window.ionic.version = '1.1.0';
+window.ionic.version = '1.2.4-nightly-1917';
(function (ionic) {
@@ -244,6 +244,17 @@ window.ionic.version = '1.1.0';
};
},
+ getOffsetTop: function(el) {
+ var curtop = 0;
+ if (el.offsetParent) {
+ do {
+ curtop += el.offsetTop;
+ el = el.offsetParent;
+ } while (el)
+ return curtop;
+ }
+ },
+
/**
* @ngdoc method
* @name ionic.DomUtil#ready
@@ -1628,7 +1639,7 @@ window.ionic.version = '1.1.0';
index: 10,
defaults: {
hold_timeout: 500,
- hold_threshold: 1
+ hold_threshold: 9
},
timer: null,
handler: function holdGesture(ev, inst) {
@@ -2036,6 +2047,8 @@ window.ionic.version = '1.1.0';
var IOS = 'ios';
var ANDROID = 'android';
var WINDOWS_PHONE = 'windowsphone';
+ var EDGE = 'edge';
+ var CROSSWALK = 'crosswalk';
var requestAnimationFrame = ionic.requestAnimationFrame;
/**
@@ -2255,6 +2268,18 @@ window.ionic.version = '1.1.0';
isWindowsPhone: function() {
return self.is(WINDOWS_PHONE);
},
+ /**
+ * @ngdoc method
+ * @name ionic.Platform#isEdge
+ * @returns {boolean} Whether we are running on MS Edge/Windows 10 (inc. Phone)
+ */
+ isEdge: function() {
+ return self.is(EDGE);
+ },
+
+ isCrosswalk: function() {
+ return self.is(CROSSWALK);
+ },
/**
* @ngdoc method
@@ -2275,12 +2300,14 @@ window.ionic.version = '1.1.0';
platformName = n.toLowerCase();
} else if (getParameterByName('ionicplatform')) {
platformName = getParameterByName('ionicplatform');
+ } else if (self.ua.indexOf('Edge') > -1) {
+ platformName = EDGE;
+ } else if (self.ua.indexOf('Windows Phone') > -1) {
+ platformName = WINDOWS_PHONE;
} else if (self.ua.indexOf('Android') > 0) {
platformName = ANDROID;
} else if (/iPhone|iPad|iPod/.test(self.ua)) {
platformName = IOS;
- } else if (self.ua.indexOf('Windows Phone') > -1) {
- platformName = WINDOWS_PHONE;
} else {
platformName = self.navigator.platform && navigator.platform.toLowerCase().split(' ')[0] || '';
}
@@ -2327,7 +2354,12 @@ window.ionic.version = '1.1.0';
}
},
- // Check if the platform is the one detected by cordova
+ /**
+ * @ngdoc method
+ * @name ionic.Platform#is
+ * @param {string} Platform name.
+ * @returns {boolean} Whether the platform name provided is detected.
+ */
is: function(type) {
type = type.toLowerCase();
// check if it has an array of platforms
@@ -2414,7 +2446,19 @@ window.ionic.version = '1.1.0';
var platformName = null, // just the name, like iOS or Android
platformVersion = null, // a float of the major and minor, like 7.1
readyCallbacks = [],
- windowLoadListenderAttached;
+ windowLoadListenderAttached,
+ platformReadyTimer = 2000; // How long to wait for platform ready before emitting a warning
+
+ verifyPlatformReady();
+
+ // Warn the user if deviceready did not fire in a reasonable amount of time, and how to fix it.
+ function verifyPlatformReady() {
+ setTimeout(function() {
+ if(!self.isReady && self.isWebView()) {
+ void 0;
+ }
+ }, platformReadyTimer);
+ }
// setup listeners to know when the device is ready to go
function onWindowLoad() {
@@ -2454,13 +2498,17 @@ window.ionic.version = '1.1.0';
});
}
-})(this, document, ionic);
+})(window, document, ionic);
(function(document, ionic) {
'use strict';
// Ionic CSS polyfills
ionic.CSS = {};
+ ionic.CSS.TRANSITION = [];
+ ionic.CSS.TRANSFORM = [];
+
+ ionic.EVENTS = {};
(function() {
@@ -2484,6 +2532,9 @@ window.ionic.version = '1.1.0';
}
}
+ // Fallback in case the keys don't exist at all
+ ionic.CSS.TRANSITION = ionic.CSS.TRANSITION || 'transition';
+
// The only prefix we care about is webkit for transitions.
var isWebkit = ionic.CSS.TRANSITION.indexOf('webkit') > -1;
@@ -2494,6 +2545,30 @@ window.ionic.version = '1.1.0';
ionic.CSS.TRANSITIONEND = (isWebkit ? 'webkitTransitionEnd ' : '') + 'transitionend';
})();
+ (function() {
+ var touchStartEvent = 'touchstart';
+ var touchMoveEvent = 'touchmove';
+ var touchEndEvent = 'touchend';
+ var touchCancelEvent = 'touchcancel';
+
+ if (window.navigator.pointerEnabled) {
+ touchStartEvent = 'pointerdown';
+ touchMoveEvent = 'pointermove';
+ touchEndEvent = 'pointerup';
+ touchCancelEvent = 'pointercancel';
+ } else if (window.navigator.msPointerEnabled) {
+ touchStartEvent = 'MSPointerDown';
+ touchMoveEvent = 'MSPointerMove';
+ touchEndEvent = 'MSPointerUp';
+ touchCancelEvent = 'MSPointerCancel';
+ }
+
+ ionic.EVENTS.touchstart = touchStartEvent;
+ ionic.EVENTS.touchmove = touchMoveEvent;
+ ionic.EVENTS.touchend = touchEndEvent;
+ ionic.EVENTS.touchcancel = touchCancelEvent;
+ })();
+
// classList polyfill for them older Androids
// https://gist.github.com/devongovett/1381839
if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') {
@@ -2662,7 +2737,7 @@ ionic.tap = {
if (window.navigator.pointerEnabled) {
tapEventListener('pointerdown');
tapEventListener('pointerup');
- tapEventListener('pointcancel');
+ tapEventListener('pointercancel');
tapTouchMoveListener = 'pointermove';
} else if (window.navigator.msPointerEnabled) {
@@ -2712,6 +2787,11 @@ ionic.tap = {
(ele.tagName == 'INPUT' && (/^(date|time|datetime-local|month|week)$/i).test(ele.type));
},
+ isVideo: function(ele) {
+ return !!ele &&
+ (ele.tagName == 'VIDEO');
+ },
+
isKeyboardElement: function(ele) {
if ( !ionic.Platform.isIOS() || ionic.Platform.isIPad() ) {
return ionic.tap.isTextInput(ele) && !ionic.tap.isDateInput(ele);
@@ -2778,6 +2858,9 @@ ionic.tap = {
},
requiresNativeClick: function(ele) {
+ if (ionic.Platform.isWindowsPhone() && (ele.tagName == 'A' || ele.tagName == 'BUTTON' || ele.hasAttribute('ng-click') || (ele.tagName == 'INPUT' && (ele.type == 'button' || ele.type == 'submit')))) {
+ return true; //Windows Phone edge case, prevent ng-click (and similar) events from firing twice on this platform
+ }
if (!ele || ele.disabled || (/^(file|range)$/i).test(ele.type) || (/^(object|video)$/i).test(ele.tagName) || ionic.tap.isLabelContainingFileInput(ele)) {
return true;
}
@@ -2796,7 +2879,7 @@ ionic.tap = {
if (ele && ele.nodeType === 1) {
var element = ele;
while (element) {
- if ((element.dataset ? element.dataset.tapDisabled : element.getAttribute('data-tap-disabled')) == 'true') {
+ if ((element.dataset ? element.dataset.tapDisabled : element.getAttribute && element.getAttribute('data-tap-disabled')) == 'true') {
return true;
}
element = element.parentElement;
@@ -2892,14 +2975,17 @@ function tapMouseDown(e) {
if (e.isIonicTap || tapIgnoreEvent(e)) return null;
if (tapEnabledTouchEvents) {
- void 0;
+ //console.log('mousedown', 'stop event');
e.stopPropagation();
- if ((!ionic.tap.isTextInput(e.target) || tapLastTouchTarget !== e.target) && !(/^(select|option)$/i).test(e.target.tagName)) {
+ if (!ionic.Platform.isEdge() && (!ionic.tap.isTextInput(e.target) || tapLastTouchTarget !== e.target) &&
+ !isSelectOrOption(e.target.tagName) && !ionic.tap.isVideo(e.target)) {
// If you preventDefault on a text input then you cannot move its text caret/cursor.
// Allow through only the text input default. However, without preventDefault on an
// input the 300ms delay can change focus on inputs after the keyboard shows up.
// The focusin event handles the chance of focus changing after the keyboard shows.
+ // Windows Phone - if you preventDefault on a video element then you cannot operate
+ // its native controls.
e.preventDefault();
}
@@ -2921,7 +3007,7 @@ function tapMouseUp(e) {
return false;
}
- if (tapIgnoreEvent(e) || (/^(select|option)$/i).test(e.target.tagName)) return false;
+ if (tapIgnoreEvent(e) || isSelectOrOption(e.target.tagName)) return false;
if (!tapHasPointerMoved(e)) {
tapClick(e);
@@ -2963,6 +3049,7 @@ function tapTouchStart(e) {
var textInput = tapTargetElement(tapContainingElement(e.target));
if (textInput !== tapActiveEle) {
// don't preventDefault on an already focused input or else iOS's text caret isn't usable
+ //console.log('Would prevent default here');
e.preventDefault();
}
}
@@ -2976,7 +3063,7 @@ function tapTouchEnd(e) {
if (!tapHasPointerMoved(e)) {
tapClick(e);
- if ((/^(select|option)$/i).test(e.target.tagName)) {
+ if (isSelectOrOption(e.target.tagName)) {
e.preventDefault();
}
}
@@ -3012,6 +3099,10 @@ function tapIgnoreEvent(e) {
if (e.isTapHandled) return true;
e.isTapHandled = true;
+ if(ionic.tap.isElementTapDisabled(e.target)) {
+ return true;
+ }
+
if (ionic.scroll.isScrolling && ionic.tap.containsOrIsTextInput(e.target)) {
e.preventDefault();
return true;
@@ -3033,7 +3124,7 @@ function tapHandleFocus(ele) {
// already is the active element and has focus
triggerFocusIn = true;
- } else if ((/^(input|textarea)$/i).test(ele.tagName) || ele.isContentEditable) {
+ } else if ((/^(input|textarea|ion-label)$/i).test(ele.tagName) || ele.isContentEditable) {
triggerFocusIn = true;
ele.focus && ele.focus();
ele.value = ele.value;
@@ -3056,7 +3147,7 @@ function tapHandleFocus(ele) {
function tapFocusOutActive() {
var ele = tapActiveElement();
if (ele && ((/^(input|textarea|select)$/i).test(ele.tagName) || ele.isContentEditable)) {
- void 0;
+ //console.log('tapFocusOutActive', ele.tagName);
ele.blur();
}
tapActiveElement(null);
@@ -3077,7 +3168,7 @@ function tapFocusIn(e) {
// 2) There is an active element which is a text input
// 3) A text input was just set to be focused on by a touch event
// 4) A new focus has been set, however the target isn't the one the touch event wanted
- void 0;
+ //console.log('focusin', 'tapTouchFocusedInput');
tapTouchFocusedInput.focus();
tapTouchFocusedInput = null;
}
@@ -3135,6 +3226,10 @@ function tapTargetElement(ele) {
return ele;
}
+function isSelectOrOption(tagName){
+ return (/^(select|option)$/i).test(tagName);
+}
+
ionic.DomUtil.ready(function() {
var ng = typeof angular !== 'undefined' ? angular : null;
//do nothing for e2e tests
@@ -3556,6 +3651,12 @@ var keyboardLandscapeViewportHeight = 0;
var keyboardActiveElement;
/**
+ * The previously focused input used to reset keyboard after focusing on a
+ * new non-keyboard element
+ */
+var lastKeyboardActiveElement;
+
+/**
* The scroll view containing the currently focused input.
*/
var scrollView;
@@ -3771,6 +3872,9 @@ function keyboardFocusIn(e) {
e.target.readOnly ||
!ionic.tap.isKeyboardElement(e.target) ||
!(scrollView = ionic.DomUtil.getParentWithClass(e.target, SCROLL_CONTAINER_CSS))) {
+ if (keyboardActiveElement) {
+ lastKeyboardActiveElement = keyboardActiveElement;
+ }
keyboardActiveElement = null;
return;
}
@@ -4006,9 +4110,9 @@ function keyboardHide() {
ionic.keyboard.isOpen = false;
ionic.keyboard.isClosing = false;
- if (keyboardActiveElement) {
+ if (keyboardActiveElement || lastKeyboardActiveElement) {
ionic.trigger('resetScrollView', {
- target: keyboardActiveElement
+ target: keyboardActiveElement || lastKeyboardActiveElement
}, true);
}
@@ -4032,6 +4136,7 @@ function keyboardHide() {
}
keyboardActiveElement = null;
+ lastKeyboardActiveElement = null;
}
/**
@@ -4619,7 +4724,7 @@ var zyngaCore = { effect: {} };
return id;
}
};
-})(this);
+})(window);
/*
* Scroller
@@ -4800,6 +4905,9 @@ ionic.views.Scroll = ionic.views.View.inherit({
return self.options.freeze;
};
+ // We can just use the standard freeze pop in our mouth
+ self.freezeShut = self.freeze;
+
self.setScrollStart = function() {
ionic.scroll.isScrolling = Math.abs(ionic.scroll.lastTop - self.__scrollTop) > 1;
clearTimeout(self.scrollTimer);
@@ -5274,6 +5382,7 @@ ionic.views.Scroll = ionic.views.View.inherit({
document.addEventListener("touchmove", self.touchMove, false);
document.addEventListener("touchend", self.touchEnd, false);
document.addEventListener("touchcancel", self.touchEnd, false);
+ document.addEventListener("wheel", self.mouseWheel, false);
} else if (window.navigator.pointerEnabled) {
// Pointer Events
@@ -6872,7 +6981,7 @@ ionic.scroll = {
(function(ionic) {
var NOOP = function() {};
- var depreciated = function(name) {
+ var deprecated = function(name) {
void 0;
};
ionic.views.ScrollNative = ionic.views.View.inherit({
@@ -6881,6 +6990,8 @@ ionic.scroll = {
var self = this;
self.__container = self.el = options.el;
self.__content = options.el.firstElementChild;
+ // Whether scrolling is frozen or not
+ self.__frozen = false;
self.isNative = true;
self.__scrollTop = self.el.scrollTop;
@@ -6890,6 +7001,16 @@ ionic.scroll = {
self.__maxScrollTop = Math.max((self.__contentHeight) - self.__clientHeight, 0);
self.__maxScrollLeft = Math.max((self.__contentWidth) - self.__clientWidth, 0);
+ if(options.startY >= 0 || options.startX >= 0) {
+ ionic.requestAnimationFrame(function() {
+ self.el.scrollTop = options.startY || 0;
+ self.el.scrollLeft = options.startX || 0;
+
+ self.__scrollTop = self.el.scrollTop;
+ self.__scrollLeft = self.el.scrollLeft;
+ });
+ }
+
self.options = {
freeze: false,
@@ -6922,16 +7043,22 @@ ionic.scroll = {
}, 80);
};
- self.freeze = NOOP;
+ self.freeze = function(shouldFreeze) {
+ self.__frozen = shouldFreeze;
+ };
+ // A more powerful freeze pop that dominates all other freeze pops
+ self.freezeShut = function(shouldFreezeShut) {
+ self.__frozenShut = shouldFreezeShut;
+ };
self.__initEventHandlers();
},
/** Methods not used in native scrolling */
- __callback: function() { depreciated('__callback'); },
- zoomTo: function() { depreciated('zoomTo'); },
- zoomBy: function() { depreciated('zoomBy'); },
- activatePullToRefresh: function() { depreciated('activatePullToRefresh'); },
+ __callback: function() { deprecated('__callback'); },
+ zoomTo: function() { deprecated('zoomTo'); },
+ zoomBy: function() { deprecated('zoomBy'); },
+ activatePullToRefresh: function() { deprecated('activatePullToRefresh'); },
/**
* Returns the scroll position and zooming values
@@ -7071,6 +7198,19 @@ ionic.scroll = {
self.resize();
return;
}
+
+ var oldOverflowX = self.el.style.overflowX;
+ var oldOverflowY = self.el.style.overflowY;
+
+ clearTimeout(self.__scrollToCleanupTimeout);
+ self.__scrollToCleanupTimeout = setTimeout(function() {
+ self.el.style.overflowX = oldOverflowX;
+ self.el.style.overflowY = oldOverflowY;
+ }, 500);
+
+ self.el.style.overflowY = 'hidden';
+ self.el.style.overflowX = 'hidden';
+
animateScroll(top, left);
function animateScroll(Y, X) {
@@ -7082,6 +7222,8 @@ ionic.scroll = {
fromX = self.el.scrollLeft;
if (fromY === Y && fromX === X) {
+ self.el.style.overflowX = oldOverflowX;
+ self.el.style.overflowY = oldOverflowY;
self.resize();
return; /* Prevent scrolling to the Y point if already there */
}
@@ -7112,6 +7254,8 @@ ionic.scroll = {
} else {
// done
ionic.tap.removeClonedInputs(self.__container, self);
+ self.el.style.overflowX = oldOverflowX;
+ self.el.style.overflowY = oldOverflowY;
self.resize();
}
}
@@ -7169,21 +7313,29 @@ ionic.scroll = {
// save height when scroll view is shrunk so we don't need to reflow
var scrollViewOffsetHeight;
+ var lastKeyboardHeight;
+
/**
* Shrink the scroll view when the keyboard is up if necessary and if the
* focused input is below the bottom of the shrunk scroll view, scroll it
* into view.
*/
self.scrollChildIntoView = function(e) {
- //console.log("scrollChildIntoView at: " + Date.now());
+ var rect = container.getBoundingClientRect();
+ if(!self.__originalContainerHeight) {
+ self.__originalContainerHeight = rect.height;
+ }
// D
- var scrollBottomOffsetToTop = container.getBoundingClientRect().bottom;
+ //var scrollBottomOffsetToTop = rect.bottom;
// D - A
- scrollViewOffsetHeight = container.offsetHeight;
+ scrollViewOffsetHeight = self.__originalContainerHeight;
+ //console.log('Scroll view offset height', scrollViewOffsetHeight);
+ //console.dir(container);
var alreadyShrunk = self.isShrunkForKeyboard;
var isModal = container.parentNode.classList.contains('modal');
+ var isPopover = container.parentNode.classList.contains('popover');
// 680px is when the media query for 60% modal width kicks in
var isInsetModal = isModal && window.innerWidth >= 680;
@@ -7199,24 +7351,41 @@ ionic.scroll = {
* All commented calculations relative to the top of the viewport (ie E
* is the viewport height, not 0)
*/
- if (!alreadyShrunk) {
+
+
+ var changedKeyboardHeight = lastKeyboardHeight && (lastKeyboardHeight !== e.detail.keyboardHeight);
+
+ if (!alreadyShrunk || changedKeyboardHeight) {
// shrink scrollview so we can actually scroll if the input is hidden
// if it isn't shrink so we can scroll to inputs under the keyboard
// inset modals won't shrink on Android on their own when the keyboard appears
- if ( ionic.Platform.isIOS() || ionic.Platform.isFullScreen || isInsetModal ) {
+ if ( !isPopover && (ionic.Platform.isIOS() || ionic.Platform.isFullScreen || isInsetModal) ) {
// if there are things below the scroll view account for them and
// subtract them from the keyboard height when resizing
// E - D E D
- var scrollBottomOffsetToBottom = e.detail.viewportHeight - scrollBottomOffsetToTop;
+ //var scrollBottomOffsetToBottom = e.detail.viewportHeight - scrollBottomOffsetToTop;
// 0 or D - B if D > B E - B E - D
- var keyboardOffset = Math.max(0, e.detail.keyboardHeight - scrollBottomOffsetToBottom);
+ //var keyboardOffset = e.detail.keyboardHeight - scrollBottomOffsetToBottom;
ionic.requestAnimationFrame(function(){
// D - A or B - A if D > B D - A max(0, D - B)
- scrollViewOffsetHeight = scrollViewOffsetHeight - keyboardOffset;
+ scrollViewOffsetHeight = Math.max(0, Math.min(self.__originalContainerHeight, self.__originalContainerHeight - (e.detail.keyboardHeight - 43)));//keyboardOffset >= 0 ? scrollViewOffsetHeight - keyboardOffset : scrollViewOffsetHeight + keyboardOffset;
+
+ //console.log('Old container height', self.__originalContainerHeight, 'New container height', scrollViewOffsetHeight, 'Keyboard height', e.detail.keyboardHeight);
+
container.style.height = scrollViewOffsetHeight + "px";
+ /*
+ if (ionic.Platform.isIOS()) {
+ // Force redraw to avoid disappearing content
+ var disp = container.style.display;
+ container.style.display = 'none';
+ var trick = container.offsetHeight;
+ container.style.display = disp;
+ }
+ */
+ container.classList.add('keyboard-up');
//update scroll view
self.resize();
});
@@ -7225,6 +7394,8 @@ ionic.scroll = {
self.isShrunkForKeyboard = true;
}
+ lastKeyboardHeight = e.detail.keyboardHeight;
+
/*
* _______
* |---A---| <- top of scroll view
@@ -7241,26 +7412,42 @@ ionic.scroll = {
if (e.detail.isElementUnderKeyboard) {
ionic.requestAnimationFrame(function(){
+ var pos = ionic.DomUtil.getOffsetTop(e.detail.target);
+ setTimeout(function() {
+ if (ionic.Platform.isIOS()) {
+ ionic.tap.cloneFocusedInput(container, self);
+ }
+ // Scroll the input into view, with a 100px buffer
+ self.scrollTo(0, pos - (rect.top + 100), true);
+ self.onScroll();
+ }, 32);
+
+ /*
// update D if we shrunk
if (self.isShrunkForKeyboard && !alreadyShrunk) {
scrollBottomOffsetToTop = container.getBoundingClientRect().bottom;
+ console.log('Scroll bottom', scrollBottomOffsetToTop);
}
// middle of the scrollview, this is where we want to scroll to
// (D - A) / 2
var scrollMidpointOffset = scrollViewOffsetHeight * 0.5;
+ console.log('Midpoint', scrollMidpointOffset);
//console.log("container.offsetHeight: " + scrollViewOffsetHeight);
// middle of the input we want to scroll into view
// C
var inputMidpoint = ((e.detail.elementBottom + e.detail.elementTop) / 2);
+ console.log('Input midpoint');
// distance from middle of input to the bottom of the scroll view
// C - D C D
var inputMidpointOffsetToScrollBottom = inputMidpoint - scrollBottomOffsetToTop;
+ console.log('Input midpoint offset', inputMidpointOffsetToScrollBottom);
//C - D + (D - A)/2 C - D (D - A)/ 2
var scrollTop = inputMidpointOffsetToScrollBottom + scrollMidpointOffset;
+ console.log('Scroll top', scrollTop);
if ( scrollTop > 0) {
if (ionic.Platform.isIOS()) {
@@ -7275,6 +7462,7 @@ ionic.scroll = {
self.onScroll();
}
}
+ */
});
}
@@ -7288,16 +7476,46 @@ ionic.scroll = {
if (self.isShrunkForKeyboard) {
self.isShrunkForKeyboard = false;
container.style.height = "";
+
+ /*
+ if (ionic.Platform.isIOS()) {
+ // Force redraw to avoid disappearing content
+ var disp = container.style.display;
+ container.style.display = 'none';
+ var trick = container.offsetHeight;
+ container.style.display = disp;
+ }
+ */
+
+ self.__originalContainerHeight = container.getBoundingClientRect().height;
+
+ if (ionic.Platform.isIOS()) {
+ ionic.requestAnimationFrame(function() {
+ container.classList.remove('keyboard-up');
+ });
+ }
+
}
self.resize();
};
+ self.handleTouchMove = function(e) {
+ if(self.__frozenShut) {
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ };
+
container.addEventListener('scroll', self.onScroll);
//Broadcasted when keyboard is shown on some platforms.
//See js/utils/keyboard.js
container.addEventListener('scrollChildIntoView', self.scrollChildIntoView);
+ container.addEventListener(ionic.EVENTS.touchstart, self.handleTouchMove);
+ container.addEventListener(ionic.EVENTS.touchmove, self.handleTouchMove);
+
// Listen on document because container may not have had the last
// keyboardActiveElement, for example after closing a modal with a focused
// input and returning to a previously resized scroll view in an ion-content.
@@ -7316,6 +7534,9 @@ ionic.scroll = {
container.removeEventListener('scrollChildIntoView', self.scrollChildIntoView);
container.removeEventListener('resetScrollView', self.resetScrollView);
+ container.removeEventListener(ionic.EVENTS.touchstart, self.handleTouchMove);
+ container.removeEventListener(ionic.EVENTS.touchmove, self.handleTouchMove);
+
ionic.tap.removeClonedInputs(container, self);
delete self.__container;
@@ -7332,7 +7553,6 @@ ionic.scroll = {
})(ionic);
-
(function(ionic) {
'use strict';
@@ -8073,6 +8293,25 @@ ionic.views.Slider = ionic.views.View.inherit({
initialize: function (options) {
var slider = this;
+ var touchStartEvent, touchMoveEvent, touchEndEvent;
+ if (window.navigator.pointerEnabled) {
+ touchStartEvent = 'pointerdown';
+ touchMoveEvent = 'pointermove';
+ touchEndEvent = 'pointerup';
+ } else if (window.navigator.msPointerEnabled) {
+ touchStartEvent = 'MSPointerDown';
+ touchMoveEvent = 'MSPointerMove';
+ touchEndEvent = 'MSPointerUp';
+ } else {
+ touchStartEvent = 'touchstart';
+ touchMoveEvent = 'touchmove';
+ touchEndEvent = 'touchend';
+ }
+
+ var mouseStartEvent = 'mousedown';
+ var mouseMoveEvent = 'mousemove';
+ var mouseEndEvent = 'mouseup';
+
// utilities
var noop = function() {}; // simple no operation function
var offloadFn = function(fn) { setTimeout(fn || noop, 0); }; // offload a functions execution
@@ -8080,7 +8319,6 @@ ionic.views.Slider = ionic.views.View.inherit({
// check browser capabilities
var browser = {
addEventListener: !!window.addEventListener,
- touch: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch,
transitions: (function(temp) {
var props = ['transitionProperty', 'WebkitTransition', 'MozTransition', 'OTransition', 'msTransition'];
for ( var i in props ) if (temp.style[ props[i] ] !== undefined) return true;
@@ -8184,6 +8422,11 @@ ionic.views.Slider = ionic.views.View.inherit({
// do nothing if already on requested slide
if (index == to) return;
+ if (!slides) {
+ index = to;
+ return;
+ }
+
if (browser.transitions) {
var direction = Math.abs(index - to) / (index - to); // 1: backward, -1: forward
@@ -8311,7 +8554,7 @@ ionic.views.Slider = ionic.views.View.inherit({
var events = {
handleEvent: function(event) {
- if(event.type == 'mousedown' || event.type == 'mouseup' || event.type == 'mousemove') {
+ if(!event.touches && event.pageX && event.pageY) {
event.touches = [{
pageX: event.pageX,
pageY: event.pageY
@@ -8319,12 +8562,12 @@ ionic.views.Slider = ionic.views.View.inherit({
}
switch (event.type) {
- case 'mousedown': this.start(event); break;
- case 'touchstart': this.start(event); break;
- case 'touchmove': this.touchmove(event); break;
- case 'mousemove': this.touchmove(event); break;
- case 'touchend': offloadFn(this.end(event)); break;
- case 'mouseup': offloadFn(this.end(event)); break;
+ case touchStartEvent: this.start(event); break;
+ case mouseStartEvent: this.start(event); break;
+ case touchMoveEvent: this.touchmove(event); break;
+ case mouseMoveEvent: this.touchmove(event); break;
+ case touchEndEvent: offloadFn(this.end(event)); break;
+ case mouseEndEvent: offloadFn(this.end(event)); break;
case 'webkitTransitionEnd':
case 'msTransitionEnd':
case 'oTransitionEnd':
@@ -8338,6 +8581,11 @@ ionic.views.Slider = ionic.views.View.inherit({
},
start: function(event) {
+ // prevent to start if there is no valid event
+ if (!event.touches) {
+ return;
+ }
+
var touches = event.touches[0];
// measure start values
@@ -8359,20 +8607,22 @@ ionic.views.Slider = ionic.views.View.inherit({
delta = {};
// attach touchmove and touchend listeners
- if(browser.touch) {
- element.addEventListener('touchmove', this, false);
- element.addEventListener('touchend', this, false);
- } else {
- element.addEventListener('mousemove', this, false);
- element.addEventListener('mouseup', this, false);
- document.addEventListener('mouseup', this, false);
- }
+ element.addEventListener(touchMoveEvent, this, false);
+ element.addEventListener(mouseMoveEvent, this, false);
+
+ element.addEventListener(touchEndEvent, this, false);
+ element.addEventListener(mouseEndEvent, this, false);
+
+ document.addEventListener(touchEndEvent, this, false);
+ document.addEventListener(mouseEndEvent, this, false);
},
touchmove: function(event) {
+ // ensure there is a valid event
// ensure swiping with one touch and not pinching
// ensure sliding is enabled
- if (event.touches.length > 1 ||
+ if (!event.touches ||
+ event.touches.length > 1 ||
event.scale && event.scale !== 1 ||
slider.slideIsDisabled) {
return;
@@ -8410,15 +8660,24 @@ ionic.views.Slider = ionic.views.View.inherit({
translate(circle(index + 1), delta.x + slidePos[circle(index + 1)], 0);
} else {
-
- delta.x =
- delta.x /
- ( (!index && delta.x > 0 || // if first slide and sliding left
- index == slides.length - 1 && // or if last slide and sliding right
- delta.x < 0 // and if sliding at all
- ) ?
- ( Math.abs(delta.x) / width + 1 ) // determine resistance level
- : 1 ); // no resistance if false
+ // If the slider bounces, do the bounce!
+ if(options.bouncing) {
+ delta.x =
+ delta.x /
+ ( (!index && delta.x > 0 || // if first slide and sliding left
+ index == slides.length - 1 && // or if last slide and sliding right
+ delta.x < 0 // and if sliding at all
+ ) ?
+ ( Math.abs(delta.x) / width + 1 ) // determine resistance level
+ : 1 ); // no resistance if false
+ } else {
+ if(width * index - delta.x < 0) { //We are trying scroll past left boundary
+ delta.x = Math.min(delta.x, width * index); //Set delta.x so we don't go past left screen
+ }
+ if(Math.abs(delta.x) > width * (slides.length - index - 1)){ //We are trying to scroll past right bondary
+ delta.x = Math.max( -width * (slides.length - index - 1), delta.x); //Set delta.x so we don't go past right screen
+ }
+ }
// translate 1:1
translate(index - 1, delta.x + slidePos[index - 1], 0);
@@ -8508,14 +8767,14 @@ ionic.views.Slider = ionic.views.View.inherit({
}
// kill touchmove and touchend event listeners until touchstart called again
- if(browser.touch) {
- element.removeEventListener('touchmove', events, false);
- element.removeEventListener('touchend', events, false);
- } else {
- element.removeEventListener('mousemove', events, false);
- element.removeEventListener('mouseup', events, false);
- document.removeEventListener('mouseup', events, false);
- }
+ element.removeEventListener(touchMoveEvent, events, false);
+ element.removeEventListener(mouseMoveEvent, events, false);
+
+ element.removeEventListener(touchEndEvent, events, false);
+ element.removeEventListener(mouseEndEvent, events, false);
+
+ document.removeEventListener(touchEndEvent, events, false);
+ document.removeEventListener(mouseEndEvent, events, false);
options.onDragEnd && options.onDragEnd();
},
@@ -8617,7 +8876,8 @@ ionic.views.Slider = ionic.views.View.inherit({
if (browser.addEventListener) {
// remove current event listeners
- element.removeEventListener('touchstart', events, false);
+ element.removeEventListener(touchStartEvent, events, false);
+ element.removeEventListener(mouseStartEvent, events, false);
element.removeEventListener('webkitTransitionEnd', events, false);
element.removeEventListener('msTransitionEnd', events, false);
element.removeEventListener('oTransitionEnd', events, false);
@@ -8645,11 +8905,8 @@ ionic.views.Slider = ionic.views.View.inherit({
if (browser.addEventListener) {
// set touchstart event on element
- if (browser.touch) {
- element.addEventListener('touchstart', events, false);
- } else {
- element.addEventListener('mousedown', events, false);
- }
+ element.addEventListener(touchStartEvent, events, false);
+ element.addEventListener(mouseStartEvent, events, false);
if (browser.transitions) {
element.addEventListener('webkitTransitionEnd', events, false);
@@ -8674,6 +8931,4234 @@ ionic.views.Slider = ionic.views.View.inherit({
})(ionic);
+/*eslint space-after-keywords: 0*/
+
+/**
+ * Swiper 3.2.7
+ * Most modern mobile touch slider and framework with hardware accelerated transitions
+ *
+ * http://www.idangero.us/swiper/
+ *
+ * Copyright 2015, Vladimir Kharlampidi
+ * The iDangero.us
+ * http://www.idangero.us/
+ *
+ * Licensed under MIT
+ *
+ * Released on: December 7, 2015
+ */
+(function () {
+ 'use strict';
+ var $;
+ /*===========================
+ Swiper
+ ===========================*/
+ var Swiper = function (container, params, _scope, $compile) {
+
+ if (!(this instanceof Swiper)) return new Swiper(container, params);
+
+ var defaults = {
+ direction: 'horizontal',
+ touchEventsTarget: 'container',
+ initialSlide: 0,
+ speed: 300,
+ // autoplay
+ autoplay: false,
+ autoplayDisableOnInteraction: true,
+ // 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,
+ 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'
+ coverflow: {
+ rotate: 50,
+ stretch: 0,
+ depth: 100,
+ modifier: 1,
+ slideShadows : true
+ },
+ cube: {
+ slideShadows: true,
+ shadow: true,
+ shadowOffset: 20,
+ shadowScale: 0.94
+ },
+ fade: {
+ crossFade: false
+ },
+ // Parallax
+ parallax: false,
+ // Scrollbar
+ scrollbar: null,
+ scrollbarHide: true,
+ scrollbarDraggable: false,
+ scrollbarSnapOnRelease: false,
+ // Keyboard Mousewheel
+ keyboardControl: false,
+ mousewheelControl: false,
+ mousewheelReleaseOnEdges: false,
+ mousewheelInvert: false,
+ mousewheelForceToAxis: false,
+ mousewheelSensitivity: 1,
+ // Hash Navigation
+ hashnav: 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,
+ // Pagination
+ pagination: null,
+ paginationElement: 'span',
+ paginationClickable: false,
+ paginationHide: false,
+ paginationBulletRender: null,
+ // 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,
+ lazyLoadingOnTransitionStart: false,
+ // Images
+ preloadImages: true,
+ updateOnImagesReady: true,
+ // loop
+ loop: false,
+ loopAdditionalSlides: 0,
+ loopedSlides: null,
+ // Control
+ control: undefined,
+ controlInverse: false,
+ controlBy: 'slide', //or 'container'
+ // Swiping/no swiping
+ allowSwipeToPrev: true,
+ allowSwipeToNext: true,
+ swipeHandler: null, //'.swipe-handler',
+ noSwiping: true,
+ noSwipingClass: 'swiper-no-swiping',
+ // NS
+ slideClass: 'swiper-slide',
+ slideActiveClass: 'swiper-slide-active',
+ slideVisibleClass: 'swiper-slide-visible',
+ slideDuplicateClass: 'swiper-slide-duplicate',
+ slideNextClass: 'swiper-slide-next',
+ slidePrevClass: 'swiper-slide-prev',
+ wrapperClass: 'swiper-wrapper',
+ bulletClass: 'swiper-pagination-bullet',
+ bulletActiveClass: 'swiper-pagination-bullet-active',
+ buttonDisabledClass: 'swiper-button-disabled',
+ paginationHiddenClass: 'swiper-pagination-hidden',
+ // 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].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;
+ for ( var param in breakPointsParams ) {
+ s.params[param] = breakPointsParams[param];
+ }
+ s.currentBreakpoint = breakpoint;
+ }
+ };
+ // 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) {
+ s.container.each(function () {
+ new Swiper(this, params);
+ });
+ return;
+ }
+
+ // Save instance in container HTML Element and in data
+ s.container[0].swiper = s;
+ s.container.data('swiper', s);
+
+ s.classNames.push('swiper-container-' + s.params.direction);
+
+ if (s.params.freeMode) {
+ s.classNames.push('swiper-container-free-mode');
+ }
+ if (!s.support.flexbox) {
+ s.classNames.push('swiper-container-no-flexbox');
+ s.params.slidesPerColumn = 1;
+ }
+ if (s.params.autoHeight) {
+ s.classNames.push('swiper-container-autoheight');
+ }
+ // Enable slides progress when required
+ if (s.params.parallax || s.params.watchSlidesVisibility) {
+ s.params.watchSlidesProgress = true;
+ }
+ // Coverflow / 3D
+ if (['cube', 'coverflow'].indexOf(s.params.effect) >= 0) {
+ if (s.support.transforms3d) {
+ s.params.watchSlidesProgress = true;
+ s.classNames.push('swiper-container-3d');
+ }
+ else {
+ s.params.effect = 'slide';
+ }
+ }
+ if (s.params.effect !== 'slide') {
+ s.classNames.push('swiper-container-' + 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.slidesPerView = 1;
+ s.params.slidesPerColumn = 1;
+ s.params.slidesPerGroup = 1;
+ s.params.watchSlidesProgress = true;
+ s.params.spaceBetween = 0;
+ 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.paginationClickable) {
+ s.paginationContainer.addClass('swiper-pagination-clickable');
+ }
+ }
+
+ // Is Horizontal
+ function isH() {
+ return s.params.direction === 'horizontal';
+ }
+
+ // RTL
+ s.rtl = isH() && (s.container[0].dir.toLowerCase() === 'rtl' || s.container.css('direction') === 'rtl');
+ if (s.rtl) {
+ s.classNames.push('swiper-container-rtl');
+ }
+
+ // Wrong RTL support
+ if (s.rtl) {
+ s.wrongRTL = s.wrapper.css('display') === '-webkit-box';
+ }
+
+ // Columns
+ if (s.params.slidesPerColumn > 1) {
+ s.classNames.push('swiper-container-multirow');
+ }
+
+ // Check for Android
+ if (s.device.android) {
+ s.classNames.push('swiper-container-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;
+ };
+ s.lockSwipeToPrev = function () {
+ s.params.allowSwipeToPrev = false;
+ };
+ s.lockSwipes = function () {
+ s.params.allowSwipeToNext = s.params.allowSwipeToPrev = false;
+ };
+ s.unlockSwipeToNext = function () {
+ s.params.allowSwipeToNext = true;
+ };
+ s.unlockSwipeToPrev = function () {
+ s.params.allowSwipeToPrev = true;
+ };
+ s.unlockSwipes = function () {
+ s.params.allowSwipeToNext = s.params.allowSwipeToPrev = true;
+ };
+
+ /*=========================
+ Round helper
+ ===========================*/
+ function round(a) {
+ return Math.floor(a);
+ }
+ /*=========================
+ Set grab cursor
+ ===========================*/
+ if (s.params.grabCursor) {
+ s.container[0].style.cursor = 'move';
+ s.container[0].style.cursor = '-webkit-grab';
+ s.container[0].style.cursor = '-moz-grab';
+ s.container[0].style.cursor = 'grab';
+ }
+ /*=========================
+ Update on Images Ready
+ ===========================*/
+ s.imagesToLoad = [];
+ s.imagesLoaded = 0;
+
+ s.loadImage = function (imgElement, src, srcset, 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 (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')), true, _onReady);
+ }
+ };
+
+ /*=========================
+ Autoplay
+ ===========================*/
+ s.autoplayTimeoutId = undefined;
+ s.autoplaying = false;
+ s.autoplayPaused = false;
+ function autoplay() {
+ s.autoplayTimeoutId = setTimeout(function () {
+ if (s.params.loop) {
+ s.fixLoop();
+ s._slideNext();
+ }
+ else {
+ if (!s.isEnd) {
+ s._slideNext();
+ }
+ else {
+ if (!params.autoplayStopOnLast) {
+ s._slideTo(0);
+ }
+ else {
+ s.stopAutoplay();
+ }
+ }
+ }
+ }, s.params.autoplay);
+ }
+ 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 () {
+ // Update Height
+ var newHeight = s.slides.eq(s.activeIndex)[0].offsetHeight;
+ if (newHeight) s.wrapper.css('height', s.slides.eq(s.activeIndex)[0].offsetHeight + '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 && isH() || height === 0 && !isH()) {
+ 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 = isH() ? 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 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-top': (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 = isH() ? 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 (isH()) {
+ 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 (isH()) 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;
+ s.wrapper.css({width: 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])) {
+ s.snapGrid.push(s.virtualSize - s.size);
+ }
+ }
+ if (s.snapGrid.length === 0) s.snapGrid = [0];
+
+ if (s.params.spaceBetween !== 0) {
+ if (isH()) {
+ 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 = isH() ? 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 - 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 (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();
+ };
+
+ /*=========================
+ Classes
+ ===========================*/
+ s.updateClasses = function () {
+ s.slides.removeClass(s.params.slideActiveClass + ' ' + s.params.slideNextClass + ' ' + s.params.slidePrevClass);
+ var activeSlide = s.slides.eq(s.activeIndex);
+ // Active classes
+ activeSlide.addClass(s.params.slideActiveClass);
+ activeSlide.next('.' + s.params.slideClass).addClass(s.params.slideNextClass);
+ activeSlide.prev('.' + s.params.slideClass).addClass(s.params.slidePrevClass);
+
+ // Pagination
+ if (s.bullets && s.bullets.length > 0) {
+ s.bullets.removeClass(s.params.bulletActiveClass);
+ var bulletIndex;
+ if (s.params.loop) {
+ bulletIndex = Math.ceil(s.activeIndex - s.loopedSlides)/s.params.slidesPerGroup;
+ if (bulletIndex > s.slides.length - 1 - s.loopedSlides * 2) {
+ bulletIndex = bulletIndex - (s.slides.length - s.loopedSlides * 2);
+ }
+ if (bulletIndex > s.bullets.length - 1) bulletIndex = bulletIndex - s.bullets.length;
+ }
+ else {
+ if (typeof s.snapIndex !== 'undefined') {
+ bulletIndex = s.snapIndex;
+ }
+ else {
+ bulletIndex = s.activeIndex || 0;
+ }
+ }
+ if (s.paginationContainer.length > 1) {
+ s.bullets.each(function () {
+ if ($(this).index() === bulletIndex) $(this).addClass(s.params.bulletActiveClass);
+ });
+ }
+ else {
+ s.bullets.eq(bulletIndex).addClass(s.params.bulletActiveClass);
+ }
+ }
+
+ // Next/active buttons
+ if (!s.params.loop) {
+ if (s.params.prevButton) {
+ if (s.isBeginning) {
+ $(s.params.prevButton).addClass(s.params.buttonDisabledClass);
+ if (s.params.a11y && s.a11y) s.a11y.disable($(s.params.prevButton));
+ }
+ else {
+ $(s.params.prevButton).removeClass(s.params.buttonDisabledClass);
+ if (s.params.a11y && s.a11y) s.a11y.enable($(s.params.prevButton));
+ }
+ }
+ if (s.params.nextButton) {
+ if (s.isEnd) {
+ $(s.params.nextButton).addClass(s.params.buttonDisabledClass);
+ if (s.params.a11y && s.a11y) s.a11y.disable($(s.params.nextButton));
+ }
+ else {
+ $(s.params.nextButton).removeClass(s.params.buttonDisabledClass);
+ if (s.params.a11y && s.a11y) s.a11y.enable($(s.params.nextButton));
+ }
+ }
+ }
+ };
+
+ /*=========================
+ Pagination
+ ===========================*/
+ s.updatePagination = function () {
+ if (!s.params.pagination) return;
+ if (s.paginationContainer && s.paginationContainer.length > 0) {
+ var bulletsHTML = '';
+ 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) {
+ bulletsHTML += s.params.paginationBulletRender(i, s.params.bulletClass);
+ }
+ else {
+ bulletsHTML += '<' + s.params.paginationElement+' class="' + s.params.bulletClass + '"></' + s.params.paginationElement + '>';
+ }
+ }
+ s.paginationContainer.html(bulletsHTML);
+ s.bullets = s.paginationContainer.find('.' + s.params.bulletClass);
+ if (s.params.paginationClickable && s.params.a11y && s.a11y) {
+ s.a11y.initPagination();
+ }
+ }
+ };
+ /*=========================
+ 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() {
+ 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;
+ }
+ 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) {
+ s.slideTo(s.slides.length - 1, 0, false, true);
+ }
+ else {
+ s.slideTo(s.activeIndex, 0, false, true);
+ }
+ }
+ // Return locks after resize
+ s.params.allowSwipeToPrev = allowSwipeToPrev;
+ s.params.allowSwipeToNext = allowSwipeToNext;
+ };
+
+ /*=========================
+ Events
+ ===========================*/
+
+ //Define Touch Events
+ var desktopEvents = ['mousedown', 'mousemove', 'mouseup'];
+ if (window.navigator.pointerEnabled) desktopEvents = ['pointerdown', 'pointermove', 'pointerup'];
+ else if (window.navigator.msPointerEnabled) desktopEvents = ['MSPointerDown', 'MSPointerMove', 'MSPointerUp'];
+ s.touchEvents = {
+ start : s.support.touch || !s.params.simulateTouch ? 'touchstart' : desktopEvents[0],
+ move : s.support.touch || !s.params.simulateTouch ? 'touchmove' : desktopEvents[1],
+ end : s.support.touch || !s.params.simulateTouch ? 'touchend' : desktopEvents[2]
+ };
+
+
+ // 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) {
+ touchEventsTarget[action](s.touchEvents.start, s.onTouchStart, false);
+ touchEventsTarget[action](s.touchEvents.move, s.onTouchMove, moveCapture);
+ touchEventsTarget[action](s.touchEvents.end, s.onTouchEnd, false);
+ }
+ if (params.simulateTouch && !s.device.ios && !s.device.android) {
+ 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.params.nextButton)[actionDom]('click', s.onClickNext);
+ if (s.params.a11y && s.a11y) $(s.params.nextButton)[actionDom]('keydown', s.a11y.onEnterKey);
+ }
+ if (s.params.prevButton) {
+ $(s.params.prevButton)[actionDom]('click', s.onClickPrev);
+ if (s.params.a11y && s.a11y) $(s.params.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 (detach) {
+ 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(.swiper-slide-duplicate)').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(.swiper-slide-duplicate)').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',
+ // 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) 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 && 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 = Math.atan2(Math.abs(s.touches.currentY - s.touches.startY), Math.abs(s.touches.currentX - s.touches.startX)) * 180 / Math.PI;
+ isScrolling = isH() ? 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.container[0].style.cursor = 'move';
+ s.container[0].style.cursor = '-webkit-grabbing';
+ s.container[0].style.cursor = '-moz-grabbin';
+ s.container[0].style.cursor = 'grabbing';
+ }
+ }
+ isMoved = true;
+
+ var diff = s.touches.diff = isH() ? 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;
+ }
+
+ if (!s.params.followFinger) return;
+
+ // 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 = isH() ? s.touches.currentX - s.touches.startX : s.touches.currentY - s.touches.startY;
+ return;
+ }
+ }
+ else {
+ currentTranslate = startTranslate;
+ 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[isH() ? 'startX' : 'startY'],
+ time: touchStartTime
+ });
+ }
+ velocities.push({
+ position: s.touches[isH() ? '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.container[0].style.cursor = 'move';
+ s.container[0].style.cursor = '-webkit-grab';
+ s.container[0].style.cursor = '-moz-grab';
+ s.container[0].style.cursor = 'grab';
+ }
+
+ // 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;
+ }
+
+ 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
+ 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;
+
+ 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.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.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);
+ };
+
+ /*=========================
+ 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 (isH()) {
+ 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 = isH() ? 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 = isH() ? '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 () {
+
+ var toRemove = s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass);
+ angular.element(toRemove).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, scope, newNode;
+ 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++) {
+ newNode = angular.element(appendSlides[i]).clone().addClass(s.params.slideDuplicateClass);
+ newNode.removeAttr('ng-transclude');
+ newNode.removeAttr('ng-repeat');
+ scope = angular.element(appendSlides[i]).scope();
+ newNode = $compile(newNode)(scope);
+ angular.element(s.wrapper).append(newNode);
+ //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));
+
+ newNode = angular.element(prependSlides[i]).clone().addClass(s.params.slideDuplicateClass);
+ newNode.removeAttr('ng-transclude');
+ newNode.removeAttr('ng-repeat');
+
+ scope = angular.element(prependSlides[i]).scope();
+ newNode = $compile(newNode)(scope);
+ angular.element(s.wrapper).prepend(newNode);
+ }
+ };
+ s.destroyLoop = function () {
+ s.wrapper.children('.' + s.params.slideClass + '.' + s.params.slideDuplicateClass).remove();
+ s.slides.removeAttr('data-swiper-slide-index');
+ };
+ 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 (!isH()) {
+ 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]);
+ }
+ });
+ }
+ }
+ },
+ cube: {
+ setTranslate: function () {
+ var wrapperRotate = 0, cubeShadow;
+ if (s.params.cube.shadow) {
+ if (isH()) {
+ 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 (!isH()) {
+ ty = tx;
+ tx = 0;
+ }
+
+ var transform = 'rotateX(' + (isH() ? 0 : -slideAngle) + 'deg) rotateY(' + (isH() ? 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 = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
+ var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
+ if (shadowBefore.length === 0) {
+ shadowBefore = $('<div class="swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '"></div>');
+ slide.append(shadowBefore);
+ }
+ if (shadowAfter.length === 0) {
+ shadowAfter = $('<div class="swiper-slide-shadow-' + (isH() ? 'right' : 'bottom') + '"></div>');
+ slide.append(shadowAfter);
+ }
+ var shadowOpacity = slide[0].progress;
+ if (shadowBefore.length) shadowBefore[0].style.opacity = -slide[0].progress;
+ if (shadowAfter.length) shadowAfter[0].style.opacity = slide[0].progress;
+ }
+ }
+ 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 (isH()) {
+ 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(' + (isH() ? 0 : wrapperRotate) + 'deg) rotateY(' + (isH() ? -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 && !isH()) {
+ s.container.find('.swiper-cube-shadow').transition(duration);
+ }
+ }
+ },
+ coverflow: {
+ setTranslate: function () {
+ var transform = s.translate;
+ var center = isH() ? -transform + s.width / 2 : -transform + s.height / 2;
+ var rotate = isH() ? 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 = isH() ? rotate * offsetMultiplier : 0;
+ var rotateX = isH() ? 0 : rotate * offsetMultiplier;
+ // var rotateZ = 0
+ var translateZ = -translate * Math.abs(offsetMultiplier);
+
+ var translateY = isH() ? 0 : s.params.coverflow.stretch * (offsetMultiplier);
+ var translateX = isH() ? 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 = isH() ? slide.find('.swiper-slide-shadow-left') : slide.find('.swiper-slide-shadow-top');
+ var shadowAfter = isH() ? slide.find('.swiper-slide-shadow-right') : slide.find('.swiper-slide-shadow-bottom');
+ if (shadowBefore.length === 0) {
+ shadowBefore = $('<div class="swiper-slide-shadow-' + (isH() ? 'left' : 'top') + '"></div>');
+ slide.append(shadowBefore);
+ }
+ if (shadowAfter.length === 0) {
+ shadowAfter = $('<div class="swiper-slide-shadow-' + (isH() ? '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('.swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)');
+ if (slide.hasClass('swiper-lazy') && !slide.hasClass('swiper-lazy-loaded') && !slide.hasClass('swiper-lazy-loading')) {
+ img = img.add(slide[0]);
+ }
+ if (img.length === 0) return;
+
+ img.each(function () {
+ var _img = $(this);
+ _img.addClass('swiper-lazy-loading');
+ var background = _img.attr('data-background');
+ var src = _img.attr('data-src'),
+ srcset = _img.attr('data-srcset');
+ s.loadImage(_img[0], (src || background), srcset, 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 (src) {
+ _img.attr('src', src);
+ _img.removeAttr('data-src');
+ }
+
+ }
+
+ _img.addClass('swiper-lazy-loaded').removeClass('swiper-lazy-loading');
+ slide.find('.swiper-lazy-preloader, .preloader').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;
+ if (s.params.watchSlidesVisibility) {
+ s.wrapper.children('.' + s.params.slideVisibleClass).each(function () {
+ s.lazy.loadImageInSlide($(this).index());
+ });
+ }
+ else {
+ if (s.params.slidesPerView > 1) {
+ for (i = s.activeIndex; i < s.activeIndex + s.params.slidesPerView ; i++) {
+ if (s.slides[i]) s.lazy.loadImageInSlide(i);
+ }
+ }
+ else {
+ s.lazy.loadImageInSlide(s.activeIndex);
+ }
+ }
+ if (s.params.lazyLoadingInPrevNext) {
+ if (s.params.slidesPerView > 1) {
+ // Next Slides
+ for (i = s.activeIndex + s.params.slidesPerView; i < s.activeIndex + s.params.slidesPerView + s.params.slidesPerView; i++) {
+ if (s.slides[i]) s.lazy.loadImageInSlide(i);
+ }
+ // Prev Slides
+ for (i = s.activeIndex - s.params.slidesPerView; 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 = isH() ?
+ ((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()[isH() ? '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();
+ }
+ },
+ enableDraggable: function () {
+ var sb = s.scrollbar;
+ var target = s.support.touch ? sb.track : document;
+ $(sb.track).on(s.touchEvents.start, sb.dragStart);
+ $(target).on(s.touchEvents.move, sb.dragMove);
+ $(target).on(s.touchEvents.end, sb.dragEnd);
+ },
+ disableDraggable: function () {
+ var sb = s.scrollbar;
+ var target = s.support.touch ? sb.track : document;
+ $(sb.track).off(s.touchEvents.start, sb.dragStart);
+ $(target).off(s.touchEvents.move, sb.dragMove);
+ $(target).off(s.touchEvents.end, sb.dragEnd);
+ },
+ set: function () {
+ if (!s.params.scrollbar) return;
+ var sb = s.scrollbar;
+ sb.track = $(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 = isH() ? 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 (isH()) {
+ 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 && isH()) {
+ 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 (isH()) {
+ 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);
+ }
+ }
+ };
+
+ /*=========================
+ Hash Navigation
+ ===========================*/
+ s.hashnav = {
+ init: function () {
+ if (!s.params.hashnav) return;
+ s.hashnav.initialized = true;
+ var hash = document.location.hash.replace('#', '');
+ if (!hash) return;
+ var speed = 0;
+ for (var i = 0, length = s.slides.length; i < length; i++) {
+ var slide = s.slides.eq(i);
+ var slideHash = slide.attr('data-hash');
+ if (slideHash === hash && !slide.hasClass(s.params.slideDuplicateClass)) {
+ var index = slide.index();
+ s.slideTo(index, speed, s.params.runCallbacksOnInit, true);
+ }
+ }
+ },
+ setHash: function () {
+ if (!s.hashnav.initialized || !s.params.hashnav) return;
+ document.location.hash = s.slides.eq(s.activeIndex).attr('data-hash') || '';
+ }
+ };
+
+ /*=========================
+ Keyboard Control
+ ===========================*/
+ function handleKeyboard(e) {
+ if (e.originalEvent) e = e.originalEvent; //jquery fix
+ var kc = e.keyCode || e.charCode;
+ // Directions locks
+ if (!s.params.allowSwipeToNext && (isH() && kc === 39 || !isH() && kc === 40)) {
+ return false;
+ }
+ if (!s.params.allowSwipeToPrev && (isH() && kc === 37 || !isH() && kc === 38)) {
+ return false;
+ }
+ if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) {
+ return;
+ }
+ if (document.activeElement && document.activeElement.nodeName && (document.activeElement.nodeName.toLowerCase() === 'input' || document.activeElement.nodeName.toLowerCase() === 'textarea')) {
+ return;
+ }
+ if (kc === 37 || kc === 39 || kc === 38 || kc === 40) {
+ var inView = false;
+ //Check that swiper should be inside of visible area of window
+ if (s.container.parents('.swiper-slide').length > 0 && s.container.parents('.swiper-slide-active').length === 0) {
+ return;
+ }
+ var windowScroll = {
+ left: window.pageXOffset,
+ top: window.pageYOffset
+ };
+ var windowWidth = window.innerWidth;
+ var windowHeight = window.innerHeight;
+ var swiperOffset = s.container.offset();
+ if (s.rtl) swiperOffset.left = swiperOffset.left - s.container[0].scrollLeft;
+ var swiperCoord = [
+ [swiperOffset.left, swiperOffset.top],
+ [swiperOffset.left + s.width, swiperOffset.top],
+ [swiperOffset.left, swiperOffset.top + s.height],
+ [swiperOffset.left + s.width, swiperOffset.top + s.height]
+ ];
+ for (var i = 0; i < swiperCoord.length; i++) {
+ var point = swiperCoord[i];
+ if (
+ point[0] >= windowScroll.left && point[0] <= windowScroll.left + windowWidth &&
+ point[1] >= windowScroll.top && point[1] <= windowScroll.top + windowHeight
+ ) {
+ inView = true;
+ }
+
+ }
+ if (!inView) return;
+ }
+ if (isH()) {
+ if (kc === 37 || kc === 39) {
+ if (e.preventDefault) e.preventDefault();
+ else e.returnValue = false;
+ }
+ if ((kc === 39 && !s.rtl) || (kc === 37 && s.rtl)) s.slideNext();
+ if ((kc === 37 && !s.rtl) || (kc === 39 && s.rtl)) s.slidePrev();
+ }
+ else {
+ if (kc === 38 || kc === 40) {
+ if (e.preventDefault) e.preventDefault();
+ else e.returnValue = false;
+ }
+ if (kc === 40) s.slideNext();
+ if (kc === 38) s.slidePrev();
+ }
+ }
+ s.disableKeyboardControl = function () {
+ s.params.keyboardControl = false;
+ $(document).off('keydown', handleKeyboard);
+ };
+ s.enableKeyboardControl = function () {
+ s.params.keyboardControl = true;
+ $(document).on('keydown', handleKeyboard);
+ };
+
+
+ /*=========================
+ Mousewheel Control
+ ===========================*/
+ s.mousewheel = {
+ event: false,
+ lastScrollTime: (new window.Date()).getTime()
+ };
+ if (s.params.mousewheelControl) {
+ try {
+ new window.WheelEvent('wheel');
+ s.mousewheel.event = 'wheel';
+ } catch (e) {}
+
+ if (!s.mousewheel.event && document.onmousewheel !== undefined) {
+ s.mousewheel.event = 'mousewheel';
+ }
+ if (!s.mousewheel.event) {
+ s.mousewheel.event = 'DOMMouseScroll';
+ }
+ }
+ function handleMousewheel(e) {
+ if (e.originalEvent) e = e.originalEvent; //jquery fix
+ var we = s.mousewheel.event;
+ var delta = 0;
+ var rtlFactor = s.rtl ? -1 : 1;
+ //Opera & IE
+ if (e.detail) delta = -e.detail;
+ //WebKits
+ else if (we === 'mousewheel') {
+ if (s.params.mousewheelForceToAxis) {
+ if (isH()) {
+ if (Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY)) delta = e.wheelDeltaX * rtlFactor;
+ else return;
+ }
+ else {
+ if (Math.abs(e.wheelDeltaY) > Math.abs(e.wheelDeltaX)) delta = e.wheelDeltaY;
+ else return;
+ }
+ }
+ else {
+ delta = Math.abs(e.wheelDeltaX) > Math.abs(e.wheelDeltaY) ? - e.wheelDeltaX * rtlFactor : - e.wheelDeltaY;
+ }
+ }
+ //Old FireFox
+ else if (we === 'DOMMouseScroll') delta = -e.detail;
+ //New FireFox
+ else if (we === 'wheel') {
+ if (s.params.mousewheelForceToAxis) {
+ if (isH()) {
+ if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) delta = -e.deltaX * rtlFactor;
+ else return;
+ }
+ else {
+ if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) delta = -e.deltaY;
+ else return;
+ }
+ }
+ else {
+ delta = Math.abs(e.deltaX) > Math.abs(e.deltaY) ? - e.deltaX * rtlFactor : - e.deltaY;
+ }
+ }
+ if (delta === 0) return;
+
+ if (s.params.mousewheelInvert) delta = -delta;
+
+ if (!s.params.freeMode) {
+ if ((new window.Date()).getTime() - s.mousewheel.lastScrollTime > 60) {
+ if (delta < 0) {
+ if ((!s.isEnd || s.params.loop) && !s.animating) s.slideNext();
+ else if (s.params.mousewheelReleaseOnEdges) return true;
+ }
+ else {
+ if ((!s.isBeginning || s.params.loop) && !s.animating) s.slidePrev();
+ else if (s.params.mousewheelReleaseOnEdges) return true;
+ }
+ }
+ s.mousewheel.lastScrollTime = (new window.Date()).getTime();
+
+ }
+ else {
+ //Freemode or scrollContainer:
+ var position = s.getWrapperTranslate() + delta * s.params.mousewheelSensitivity;
+ var wasBeginning = s.isBeginning,
+ wasEnd = s.isEnd;
+
+ if (position >= s.minTranslate()) position = s.minTranslate();
+ if (position <= s.maxTranslate()) position = s.maxTranslate();
+
+ s.setWrapperTransition(0);
+ s.setWrapperTranslate(position);
+ s.updateProgress();
+ s.updateActiveIndex();
+
+ if (!wasBeginning && s.isBeginning || !wasEnd && s.isEnd) {
+ s.updateClasses();
+ }
+
+ if (s.params.freeModeSticky) {
+ clearTimeout(s.mousewheel.timeout);
+ s.mousewheel.timeout = setTimeout(function () {
+ s.slideReset();
+ }, 300);
+ }
+
+ // Return page scroll on edge positions
+ if (position === 0 || position === s.maxTranslate()) return;
+ }
+ if (s.params.autoplay) s.stopAutoplay();
+
+ if (e.preventDefault) e.preventDefault();
+ else e.returnValue = false;
+ return false;
+ }
+ s.disableMousewheelControl = function () {
+ if (!s.mousewheel.event) return false;
+ s.container.off(s.mousewheel.event, handleMousewheel);
+ return true;
+ };
+
+ s.enableMousewheelControl = function () {
+ if (!s.mousewheel.event) return false;
+ s.container.on(s.mousewheel.event, handleMousewheel);
+ return true;
+ };
+
+
+ /*=========================
+ 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 (isH()) {
+ 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);
+ });
+ }
+ };
+
+
+ /*=========================
+ 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="swiper-notification" 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) {
+ var nextButton = $(s.params.nextButton);
+ s.a11y.makeFocusable(nextButton);
+ s.a11y.addRole(nextButton, 'button');
+ s.a11y.addLabel(nextButton, s.params.nextSlideMessage);
+ }
+ if (s.params.prevButton) {
+ var prevButton = $(s.params.prevButton);
+ s.a11y.makeFocusable(prevButton);
+ s.a11y.addRole(prevButton, 'button');
+ s.a11y.addLabel(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.autoplay) {
+ s.startAutoplay();
+ }
+ if (s.params.keyboardControl) {
+ if (s.enableKeyboardControl) s.enableKeyboardControl();
+ }
+ if (s.params.mousewheelControl) {
+ if (s.enableMousewheelControl) s.enableMousewheelControl();
+ }
+ 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();
+ // 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();
+ // 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)
+ },
+ /*==================================================
+ 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);
+ })()
+ },
+ /*==================================================
+ Plugins
+ ====================================================*/
+ plugins: {}
+ };
+
+
+ /*===========================
+ 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.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 = selector;
+ 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++) {
+ 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++) {
+ 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++) {
+ 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;
+ },
+ data: function (key, value) {
+ if (typeof value === 'undefined') {
+ // Get value
+ if (this[0]) {
+ var dataKey = this[0].getAttribute('data-' + key);
+ if (dataKey) return dataKey;
+ else if (this[0].dom7ElementDataStorage && (key in this[0].dom7ElementDataStorage)) return this[0].dom7ElementDataStorage[key];
+ 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;
+ }
+ },
+ // 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') {
+ targetSelector = false;
+ listener = arguments[1];
+ capture = arguments[2];
+ }
+ function proxy(e) {
+ listener(e);
+ dom.off(eventName, targetSelector, proxy, capture);
+ }
+ dom.on(eventName, targetSelector, proxy, capture);
+ },
+ trigger: function (eventName, eventData) {
+ for (var i = 0; i < this.length; i++) {
+ var evt;
+ try {
+ evt = new window.CustomEvent(eventName, {detail: eventData, bubbles: true, cancelable: true});
+ }
+ catch (e) {
+ evt = document.createEvent('Event');
+ evt.initEvent(eventName, true, true);
+ evt.detail = eventData;
+ }
+ this[i].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;
+ },
+ // 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)
+ return this[0].offsetWidth + parseFloat(this.css('margin-right')) + parseFloat(this.css('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)
+ return this[0].offsetHeight + parseFloat(this.css('margin-top')) + parseFloat(this.css('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;
+ }
+ },
+ 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;
+ },
+ 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;
+ }
+ },
+ is: function (selector) {
+ if (!this[0]) 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;
+ }
+
+ },
+ 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;
+ },
+ 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;
+ },
+ 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);
+ },
+ parent: function (selector) {
+ var parents = [];
+ for (var i = 0; i < this.length; i++) {
+ 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));
+ },
+ 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;
+ },
+ 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;
+ }
+ };
+ $.fn = Dom7.prototype;
+ $.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;
+ };
+
+ return $;
+ })();
+
+
+ /*===========================
+ Get Dom libraries
+ ===========================*/
+ var swiperDomPlugins = ['jQuery', 'Zepto', 'Dom7'];
+ for (var i = 0; i < swiperDomPlugins.length; i++) {
+ if (window[swiperDomPlugins[i]]) {
+ addLibraryPlugin(window[swiperDomPlugins[i]]);
+ }
+ }
+ // Required DOM Plugins
+ var domLib;
+ if (typeof Dom7 === 'undefined') {
+ domLib = window.Dom7 || window.Zepto || window.jQuery;
+ }
+ else {
+ domLib = Dom7;
+ }
+
+ /*===========================
+ Add .swiper plugin from Dom libraries
+ ===========================*/
+ function addLibraryPlugin(lib) {
+ lib.fn.swiper = function (params) {
+ var firstInstance;
+ lib(this).each(function () {
+ var s = new Swiper(this, params);
+ if (!firstInstance) firstInstance = s;
+ });
+ return firstInstance;
+ };
+ }
+
+ if (domLib) {
+ if (!('transitionEnd' in domLib.fn)) {
+ domLib.fn.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;
+ };
+ }
+ if (!('transform' in domLib.fn)) {
+ domLib.fn.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;
+ };
+ }
+ if (!('transition' in domLib.fn)) {
+ domLib.fn.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;
+ };
+ }
+ }
+
+ ionic.views.Swiper = Swiper;
+})();
+
(function(ionic) {
'use strict';
@@ -45856,10 +50341,10 @@ angular.module('ui.router.state')
*/
/*!
- * Copyright 2014 Drifty Co.
+ * Copyright 2015 Drifty Co.
* http://drifty.com/
*
- * Ionic, v1.1.0
+ * Ionic, v1.2.4-nightly-1917
* A powerful HTML5 mobile app framework.
* http://ionicframework.com/
*
@@ -45871,7 +50356,7 @@ angular.module('ui.router.state')
(function() {
/* eslint no-unused-vars:0 */
-var IonicModule = angular.module('ionic', ['ngAnimate', 'ngSanitize', 'ui.router']),
+var IonicModule = angular.module('ionic', ['ngAnimate', 'ngSanitize', 'ui.router', 'ngIOS9UIWebViewPatch']),
extend = angular.extend,
forEach = angular.forEach,
isDefined = angular.isDefined,
@@ -46027,7 +50512,7 @@ function($rootScope, $compile, $animate, $timeout, $ionicTemplateLoader, $ionicP
element.remove();
// scope.cancel.$scope is defined near the bottom
scope.cancel.$scope = sheetEl = null;
- (done || noop)();
+ (done || noop)(opts.buttons);
});
};
@@ -46162,10 +50647,14 @@ jqLite.prototype.removeClass = function(cssClasses) {
* For example, if `retain` is called three times, the backdrop will be shown until `release`
* is called three times.
*
+ * **Notes:**
+ * - The backdrop service will broadcast 'backdrop.shown' and 'backdrop.hidden' events from the root scope,
+ * this is useful for alerting native components not in html.
+ *
* @usage
*
* ```js
- * function MyController($scope, $ionicBackdrop, $timeout) {
+ * function MyController($scope, $ionicBackdrop, $timeout, $rootScope) {
* //Show a backdrop for one second
* $scope.action = function() {
* $ionicBackdrop.retain();
@@ -46173,13 +50662,24 @@ jqLite.prototype.removeClass = function(cssClasses) {
* $ionicBackdrop.release();
* }, 1000);
* };
+ *
+ * // Execute action on backdrop disappearing
+ * $scope.$on('backdrop.hidden', function() {
+ * // Execute action
+ * });
+ *
+ * // Execute action on backdrop appearing
+ * $scope.$on('backdrop.shown', function() {
+ * // Execute action
+ * });
+ *
* }
* ```
*/
IonicModule
.factory('$ionicBackdrop', [
- '$document', '$timeout', '$$rAF',
-function($document, $timeout, $$rAF) {
+ '$document', '$timeout', '$$rAF', '$rootScope',
+function($document, $timeout, $$rAF, $rootScope) {
var el = jqLite('<div class="backdrop">');
var backdropHolds = 0;
@@ -46211,6 +50711,7 @@ function($document, $timeout, $$rAF) {
backdropHolds++;
if (backdropHolds === 1) {
el.addClass('visible');
+ $rootScope.$broadcast('backdrop.shown');
$$rAF(function() {
// If we're still at >0 backdropHolds after async...
if (backdropHolds >= 1) el.addClass('active');
@@ -46220,6 +50721,7 @@ function($document, $timeout, $$rAF) {
function release() {
if (backdropHolds === 1) {
el.removeClass('active');
+ $rootScope.$broadcast('backdrop.hidden');
$timeout(function() {
// If we're still at 0 backdropHolds after async...
if (backdropHolds === 0) el.removeClass('visible');
@@ -46303,7 +50805,7 @@ IonicModule
return {
/**
* @ngdoc method
- * @name $ionicBody#add
+ * @name $ionicBody#addClass
* @description Add a class to the document's body element.
* @param {string} class Each argument will be added to the body element.
* @returns {$ionicBody} The $ionicBody service so methods can be chained.
@@ -47402,9 +51904,9 @@ function($rootScope, $state, $location, $document, $ionicPlatform, $ionicHistory
/**
* @ngdoc method
* @name $ionicConfigProvider#scrolling.jsScrolling
- * @description Whether to use JS or Native scrolling. Defaults to JS scrolling. Setting this to
- * `false` has the same effect as setting each `ion-content` to have `overflow-scroll='true'`.
- * @param {boolean} value Defaults to `true`
+ * @description Whether to use JS or Native scrolling. Defaults to native scrolling. Setting this to
+ * `true` has the same effect as setting each `ion-content` to have `overflow-scroll='false'`.
+ * @param {boolean} value Defaults to `false` as of Ionic 1.2
* @returns {boolean}
*/
@@ -47679,8 +52181,11 @@ IonicModule
tabs: {
style: 'striped',
position: 'top'
- }
+ },
+ scrolling: {
+ jsScrolling: false
+ }
});
// Windows Phone
@@ -47962,8 +52467,8 @@ IonicModule
// http://blogs.msdn.com/b/msdn_answers/archive/2015/02/10/
// running-cordova-apps-on-windows-and-windows-phone-8-1-using-ionic-angularjs-and-other-frameworks.aspx
.config(['$compileProvider', function($compileProvider) {
- $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|tel|ftp|mailto|file|ghttps?|ms-appx|x-wmapp0):/);
- $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|content|blob|ms-appx|x-wmapp0):|data:image\//);
+ $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|sms|tel|geo|ftp|mailto|file|ghttps?|ms-appx-web|ms-appx|x-wmapp0):/);
+ $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|content|blob|ms-appx|ms-appx-web|x-wmapp0):|data:image\//);
}]);
@@ -48050,7 +52555,9 @@ function($ionicLoadingConfig, $ionicBody, $ionicTemplateLoader, $ionicBackdrop,
* @ngdoc method
* @name $ionicLoading#show
* @description Shows a loading indicator. If the indicator is already shown,
- * it will set the options given and keep the indicator shown.
+ * it will set the options given and keep the indicator shown. Note: While this
+ * function still returns an $ionicLoading instance for backwards compatiblity,
+ * its use has been deprecated.
* @param {object} opts The options for the loading indicator. Available properties:
* - `{string=}` `template` The html content of the indicator.
* - `{string=}` `templateUrl` The url of an html template to load as the content of the indicator.
@@ -48145,12 +52652,15 @@ function($ionicLoadingConfig, $ionicBody, $ionicTemplateLoader, $ionicBackdrop,
}
self.element.removeClass('active');
$ionicBody.removeClass('loading-active');
- setTimeout(function() {
+ self.element.removeClass('visible');
+ ionic.requestAnimationFrame(function() {
!self.isShown && self.element.removeClass('visible');
- }, 200);
+ });
}
$timeout.cancel(self.durationTimeout);
self.isShown = false;
+ var loading = self.element.children();
+ loading.html("");
};
return self;
@@ -48387,10 +52897,18 @@ function($rootScope, $ionicBody, $compile, $timeout, $ionicPlatform, $ionicTempl
self.scope.$parent && self.scope.$parent.$broadcast(self.viewType + '.shown', self);
self.el.classList.add('active');
self.scope.$broadcast('$ionicHeader.align');
+ self.scope.$broadcast('$ionicFooter.align');
}, 20);
return $timeout(function() {
if (!self._isShown) return;
+ self.$el.on('touchmove', function(e) {
+ //Don't allow scrolling while open by dragging on backdrop
+ var isInScroll = ionic.DomUtil.getParentOrSelfWithClass(e.target, 'scroll');
+ if (!isInScroll) {
+ e.preventDefault();
+ }
+ });
//After animating in, allow hide on backdrop click
self.$el.on('click', function(e) {
if (self.backdropClickToClose && e.target === self.el && stack.isHighest(self)) {
@@ -48663,7 +53181,7 @@ IonicModule
})
.provider('$ionicPlatform', function() {
return {
- $get: ['$q', function($q) {
+ $get: ['$q', '$ionicScrollDelegate', function($q, $ionicScrollDelegate) {
var self = {
/**
@@ -48814,6 +53332,11 @@ IonicModule
return q.promise;
}
};
+
+ window.addEventListener('statusTap', function() {
+ $ionicScrollDelegate.scrollTop(true);
+ });
+
return self;
}]
};
@@ -49026,7 +53549,7 @@ function($ionicModal, $ionicPosition, $document, $window) {
* controller (ionicPopover is built on top of $ionicPopover).
*/
fromTemplate: function(templateString, options) {
- return $ionicModal.fromTemplate(templateString, ionic.Utils.extend(POPOVER_OPTIONS, options || {}));
+ return $ionicModal.fromTemplate(templateString, ionic.Utils.extend({}, POPOVER_OPTIONS, options));
},
/**
* @ngdoc method
@@ -49037,7 +53560,7 @@ function($ionicModal, $ionicPosition, $document, $window) {
* an {@link ionic.controller:ionicPopover} controller (ionicPopover is built on top of $ionicPopover).
*/
fromTemplateUrl: function(url, options) {
- return $ionicModal.fromTemplateUrl(url, ionic.Utils.extend(POPOVER_OPTIONS, options || {}));
+ return $ionicModal.fromTemplateUrl(url, ionic.Utils.extend({}, POPOVER_OPTIONS, options));
}
};
@@ -49088,7 +53611,7 @@ var POPUP_TPL =
*
* // Triggered on a button click, or some other target
* $scope.showPopup = function() {
- * $scope.data = {}
+ * $scope.data = {};
*
* // An elaborate, custom popup
* var myPopup = $ionicPopup.show({
@@ -49112,19 +53635,23 @@ var POPUP_TPL =
* }
* ]
* });
+ *
* myPopup.then(function(res) {
* console.log('Tapped!', res);
* });
+ *
* $timeout(function() {
* myPopup.close(); //close the popup after 3 seconds for some reason
* }, 3000);
* };
+ *
* // A confirm dialog
* $scope.showConfirm = function() {
* var confirmPopup = $ionicPopup.confirm({
* title: 'Consume Ice Cream',
* template: 'Are you sure you want to eat this ice cream?'
* });
+ *
* confirmPopup.then(function(res) {
* if(res) {
* console.log('You are sure');
@@ -49140,6 +53667,7 @@ var POPUP_TPL =
* title: 'Don\'t eat that!',
* template: 'It might taste good'
* });
+ *
* alertPopup.then(function(res) {
* console.log('Thank you for not eating my delicious ice cream cone');
* });
@@ -49296,8 +53824,10 @@ function($ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScope, $ionicB
* cssClass: '', // String, The custom CSS class name
* subTitle: '', // String (optional). The sub-title of the popup.
* template: '', // String (optional). The html template to place in the popup body.
- * templateUrl: '', // String (optional). The URL of an html template to place in the popup body.
+ * templateUrl: '', // String (optional). The URL of an html template to place in the popup body.
* inputType: // String (default: 'text'). The type of input to use
+ * defaultText: // String (default: ''). The initial value placed into the input.
+ * maxLength: // Integer (default: null). Specify a maxlength attribute for the input.
* inputPlaceholder: // String (default: ''). A placeholder to use for the input.
* cancelText: // String (default: 'Cancel'. The text of the Cancel button.
* cancelType: // String (default: 'button-default'). The type of the Cancel button.
@@ -49341,7 +53871,7 @@ function($ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScope, $ionicB
subTitle: options.subTitle,
cssClass: options.cssClass,
$buttonTapped: function(button, event) {
- var result = (button.onTap || noop)(event);
+ var result = (button.onTap || noop).apply(self, [event]);
event = event.originalEvent || event; //jquery events
if (!event.defaultPrevented) {
@@ -49391,7 +53921,7 @@ function($ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScope, $ionicB
};
self.remove = function() {
- if (self.removed || !$ionicModal.stack.isHighest(self)) return;
+ if (self.removed) return;
self.hide(function() {
self.element.remove();
@@ -49414,8 +53944,8 @@ function($ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScope, $ionicB
var showDelay = 0;
if (popupStack.length > 0) {
- popupStack[popupStack.length - 1].hide();
showDelay = config.stackPushDelay;
+ $timeout(popupStack[popupStack.length - 1].hide, showDelay, false);
} else {
//Add popup-open & backdrop if this is first popup
$ionicBody.addClass('popup-open');
@@ -49448,6 +53978,8 @@ function($ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScope, $ionicB
popupStack.splice(index, 1);
}
+ popup.remove();
+
if (popupStack.length > 0) {
popupStack[popupStack.length - 1].show();
} else {
@@ -49463,7 +53995,6 @@ function($ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScope, $ionicB
($ionicPopup._backButtonActionDone || noop)();
}
- popup.remove();
return result;
});
@@ -49508,14 +54039,21 @@ function($ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScope, $ionicB
function showPrompt(opts) {
var scope = $rootScope.$new(true);
scope.data = {};
+ scope.data.fieldtype = opts.inputType ? opts.inputType : 'text';
+ scope.data.response = opts.defaultText ? opts.defaultText : '';
+ scope.data.placeholder = opts.inputPlaceholder ? opts.inputPlaceholder : '';
+ scope.data.maxlength = opts.maxLength ? parseInt(opts.maxLength) : '';
var text = '';
if (opts.template && /<[a-z][\s\S]*>/i.test(opts.template) === false) {
text = '<span>' + opts.template + '</span>';
delete opts.template;
}
return showPopup(extend({
- template: text + '<input ng-model="data.response" type="' + (opts.inputType || 'text') +
- '" placeholder="' + (opts.inputPlaceholder || '') + '">',
+ template: text + '<input ng-model="data.response" '
+ + 'type="{{ data.fieldtype }}"'
+ + 'maxlength="{{ data.maxlength }}"'
+ + 'placeholder="{{ data.placeholder }}"'
+ + '>',
scope: scope,
buttons: [{
text: opts.cancelText || 'Cancel',
@@ -49764,7 +54302,7 @@ IonicModule
* @name $ionicScrollDelegate#freezeScroll
* @description Does not allow this scroll view to scroll either x or y.
* @param {boolean=} shouldFreeze Should this scroll view be prevented from scrolling or not.
- * @returns {object} If the scroll view is being prevented from scrolling or not.
+ * @returns {boolean} If the scroll view is being prevented from scrolling or not.
*/
'freezeScroll',
/**
@@ -50074,7 +54612,16 @@ IonicModule
* @name $ionicTabsDelegate#selectedIndex
* @returns `number` The index of the selected tab, or -1.
*/
- 'selectedIndex'
+ 'selectedIndex',
+ /**
+ * @ngdoc method
+ * @name $ionicTabsDelegate#showBar
+ * @description
+ * Set/get whether the {@link ionic.directive:ionTabs} is shown
+ * @param {boolean} show Whether to show the bar.
+ * @returns {boolean} Whether the bar is shown.
+ */
+ 'showBar'
/**
* @ngdoc method
* @name $ionicTabsDelegate#$getByHandle
@@ -50087,7 +54634,6 @@ IonicModule
*/
]));
-
// closure to keep things neat
(function() {
var templatesToCache = [];
@@ -50508,8 +55054,9 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe
if (renderStart && renderEnd) {
// CSS "auto" transitioned, not manually transitioned
// wait a frame so the styles apply before auto transitioning
- $timeout(onReflow, 16);
-
+ $timeout(function() {
+ ionic.requestAnimationFrame(onReflow);
+ });
} else if (!renderEnd) {
// just the start of a manual transition
// but it will not render the end of the transition
@@ -50574,10 +55121,6 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe
$timeout.cancel(enteringEle.data(DATA_FALLBACK_TIMER));
leavingEle && $timeout.cancel(leavingEle.data(DATA_FALLBACK_TIMER));
- // emit that the views have finished transitioning
- // each parent nav-view will update which views are active and cached
- switcher.emit('after', enteringData, leavingData);
-
// resolve that this one transition (there could be many w/ nested views)
deferred && deferred.resolve(navViewCtrl);
@@ -50585,6 +55128,10 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe
// transition promises should be added to the services array of promises
if (transitionId === transitionCounter) {
$q.all(transitionPromises).then(ionicViewSwitcher.transitionEnd);
+
+ // emit that the views have finished transitioning
+ // each parent nav-view will update which views are active and cached
+ switcher.emit('after', enteringData, leavingData);
switcher.cleanup(enteringData);
}
@@ -50593,6 +55140,7 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe
instance.triggerTransitionEnd();
});
+
// remove any references that could cause memory issues
nextTransition = nextDirection = enteringView = leavingView = enteringEle = leavingEle = null;
}
@@ -50809,6 +55357,82 @@ function($timeout, $document, $q, $ionicClickBlock, $ionicConfig, $ionicNavBarDe
}]);
/**
+ * ================== angular-ios9-uiwebview.patch.js v1.1.1 ==================
+ *
+ * This patch works around iOS9 UIWebView regression that causes infinite digest
+ * errors in Angular.
+ *
+ * The patch can be applied to Angular 1.2.0 – 1.4.5. Newer versions of Angular
+ * have the workaround baked in.
+ *
+ * To apply this patch load/bundle this file with your application and add a
+ * dependency on the "ngIOS9UIWebViewPatch" module to your main app module.
+ *
+ * For example:
+ *
+ * ```
+ * angular.module('myApp', ['ngRoute'])`
+ * ```
+ *
+ * becomes
+ *
+ * ```
+ * angular.module('myApp', ['ngRoute', 'ngIOS9UIWebViewPatch'])
+ * ```
+ *
+ *
+ * More info:
+ * - https://openradar.appspot.com/22186109
+ * - https://github.com/angular/angular.js/issues/12241
+ * - https://github.com/driftyco/ionic/issues/4082
+ *
+ *
+ * @license AngularJS
+ * (c) 2010-2015 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+
+angular.module('ngIOS9UIWebViewPatch', ['ng']).config(['$provide', function($provide) {
+ 'use strict';
+
+ $provide.decorator('$browser', ['$delegate', '$window', function($delegate, $window) {
+
+ if (isIOS9UIWebView($window.navigator.userAgent)) {
+ return applyIOS9Shim($delegate);
+ }
+
+ return $delegate;
+
+ function isIOS9UIWebView(userAgent) {
+ return /(iPhone|iPad|iPod).* OS 9_\d/.test(userAgent) && !/Version\/9\./.test(userAgent);
+ }
+
+ function applyIOS9Shim(browser) {
+ var pendingLocationUrl = null;
+ var originalUrlFn = browser.url;
+
+ browser.url = function() {
+ if (arguments.length) {
+ pendingLocationUrl = arguments[0];
+ return originalUrlFn.apply(browser, arguments);
+ }
+
+ return pendingLocationUrl || originalUrlFn.apply(browser, arguments);
+ };
+
+ window.addEventListener('popstate', clearPendingLocationUrl, false);
+ window.addEventListener('hashchange', clearPendingLocationUrl, false);
+
+ function clearPendingLocationUrl() {
+ pendingLocationUrl = null;
+ }
+
+ return browser;
+ }
+ }]);
+}]);
+
+/**
* @private
* Parts of Ionic requires that $scope data is attached to the element.
* We do not want to disable adding $scope data to the $element when
@@ -51330,13 +55954,15 @@ function($scope, $attrs, $element, $timeout) {
};
var computedStyle = window.getComputedStyle(self.scrollEl) || {};
return {
- left: computedStyle.overflowX === 'scroll' ||
- computedStyle.overflowX === 'auto' ||
- self.scrollEl.style['overflow-x'] === 'scroll' ?
+ left: maxValues.left &&
+ (computedStyle.overflowX === 'scroll' ||
+ computedStyle.overflowX === 'auto' ||
+ self.scrollEl.style['overflow-x'] === 'scroll') ?
calculateMaxValue(maxValues.left) : -1,
- top: computedStyle.overflowY === 'scroll' ||
- computedStyle.overflowY === 'auto' ||
- self.scrollEl.style['overflow-y'] === 'scroll' ?
+ top: maxValues.top &&
+ (computedStyle.overflowY === 'scroll' ||
+ computedStyle.overflowY === 'auto' ||
+ self.scrollEl.style['overflow-y'] === 'scroll' ) ?
calculateMaxValue(maxValues.top) : -1
};
};
@@ -51368,18 +55994,20 @@ function($scope, $attrs, $element, $timeout) {
* method to control specific ionList instances.
*
* @usage
- *
- * ````html
+ * ```html
+ * {% raw %}
* <ion-content ng-controller="MyCtrl">
* <button class="button" ng-click="showDeleteButtons()"></button>
* <ion-list>
* <ion-item ng-repeat="i in items">
- * {% raw %}Hello, {{i}}!{% endraw %}
+ * Hello, {{i}}!
* <ion-delete-button class="ion-minus-circled"></ion-delete-button>
* </ion-item>
* </ion-list>
* </ion-content>
+ * {% endraw %}
* ```
+
* ```js
* function MyCtrl($scope, $ionicListDelegate) {
* $scope.showDeleteButtons = function() {
@@ -52253,6 +56881,9 @@ function($scope, $element, $attrs, $compile, $controller, $ionicNavBarDelegate,
if (viewLocals && viewLocals.$$controller) {
viewLocals.$scope = viewScope;
var controller = $controller(viewLocals.$$controller, viewLocals);
+ if (viewLocals.$$controllerAs) {
+ viewScope[viewLocals.$$controllerAs] = controller;
+ }
$element.children().data('$ngControllerController', controller);
}
@@ -52531,13 +57162,31 @@ IonicModule
$onPulling: '&onPulling'
});
+ function handleMousedown(e) {
+ e.touches = e.touches || [{
+ screenX: e.screenX,
+ screenY: e.screenY
+ }];
+ // Mouse needs this
+ startY = Math.floor(e.touches[0].screenY);
+ }
+
+ function handleTouchstart(e) {
+ e.touches = e.touches || [{
+ screenX: e.screenX,
+ screenY: e.screenY
+ }];
+
+ startY = e.touches[0].screenY;
+ }
+
function handleTouchend() {
+ // reset Y
+ startY = null;
// if this wasn't an overscroll, get out immediately
if (!canOverscroll && !isDragging) {
return;
}
- // reset Y
- startY = null;
// the user has overscrolled but went back to native scrolling
if (!isDragging) {
dragOffset = 0;
@@ -52561,23 +57210,35 @@ IonicModule
}
function handleTouchmove(e) {
+ e.touches = e.touches || [{
+ screenX: e.screenX,
+ screenY: e.screenY
+ }];
+
+ // Force mouse events to have had a down event first
+ if (!startY && e.type == 'mousemove') {
+ return;
+ }
+
// if multitouch or regular scroll event, get out immediately
if (!canOverscroll || e.touches.length > 1) {
return;
}
//if this is a new drag, keep track of where we start
if (startY === null) {
- startY = parseInt(e.touches[0].screenY, 10);
+ startY = e.touches[0].screenY;
}
+ deltaY = e.touches[0].screenY - startY;
+
+ // how far have we dragged so far?
// kitkat fix for touchcancel events http://updates.html5rocks.com/2014/05/A-More-Compatible-Smoother-Touch
- if (ionic.Platform.isAndroid() && ionic.Platform.version() === 4.4 && scrollParent.scrollTop === 0) {
+ // Only do this if we're not on crosswalk
+ if (ionic.Platform.isAndroid() && ionic.Platform.version() === 4.4 && !ionic.Platform.isCrosswalk() && scrollParent.scrollTop === 0 && deltaY > 0) {
isDragging = true;
e.preventDefault();
}
- // how far have we dragged so far?
- deltaY = parseInt(e.touches[0].screenY, 10) - startY;
// if we've dragged up and back down in to native scroll territory
if (deltaY - dragOffset <= 0 || scrollParent.scrollTop !== 0) {
@@ -52588,7 +57249,7 @@ IonicModule
}
if (isDragging) {
- nativescroll(scrollParent, parseInt(deltaY - dragOffset, 10) * -1);
+ nativescroll(scrollParent, deltaY - dragOffset * -1);
}
// if we're not at overscroll 0 yet, 0 out
@@ -52613,7 +57274,7 @@ IonicModule
isDragging = true;
// overscroll according to the user's drag so far
- overscroll(parseInt((deltaY - dragOffset) / 3, 10));
+ overscroll((deltaY - dragOffset) / 3);
// update the icon accordingly
if (!activated && lastOverscroll > ptrThreshold) {
@@ -52709,7 +57370,7 @@ IonicModule
// fraction based on the easing method
easedT = easeOutCubic(time);
- overscroll(parseInt((easedT * (Y - from)) + from, 10));
+ overscroll(Math.floor((easedT * (Y - from)) + from));
if (time < 1) {
ionic.requestAnimationFrame(scroll);
@@ -52730,6 +57391,21 @@ IonicModule
}
+ var touchStartEvent, touchMoveEvent, touchEndEvent;
+ if (window.navigator.pointerEnabled) {
+ touchStartEvent = 'pointerdown';
+ touchMoveEvent = 'pointermove';
+ touchEndEvent = 'pointerup';
+ } else if (window.navigator.msPointerEnabled) {
+ touchStartEvent = 'MSPointerDown';
+ touchMoveEvent = 'MSPointerMove';
+ touchEndEvent = 'MSPointerUp';
+ } else {
+ touchStartEvent = 'touchstart';
+ touchMoveEvent = 'touchmove';
+ touchEndEvent = 'touchend';
+ }
+
self.init = function() {
scrollParent = $element.parent().parent()[0];
scrollChild = $element.parent()[0];
@@ -52739,8 +57415,13 @@ IonicModule
throw new Error('Refresher must be immediate child of ion-content or ion-scroll');
}
- ionic.on('touchmove', handleTouchmove, scrollChild);
- ionic.on('touchend', handleTouchend, scrollChild);
+
+ ionic.on(touchStartEvent, handleTouchstart, scrollChild);
+ ionic.on(touchMoveEvent, handleTouchmove, scrollChild);
+ ionic.on(touchEndEvent, handleTouchend, scrollChild);
+ ionic.on('mousedown', handleMousedown, scrollChild);
+ ionic.on('mousemove', handleTouchmove, scrollChild);
+ ionic.on('mouseup', handleTouchend, scrollChild);
ionic.on('scroll', handleScroll, scrollParent);
// cleanup when done
@@ -52748,8 +57429,12 @@ IonicModule
};
function destroy() {
- ionic.off('touchmove', handleTouchmove, scrollChild);
- ionic.off('touchend', handleTouchend, scrollChild);
+ ionic.off(touchStartEvent, handleTouchstart, scrollChild);
+ ionic.off(touchMoveEvent, handleTouchmove, scrollChild);
+ ionic.off(touchEndEvent, handleTouchend, scrollChild);
+ ionic.off('mousedown', handleMousedown, scrollChild);
+ ionic.off('mousemove', handleTouchmove, scrollChild);
+ ionic.off('mouseup', handleTouchend, scrollChild);
ionic.off('scroll', handleScroll, scrollParent);
scrollParent = null;
scrollChild = null;
@@ -52785,7 +57470,13 @@ IonicModule
function start() {
// startCallback
$element[0].classList.add('refreshing');
- $scope.$onRefresh();
+ var q = $scope.$onRefresh();
+
+ if (q && q.then) {
+ q['finally'](function() {
+ $scope.$broadcast('scroll.refreshComplete');
+ });
+ }
}
function show() {
@@ -52866,7 +57557,7 @@ function($scope,
if (!isDefined(scrollViewOptions.bouncing)) {
ionic.Platform.ready(function() {
- if (scrollView.options) {
+ if (scrollView && scrollView.options) {
scrollView.options.bouncing = true;
if (ionic.Platform.isAndroid()) {
// No bouncing by default on Android
@@ -52920,12 +57611,18 @@ function($scope,
self.scrollTop = function(shouldAnimate) {
self.resize().then(function() {
+ if (!scrollView) {
+ return;
+ }
scrollView.scrollTo(0, 0, !!shouldAnimate);
});
};
self.scrollBottom = function(shouldAnimate) {
self.resize().then(function() {
+ if (!scrollView) {
+ return;
+ }
var max = scrollView.getScrollMax();
scrollView.scrollTo(max.left, max.top, !!shouldAnimate);
});
@@ -52933,30 +57630,45 @@ function($scope,
self.scrollTo = function(left, top, shouldAnimate) {
self.resize().then(function() {
+ if (!scrollView) {
+ return;
+ }
scrollView.scrollTo(left, top, !!shouldAnimate);
});
};
self.zoomTo = function(zoom, shouldAnimate, originLeft, originTop) {
self.resize().then(function() {
+ if (!scrollView) {
+ return;
+ }
scrollView.zoomTo(zoom, !!shouldAnimate, originLeft, originTop);
});
};
self.zoomBy = function(zoom, shouldAnimate, originLeft, originTop) {
self.resize().then(function() {
+ if (!scrollView) {
+ return;
+ }
scrollView.zoomBy(zoom, !!shouldAnimate, originLeft, originTop);
});
};
self.scrollBy = function(left, top, shouldAnimate) {
self.resize().then(function() {
+ if (!scrollView) {
+ return;
+ }
scrollView.scrollBy(left, top, !!shouldAnimate);
});
};
self.anchorScroll = function(shouldAnimate) {
self.resize().then(function() {
+ if (!scrollView) {
+ return;
+ }
var hash = $location.hash();
var elm = hash && $document[0].getElementById(hash);
if (!(hash && elm)) {
@@ -52975,6 +57687,7 @@ function($scope,
};
self.freezeScroll = scrollView.freeze;
+ self.freezeScrollShut = scrollView.freezeShut;
self.freezeAllScrolls = function(shouldFreeze) {
for (var i = 0; i < $ionicScrollDelegate._instances.length; i++) {
@@ -53156,9 +57869,10 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
// equal 0, otherwise remove the class from the body element
$ionicBody.enableClass((percentage !== 0), 'menu-open');
- freezeAllScrolls(false);
+ self.content.setCanScroll(percentage == 0);
};
+ /*
function freezeAllScrolls(shouldFreeze) {
if (shouldFreeze && !self.isScrollFreeze) {
$ionicScrollDelegate.freezeAllScrolls(shouldFreeze);
@@ -53168,6 +57882,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
}
self.isScrollFreeze = shouldFreeze;
}
+ */
/**
* Open the menu the given pixel amount.
@@ -53300,14 +58015,15 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
self.close();
isAsideExposed = shouldExposeAside;
- if (self.left && self.left.isEnabled) {
+ if ((self.left && self.left.isEnabled) && (self.right && self.right.isEnabled)) {
+ self.content.setMarginLeftAndRight(isAsideExposed ? self.left.width : 0, isAsideExposed ? self.right.width : 0);
+ } else if (self.left && self.left.isEnabled) {
// set the left marget width if it should be exposed
// otherwise set false so there's no left margin
self.content.setMarginLeft(isAsideExposed ? self.left.width : 0);
} else if (self.right && self.right.isEnabled) {
self.content.setMarginRight(isAsideExposed ? self.right.width : 0);
}
-
self.$scope.$emit('$ionicExposeAside', isAsideExposed);
};
@@ -53317,8 +58033,6 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
// End a drag with the given event
self._endDrag = function(e) {
- freezeAllScrolls(false);
-
if (isAsideExposed) return;
if (isDragging) {
@@ -53356,7 +58070,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
if (isDragging) {
self.openAmount(offsetX + (lastX - startX));
- freezeAllScrolls(true);
+ //self.content.setCanScroll(false);
}
};
@@ -53395,7 +58109,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
var menuEnabled = enableMenuWithBackViews ? true : !backView;
if (!menuEnabled) {
var currentView = $ionicHistory.currentView() || {};
- return backView.historyId !== currentView.historyId;
+ return (dragIsWithinBounds && (backView.historyId !== currentView.historyId));
}
return ($scope.dragContent || self.isOpen()) &&
@@ -53435,12 +58149,10 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
deregisterBackButtonAction();
self.$scope = null;
if (self.content) {
+ self.content.setCanScroll(true);
self.content.element = null;
self.content = null;
}
-
- // ensure scrolls are unfrozen
- freezeAllScrolls(false);
});
self.initialize({
@@ -53786,6 +58498,10 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
var animations = {
android: function(ele) {
+ var self = this;
+
+ this.stop = false;
+
var rIndex = 0;
var rotateCircle = 0;
var startTime;
@@ -53793,6 +58509,8 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
var circleEle = ele.querySelector('circle');
function run() {
+ if (self.stop) return;
+
var v = easeInOutCubic(Date.now() - startTime, 650);
var scaleX = 1;
var translateX = 0;
@@ -53828,6 +58546,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
return function() {
startTime = Date.now();
run();
+ return self;
};
}
@@ -53848,7 +58567,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
'$attrs',
'$ionicConfig',
function($element, $attrs, $ionicConfig) {
- var spinnerName;
+ var spinnerName, anim;
this.init = function() {
spinnerName = $attrs.icon || $ionicConfig.spinner.icon();
@@ -53871,7 +58590,11 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
};
this.start = function() {
- animations[spinnerName] && animations[spinnerName]($element[0])();
+ animations[spinnerName] && (anim = animations[spinnerName]($element[0])());
+ };
+
+ this.stop = function() {
+ animations[spinnerName] && (anim.stop = true);
};
}]);
@@ -53916,6 +58639,7 @@ function($scope, $element, $ionicHistory) {
var selectedTab = null;
var previousSelectedTab = null;
var selectedTabIndex;
+ var isVisible = true;
self.tabs = [];
self.selectedIndex = function() {
@@ -54022,6 +58746,17 @@ function($scope, $element, $ionicHistory) {
return false;
};
+ self.showBar = function(show) {
+ if (arguments.length) {
+ if (show) {
+ $element.removeClass('tabs-item-hide');
+ } else {
+ $element.addClass('tabs-item-hide');
+ }
+ isVisible = !!show;
+ }
+ return isVisible;
+ };
}]);
IonicModule
@@ -54188,7 +58923,7 @@ IonicModule
'<div class="action-sheet" ng-class="{\'action-sheet-has-icons\': $actionSheetHasIcon}">' +
'<div class="action-sheet-group action-sheet-options">' +
'<div class="action-sheet-title" ng-if="titleText" ng-bind-html="titleText"></div>' +
- '<button class="button action-sheet-option" ng-click="buttonClicked($index)" ng-repeat="b in buttons" ng-bind-html="b.text"></button>' +
+ '<button class="button action-sheet-option" ng-click="buttonClicked($index)" ng-class="b.className" ng-repeat="b in buttons" ng-bind-html="b.text"></button>' +
'<button class="button destructive action-sheet-destructive" ng-if="destructiveText" ng-click="destructiveButtonClicked()" ng-bind-html="destructiveText"></button>' +
'</div>' +
'<div class="action-sheet-group action-sheet-cancel" ng-if="cancelText">' +
@@ -54315,7 +59050,7 @@ IonicModule
* <ion-scroll direction="x" class="available-scroller">
* <div class="photo" collection-repeat="photo in main.photos"
* item-height="250" item-width="photo.width + 30">
- * <img ng-src="{{photo.src}}">
+ * <img ng-src="{% raw %}{{photo.src}}{% endraw %}">
* </div>
* </ion-scroll>
* </ion-content>
@@ -54597,17 +59332,15 @@ function CollectionRepeatDirective($ionicCollectionManager, $parse, $window, $$r
// If it's a constant, it's either a percent or just a constant pixel number.
if (isConstant) {
- var intValue = parseInt(parsedValue());
-
// For percents, store the percent getter on .getValue()
if (attrValue.indexOf('%') > -1) {
- var decimalValue = intValue / 100;
+ var decimalValue = parseFloat(parsedValue()) / 100;
dimensionData.getValue = dimensionData === heightData ?
function() { return Math.floor(decimalValue * scrollView.__clientHeight); } :
function() { return Math.floor(decimalValue * scrollView.__clientWidth); };
} else {
// For static constants, just store the static constant.
- dimensionData.value = intValue;
+ dimensionData.value = parseInt(parsedValue());
}
} else {
@@ -54616,14 +59349,14 @@ function CollectionRepeatDirective($ionicCollectionManager, $parse, $window, $$r
function heightGetter(scope, locals) {
var result = parsedValue(scope, locals);
if (result.charAt && result.charAt(result.length - 1) === '%') {
- return Math.floor(parseInt(result) / 100 * scrollView.__clientHeight);
+ return Math.floor(parseFloat(result) / 100 * scrollView.__clientHeight);
}
return parseInt(result);
} :
function widthGetter(scope, locals) {
var result = parsedValue(scope, locals);
if (result.charAt && result.charAt(result.length - 1) === '%') {
- return Math.floor(parseInt(result) / 100 * scrollView.__clientWidth);
+ return Math.floor(parseFloat(result) / 100 * scrollView.__clientWidth);
}
return parseInt(result);
};
@@ -55324,13 +60057,12 @@ function($timeout, $controller, $ionicBind, $ionicConfig) {
element.addClass('scroll-content-false');
}
- var nativeScrolling = attr.overflowScroll === "true" || !$ionicConfig.scrolling.jsScrolling();
+ var nativeScrolling = attr.overflowScroll !== "false" && (attr.overflowScroll === "true" || !$ionicConfig.scrolling.jsScrolling());
// collection-repeat requires JS scrolling
if (nativeScrolling) {
nativeScrolling = !element[0].querySelector('[collection-repeat]');
}
-
return { pre: prelink };
function prelink($scope, $element, $attr) {
var parentScope = $scope.$parent;
@@ -55413,6 +60145,8 @@ function($timeout, $controller, $ionicBind, $ionicConfig) {
scrollViewOptions: scrollViewOptions
});
+ $scope.scrollCtrl = scrollCtrl;
+
$scope.$on('$destroy', function() {
if (scrollViewOptions) {
scrollViewOptions.scrollingComplete = noop;
@@ -55461,7 +60195,6 @@ function($timeout, $controller, $ionicBind, $ionicConfig) {
* the most common use-case. However, for added flexibility, any valid media query could be added
* as the value, such as `(min-width:600px)` or even multiple queries such as
* `(min-width:750px) and (max-width:1200px)`.
-
* @usage
* ```html
* <ion-side-menus>
@@ -55477,12 +60210,21 @@ function($timeout, $controller, $ionicBind, $ionicConfig) {
* For a complete side menu example, see the
* {@link ionic.directive:ionSideMenus} documentation.
*/
+
IonicModule.directive('exposeAsideWhen', ['$window', function($window) {
return {
restrict: 'A',
require: '^ionSideMenus',
link: function($scope, $element, $attr, sideMenuCtrl) {
+ // Setup a match media query listener that triggers a ui change only when a change
+ // in media matching status occurs
+ var mq = $attr.exposeAsideWhen == 'large' ? '(min-width:768px)' : $attr.exposeAsideWhen;
+ var mql = $window.matchMedia(mq);
+ mql.addListener(function() {
+ onResize();
+ });
+
function checkAsideExpose() {
var mq = $attr.exposeAsideWhen == 'large' ? '(min-width:768px)' : $attr.exposeAsideWhen;
sideMenuCtrl.exposeAside($window.matchMedia(mq).matches);
@@ -55499,18 +60241,10 @@ IonicModule.directive('exposeAsideWhen', ['$window', function($window) {
}, 300, false);
$scope.$evalAsync(checkAsideExpose);
-
- ionic.on('resize', onResize, $window);
-
- $scope.$on('$destroy', function() {
- ionic.off('resize', onResize, $window);
- });
-
}
};
}]);
-
var GESTURE_DIRECTIVES = 'onHold onTap onDoubleTap onTouch onRelease onDragStart onDrag onDragEnd onDragUp onDragRight onDragDown onDragLeft onSwipe onSwipeUp onSwipeRight onSwipeDown onSwipeLeft'.split(' ');
GESTURE_DIRECTIVES.forEach(function(name) {
@@ -55817,7 +60551,7 @@ function gestureDirective(directiveName) {
IonicModule
-.directive('ionHeaderBar', tapScrollToTopDirective())
+//.directive('ionHeaderBar', tapScrollToTopDirective())
/**
* @ngdoc directive
@@ -55894,7 +60628,7 @@ IonicModule
*/
.directive('ionFooterBar', headerFooterBarDirective(false));
-function tapScrollToTopDirective() {
+function tapScrollToTopDirective() { //eslint-disable-line no-unused-vars
return ['$ionicScrollDelegate', function($ionicScrollDelegate) {
return {
restrict: 'E',
@@ -55981,6 +60715,12 @@ function headerFooterBarDirective(isHeader) {
$scope.$watch('$hasTabs', function(val) {
$element.toggleClass('has-tabs', !!val);
});
+ ctrl.align();
+ $scope.$on('$ionicFooter.align', function() {
+ ionic.requestAnimationFrame(function() {
+ ctrl.align();
+ });
+ });
}
}
}
@@ -56100,6 +60840,137 @@ IonicModule
/**
* @ngdoc directive
+* @name ionInput
+* @parent ionic.directive:ionList
+* @module ionic
+* @restrict E
+* Creates a text input group that can easily be focused
+*
+* @usage
+*
+* ```html
+* <ion-list>
+* <ion-input>
+* <input type="text" placeholder="First Name">
+* <ion-input>
+*
+* <ion-input>
+* <ion-label>Username</ion-label>
+* <input type="text">
+* </ion-input>
+* </ion-list>
+* ```
+*/
+
+var labelIds = -1;
+
+IonicModule
+.directive('ionInput', [function() {
+ return {
+ restrict: 'E',
+ controller: ['$scope', '$element', function($scope, $element) {
+ this.$scope = $scope;
+ this.$element = $element;
+
+ this.setInputAriaLabeledBy = function(id) {
+ var inputs = $element[0].querySelectorAll('input,textarea');
+ inputs.length && inputs[0].setAttribute('aria-labelledby', id);
+ };
+
+ this.focus = function() {
+ var inputs = $element[0].querySelectorAll('input,textarea');
+ inputs.length && inputs[0].focus();
+ };
+ }]
+ };
+}]);
+
+/**
+* @ngdoc directive
+* @name ionLabel
+* @parent ionic.directive:ionList
+* @module ionic
+* @restrict E
+*
+* New in Ionic 1.2. It is strongly recommended that you use `<ion-label>` in place
+* of any `<label>` elements for maximum cross-browser support and performance.
+*
+* Creates a label for a form input.
+*
+* @usage
+*
+* ```html
+* <ion-list>
+* <ion-input>
+* <ion-label>Username</ion-label>
+* <input type="text">
+* </ion-input>
+* </ion-list>
+* ```
+*/
+IonicModule
+.directive('ionLabel', [function() {
+ return {
+ restrict: 'E',
+ require: '?^ionInput',
+ compile: function() {
+
+ return function link($scope, $element, $attrs, ionInputCtrl) {
+ var element = $element[0];
+
+ $element.addClass('input-label');
+
+ $element.attr('aria-label', $element.text());
+ var id = element.id || '_label-' + ++labelIds;
+
+ if (!element.id) {
+ $element.attr('id', id);
+ }
+
+ if (ionInputCtrl) {
+
+ ionInputCtrl.setInputAriaLabeledBy(id);
+
+ $element.on('click', function() {
+ ionInputCtrl.focus();
+ });
+ }
+ };
+ }
+ };
+}]);
+
+/**
+ * Input label adds accessibility to <span class="input-label">.
+ */
+IonicModule
+.directive('inputLabel', [function() {
+ return {
+ restrict: 'C',
+ require: '?^ionInput',
+ compile: function() {
+
+ return function link($scope, $element, $attrs, ionInputCtrl) {
+ var element = $element[0];
+
+ $element.attr('aria-label', $element.text());
+ var id = element.id || '_label-' + ++labelIds;
+
+ if (!element.id) {
+ $element.attr('id', id);
+ }
+
+ if (ionInputCtrl) {
+ ionInputCtrl.setInputAriaLabeledBy(id);
+ }
+
+ };
+ }
+ };
+}]);
+
+/**
+* @ngdoc directive
* @name ionItem
* @parent ionic.directive:ionList
* @module ionic
@@ -56306,7 +61177,7 @@ var ITEM_TPL_OPTION_BUTTONS =
* @description
* Creates an option button inside a list item, that is visible when the item is swiped
* to the left by the user. Swiped open option buttons can be hidden with
-* {@link ionic.service:$ionicListDelegate#closeOptionButtons $ionicListDelegate#closeOptionButtons}.
+* {@link ionic.service:$ionicListDelegate#closeOptionButtons $ionicListDelegate.closeOptionButtons}.
*
* Can be assigned any button class.
*
@@ -56487,7 +61358,7 @@ IonicModule
}
//for testing
- var keyboardHeight = e.keyboardHeight || e.detail.keyboardHeight;
+ var keyboardHeight = e.keyboardHeight || (e.detail && e.detail.keyboardHeight);
element.css('bottom', keyboardHeight + "px");
scrollCtrl = element.controller('$ionicScroll');
if (scrollCtrl) {
@@ -56740,7 +61611,7 @@ function($timeout) {
* <a menu-close href="#/home" class="item">Home</a>
* ```
*
- * Note that if your destination state uses a resolve and that resolve asyncronously
+ * Note that if your destination state uses a resolve and that resolve asynchronously
* takes longer than a standard transition (300ms), you'll need to set the
* `nextViewOptions` manually as your resolve completes.
*
@@ -56750,6 +61621,7 @@ function($timeout) {
* disableAnimate: true,
* expire: 300
* });
+ * ```
*/
IonicModule
.directive('menuClose', ['$ionicHistory', '$timeout', function($ionicHistory, $timeout) {
@@ -57337,7 +62209,7 @@ IonicModule
* });
* });
* ```
- * Then on app start, $stateProvider will look at the url, see it matches the index state,
+ * Then on app start, $stateProvider will look at the url, see if it matches the index state,
* and then try to load home.html into the `<ion-nav-view>`.
*
* Pages are loaded by the URLs given. One simple way to create templates in Angular is to put
@@ -57595,7 +62467,7 @@ IonicModule
* @description
* The radio directive is no different than the HTML radio input, except it's styled differently.
*
- * Radio behaves like any [AngularJS radio](http://docs.angularjs.org/api/ng/input/input[radio]).
+ * Radio behaves like [AngularJS radio](http://docs.angularjs.org/api/ng/input/input[radio]).
*
* @usage
* ```html
@@ -57623,13 +62495,16 @@ IonicModule
template:
'<label class="item item-radio">' +
'<input type="radio" name="radio-group">' +
- '<div class="item-content disable-pointer-events" ng-transclude></div>' +
- '<i class="radio-icon disable-pointer-events icon ion-checkmark"></i>' +
+ '<div class="radio-content">' +
+ '<div class="item-content disable-pointer-events" ng-transclude></div>' +
+ '<i class="radio-icon disable-pointer-events icon ion-checkmark"></i>' +
+ '</div>' +
'</label>',
compile: function(element, attr) {
if (attr.icon) {
- element.children().eq(2).removeClass('ion-checkmark').addClass(attr.icon);
+ var iconElm = element.find('i');
+ iconElm.removeClass('ion-checkmark').addClass(attr.icon);
}
var input = element.find('input');
@@ -57816,12 +62691,13 @@ IonicModule
'$timeout',
'$controller',
'$ionicBind',
-function($timeout, $controller, $ionicBind) {
+ '$ionicConfig',
+function($timeout, $controller, $ionicBind, $ionicConfig) {
return {
restrict: 'E',
scope: true,
controller: function() {},
- compile: function(element) {
+ compile: function(element, attr) {
element.addClass('scroll-view ionic-scroll');
//We cannot transclude here because it breaks element.data() inheritance on compile
@@ -57829,6 +62705,8 @@ function($timeout, $controller, $ionicBind) {
innerElement.append(element.contents());
element.append(innerElement);
+ var nativeScrolling = attr.overflowScroll !== "false" && (attr.overflowScroll === "true" || !$ionicConfig.scrolling.jsScrolling());
+
return { pre: prelink };
function prelink($scope, $element, $attr) {
$ionicBind($scope, $attr, {
@@ -57856,6 +62734,12 @@ function($timeout, $controller, $ionicBind) {
if (!$scope.direction) { $scope.direction = 'y'; }
var isPaging = $scope.$eval($scope.paging) === true;
+ if (nativeScrolling) {
+ $element.addClass('overflow-scroll');
+ }
+
+ $element.addClass('scroll-' + $scope.direction);
+
var scrollViewOptions = {
el: $element[0],
delegateHandle: $attr.delegateHandle,
@@ -57869,8 +62753,10 @@ function($timeout, $controller, $ionicBind) {
zooming: $scope.$eval($scope.zooming) === true,
maxZoom: $scope.$eval($scope.maxZoom) || 3,
minZoom: $scope.$eval($scope.minZoom) || 0.5,
- preventDefault: true
+ preventDefault: true,
+ nativeScrolling: nativeScrolling
};
+
if (isPaging) {
scrollViewOptions.speedMultiplier = 0.8;
scrollViewOptions.bouncing = false;
@@ -58081,6 +62967,22 @@ function($timeout, $ionicGesture, $window) {
element: element[0],
onDrag: function() {},
endDrag: function() {},
+ setCanScroll: function(canScroll) {
+ var c = $element[0].querySelector('.scroll');
+
+ if (!c) {
+ return;
+ }
+
+ var content = angular.element(c.parentElement);
+ if (!content) {
+ return;
+ }
+
+ // freeze our scroll container if we have one
+ var scrollScope = content.scope();
+ scrollScope.scrollCtrl && scrollScope.scrollCtrl.freezeScrollShut(!canScroll);
+ },
getTranslateX: function() {
return $scope.sideMenuContentTranslateX || 0;
},
@@ -58115,6 +63017,24 @@ function($timeout, $ionicGesture, $window) {
// reset incase left gets grabby
$element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(0,0,0)';
}),
+ setMarginLeftAndRight: ionic.animationFrameThrottle(function(amountLeft, amountRight) {
+ amountLeft = amountLeft && parseInt(amountLeft, 10) || 0;
+ amountRight = amountRight && parseInt(amountRight, 10) || 0;
+
+ var amount = amountLeft + amountRight;
+
+ if (amount > 0) {
+ $element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(' + amountLeft + 'px,0,0)';
+ $element[0].style.width = ($window.innerWidth - amount) + 'px';
+ content.offsetX = amountLeft;
+ } else {
+ $element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(0,0,0)';
+ $element[0].style.width = '';
+ content.offsetX = 0;
+ }
+ // reset incase left gets grabby
+ //$element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(0,0,0)';
+ }),
enableAnimation: function() {
$scope.animationEnabled = true;
$element[0].classList.add('menu-animated');
@@ -58130,9 +63050,7 @@ function($timeout, $ionicGesture, $window) {
// add gesture handlers
var gestureOpts = { stop_browser_behavior: false };
- if (ionic.DomUtil.getParentOrSelfWithClass($element[0], 'overflow-scroll')) {
- gestureOpts.prevent_default_directions = ['left', 'right'];
- }
+ gestureOpts.prevent_default_directions = ['left', 'right'];
var contentTapGesture = $ionicGesture.on('tap', onContentTap, $element, gestureOpts);
var dragRightGesture = $ionicGesture.on('dragright', onDragX, $element, gestureOpts);
var dragLeftGesture = $ionicGesture.on('dragleft', onDragX, $element, gestureOpts);
@@ -58273,6 +63191,8 @@ IonicModule
* @ngdoc directive
* @name ionSlideBox
* @module ionic
+ * @deprecated will be removed in the next Ionic release in favor of the new ion-slides component.
+ * Don't depend on the internal behavior of this widget.
* @delegate ionic.service:$ionicSlideBoxDelegate
* @restrict E
* @description
@@ -58307,12 +63227,13 @@ IonicModule
*/
IonicModule
.directive('ionSlideBox', [
+ '$animate',
'$timeout',
'$compile',
'$ionicSlideBoxDelegate',
'$ionicHistory',
'$ionicScrollDelegate',
-function($timeout, $compile, $ionicSlideBoxDelegate, $ionicHistory, $ionicScrollDelegate) {
+function($animate, $timeout, $compile, $ionicSlideBoxDelegate, $ionicHistory, $ionicScrollDelegate) {
return {
restrict: 'E',
replace: true,
@@ -58325,12 +63246,14 @@ function($timeout, $compile, $ionicSlideBoxDelegate, $ionicHistory, $ionicScroll
pagerClick: '&',
disableScroll: '@',
onSlideChanged: '&',
- activeSlide: '=?'
+ activeSlide: '=?',
+ bounce: '@'
},
controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) {
var _this = this;
var continuous = $scope.$eval($scope.doesContinue) === true;
+ var bouncing = ($scope.$eval($scope.bounce) !== false); //Default to true
var shouldAutoPlay = isDefined($attrs.autoPlay) ? !!$scope.autoPlay : false;
var slideInterval = shouldAutoPlay ? $scope.$eval($scope.slideInterval) || 4000 : 0;
@@ -58339,6 +63262,7 @@ function($timeout, $compile, $ionicSlideBoxDelegate, $ionicHistory, $ionicScroll
auto: slideInterval,
continuous: continuous,
startSlide: $scope.activeSlide,
+ bouncing: bouncing,
slidesChanged: function() {
$scope.currentSlide = slider.currentIndex();
@@ -58409,7 +63333,6 @@ function($timeout, $compile, $ionicSlideBoxDelegate, $ionicHistory, $ionicScroll
};
this.onPagerClick = function(index) {
- void 0;
$scope.pagerClick({index: index});
};
@@ -58423,6 +63346,9 @@ function($timeout, $compile, $ionicSlideBoxDelegate, $ionicHistory, $ionicScroll
'</div>',
link: function($scope, $element, $attr) {
+ // Disable ngAnimate for slidebox and its children
+ $animate.enabled(false, $element);
+
// if showPager is undefined, show the pager
if (!isDefined($attr.showPager)) {
$scope.showPager = true;
@@ -58451,7 +63377,7 @@ function($timeout, $compile, $ionicSlideBoxDelegate, $ionicHistory, $ionicScroll
.directive('ionSlide', function() {
return {
restrict: 'E',
- require: '^ionSlideBox',
+ require: '?^ionSlideBox',
compile: function(element) {
element.addClass('slider-slide');
}
@@ -58493,6 +63419,132 @@ function($timeout, $compile, $ionicSlideBoxDelegate, $ionicHistory, $ionicScroll
});
+
+/**
+ * @ngdoc directive
+ * @name ionSlides
+ * @module ionic
+ * @delegate ionic.service:$ionicSlideBoxDelegate
+ * @restrict E
+ * @description
+ * The Slides component is a powerful multi-page container where each page can be swiped or dragged between.
+ *
+ * Note: this is a new version of the Ionic Slide Box based on the [Swiper](http://www.idangero.us/swiper/#.Vmc1J-ODFBc) widget from
+ * [idangerous](http://www.idangero.us/).
+ *
+ * ![SlideBox](http://ionicframework.com.s3.amazonaws.com/docs/controllers/slideBox.gif)
+ *
+ * @usage
+ * ```html
+ * <ion-slides on-slide-changed="slideHasChanged($index)">
+ * <ion-slide-page>
+ * <div class="box blue"><h1>BLUE</h1></div>
+ * </ion-slide-page>
+ * <ion-slide-page>
+ * <div class="box yellow"><h1>YELLOW</h1></div>
+ * </ion-slide-page>
+ * <ion-slide-page>
+ * <div class="box pink"><h1>PINK</h1></div>
+ * </ion-slide-page>
+ * </ion-slides>
+ * ```
+ *
+ * @param {string=} delegate-handle The handle used to identify this slideBox
+ * with {@link ionic.service:$ionicSlideBoxDelegate}.
+ * @param {object=} options to pass to the widget. See the full ist here: [http://www.idangero.us/swiper/api/](http://www.idangero.us/swiper/api/)
+ */
+IonicModule
+.directive('ionSlides', [
+ '$animate',
+ '$timeout',
+ '$compile',
+function($animate, $timeout, $compile) {
+ return {
+ restrict: 'E',
+ transclude: true,
+ scope: {
+ options: '=',
+ slider: '='
+ },
+ template: '<div class="swiper-container">' +
+ '<div class="swiper-wrapper" ng-transclude>' +
+ '</div>' +
+ '<div ng-hide="!showPager" class="swiper-pagination"></div>' +
+ '</div>',
+ controller: ['$scope', '$element', function($scope, $element) {
+ var _this = this;
+
+ this.update = function() {
+ $timeout(function() {
+ if (!_this.__slider) {
+ return;
+ }
+
+ _this.__slider.update();
+ if (_this._options.loop) {
+ _this.__slider.createLoop();
+ }
+
+ // Don't allow pager to show with > 10 slides
+ if (_this.__slider.slides.length > 10) {
+ $scope.showPager = false;
+ }
+ });
+ };
+
+ this.rapidUpdate = ionic.debounce(function() {
+ _this.update();
+ }, 50);
+
+ this.getSlider = function() {
+ return _this.__slider;
+ };
+
+ var options = $scope.options || {};
+
+ var newOptions = angular.extend({
+ pagination: '.swiper-pagination',
+ paginationClickable: true,
+ lazyLoading: true,
+ preloadImages: false
+ }, options);
+
+ this._options = newOptions;
+
+ $timeout(function() {
+ var slider = new ionic.views.Swiper($element.children()[0], newOptions, $scope, $compile);
+
+ _this.__slider = slider;
+ $scope.slider = _this.__slider;
+
+ $scope.$on('$destroy', function() {
+ slider.destroy();
+ });
+ });
+
+ }],
+
+
+ link: function($scope) {
+ $scope.showPager = true;
+ // Disable ngAnimate for slidebox and its children
+ //$animate.enabled(false, $element);
+ }
+ };
+}])
+.directive('ionSlidePage', [function() {
+ return {
+ restrict: 'E',
+ require: '?^ionSlides',
+ transclude: true,
+ replace: true,
+ template: '<div class="swiper-slide" ng-transclude></div>',
+ link: function($scope, $element, $attr, ionSlidesCtrl) {
+ ionSlidesCtrl.rapidUpdate();
+ }
+ };
+}]);
+
/**
* @ngdoc directive
* @name ionSpinner
@@ -58683,6 +63735,10 @@ IonicModule
link: function($scope, $element, $attrs, ctrl) {
var spinnerName = ctrl.init();
$element.addClass('spinner spinner-' + spinnerName);
+
+ $element.on('$destroy', function onDestroy() {
+ ctrl.stop();
+ });
}
};
});
@@ -58982,7 +64038,7 @@ IonicModule
*
* @usage
* ```html
- * <ion-tabs class="tabs-positive tabs-icon-only">
+ * <ion-tabs class="tabs-positive tabs-icon-top">
*
* <ion-tab title="Home" icon-on="ion-ios-filing" icon-off="ion-ios-filing-outline">
* <!-- Tab 1 content -->
@@ -59076,6 +64132,34 @@ function($ionicTabsDelegate, $ionicConfig) {
}]);
/**
+* @ngdoc directive
+* @name ionTitle
+* @module ionic
+* @restrict E
+*
+* Used for titles in header and nav bars. New in 1.2
+*
+* Identical to <div class="title"> but with future compatibility for Ionic 2
+*
+* @usage
+*
+* ```html
+* <ion-nav-bar>
+* <ion-title>Hello</ion-title>
+* <ion-nav-bar>
+* ```
+*/
+IonicModule
+.directive('ionTitle', [function() {
+ return {
+ restrict: 'E',
+ compile: function(element) {
+ element.addClass('title');
+ }
+ };
+}]);
+
+/**
* @ngdoc directive
* @name ionToggle
* @module ionic