mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-08 23:58:13 +08:00
merge
This commit is contained in:
35
dist/css/ionic.css
vendored
35
dist/css/ionic.css
vendored
@ -2282,8 +2282,37 @@ body, .ionic-body {
|
||||
text-align: center;
|
||||
position: relative; }
|
||||
|
||||
.ionic-refresher-content {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
position: relative; }
|
||||
|
||||
.ionic-refresher {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background-color: #4a87ee;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
bottom: 25px; }
|
||||
|
||||
.scroll-refreshing {
|
||||
-webkit-transition: height 0.1s ease-in-out; }
|
||||
.scroll-refreshing .ionic-refresher {
|
||||
-webkit-animation: refresher-pulsate 1.5s linear;
|
||||
-webkit-animation-iteration-count: infinite; }
|
||||
|
||||
@-webkit-keyframes refresher-pulsate {
|
||||
0% {
|
||||
-webkit-transform: scale(2, 2); }
|
||||
|
||||
50% {
|
||||
-webkit-transform: scale(1.5, 1.5); }
|
||||
|
||||
100% {
|
||||
-webkit-transform: scale(2, 2); } }
|
||||
|
||||
.overflow-scroll {
|
||||
overflow: auto;
|
||||
@ -4936,7 +4965,7 @@ a.button {
|
||||
|
||||
@-webkit-keyframes slideOutRight {
|
||||
0% {
|
||||
-webkit-transform: translate3d(0%, 0, 0); }
|
||||
-webkit-transform: translate3d(0, 0, 0); }
|
||||
|
||||
100% {
|
||||
-webkit-transform: translate3d(100%, 0, 0); } }
|
||||
@ -4975,12 +5004,12 @@ a.button {
|
||||
-webkit-animation-name: slideOutRight; }
|
||||
|
||||
.slide-out-right.ng-enter, .slide-out-right > .ng-enter {
|
||||
-webkit-animation-duration: 2250ms;
|
||||
-webkit-animation-duration: 250ms;
|
||||
-webkit-animation-fill-mode: both;
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
-webkit-animation-name: slideOutRight; }
|
||||
.slide-out-right.ng-leave, .slide-out-right > .ng-leave {
|
||||
-webkit-animation-duration: 2250ms;
|
||||
-webkit-animation-duration: 250ms;
|
||||
-webkit-animation-fill-mode: both;
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
-webkit-animation-name: slideInRight; }
|
||||
|
||||
218
dist/js/ionic-angular.js
vendored
218
dist/js/ionic-angular.js
vendored
@ -548,11 +548,39 @@ angular.module('ionic.ui.content', [])
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
template: '<div class="scroll-refresher"><div class="scroll-refresher-content" ng-transclude></div></div>'
|
||||
require: ['^?content', '^?list'],
|
||||
template: '<div class="scroll-refresher"><div class="ionic-refresher-content"><div class="ionic-refresher"></div></div></div>',
|
||||
scope: true,
|
||||
link: function($scope, $element, $attr, scrollCtrl) {
|
||||
var icon = $element[0].querySelector('.ionic-refresher');
|
||||
|
||||
// Scale up the refreshing icon
|
||||
var onRefreshOpening = ionic.throttle(function(e, amt) {
|
||||
icon.style[ionic.CSS.TRANSFORM] = 'scale(' + Math.min((1 + amt), 2) + ')';
|
||||
}, 100);
|
||||
|
||||
$scope.$on('onRefreshing', function(e) {
|
||||
icon.style[ionic.CSS.TRANSFORM] = 'scale(2)';
|
||||
});
|
||||
|
||||
$scope.$on('onRefresh', function(e) {
|
||||
icon.style[ionic.CSS.TRANSFORM] = 'scale(1)';
|
||||
});
|
||||
$scope.$on('onRefreshOpening', onRefreshOpening);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.directive('scroll-refresher', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
template: '<div class="scroll-refresher"><div class="scroll-refresher-content"></div></div>'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
})();
|
||||
;
|
||||
(function() {
|
||||
@ -560,10 +588,10 @@ angular.module('ionic.ui.content', [])
|
||||
|
||||
angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
|
||||
.directive('listItem', ['$timeout', function($timeout) {
|
||||
.directive('item', ['$timeout', function($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: ['?^list', '?^virtualList'],
|
||||
require: ['?^list'],
|
||||
replace: true,
|
||||
transclude: true,
|
||||
scope: {
|
||||
@ -574,8 +602,9 @@ angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
canReorder: '@',
|
||||
canSwipe: '@',
|
||||
buttons: '=',
|
||||
type: '@'
|
||||
},
|
||||
template: '<a href="#" class="item item-slider">\
|
||||
template: '<a href="#" class="item">\
|
||||
<div class="item-edit" ng-if="canDelete && isEditing">\
|
||||
<button class="button button-icon" ng-click="onDelete()"><i ng-class="deleteIcon"></i></button>\
|
||||
</div>\
|
||||
@ -589,20 +618,6 @@ angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
</div>\
|
||||
</a>',
|
||||
|
||||
/*
|
||||
template: '<li class="list-item">\
|
||||
<div class="list-item-edit" ng-if="canDelete && isEditing">\
|
||||
<button class="button button-icon" ng-click="onDelete()"><i ng-class="deleteIcon"></i></button>\
|
||||
</div>\
|
||||
<div class="list-item-content" ng-transclude>\
|
||||
</div>\
|
||||
<div class="list-item-drag" ng-if="canReorder && isEditing">\
|
||||
<button data-ionic-action="reorder" class="button button-icon"><i ng-class="reorderIcon"></i></button>\
|
||||
</div>\
|
||||
<div class="list-item-buttons" ng-if="canSwipe && !isEditing">\
|
||||
<button ng-click="buttonClicked(button)" class="button" ng-class="button.type" ng-repeat="button in buttons">{{button.text}}</button>\
|
||||
</div>\
|
||||
</li>',*/
|
||||
link: function($scope, $element, $attr, list) {
|
||||
// Grab the parent list controller
|
||||
if(list[0]) {
|
||||
@ -611,6 +626,13 @@ angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
list = list[1];
|
||||
}
|
||||
|
||||
// Add the list item type class
|
||||
$element.addClass($attr.type || 'item-slider');
|
||||
|
||||
if($attr.type !== 'item-slider') {
|
||||
$scope.canSwipe = false;
|
||||
}
|
||||
|
||||
$scope.isEditing = false;
|
||||
$scope.deleteIcon = list.scope.deleteIcon;
|
||||
$scope.reorderIcon = list.scope.reorderIcon;
|
||||
@ -647,6 +669,7 @@ angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
isEditing: '=',
|
||||
deleteIcon: '@',
|
||||
reorderIcon: '@',
|
||||
hasPullToRefresh: '@',
|
||||
onRefresh: '&',
|
||||
onRefreshOpening: '&'
|
||||
},
|
||||
@ -669,12 +692,14 @@ angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
var lv = new ionic.views.ListView({
|
||||
el: $element[0],
|
||||
listEl: $element[0].children[0],
|
||||
hasPullToRefresh: (typeof $scope.onRefresh !== 'undefined'),
|
||||
hasPullToRefresh: ($scope.hasPullToRefresh !== 'false'),
|
||||
onRefresh: function() {
|
||||
$scope.onRefresh();
|
||||
$scope.$parent.$broadcast('onRefresh');
|
||||
},
|
||||
onRefreshOpening: function(amt) {
|
||||
$scope.onRefreshOpening({amount: amt});
|
||||
$scope.$parent.$broadcast('onRefreshOpening', amt);
|
||||
}
|
||||
});
|
||||
|
||||
@ -723,6 +748,31 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
|
||||
angular.extend(this, ionic.controllers.NavController.prototype);
|
||||
|
||||
/**
|
||||
* Push a template onto the navigation stack.
|
||||
* @param {string} templateUrl the URL of the template to load.
|
||||
*/
|
||||
this.pushFromTemplate = ionic.debounce(function(templateUrl) {
|
||||
var childScope = $scope.$new();
|
||||
childScope.isVisible = true;
|
||||
|
||||
// Load the given template
|
||||
TemplateLoader.load(templateUrl).then(function(templateString) {
|
||||
|
||||
// Compile the template with the new scrope, and append it to the navigation's content area
|
||||
var el = $compile(templateString)(childScope, function(cloned, scope) {
|
||||
var content = angular.element($element[0].querySelector('.content, .scroll'));
|
||||
$animate.enter(cloned, angular.element(content));
|
||||
});
|
||||
});
|
||||
}, 300, true);
|
||||
|
||||
// Pop function, debounced
|
||||
this.popController = ionic.debounce(function() {
|
||||
_this.pop();
|
||||
}, 300, true);
|
||||
|
||||
|
||||
ionic.controllers.NavController.call(this, {
|
||||
content: {
|
||||
},
|
||||
@ -746,7 +796,7 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
// Support Android hardware back button (native only, not mobile web)
|
||||
var onHardwareBackButton = function(e) {
|
||||
$scope.$apply(function() {
|
||||
_this.pop();
|
||||
_this.popController();
|
||||
});
|
||||
}
|
||||
Platform.onHardwareBackButton(onHardwareBackButton);
|
||||
@ -759,28 +809,6 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
this.endDrag = function(e) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Push a template onto the navigation stack.
|
||||
* @param {string} templateUrl the URL of the template to load.
|
||||
*/
|
||||
this.pushFromTemplate = function(templateUrl) {
|
||||
var childScope = $scope.$new();
|
||||
childScope.isVisible = true;
|
||||
|
||||
// Load the given template
|
||||
TemplateLoader.load(templateUrl).then(function(templateString) {
|
||||
|
||||
// Compile the template with the new scrope, and append it to the navigation's content area
|
||||
var el = $compile(templateString)(childScope, function(cloned, scope) {
|
||||
var content = angular.element($element[0].querySelector('.content'));
|
||||
|
||||
//content.append(cloned);
|
||||
//angular.element(content).append(cloned);
|
||||
$animate.enter(cloned, angular.element(content));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Push a controller to the stack. This is called by the child
|
||||
* nav-content directive when it is linked to a scope on the page.
|
||||
@ -827,7 +855,7 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
scope.$watch('navController.controllers.length', function(value) {
|
||||
});
|
||||
scope.goBack = function() {
|
||||
navCtrl.pop();
|
||||
navCtrl.popController();
|
||||
};
|
||||
}
|
||||
};
|
||||
@ -884,7 +912,7 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
|
||||
// Store that we should go forwards on the animation. This toggles
|
||||
// based on the visibility sequence (to support reverse transitions)
|
||||
var wasVisible = null;
|
||||
var lastDirection = null;
|
||||
|
||||
$scope.title = $attr.title;
|
||||
$scope.pushAnimation = $attr.pushAnimation || 'slide-in-left';
|
||||
@ -900,6 +928,24 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
navCtrl.showNavBar();
|
||||
}
|
||||
|
||||
$scope.visibilityChanged = function(direction) {
|
||||
lastDirection = direction;
|
||||
|
||||
if(!childElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
var clone = childElement;
|
||||
|
||||
if(direction == 'push') {
|
||||
clone.addClass(childScope.pushAnimation);
|
||||
clone.removeClass(childScope.popAnimation);
|
||||
} else if(direction == 'pop') {
|
||||
clone.addClass(childScope.popAnimation);
|
||||
clone.removeClass(childScope.pushAnimation);
|
||||
}
|
||||
};
|
||||
|
||||
// Push this controller onto the stack
|
||||
$scope.pushController($scope, $element);
|
||||
|
||||
@ -911,39 +957,33 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
transclude(childScope, function(clone) {
|
||||
childElement = clone;
|
||||
|
||||
// Check if this is visible, and if so, create it and show it
|
||||
if(wasVisible === false) {
|
||||
clone.removeClass(childScope.pushAnimation);
|
||||
clone.addClass(childScope.popAnimation);
|
||||
} else {
|
||||
if(lastDirection == 'push') {
|
||||
clone.addClass(childScope.pushAnimation);
|
||||
clone.removeClass(childScope.popAnimation);
|
||||
} else if(lastDirection == 'pop') {
|
||||
clone.addClass(childScope.popAnimation);
|
||||
}
|
||||
|
||||
$animate.enter(clone, $element.parent(), $element);
|
||||
wasVisible = true;
|
||||
$animate.enter(clone, $element.parent(), $element, function() {
|
||||
clone.removeClass(childScope.pushAnimation);
|
||||
clone.removeClass(childScope.popAnimation);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Taken from ngIf
|
||||
if(childElement) {
|
||||
var clone = childElement;
|
||||
// Check if this is visible, and if so, create it and show it
|
||||
if(wasVisible === false) {
|
||||
clone.removeClass(childScope.pushAnimation);
|
||||
clone.addClass(childScope.popAnimation);
|
||||
} else {
|
||||
clone.addClass(childScope.pushAnimation);
|
||||
clone.removeClass(childScope.popAnimation);
|
||||
$animate.leave(childElement, function() {
|
||||
if(childScope) {
|
||||
childElement.removeClass(childScope.pushAnimation);
|
||||
childElement.removeClass(childScope.popAnimation);
|
||||
}
|
||||
$animate.leave(childElement);
|
||||
});
|
||||
childElement = undefined;
|
||||
wasVisible = false;
|
||||
}
|
||||
if(childScope) {
|
||||
childScope.$destroy();
|
||||
childScope = undefined;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -975,27 +1015,18 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture'])
|
||||
angular.extend(this, ionic.controllers.SideMenuController.prototype);
|
||||
|
||||
ionic.controllers.SideMenuController.call(this, {
|
||||
// Our quick implementation of the left side menu
|
||||
left: {
|
||||
width: 270,
|
||||
pushDown: function() {
|
||||
$scope.leftZIndex = -1;
|
||||
},
|
||||
bringUp: function() {
|
||||
$scope.leftZIndex = 0;
|
||||
}
|
||||
},
|
||||
|
||||
// Our quick implementation of the right side menu
|
||||
right: {
|
||||
width: 270,
|
||||
pushDown: function() {
|
||||
$scope.rightZIndex = -1;
|
||||
},
|
||||
bringUp: function() {
|
||||
$scope.rightZIndex = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$scope.contentTranslateX = 0;
|
||||
$scope.sideMenuContentTranslateX = 0;
|
||||
|
||||
$scope.sideMenuCtrl = this;
|
||||
})
|
||||
@ -1027,28 +1058,32 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture'])
|
||||
defaultPrevented = e.defaultPrevented;
|
||||
});
|
||||
|
||||
Gesture.on('drag', function(e) {
|
||||
var dragFn = function(e) {
|
||||
if(defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
sideMenuCtrl._handleDrag(e);
|
||||
}, $element[0]);
|
||||
};
|
||||
|
||||
Gesture.on('release', function(e) {
|
||||
Gesture.on('drag', dragFn, $element[0]);
|
||||
|
||||
var dragReleaseFn = function(e) {
|
||||
if(!defaultPrevented) {
|
||||
sideMenuCtrl._endDrag(e);
|
||||
}
|
||||
defaultPrevented = false;
|
||||
}, $element[0]);
|
||||
};
|
||||
|
||||
Gesture.on('release', dragReleaseFn, $element[0]);
|
||||
|
||||
sideMenuCtrl.setContent({
|
||||
onDrag: function(e) {},
|
||||
endDrag: function(e) {},
|
||||
getTranslateX: function() {
|
||||
return $scope.contentTranslateX || 0;
|
||||
return $scope.sideMenuContentTranslateX || 0;
|
||||
},
|
||||
setTranslateX: function(amount) {
|
||||
$scope.contentTranslateX = amount;
|
||||
$scope.sideMenuContentTranslateX = amount;
|
||||
$element[0].style.webkitTransform = 'translate3d(' + amount + 'px, 0, 0)';
|
||||
},
|
||||
enableAnimation: function() {
|
||||
@ -1062,6 +1097,12 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture'])
|
||||
$element[0].classList.remove('menu-animated');
|
||||
}
|
||||
});
|
||||
|
||||
// Cleanup
|
||||
$scope.$on('$destroy', function() {
|
||||
Gesture.off('drag', dragFn);
|
||||
Gesture.off('release', dragReleaseFn);
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
@ -1080,10 +1121,23 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture'])
|
||||
return function($scope, $element, $attr, sideMenuCtrl) {
|
||||
$scope.side = $attr.side;
|
||||
|
||||
|
||||
if($scope.side == 'left') {
|
||||
sideMenuCtrl.left.isEnabled = true;
|
||||
sideMenuCtrl.left.pushDown = function() {
|
||||
$element[0].style.zIndex = -1;
|
||||
};
|
||||
sideMenuCtrl.left.bringUp = function() {
|
||||
$element[0].style.zIndex = 0;
|
||||
};
|
||||
} else if($scope.side == 'right') {
|
||||
sideMenuCtrl.right.isEnabled = true;
|
||||
sideMenuCtrl.right.pushDown = function() {
|
||||
$element[0].style.zIndex = -1;
|
||||
};
|
||||
sideMenuCtrl.right.bringUp = function() {
|
||||
$element[0].style.zIndex = 0;
|
||||
};
|
||||
}
|
||||
|
||||
$element.append(transclude($scope));
|
||||
|
||||
177
dist/js/ionic.js
vendored
177
dist/js/ionic.js
vendored
@ -8,6 +8,8 @@ http://ionicframework.com/
|
||||
By @maxlynch, @helloimben, @adamdbradley <3
|
||||
|
||||
Licensed under the MIT license. Please see LICENSE for more information.
|
||||
|
||||
Make awesome shit.
|
||||
*/
|
||||
;
|
||||
|
||||
@ -1835,7 +1837,58 @@ window.ionic = {
|
||||
;
|
||||
(function(ionic) {
|
||||
|
||||
/**
|
||||
* Various utilities used throughout Ionic
|
||||
*
|
||||
* Some of these are adopted from underscore.js and backbone.js, both also MIT licensed.
|
||||
*/
|
||||
ionic.Utils = {
|
||||
|
||||
/**
|
||||
* Return a function that will be called with the given context
|
||||
*/
|
||||
proxy: function(func, context) {
|
||||
var args = Array.prototype.slice.call(arguments, 2);
|
||||
return function() {
|
||||
return func.apply(context, args.concat(Array.prototype.slice.call(arguments)));
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Only call a function once in the given interval.
|
||||
*
|
||||
* @param func {Function} the function to call
|
||||
* @param wait {int} how long to wait before/after to allow function calls
|
||||
* @param immediate {boolean} whether to call immediately or after the wait interval
|
||||
*/
|
||||
debounce: function(func, wait, immediate) {
|
||||
var timeout, args, context, timestamp, result;
|
||||
return function() {
|
||||
context = this;
|
||||
args = arguments;
|
||||
timestamp = new Date();
|
||||
var later = function() {
|
||||
var last = (new Date()) - timestamp;
|
||||
if (last < wait) {
|
||||
timeout = setTimeout(later, wait - last);
|
||||
} else {
|
||||
timeout = null;
|
||||
if (!immediate) result = func.apply(context, args);
|
||||
}
|
||||
};
|
||||
var callNow = immediate && !timeout;
|
||||
if (!timeout) {
|
||||
timeout = setTimeout(later, wait);
|
||||
}
|
||||
if (callNow) result = func.apply(context, args);
|
||||
return result;
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Throttle the given fun, only allowing it to be
|
||||
* called at most every `wait` ms.
|
||||
*/
|
||||
throttle: function(func, wait, options) {
|
||||
var context, args, result;
|
||||
var timeout = null;
|
||||
@ -1915,9 +1968,12 @@ window.ionic = {
|
||||
}
|
||||
};
|
||||
|
||||
// Bind a few of the most useful functions to the ionic scope
|
||||
ionic.inherit = ionic.Utils.inherit;
|
||||
ionic.extend = ionic.Utils.extend;
|
||||
ionic.throttle = ionic.Utils.throttle;
|
||||
ionic.proxy = ionic.Utils.proxy;
|
||||
ionic.debounce = ionic.Utils.debounce;
|
||||
|
||||
})(window.ionic);
|
||||
;
|
||||
@ -1977,7 +2033,7 @@ window.ionic = {
|
||||
dragThreshold: 10,
|
||||
|
||||
// Resistance when scrolling too far up or down
|
||||
rubberBandResistance: 3,
|
||||
rubberBandResistance: 2,
|
||||
|
||||
// Scroll event names. These are custom so can be configured
|
||||
scrollEventName: 'momentumScrolled',
|
||||
@ -1985,6 +2041,10 @@ window.ionic = {
|
||||
|
||||
hasPullToRefresh: true,
|
||||
|
||||
// Whether to disable overflow rubber banding when content is small
|
||||
// enough to fit in the viewport (i.e. doesn't need scrolling)
|
||||
disableNonOverflowRubberBand: false,
|
||||
|
||||
// Called as the refresher is opened, an amount is passed
|
||||
onRefreshOpening: function() {},
|
||||
// Called when let go and is refreshing
|
||||
@ -2178,6 +2238,10 @@ window.ionic = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the current scroll bounds needs to be brought back to the min/max
|
||||
* allowable given the total scrollable area.
|
||||
*/
|
||||
needsWrapping: function() {
|
||||
var _this = this;
|
||||
|
||||
@ -2400,14 +2464,6 @@ window.ionic = {
|
||||
var parentWidth = this.el.parentNode.offsetWidth;
|
||||
var parentHeight = this.el.parentNode.offsetHeight;
|
||||
|
||||
var maxX = Math.min(0, (-totalWidth + parentWidth));
|
||||
var maxY = Math.min(0, (-totalHeight + parentHeight));
|
||||
|
||||
// Check if we even have enough content to scroll, if not, don't start the drag
|
||||
if((this.isHorizontalEnabled && maxX == 0) || (this.isVerticalEnabled && maxY == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.x = scrollLeft;
|
||||
this.y = scrollTop;
|
||||
|
||||
@ -2444,6 +2500,16 @@ window.ionic = {
|
||||
resist: 1,
|
||||
startTime: Date.now()
|
||||
};
|
||||
|
||||
if(this.disableNonOverflowRubberBand === true) {
|
||||
var maxX = Math.min(0, (-totalWidth + parentWidth));
|
||||
var maxY = Math.min(0, (-totalHeight + parentHeight));
|
||||
|
||||
// Check if we even have enough content to scroll, if not, don't start the drag
|
||||
if((this.isHorizontalEnabled && maxX == 0) || (this.isVerticalEnabled && maxY == 0)) {
|
||||
this._drag.noRubberBand = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2511,10 +2577,23 @@ window.ionic = {
|
||||
var newX = _this.x + deltaX;
|
||||
var newY = _this.y + deltaY;
|
||||
|
||||
if(drag.noRubberBand === true) {
|
||||
if(newY > 0) {
|
||||
newY = 0;
|
||||
} else if(newY < maxY) {
|
||||
newY = maxY;
|
||||
}
|
||||
if(newX > 0) {
|
||||
newX = 0;
|
||||
} else if(newX < maxX) {
|
||||
newX = maxX;
|
||||
}
|
||||
} else {
|
||||
// Check if the dragging is beyond the bottom or top
|
||||
if(newY > 0 || (-newY + parentHeight) > totalHeight) {
|
||||
newY = _this.y + deltaY / _this.rubberBandResistance;
|
||||
}
|
||||
}
|
||||
|
||||
if(!_this.isHorizontalEnabled) {
|
||||
newX = 0;
|
||||
@ -2525,7 +2604,6 @@ window.ionic = {
|
||||
|
||||
if(_this._refresher && newY > 0) {
|
||||
// We are pulling to refresh, so update the refresher
|
||||
//_this._refresher.style[ionic.CSS.TRANSFORM] = 'translate3d(0, ' + newY + 'px, 0)';
|
||||
if(_this._isRefresherHidden) {
|
||||
// Show it only in a drag and if we haven't showed it yet
|
||||
_this._refresher.style.display = 'block';
|
||||
@ -2542,7 +2620,7 @@ window.ionic = {
|
||||
}
|
||||
|
||||
// Update the new translated Y point of the container
|
||||
_this.el.style.webkitTransform = 'translate3d(' + newX + 'px,' + newY + 'px, 0)';
|
||||
_this.el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + newX + 'px,' + newY + 'px, 0)';
|
||||
} else {
|
||||
|
||||
_this._isHoldingRefresh = false;
|
||||
@ -2553,7 +2631,7 @@ window.ionic = {
|
||||
_this._isRefresherHidden = true;
|
||||
}
|
||||
// Update the new translated Y point of the container
|
||||
_this.el.style.webkitTransform = 'translate3d(' + newX + 'px,' + newY + 'px, 0)';
|
||||
_this.el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + newX + 'px,' + newY + 'px, 0)';
|
||||
}
|
||||
|
||||
// Store the last points
|
||||
@ -3165,8 +3243,6 @@ window.ionic = {
|
||||
|
||||
this._isDragging = false;
|
||||
|
||||
console.log(e.gesture.direction);
|
||||
|
||||
// Check if this is a reorder drag
|
||||
if(ionic.DomUtil.getParentOrSelfWithClass(e.target, ITEM_DRAG_CLASS) && (e.gesture.direction == 'up' || e.gesture.direction == 'down')) {
|
||||
var item = this._getItem(e.target);
|
||||
@ -3467,6 +3543,39 @@ window.ionic = {
|
||||
}
|
||||
});
|
||||
|
||||
ionic.views.SideMenuContent = ionic.views.View.inherit({
|
||||
initialize: function(opts) {
|
||||
var _this = this;
|
||||
|
||||
ionic.extend(this, {
|
||||
animationClass: 'menu-animated',
|
||||
onDrag: function(e) {},
|
||||
onEndDrag: function(e) {},
|
||||
}, opts);
|
||||
|
||||
ionic.onGesture('drag', ionic.proxy(this._onDrag, this), this.el);
|
||||
ionic.onGesture('release', ionic.proxy(this._onEndDrag, this), this.el);
|
||||
},
|
||||
_onDrag: function(e) {
|
||||
this.onDrag && this.onDrag(e);
|
||||
},
|
||||
_onEndDrag: function(e) {
|
||||
this.onEndDrag && this.onEndDrag(e);
|
||||
},
|
||||
disableAnimation: function() {
|
||||
this.el.classList.remove(this.animationClass);
|
||||
},
|
||||
enableAnimation: function() {
|
||||
this.el.classList.add(this.animationClass);
|
||||
},
|
||||
getTranslateX: function() {
|
||||
return parseFloat(this.el.style.webkitTransform.replace('translate3d(', '').split(',')[0]);
|
||||
},
|
||||
setTranslateX: function(x) {
|
||||
this.el.style.webkitTransform = 'translate3d(' + x + 'px, 0, 0)';
|
||||
}
|
||||
});
|
||||
|
||||
})(ionic);
|
||||
;
|
||||
/**
|
||||
@ -4142,21 +4251,17 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({
|
||||
return;
|
||||
|
||||
// Actually switch the active controllers
|
||||
|
||||
// Remove the old one
|
||||
//last && last.detach();
|
||||
if(last) {
|
||||
last.isVisible = false;
|
||||
last.visibilityChanged && last.visibilityChanged();
|
||||
last.visibilityChanged && last.visibilityChanged('push');
|
||||
}
|
||||
|
||||
// Grab the top controller on the stack
|
||||
var next = this.controllers[this.controllers.length - 1];
|
||||
|
||||
// TODO: No DOM stuff here
|
||||
//this.content.el.appendChild(next.el);
|
||||
next.isVisible = true;
|
||||
next.visibilityChanged && next.visibilityChanged();
|
||||
// Trigger visibility change, but send 'first' if this is the first page
|
||||
next.visibilityChanged && next.visibilityChanged(last ? 'push' : 'first');
|
||||
|
||||
this._updateNavBar();
|
||||
|
||||
@ -4181,7 +4286,7 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({
|
||||
last = this.controllers.pop();
|
||||
if(last) {
|
||||
last.isVisible = false;
|
||||
last.visibilityChanged && last.visibilityChanged();
|
||||
last.visibilityChanged && last.visibilityChanged('pop');
|
||||
}
|
||||
|
||||
// Remove the old one
|
||||
@ -4192,7 +4297,7 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({
|
||||
// TODO: No DOM stuff here
|
||||
//this.content.el.appendChild(next.el);
|
||||
next.isVisible = true;
|
||||
next.visibilityChanged && next.visibilityChanged();
|
||||
next.visibilityChanged && next.visibilityChanged('pop');
|
||||
|
||||
// Switch to it (TODO: Animate or such things here)
|
||||
|
||||
@ -4264,7 +4369,7 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({
|
||||
self._handleDrag(e);
|
||||
};
|
||||
|
||||
this.content.endDrag = function(e) {
|
||||
this.content.onEndDrag =function(e) {
|
||||
self._endDrag(e);
|
||||
};
|
||||
}
|
||||
@ -4354,12 +4459,12 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({
|
||||
*/
|
||||
openPercentage: function(percentage) {
|
||||
var p = percentage / 100;
|
||||
var maxLeft = this.left.width;
|
||||
|
||||
if(this.left && percentage >= 0) {
|
||||
this.openAmount(this.left.width * p);
|
||||
} else if(this.right && percentage < 0) {
|
||||
var maxRight = this.right.width;
|
||||
if(percentage >= 0) {
|
||||
this.openAmount(maxLeft * p);
|
||||
} else {
|
||||
this.openAmount(maxRight * p);
|
||||
this.openAmount(this.right.width * p);
|
||||
}
|
||||
},
|
||||
|
||||
@ -4369,11 +4474,11 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({
|
||||
* negative value for right menu (only one menu will be visible at a time).
|
||||
*/
|
||||
openAmount: function(amount) {
|
||||
var maxLeft = this.left.width;
|
||||
var maxRight = this.right.width;
|
||||
var maxLeft = this.left && this.left.width || 0;
|
||||
var maxRight = this.right && this.right.width || 0;
|
||||
|
||||
// Check if we can move to that side, depending if the left/right panel is enabled
|
||||
if((!this.left.isEnabled && amount > 0) || (!this.right.isEnabled && amount < 0)) {
|
||||
if((!(this.left && this.left.isEnabled) && amount > 0) || (!(this.right && this.right.isEnabled) && amount < 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4388,17 +4493,17 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({
|
||||
this._rightShowing = false;
|
||||
|
||||
// Push the z-index of the right menu down
|
||||
this.right.pushDown();
|
||||
this.right && this.right.pushDown();
|
||||
// Bring the z-index of the left menu up
|
||||
this.left.bringUp();
|
||||
this.left && this.left.bringUp();
|
||||
} else {
|
||||
this._rightShowing = true;
|
||||
this._leftShowing = false;
|
||||
|
||||
// Bring the z-index of the right menu up
|
||||
this.right.bringUp();
|
||||
this.right && this.right.bringUp();
|
||||
// Push the z-index of the left menu down
|
||||
this.left.pushDown();
|
||||
this.left && this.left.pushDown();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -8,4 +8,6 @@ http://ionicframework.com/
|
||||
By @maxlynch, @helloimben, @adamdbradley <3
|
||||
|
||||
Licensed under the MIT license. Please see LICENSE for more information.
|
||||
|
||||
Make awesome shit.
|
||||
*/
|
||||
|
||||
@ -60,21 +60,17 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({
|
||||
return;
|
||||
|
||||
// Actually switch the active controllers
|
||||
|
||||
// Remove the old one
|
||||
//last && last.detach();
|
||||
if(last) {
|
||||
last.isVisible = false;
|
||||
last.visibilityChanged && last.visibilityChanged();
|
||||
last.visibilityChanged && last.visibilityChanged('push');
|
||||
}
|
||||
|
||||
// Grab the top controller on the stack
|
||||
var next = this.controllers[this.controllers.length - 1];
|
||||
|
||||
// TODO: No DOM stuff here
|
||||
//this.content.el.appendChild(next.el);
|
||||
next.isVisible = true;
|
||||
next.visibilityChanged && next.visibilityChanged();
|
||||
// Trigger visibility change, but send 'first' if this is the first page
|
||||
next.visibilityChanged && next.visibilityChanged(last ? 'push' : 'first');
|
||||
|
||||
this._updateNavBar();
|
||||
|
||||
@ -99,7 +95,7 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({
|
||||
last = this.controllers.pop();
|
||||
if(last) {
|
||||
last.isVisible = false;
|
||||
last.visibilityChanged && last.visibilityChanged();
|
||||
last.visibilityChanged && last.visibilityChanged('pop');
|
||||
}
|
||||
|
||||
// Remove the old one
|
||||
@ -110,7 +106,7 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({
|
||||
// TODO: No DOM stuff here
|
||||
//this.content.el.appendChild(next.el);
|
||||
next.isVisible = true;
|
||||
next.visibilityChanged && next.visibilityChanged();
|
||||
next.visibilityChanged && next.visibilityChanged('pop');
|
||||
|
||||
// Switch to it (TODO: Animate or such things here)
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
self._handleDrag(e);
|
||||
};
|
||||
|
||||
this.content.endDrag = function(e) {
|
||||
this.content.onEndDrag =function(e) {
|
||||
self._endDrag(e);
|
||||
};
|
||||
}
|
||||
@ -115,12 +115,12 @@
|
||||
*/
|
||||
openPercentage: function(percentage) {
|
||||
var p = percentage / 100;
|
||||
var maxLeft = this.left.width;
|
||||
|
||||
if(this.left && percentage >= 0) {
|
||||
this.openAmount(this.left.width * p);
|
||||
} else if(this.right && percentage < 0) {
|
||||
var maxRight = this.right.width;
|
||||
if(percentage >= 0) {
|
||||
this.openAmount(maxLeft * p);
|
||||
} else {
|
||||
this.openAmount(maxRight * p);
|
||||
this.openAmount(this.right.width * p);
|
||||
}
|
||||
},
|
||||
|
||||
@ -130,11 +130,11 @@
|
||||
* negative value for right menu (only one menu will be visible at a time).
|
||||
*/
|
||||
openAmount: function(amount) {
|
||||
var maxLeft = this.left.width;
|
||||
var maxRight = this.right.width;
|
||||
var maxLeft = this.left && this.left.width || 0;
|
||||
var maxRight = this.right && this.right.width || 0;
|
||||
|
||||
// Check if we can move to that side, depending if the left/right panel is enabled
|
||||
if((!this.left.isEnabled && amount > 0) || (!this.right.isEnabled && amount < 0)) {
|
||||
if((!(this.left && this.left.isEnabled) && amount > 0) || (!(this.right && this.right.isEnabled) && amount < 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -149,17 +149,17 @@
|
||||
this._rightShowing = false;
|
||||
|
||||
// Push the z-index of the right menu down
|
||||
this.right.pushDown();
|
||||
this.right && this.right.pushDown();
|
||||
// Bring the z-index of the left menu up
|
||||
this.left.bringUp();
|
||||
this.left && this.left.bringUp();
|
||||
} else {
|
||||
this._rightShowing = true;
|
||||
this._leftShowing = false;
|
||||
|
||||
// Bring the z-index of the right menu up
|
||||
this.right.bringUp();
|
||||
this.right && this.right.bringUp();
|
||||
// Push the z-index of the left menu down
|
||||
this.left.pushDown();
|
||||
this.left && this.left.pushDown();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
32
js/ext/angular/src/directive/ionicContent.js
vendored
32
js/ext/angular/src/directive/ionicContent.js
vendored
@ -76,9 +76,37 @@ angular.module('ionic.ui.content', [])
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
template: '<div class="scroll-refresher"><div class="scroll-refresher-content" ng-transclude></div></div>'
|
||||
require: ['^?content', '^?list'],
|
||||
template: '<div class="scroll-refresher"><div class="ionic-refresher-content"><div class="ionic-refresher"></div></div></div>',
|
||||
scope: true,
|
||||
link: function($scope, $element, $attr, scrollCtrl) {
|
||||
var icon = $element[0].querySelector('.ionic-refresher');
|
||||
|
||||
// Scale up the refreshing icon
|
||||
var onRefreshOpening = ionic.throttle(function(e, amt) {
|
||||
icon.style[ionic.CSS.TRANSFORM] = 'scale(' + Math.min((1 + amt), 2) + ')';
|
||||
}, 100);
|
||||
|
||||
$scope.$on('onRefreshing', function(e) {
|
||||
icon.style[ionic.CSS.TRANSFORM] = 'scale(2)';
|
||||
});
|
||||
|
||||
$scope.$on('onRefresh', function(e) {
|
||||
icon.style[ionic.CSS.TRANSFORM] = 'scale(1)';
|
||||
});
|
||||
$scope.$on('onRefreshOpening', onRefreshOpening);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.directive('scroll-refresher', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
template: '<div class="scroll-refresher"><div class="scroll-refresher-content"></div></div>'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
})();
|
||||
|
||||
33
js/ext/angular/src/directive/ionicList.js
vendored
33
js/ext/angular/src/directive/ionicList.js
vendored
@ -3,10 +3,10 @@
|
||||
|
||||
angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
|
||||
.directive('listItem', ['$timeout', function($timeout) {
|
||||
.directive('item', ['$timeout', function($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: ['?^list', '?^virtualList'],
|
||||
require: ['?^list'],
|
||||
replace: true,
|
||||
transclude: true,
|
||||
scope: {
|
||||
@ -17,8 +17,9 @@ angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
canReorder: '@',
|
||||
canSwipe: '@',
|
||||
buttons: '=',
|
||||
type: '@'
|
||||
},
|
||||
template: '<a href="#" class="item item-slider">\
|
||||
template: '<a href="#" class="item">\
|
||||
<div class="item-edit" ng-if="canDelete && isEditing">\
|
||||
<button class="button button-icon" ng-click="onDelete()"><i ng-class="deleteIcon"></i></button>\
|
||||
</div>\
|
||||
@ -32,20 +33,6 @@ angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
</div>\
|
||||
</a>',
|
||||
|
||||
/*
|
||||
template: '<li class="list-item">\
|
||||
<div class="list-item-edit" ng-if="canDelete && isEditing">\
|
||||
<button class="button button-icon" ng-click="onDelete()"><i ng-class="deleteIcon"></i></button>\
|
||||
</div>\
|
||||
<div class="list-item-content" ng-transclude>\
|
||||
</div>\
|
||||
<div class="list-item-drag" ng-if="canReorder && isEditing">\
|
||||
<button data-ionic-action="reorder" class="button button-icon"><i ng-class="reorderIcon"></i></button>\
|
||||
</div>\
|
||||
<div class="list-item-buttons" ng-if="canSwipe && !isEditing">\
|
||||
<button ng-click="buttonClicked(button)" class="button" ng-class="button.type" ng-repeat="button in buttons">{{button.text}}</button>\
|
||||
</div>\
|
||||
</li>',*/
|
||||
link: function($scope, $element, $attr, list) {
|
||||
// Grab the parent list controller
|
||||
if(list[0]) {
|
||||
@ -54,6 +41,13 @@ angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
list = list[1];
|
||||
}
|
||||
|
||||
// Add the list item type class
|
||||
$element.addClass($attr.type || 'item-slider');
|
||||
|
||||
if($attr.type !== 'item-slider') {
|
||||
$scope.canSwipe = false;
|
||||
}
|
||||
|
||||
$scope.isEditing = false;
|
||||
$scope.deleteIcon = list.scope.deleteIcon;
|
||||
$scope.reorderIcon = list.scope.reorderIcon;
|
||||
@ -90,6 +84,7 @@ angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
isEditing: '=',
|
||||
deleteIcon: '@',
|
||||
reorderIcon: '@',
|
||||
hasPullToRefresh: '@',
|
||||
onRefresh: '&',
|
||||
onRefreshOpening: '&'
|
||||
},
|
||||
@ -112,12 +107,14 @@ angular.module('ionic.ui.list', ['ngAnimate'])
|
||||
var lv = new ionic.views.ListView({
|
||||
el: $element[0],
|
||||
listEl: $element[0].children[0],
|
||||
hasPullToRefresh: (typeof $scope.onRefresh !== 'undefined'),
|
||||
hasPullToRefresh: ($scope.hasPullToRefresh !== 'false'),
|
||||
onRefresh: function() {
|
||||
$scope.onRefresh();
|
||||
$scope.$parent.$broadcast('onRefresh');
|
||||
},
|
||||
onRefreshOpening: function(amt) {
|
||||
$scope.onRefreshOpening({amount: amt});
|
||||
$scope.$parent.$broadcast('onRefreshOpening', amt);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
101
js/ext/angular/src/directive/ionicNav.js
vendored
101
js/ext/angular/src/directive/ionicNav.js
vendored
@ -8,6 +8,31 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
|
||||
angular.extend(this, ionic.controllers.NavController.prototype);
|
||||
|
||||
/**
|
||||
* Push a template onto the navigation stack.
|
||||
* @param {string} templateUrl the URL of the template to load.
|
||||
*/
|
||||
this.pushFromTemplate = ionic.debounce(function(templateUrl) {
|
||||
var childScope = $scope.$new();
|
||||
childScope.isVisible = true;
|
||||
|
||||
// Load the given template
|
||||
TemplateLoader.load(templateUrl).then(function(templateString) {
|
||||
|
||||
// Compile the template with the new scrope, and append it to the navigation's content area
|
||||
var el = $compile(templateString)(childScope, function(cloned, scope) {
|
||||
var content = angular.element($element[0].querySelector('.content, .scroll'));
|
||||
$animate.enter(cloned, angular.element(content));
|
||||
});
|
||||
});
|
||||
}, 300, true);
|
||||
|
||||
// Pop function, debounced
|
||||
this.popController = ionic.debounce(function() {
|
||||
_this.pop();
|
||||
}, 300, true);
|
||||
|
||||
|
||||
ionic.controllers.NavController.call(this, {
|
||||
content: {
|
||||
},
|
||||
@ -31,7 +56,7 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
// Support Android hardware back button (native only, not mobile web)
|
||||
var onHardwareBackButton = function(e) {
|
||||
$scope.$apply(function() {
|
||||
_this.pop();
|
||||
_this.popController();
|
||||
});
|
||||
}
|
||||
Platform.onHardwareBackButton(onHardwareBackButton);
|
||||
@ -44,28 +69,6 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
this.endDrag = function(e) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Push a template onto the navigation stack.
|
||||
* @param {string} templateUrl the URL of the template to load.
|
||||
*/
|
||||
this.pushFromTemplate = function(templateUrl) {
|
||||
var childScope = $scope.$new();
|
||||
childScope.isVisible = true;
|
||||
|
||||
// Load the given template
|
||||
TemplateLoader.load(templateUrl).then(function(templateString) {
|
||||
|
||||
// Compile the template with the new scrope, and append it to the navigation's content area
|
||||
var el = $compile(templateString)(childScope, function(cloned, scope) {
|
||||
var content = angular.element($element[0].querySelector('.content'));
|
||||
|
||||
//content.append(cloned);
|
||||
//angular.element(content).append(cloned);
|
||||
$animate.enter(cloned, angular.element(content));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Push a controller to the stack. This is called by the child
|
||||
* nav-content directive when it is linked to a scope on the page.
|
||||
@ -112,7 +115,7 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
scope.$watch('navController.controllers.length', function(value) {
|
||||
});
|
||||
scope.goBack = function() {
|
||||
navCtrl.pop();
|
||||
navCtrl.popController();
|
||||
};
|
||||
}
|
||||
};
|
||||
@ -169,7 +172,7 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
|
||||
// Store that we should go forwards on the animation. This toggles
|
||||
// based on the visibility sequence (to support reverse transitions)
|
||||
var wasVisible = null;
|
||||
var lastDirection = null;
|
||||
|
||||
$scope.title = $attr.title;
|
||||
$scope.pushAnimation = $attr.pushAnimation || 'slide-in-left';
|
||||
@ -185,6 +188,24 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
navCtrl.showNavBar();
|
||||
}
|
||||
|
||||
$scope.visibilityChanged = function(direction) {
|
||||
lastDirection = direction;
|
||||
|
||||
if(!childElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
var clone = childElement;
|
||||
|
||||
if(direction == 'push') {
|
||||
clone.addClass(childScope.pushAnimation);
|
||||
clone.removeClass(childScope.popAnimation);
|
||||
} else if(direction == 'pop') {
|
||||
clone.addClass(childScope.popAnimation);
|
||||
clone.removeClass(childScope.pushAnimation);
|
||||
}
|
||||
};
|
||||
|
||||
// Push this controller onto the stack
|
||||
$scope.pushController($scope, $element);
|
||||
|
||||
@ -196,39 +217,33 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
|
||||
transclude(childScope, function(clone) {
|
||||
childElement = clone;
|
||||
|
||||
// Check if this is visible, and if so, create it and show it
|
||||
if(wasVisible === false) {
|
||||
clone.removeClass(childScope.pushAnimation);
|
||||
clone.addClass(childScope.popAnimation);
|
||||
} else {
|
||||
if(lastDirection == 'push') {
|
||||
clone.addClass(childScope.pushAnimation);
|
||||
clone.removeClass(childScope.popAnimation);
|
||||
} else if(lastDirection == 'pop') {
|
||||
clone.addClass(childScope.popAnimation);
|
||||
}
|
||||
|
||||
$animate.enter(clone, $element.parent(), $element);
|
||||
wasVisible = true;
|
||||
$animate.enter(clone, $element.parent(), $element, function() {
|
||||
clone.removeClass(childScope.pushAnimation);
|
||||
clone.removeClass(childScope.popAnimation);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Taken from ngIf
|
||||
if(childElement) {
|
||||
var clone = childElement;
|
||||
// Check if this is visible, and if so, create it and show it
|
||||
if(wasVisible === false) {
|
||||
clone.removeClass(childScope.pushAnimation);
|
||||
clone.addClass(childScope.popAnimation);
|
||||
} else {
|
||||
clone.addClass(childScope.pushAnimation);
|
||||
clone.removeClass(childScope.popAnimation);
|
||||
$animate.leave(childElement, function() {
|
||||
if(childScope) {
|
||||
childElement.removeClass(childScope.pushAnimation);
|
||||
childElement.removeClass(childScope.popAnimation);
|
||||
}
|
||||
$animate.leave(childElement);
|
||||
});
|
||||
childElement = undefined;
|
||||
wasVisible = false;
|
||||
}
|
||||
if(childScope) {
|
||||
childScope.$destroy();
|
||||
childScope = undefined;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
52
js/ext/angular/src/directive/ionicSideMenu.js
vendored
52
js/ext/angular/src/directive/ionicSideMenu.js
vendored
@ -20,27 +20,18 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture'])
|
||||
angular.extend(this, ionic.controllers.SideMenuController.prototype);
|
||||
|
||||
ionic.controllers.SideMenuController.call(this, {
|
||||
// Our quick implementation of the left side menu
|
||||
left: {
|
||||
width: 270,
|
||||
pushDown: function() {
|
||||
$scope.leftZIndex = -1;
|
||||
},
|
||||
bringUp: function() {
|
||||
$scope.leftZIndex = 0;
|
||||
}
|
||||
},
|
||||
|
||||
// Our quick implementation of the right side menu
|
||||
right: {
|
||||
width: 270,
|
||||
pushDown: function() {
|
||||
$scope.rightZIndex = -1;
|
||||
},
|
||||
bringUp: function() {
|
||||
$scope.rightZIndex = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$scope.contentTranslateX = 0;
|
||||
$scope.sideMenuContentTranslateX = 0;
|
||||
|
||||
$scope.sideMenuCtrl = this;
|
||||
})
|
||||
@ -72,28 +63,32 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture'])
|
||||
defaultPrevented = e.defaultPrevented;
|
||||
});
|
||||
|
||||
Gesture.on('drag', function(e) {
|
||||
var dragFn = function(e) {
|
||||
if(defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
sideMenuCtrl._handleDrag(e);
|
||||
}, $element[0]);
|
||||
};
|
||||
|
||||
Gesture.on('release', function(e) {
|
||||
Gesture.on('drag', dragFn, $element[0]);
|
||||
|
||||
var dragReleaseFn = function(e) {
|
||||
if(!defaultPrevented) {
|
||||
sideMenuCtrl._endDrag(e);
|
||||
}
|
||||
defaultPrevented = false;
|
||||
}, $element[0]);
|
||||
};
|
||||
|
||||
Gesture.on('release', dragReleaseFn, $element[0]);
|
||||
|
||||
sideMenuCtrl.setContent({
|
||||
onDrag: function(e) {},
|
||||
endDrag: function(e) {},
|
||||
getTranslateX: function() {
|
||||
return $scope.contentTranslateX || 0;
|
||||
return $scope.sideMenuContentTranslateX || 0;
|
||||
},
|
||||
setTranslateX: function(amount) {
|
||||
$scope.contentTranslateX = amount;
|
||||
$scope.sideMenuContentTranslateX = amount;
|
||||
$element[0].style.webkitTransform = 'translate3d(' + amount + 'px, 0, 0)';
|
||||
},
|
||||
enableAnimation: function() {
|
||||
@ -107,6 +102,12 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture'])
|
||||
$element[0].classList.remove('menu-animated');
|
||||
}
|
||||
});
|
||||
|
||||
// Cleanup
|
||||
$scope.$on('$destroy', function() {
|
||||
Gesture.off('drag', dragFn);
|
||||
Gesture.off('release', dragReleaseFn);
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
@ -125,10 +126,23 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture'])
|
||||
return function($scope, $element, $attr, sideMenuCtrl) {
|
||||
$scope.side = $attr.side;
|
||||
|
||||
|
||||
if($scope.side == 'left') {
|
||||
sideMenuCtrl.left.isEnabled = true;
|
||||
sideMenuCtrl.left.pushDown = function() {
|
||||
$element[0].style.zIndex = -1;
|
||||
};
|
||||
sideMenuCtrl.left.bringUp = function() {
|
||||
$element[0].style.zIndex = 0;
|
||||
};
|
||||
} else if($scope.side == 'right') {
|
||||
sideMenuCtrl.right.isEnabled = true;
|
||||
sideMenuCtrl.right.pushDown = function() {
|
||||
$element[0].style.zIndex = -1;
|
||||
};
|
||||
sideMenuCtrl.right.bringUp = function() {
|
||||
$element[0].style.zIndex = 0;
|
||||
};
|
||||
}
|
||||
|
||||
$element.append(transclude($scope));
|
||||
|
||||
@ -64,19 +64,31 @@
|
||||
<body>
|
||||
|
||||
<div ng-controller="TestCtrl" class="reveal-animation scroll-content">
|
||||
<list is-editing="isEditingItems" on-refresh-holding="almostRefreshing()" on-refresh-opening="almostRefreshProjects(ratio)" on-refresh="refreshProjects()" animation="my-repeat-animation" delete-icon="icon ion-minus-circled" reorder-icon="icon ion-navicon">
|
||||
<list-refresher>
|
||||
</list-refresher>
|
||||
<list-item ng-repeat="item in items"
|
||||
<list is-editing="isEditingItems"
|
||||
on-refresh-holding="almostRefreshing()"
|
||||
on-refresh-opening="almostRefreshProjects(ratio)"
|
||||
on-refresh="refreshProjects()"
|
||||
animation="my-repeat-animation"
|
||||
delete-icon="icon ion-minus-circled"
|
||||
reorder-icon="icon ion-navicon">
|
||||
|
||||
<refresher>
|
||||
<div id="refresh-content">
|
||||
<i class="icon ion-ios7-reloading"></i>
|
||||
</div>
|
||||
</refresher>
|
||||
<item
|
||||
ng-repeat="item in items"
|
||||
buttons="item.buttons"
|
||||
can-delete="true"
|
||||
can-reorder="true"
|
||||
can-swipe="true"
|
||||
on-delete="deleteProject(project)"
|
||||
on-select="selectProject(project)">
|
||||
<i class="icon ion-email ion-primary"></i>
|
||||
{{item.text}}
|
||||
<i class="{{item.icon}}"></i>
|
||||
</list-item>
|
||||
</item>
|
||||
</list>
|
||||
<button ng-click="edit()" class="button button-success">Edit</button>
|
||||
</div>
|
||||
@ -86,32 +98,6 @@
|
||||
<script>
|
||||
angular.module('navTest', ['ionic.ui.list', 'ionic.ui.content', 'ngAnimate'])
|
||||
|
||||
.directive('spinner', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
scope: {
|
||||
ratio: '='
|
||||
},
|
||||
template: '<div class="spinner"><div class="spin-thing"></div></div>',
|
||||
link: function($scope, $element, $attr) {
|
||||
$scope.$watch('ratio', function(value) {
|
||||
if(value > 0.97) {
|
||||
value = 1;
|
||||
}
|
||||
|
||||
var a = (value * 360) % 360;
|
||||
var r = (a * Math.PI) / 180;
|
||||
var x = (Math.sin(r) * 20) + 14;
|
||||
var y = (Math.cos(r) * -20) + 14;
|
||||
|
||||
$element[0].firstElementChild.style.webkitTransform = 'translate3d(' + x + 'px, ' + y + 'px, 0)';
|
||||
//$element[0].firstElementChild.setAttribute('d', anim);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.controller('TestCtrl', function($scope) {
|
||||
$scope.refreshRatio = { ratio: 0 };
|
||||
var removeItem = function(item) {
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link href="/vendor/font-awesome/css/font-awesome.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="../../../../dist/css/ionic.css">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.3/angular.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.3/angular-touch.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.3/angular-animate.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-touch.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-animate.js"></script>
|
||||
<style>
|
||||
.view {
|
||||
position: fixed;
|
||||
@ -34,8 +34,10 @@
|
||||
<navs>
|
||||
<nav-bar></nav-bar>
|
||||
|
||||
<content has-header="true" ng-controller="AppCtrl">
|
||||
<div ng-controller="AppCtrl">
|
||||
<content has-header="true">
|
||||
</content>
|
||||
</div>
|
||||
</navs>
|
||||
|
||||
<script id="page.html" type="text/ng-template">
|
||||
@ -65,7 +67,7 @@
|
||||
|
||||
}
|
||||
|
||||
angular.module('navTest', ['ionic.ui.nav', 'ionic.ui.content', 'ionic.ui.list', 'ngAnimate'])
|
||||
angular.module('navTest', ['ionic', 'ngAnimate'])
|
||||
|
||||
.controller('AppCtrl', function($scope, $compile, $element) {
|
||||
$scope.navController.pushFromTemplate('page.html');
|
||||
|
||||
@ -16,24 +16,37 @@
|
||||
<div ng-controller="MenuCtrl">
|
||||
<side-menu>
|
||||
<pane side-menu-content>
|
||||
<header class="bar bar-header bar-dark">
|
||||
<button class="button" ng-click="openLeft()"><i class="icon-reorder"></i></button>
|
||||
<header class="bar bar-header bar-primary">
|
||||
<button class="button button-icon" ng-click="openLeft()"><i class="icon ion-navicon"></i></button>
|
||||
<h1 class="title">Slide me</h1>
|
||||
</header>
|
||||
<div class="content has-header">
|
||||
<h1>Slide me side to side!</h1>
|
||||
<h1>Content</h1>
|
||||
</div>
|
||||
</pane>
|
||||
<menu side="left">
|
||||
<h2>Left</h2>
|
||||
<header class="bar bar-header bar-primary">
|
||||
<h1 class="title">Left</h1>
|
||||
</header>
|
||||
<content has-header="true">
|
||||
<ul class="list">
|
||||
<a href="#" class="list-item" ng-repeat="item in list">
|
||||
<a href="#" class="item" ng-repeat="item in list">
|
||||
{{item.text}}
|
||||
</a>
|
||||
</ul>
|
||||
</content>
|
||||
</menu>
|
||||
<menu side="right">
|
||||
<h2>Items</h2>
|
||||
<header class="bar bar-header bar-primary">
|
||||
<h1 class="title">Right</h1>
|
||||
</header>
|
||||
<content has-header="true">
|
||||
<ul class="list">
|
||||
<a href="#" class="item" ng-repeat="item in list">
|
||||
{{item.text}}
|
||||
</a>
|
||||
</ul>
|
||||
</content>
|
||||
</menu>
|
||||
</side-menu>
|
||||
</div>
|
||||
@ -43,6 +56,12 @@
|
||||
angular.module('sideMenuTest', ['ionic'])
|
||||
|
||||
.controller('MenuCtrl', function($scope) {
|
||||
$scope.list = [];
|
||||
for(var i = 0; i < 20; i++) {
|
||||
$scope.list.push({
|
||||
text: 'Item ' + i
|
||||
});
|
||||
}
|
||||
$scope.openLeft = function() {
|
||||
$scope.sideMenuCtrl.toggleLeft();
|
||||
};
|
||||
|
||||
@ -60,7 +60,7 @@
|
||||
<h1 class="title">Tasks</h1>
|
||||
<button class="button button-clear button-primary" ng-click="isEditingItems = !isEditingItems">Edit</button>
|
||||
</header>
|
||||
<content has-header="true" has-tabs="true" scroll="false">
|
||||
<content has-header="true" has-footer="true" scroll="false">
|
||||
<list on-refresh="onRefresh()" is-editing="isEditingItems" animation="fade-out" delete-icon="icon ion-minus-circled" reorder-icon="icon ion-navicon">
|
||||
<refresher>
|
||||
<div id="refresh-content">
|
||||
@ -68,7 +68,7 @@
|
||||
<i class="icon ion-ios7-reloading"></i>
|
||||
</div>
|
||||
</refresher>
|
||||
<list-item ng-repeat="item in items"
|
||||
<item ng-repeat="item in items"
|
||||
item="item"
|
||||
buttons="item.buttons"
|
||||
can-delete="true"
|
||||
|
||||
@ -1,6 +1,57 @@
|
||||
(function(ionic) {
|
||||
|
||||
/**
|
||||
* Various utilities used throughout Ionic
|
||||
*
|
||||
* Some of these are adopted from underscore.js and backbone.js, both also MIT licensed.
|
||||
*/
|
||||
ionic.Utils = {
|
||||
|
||||
/**
|
||||
* Return a function that will be called with the given context
|
||||
*/
|
||||
proxy: function(func, context) {
|
||||
var args = Array.prototype.slice.call(arguments, 2);
|
||||
return function() {
|
||||
return func.apply(context, args.concat(Array.prototype.slice.call(arguments)));
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Only call a function once in the given interval.
|
||||
*
|
||||
* @param func {Function} the function to call
|
||||
* @param wait {int} how long to wait before/after to allow function calls
|
||||
* @param immediate {boolean} whether to call immediately or after the wait interval
|
||||
*/
|
||||
debounce: function(func, wait, immediate) {
|
||||
var timeout, args, context, timestamp, result;
|
||||
return function() {
|
||||
context = this;
|
||||
args = arguments;
|
||||
timestamp = new Date();
|
||||
var later = function() {
|
||||
var last = (new Date()) - timestamp;
|
||||
if (last < wait) {
|
||||
timeout = setTimeout(later, wait - last);
|
||||
} else {
|
||||
timeout = null;
|
||||
if (!immediate) result = func.apply(context, args);
|
||||
}
|
||||
};
|
||||
var callNow = immediate && !timeout;
|
||||
if (!timeout) {
|
||||
timeout = setTimeout(later, wait);
|
||||
}
|
||||
if (callNow) result = func.apply(context, args);
|
||||
return result;
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Throttle the given fun, only allowing it to be
|
||||
* called at most every `wait` ms.
|
||||
*/
|
||||
throttle: function(func, wait, options) {
|
||||
var context, args, result;
|
||||
var timeout = null;
|
||||
@ -80,8 +131,11 @@
|
||||
}
|
||||
};
|
||||
|
||||
// Bind a few of the most useful functions to the ionic scope
|
||||
ionic.inherit = ionic.Utils.inherit;
|
||||
ionic.extend = ionic.Utils.extend;
|
||||
ionic.throttle = ionic.Utils.throttle;
|
||||
ionic.proxy = ionic.Utils.proxy;
|
||||
ionic.debounce = ionic.Utils.debounce;
|
||||
|
||||
})(window.ionic);
|
||||
|
||||
@ -376,8 +376,6 @@
|
||||
|
||||
this._isDragging = false;
|
||||
|
||||
console.log(e.gesture.direction);
|
||||
|
||||
// Check if this is a reorder drag
|
||||
if(ionic.DomUtil.getParentOrSelfWithClass(e.target, ITEM_DRAG_CLASS) && (e.gesture.direction == 'up' || e.gesture.direction == 'down')) {
|
||||
var item = this._getItem(e.target);
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
dragThreshold: 10,
|
||||
|
||||
// Resistance when scrolling too far up or down
|
||||
rubberBandResistance: 3,
|
||||
rubberBandResistance: 2,
|
||||
|
||||
// Scroll event names. These are custom so can be configured
|
||||
scrollEventName: 'momentumScrolled',
|
||||
@ -48,6 +48,10 @@
|
||||
|
||||
hasPullToRefresh: true,
|
||||
|
||||
// Whether to disable overflow rubber banding when content is small
|
||||
// enough to fit in the viewport (i.e. doesn't need scrolling)
|
||||
disableNonOverflowRubberBand: false,
|
||||
|
||||
// Called as the refresher is opened, an amount is passed
|
||||
onRefreshOpening: function() {},
|
||||
// Called when let go and is refreshing
|
||||
@ -241,6 +245,10 @@
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the current scroll bounds needs to be brought back to the min/max
|
||||
* allowable given the total scrollable area.
|
||||
*/
|
||||
needsWrapping: function() {
|
||||
var _this = this;
|
||||
|
||||
@ -463,14 +471,6 @@
|
||||
var parentWidth = this.el.parentNode.offsetWidth;
|
||||
var parentHeight = this.el.parentNode.offsetHeight;
|
||||
|
||||
var maxX = Math.min(0, (-totalWidth + parentWidth));
|
||||
var maxY = Math.min(0, (-totalHeight + parentHeight));
|
||||
|
||||
// Check if we even have enough content to scroll, if not, don't start the drag
|
||||
if((this.isHorizontalEnabled && maxX == 0) || (this.isVerticalEnabled && maxY == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.x = scrollLeft;
|
||||
this.y = scrollTop;
|
||||
|
||||
@ -507,6 +507,16 @@
|
||||
resist: 1,
|
||||
startTime: Date.now()
|
||||
};
|
||||
|
||||
if(this.disableNonOverflowRubberBand === true) {
|
||||
var maxX = Math.min(0, (-totalWidth + parentWidth));
|
||||
var maxY = Math.min(0, (-totalHeight + parentHeight));
|
||||
|
||||
// Check if we even have enough content to scroll, if not, don't start the drag
|
||||
if((this.isHorizontalEnabled && maxX == 0) || (this.isVerticalEnabled && maxY == 0)) {
|
||||
this._drag.noRubberBand = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -574,10 +584,23 @@
|
||||
var newX = _this.x + deltaX;
|
||||
var newY = _this.y + deltaY;
|
||||
|
||||
if(drag.noRubberBand === true) {
|
||||
if(newY > 0) {
|
||||
newY = 0;
|
||||
} else if(newY < maxY) {
|
||||
newY = maxY;
|
||||
}
|
||||
if(newX > 0) {
|
||||
newX = 0;
|
||||
} else if(newX < maxX) {
|
||||
newX = maxX;
|
||||
}
|
||||
} else {
|
||||
// Check if the dragging is beyond the bottom or top
|
||||
if(newY > 0 || (-newY + parentHeight) > totalHeight) {
|
||||
newY = _this.y + deltaY / _this.rubberBandResistance;
|
||||
}
|
||||
}
|
||||
|
||||
if(!_this.isHorizontalEnabled) {
|
||||
newX = 0;
|
||||
@ -588,7 +611,6 @@
|
||||
|
||||
if(_this._refresher && newY > 0) {
|
||||
// We are pulling to refresh, so update the refresher
|
||||
//_this._refresher.style[ionic.CSS.TRANSFORM] = 'translate3d(0, ' + newY + 'px, 0)';
|
||||
if(_this._isRefresherHidden) {
|
||||
// Show it only in a drag and if we haven't showed it yet
|
||||
_this._refresher.style.display = 'block';
|
||||
@ -605,7 +627,7 @@
|
||||
}
|
||||
|
||||
// Update the new translated Y point of the container
|
||||
_this.el.style.webkitTransform = 'translate3d(' + newX + 'px,' + newY + 'px, 0)';
|
||||
_this.el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + newX + 'px,' + newY + 'px, 0)';
|
||||
} else {
|
||||
|
||||
_this._isHoldingRefresh = false;
|
||||
@ -616,7 +638,7 @@
|
||||
_this._isRefresherHidden = true;
|
||||
}
|
||||
// Update the new translated Y point of the container
|
||||
_this.el.style.webkitTransform = 'translate3d(' + newX + 'px,' + newY + 'px, 0)';
|
||||
_this.el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + newX + 'px,' + newY + 'px, 0)';
|
||||
}
|
||||
|
||||
// Store the last points
|
||||
|
||||
@ -22,4 +22,37 @@
|
||||
}
|
||||
});
|
||||
|
||||
ionic.views.SideMenuContent = ionic.views.View.inherit({
|
||||
initialize: function(opts) {
|
||||
var _this = this;
|
||||
|
||||
ionic.extend(this, {
|
||||
animationClass: 'menu-animated',
|
||||
onDrag: function(e) {},
|
||||
onEndDrag: function(e) {},
|
||||
}, opts);
|
||||
|
||||
ionic.onGesture('drag', ionic.proxy(this._onDrag, this), this.el);
|
||||
ionic.onGesture('release', ionic.proxy(this._onEndDrag, this), this.el);
|
||||
},
|
||||
_onDrag: function(e) {
|
||||
this.onDrag && this.onDrag(e);
|
||||
},
|
||||
_onEndDrag: function(e) {
|
||||
this.onEndDrag && this.onEndDrag(e);
|
||||
},
|
||||
disableAnimation: function() {
|
||||
this.el.classList.remove(this.animationClass);
|
||||
},
|
||||
enableAnimation: function() {
|
||||
this.el.classList.add(this.animationClass);
|
||||
},
|
||||
getTranslateX: function() {
|
||||
return parseFloat(this.el.style.webkitTransform.replace('translate3d(', '').split(',')[0]);
|
||||
},
|
||||
setTranslateX: function(x) {
|
||||
this.el.style.webkitTransform = 'translate3d(' + x + 'px, 0, 0)';
|
||||
}
|
||||
});
|
||||
|
||||
})(ionic);
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
}
|
||||
@-webkit-keyframes slideOutRight {
|
||||
0% {
|
||||
-webkit-transform: translate3d(0%,0,0);
|
||||
-webkit-transform: translate3d(0,0,0);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: translate3d(100%,0,0);
|
||||
@ -87,13 +87,13 @@
|
||||
|
||||
.slide-out-right {
|
||||
&.ng-enter, > .ng-enter {
|
||||
-webkit-animation-duration: 2250ms;
|
||||
-webkit-animation-duration: 250ms;
|
||||
-webkit-animation-fill-mode: both;
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
-webkit-animation-name: slideOutRight;
|
||||
}
|
||||
&.ng-leave, > .ng-leave {
|
||||
-webkit-animation-duration: 2250ms;
|
||||
-webkit-animation-duration: 250ms;
|
||||
-webkit-animation-fill-mode: both;
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
-webkit-animation-name: slideInRight;
|
||||
|
||||
@ -122,8 +122,36 @@ body, .ionic-body {
|
||||
//@include display-flex();
|
||||
//@include align-items(center);
|
||||
}
|
||||
.ionic-refresher-content {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
.ionic-refresher {
|
||||
// A custom refresher
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background-color: $brand-primary;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
bottom: 25px;
|
||||
}
|
||||
.scroll-refreshing {
|
||||
-webkit-transition: height 0.1s ease-in-out;
|
||||
|
||||
.ionic-refresher {
|
||||
-webkit-animation: refresher-pulsate 1.5s linear;
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes refresher-pulsate {
|
||||
0% {-webkit-transform: scale(2, 2); }
|
||||
50% {-webkit-transform: scale(1.5, 1.5); }
|
||||
100% {-webkit-transform: scale(2, 2); }
|
||||
}
|
||||
|
||||
.overflow-scroll {
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
</header>
|
||||
|
||||
<div id="list">
|
||||
<main id="content" class="scroll">
|
||||
<main id="content" class="content overflow-scroll">
|
||||
|
||||
<div class="list">
|
||||
|
||||
@ -500,6 +500,8 @@
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
57
test/side-menus.html
Normal file
57
test/side-menus.html
Normal file
@ -0,0 +1,57 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Side Menus</title>
|
||||
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link href="../dist/css/ionic.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="content" class="pane">
|
||||
<header class="bar bar-header bar-dark">
|
||||
<h1 class="title">Center</h1>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<div id="menu-left" class="menu menu-left">
|
||||
<header class="bar bar-header bar-dark">
|
||||
<h1 class="title">Left</h1>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<div id="menu-right" class="menu menu-right">
|
||||
<header class="bar bar-header bar-dark">
|
||||
<h1 class="title">Right</h1>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<script src="../dist/js/ionic.js"></script>
|
||||
|
||||
<script>
|
||||
var contentEl = document.getElementById('content');
|
||||
var content = new ionic.views.SideMenuContent({
|
||||
el: contentEl
|
||||
});
|
||||
|
||||
var leftMenuEl = document.getElementById('menu-left');
|
||||
var leftMenu = new ionic.views.SideMenu({
|
||||
el: leftMenuEl,
|
||||
width: 270
|
||||
});
|
||||
|
||||
var rightMenuEl = document.getElementById('menu-right');
|
||||
var rightMenu = new ionic.views.SideMenu({
|
||||
el: rightMenuEl,
|
||||
width: 270
|
||||
});
|
||||
|
||||
var sm = new ionic.controllers.SideMenuController({
|
||||
content: content,
|
||||
left: leftMenu,
|
||||
right: rightMenu
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user