mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
refactor(sideMenu): move controller logic to $ionicSideMenus
This commit is contained in:
320
js/angular/controller/sideMenuController.js
vendored
320
js/angular/controller/sideMenuController.js
vendored
@@ -6,37 +6,314 @@ IonicModule
|
||||
'$ionicPlatform',
|
||||
function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform) {
|
||||
var self = this;
|
||||
extend(this, ionic.controllers.SideMenuController.prototype);
|
||||
var rightShowing, leftShowing, isDragging;
|
||||
var startX, lastX, offsetX;
|
||||
|
||||
this.$scope = $scope;
|
||||
self.$scope = $scope;
|
||||
|
||||
ionic.controllers.SideMenuController.call(this, {
|
||||
left: { width: 275 },
|
||||
right: { width: 275 }
|
||||
});
|
||||
self.initialize = function(options) {
|
||||
self.left = options.left;
|
||||
self.right = options.right;
|
||||
self.setContent(options.content);
|
||||
self.dragThresholdX = options.dragThresholdX || 10;
|
||||
};
|
||||
|
||||
this.canDragContent = function(canDrag) {
|
||||
/**
|
||||
* Set the content view controller if not passed in the constructor options.
|
||||
*
|
||||
* @param {object} content
|
||||
*/
|
||||
self.setContent = function(content) {
|
||||
if(content) {
|
||||
self.content = content;
|
||||
|
||||
self.content.onDrag = function(e) {
|
||||
self._handleDrag(e);
|
||||
};
|
||||
|
||||
self.content.endDrag = function(e) {
|
||||
self._endDrag(e);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
self.isOpenLeft = function() {
|
||||
return self.getOpenAmount() > 0;
|
||||
};
|
||||
|
||||
self.isOpenRight = function() {
|
||||
return self.getOpenAmount() < 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggle the left menu to open 100%
|
||||
*/
|
||||
self.toggleLeft = function(shouldOpen) {
|
||||
var openAmount = self.getOpenAmount();
|
||||
if (arguments.length === 0) {
|
||||
shouldOpen = openAmount <= 0;
|
||||
}
|
||||
self.content.enableAnimation();
|
||||
if(!shouldOpen) {
|
||||
self.openPercentage(0);
|
||||
} else {
|
||||
self.openPercentage(100);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggle the right menu to open 100%
|
||||
*/
|
||||
self.toggleRight = function(shouldOpen) {
|
||||
var openAmount = self.getOpenAmount();
|
||||
if (arguments.length === 0) {
|
||||
shouldOpen = openAmount >= 0;
|
||||
}
|
||||
self.content.enableAnimation();
|
||||
if(!shouldOpen) {
|
||||
self.openPercentage(0);
|
||||
} else {
|
||||
self.openPercentage(-100);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Close all menus.
|
||||
*/
|
||||
self.close = function() {
|
||||
self.openPercentage(0);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {float} The amount the side menu is open, either positive or negative for left (positive), or right (negative)
|
||||
*/
|
||||
self.getOpenAmount = function() {
|
||||
return self.content && self.content.getTranslateX() || 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {float} The ratio of open amount over menu width. For example, a
|
||||
* menu of width 100 open 50 pixels would be open 50% or a ratio of 0.5. Value is negative
|
||||
* for right menu.
|
||||
*/
|
||||
self.getOpenRatio = function() {
|
||||
var amount = self.getOpenAmount();
|
||||
if(amount >= 0) {
|
||||
return amount / self.left.width;
|
||||
}
|
||||
return amount / self.right.width;
|
||||
};
|
||||
|
||||
self.isOpen = function() {
|
||||
return self.getOpenAmount() !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {float} The percentage of open amount over menu width. For example, a
|
||||
* menu of width 100 open 50 pixels would be open 50%. Value is negative
|
||||
* for right menu.
|
||||
*/
|
||||
self.getOpenPercentage = function() {
|
||||
return self.getOpenRatio() * 100;
|
||||
};
|
||||
|
||||
/**
|
||||
* Open the menu with a given percentage amount.
|
||||
* @param {float} percentage The percentage (positive or negative for left/right) to open the menu.
|
||||
*/
|
||||
self.openPercentage = function(percentage) {
|
||||
var p = percentage / 100;
|
||||
|
||||
if(self.left && percentage >= 0) {
|
||||
self.openAmount(self.left.width * p);
|
||||
} else if(self.right && percentage < 0) {
|
||||
var maxRight = self.right.width;
|
||||
self.openAmount(self.right.width * p);
|
||||
}
|
||||
|
||||
if(percentage !== 0) {
|
||||
document.body.classList.add('menu-open');
|
||||
} else {
|
||||
document.body.classList.remove('menu-open');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Open the menu the given pixel amount.
|
||||
* @param {float} amount the pixel amount to open the menu. Positive value for left menu,
|
||||
* negative value for right menu (only one menu will be visible at a time).
|
||||
*/
|
||||
self.openAmount = function(amount) {
|
||||
var maxLeft = self.left && self.left.width || 0;
|
||||
var maxRight = self.right && self.right.width || 0;
|
||||
|
||||
// Check if we can move to that side, depending if the left/right panel is enabled
|
||||
if(!(self.left && self.left.isEnabled) && amount > 0) {
|
||||
self.content.setTranslateX(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(self.right && self.right.isEnabled) && amount < 0) {
|
||||
self.content.setTranslateX(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(leftShowing && amount > maxLeft) {
|
||||
self.content.setTranslateX(maxLeft);
|
||||
return;
|
||||
}
|
||||
|
||||
if(rightShowing && amount < -maxRight) {
|
||||
self.content.setTranslateX(-maxRight);
|
||||
return;
|
||||
}
|
||||
|
||||
self.content.setTranslateX(amount);
|
||||
|
||||
if(amount >= 0) {
|
||||
leftShowing = true;
|
||||
rightShowing = false;
|
||||
|
||||
if(amount > 0) {
|
||||
// Push the z-index of the right menu down
|
||||
self.right && self.right.pushDown && self.right.pushDown();
|
||||
// Bring the z-index of the left menu up
|
||||
self.left && self.left.bringUp && self.left.bringUp();
|
||||
}
|
||||
} else {
|
||||
rightShowing = true;
|
||||
leftShowing = false;
|
||||
|
||||
// Bring the z-index of the right menu up
|
||||
self.right && self.right.bringUp && self.right.bringUp();
|
||||
// Push the z-index of the left menu down
|
||||
self.left && self.left.pushDown && self.left.pushDown();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Given an event object, find the final resting position of this side
|
||||
* menu. For example, if the user "throws" the content to the right and
|
||||
* releases the touch, the left menu should snap open (animated, of course).
|
||||
*
|
||||
* @param {Event} e the gesture event to use for snapping
|
||||
*/
|
||||
self.snapToRest = function(e) {
|
||||
// We want to animate at the end of this
|
||||
self.content.enableAnimation();
|
||||
isDragging = false;
|
||||
|
||||
// Check how much the panel is open after the drag, and
|
||||
// what the drag velocity is
|
||||
var ratio = self.getOpenRatio();
|
||||
|
||||
if(ratio === 0) {
|
||||
// Just to be safe
|
||||
self.openPercentage(0);
|
||||
return;
|
||||
}
|
||||
|
||||
var velocityThreshold = 0.3;
|
||||
var velocityX = e.gesture.velocityX;
|
||||
var direction = e.gesture.direction;
|
||||
|
||||
// Going right, less than half, too slow (snap back)
|
||||
if(ratio > 0 && ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
|
||||
self.openPercentage(0);
|
||||
}
|
||||
|
||||
// Going left, more than half, too slow (snap back)
|
||||
else if(ratio > 0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
||||
self.openPercentage(100);
|
||||
}
|
||||
|
||||
// Going left, less than half, too slow (snap back)
|
||||
else if(ratio < 0 && ratio > -0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
||||
self.openPercentage(0);
|
||||
}
|
||||
|
||||
// Going right, more than half, too slow (snap back)
|
||||
else if(ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
|
||||
self.openPercentage(-100);
|
||||
}
|
||||
|
||||
// Going right, more than half, or quickly (snap open)
|
||||
else if(direction == 'right' && ratio >= 0 && (ratio >= 0.5 || velocityX > velocityThreshold)) {
|
||||
self.openPercentage(100);
|
||||
}
|
||||
|
||||
// Going left, more than half, or quickly (span open)
|
||||
else if(direction == 'left' && ratio <= 0 && (ratio <= -0.5 || velocityX > velocityThreshold)) {
|
||||
self.openPercentage(-100);
|
||||
}
|
||||
|
||||
// Snap back for safety
|
||||
else {
|
||||
self.openPercentage(0);
|
||||
}
|
||||
};
|
||||
|
||||
// End a drag with the given event
|
||||
self._endDrag = function(e) {
|
||||
if(isDragging) {
|
||||
self.snapToRest(e);
|
||||
}
|
||||
startX = null;
|
||||
lastX = null;
|
||||
offsetX = null;
|
||||
};
|
||||
|
||||
// Handle a drag event
|
||||
self._handleDrag = function(e) {
|
||||
|
||||
// If we don't have start coords, grab and store them
|
||||
if(!startX) {
|
||||
startX = e.gesture.touches[0].pageX;
|
||||
lastX = startX;
|
||||
} else {
|
||||
// Grab the current tap coords
|
||||
lastX = e.gesture.touches[0].pageX;
|
||||
}
|
||||
|
||||
// Calculate difference from the tap points
|
||||
if(!isDragging && Math.abs(lastX - startX) > self.dragThresholdX) {
|
||||
// if the difference is greater than threshold, start dragging using the current
|
||||
// point as the starting point
|
||||
startX = lastX;
|
||||
|
||||
isDragging = true;
|
||||
// Initialize dragging
|
||||
self.content.disableAnimation();
|
||||
offsetX = self.getOpenAmount();
|
||||
}
|
||||
|
||||
if(isDragging) {
|
||||
self.openAmount(offsetX + (lastX - startX));
|
||||
}
|
||||
};
|
||||
|
||||
self.canDragContent = function(canDrag) {
|
||||
if (arguments.length) {
|
||||
$scope.dragContent = !!canDrag;
|
||||
}
|
||||
return $scope.dragContent;
|
||||
};
|
||||
|
||||
this.edgeThreshold = 25;
|
||||
this.edgeThresholdEnabled = false;
|
||||
this.edgeDragThreshold = function(value) {
|
||||
self.edgeThreshold = 25;
|
||||
self.edgeThresholdEnabled = false;
|
||||
self.edgeDragThreshold = function(value) {
|
||||
if (arguments.length) {
|
||||
if (angular.isNumber(value) && value > 0) {
|
||||
this.edgeThreshold = value;
|
||||
this.edgeThresholdEnabled = true;
|
||||
self.edgeThreshold = value;
|
||||
self.edgeThresholdEnabled = true;
|
||||
} else {
|
||||
this.edgeThresholdEnabled = !!value;
|
||||
self.edgeThresholdEnabled = !!value;
|
||||
}
|
||||
}
|
||||
return this.edgeThresholdEnabled;
|
||||
return self.edgeThresholdEnabled;
|
||||
};
|
||||
|
||||
this.isDraggableTarget = function(e) {
|
||||
self.isDraggableTarget = function(e) {
|
||||
//Only restrict edge when sidemenu is closed and restriction is enabled
|
||||
var shouldOnlyAllowEdgeDrag = self.edgeThresholdEnabled && !self.isOpen();
|
||||
var startX = e.gesture.startEvent && e.gesture.startEvent.center &&
|
||||
@@ -56,9 +333,9 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform) {
|
||||
|
||||
$scope.sideMenuContentTranslateX = 0;
|
||||
|
||||
|
||||
var deregisterBackButtonAction = angular.noop;
|
||||
var closeSideMenu = angular.bind(this, this.close);
|
||||
var closeSideMenu = angular.bind(self, self.close);
|
||||
|
||||
$scope.$watch(function() {
|
||||
return self.getOpenAmount() !== 0;
|
||||
}, function(isOpen) {
|
||||
@@ -72,10 +349,17 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform) {
|
||||
});
|
||||
|
||||
var deregisterInstance = $ionicSideMenuDelegate._registerInstance(
|
||||
this, $attrs.delegateHandle
|
||||
self, $attrs.delegateHandle
|
||||
);
|
||||
|
||||
$scope.$on('$destroy', function() {
|
||||
deregisterInstance();
|
||||
deregisterBackButtonAction();
|
||||
});
|
||||
|
||||
self.initialize({
|
||||
left: { width: 275 },
|
||||
right: { width: 275 }
|
||||
});
|
||||
|
||||
}]);
|
||||
|
||||
@@ -1,313 +0,0 @@
|
||||
(function(ionic) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* The SideMenuController is a controller with a left and/or right menu that
|
||||
* can be slid out and toggled. Seen on many an app.
|
||||
*
|
||||
* The right or left menu can be disabled or not used at all, if desired.
|
||||
*/
|
||||
ionic.controllers.SideMenuController = ionic.controllers.ViewController.inherit({
|
||||
initialize: function(options) {
|
||||
var self = this;
|
||||
|
||||
this.left = options.left;
|
||||
this.right = options.right;
|
||||
this.content = options.content;
|
||||
this.dragThresholdX = options.dragThresholdX || 10;
|
||||
|
||||
this._rightShowing = false;
|
||||
this._leftShowing = false;
|
||||
this._isDragging = false;
|
||||
|
||||
if(this.content) {
|
||||
this.content.onDrag = function(e) {
|
||||
self._handleDrag(e);
|
||||
};
|
||||
|
||||
this.content.onEndDrag =function(e) {
|
||||
self._endDrag(e);
|
||||
};
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Set the content view controller if not passed in the constructor options.
|
||||
*
|
||||
* @param {object} content
|
||||
*/
|
||||
setContent: function(content) {
|
||||
var self = this;
|
||||
|
||||
this.content = content;
|
||||
|
||||
this.content.onDrag = function(e) {
|
||||
self._handleDrag(e);
|
||||
};
|
||||
|
||||
this.content.endDrag = function(e) {
|
||||
self._endDrag(e);
|
||||
};
|
||||
},
|
||||
|
||||
isOpenLeft: function() {
|
||||
return this.getOpenAmount() > 0;
|
||||
},
|
||||
|
||||
isOpenRight: function() {
|
||||
return this.getOpenAmount() < 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle the left menu to open 100%
|
||||
*/
|
||||
toggleLeft: function(shouldOpen) {
|
||||
var openAmount = this.getOpenAmount();
|
||||
if (arguments.length === 0) {
|
||||
shouldOpen = openAmount <= 0;
|
||||
}
|
||||
this.content.enableAnimation();
|
||||
if(!shouldOpen) {
|
||||
this.openPercentage(0);
|
||||
} else {
|
||||
this.openPercentage(100);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle the right menu to open 100%
|
||||
*/
|
||||
toggleRight: function(shouldOpen) {
|
||||
var openAmount = this.getOpenAmount();
|
||||
if (arguments.length === 0) {
|
||||
shouldOpen = openAmount >= 0;
|
||||
}
|
||||
this.content.enableAnimation();
|
||||
if(!shouldOpen) {
|
||||
this.openPercentage(0);
|
||||
} else {
|
||||
this.openPercentage(-100);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Close all menus.
|
||||
*/
|
||||
close: function() {
|
||||
this.openPercentage(0);
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {float} The amount the side menu is open, either positive or negative for left (positive), or right (negative)
|
||||
*/
|
||||
getOpenAmount: function() {
|
||||
return this.content && this.content.getTranslateX() || 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {float} The ratio of open amount over menu width. For example, a
|
||||
* menu of width 100 open 50 pixels would be open 50% or a ratio of 0.5. Value is negative
|
||||
* for right menu.
|
||||
*/
|
||||
getOpenRatio: function() {
|
||||
var amount = this.getOpenAmount();
|
||||
if(amount >= 0) {
|
||||
return amount / this.left.width;
|
||||
}
|
||||
return amount / this.right.width;
|
||||
},
|
||||
|
||||
isOpen: function() {
|
||||
return this.getOpenAmount() !== 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {float} The percentage of open amount over menu width. For example, a
|
||||
* menu of width 100 open 50 pixels would be open 50%. Value is negative
|
||||
* for right menu.
|
||||
*/
|
||||
getOpenPercentage: function() {
|
||||
return this.getOpenRatio() * 100;
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the menu with a given percentage amount.
|
||||
* @param {float} percentage The percentage (positive or negative for left/right) to open the menu.
|
||||
*/
|
||||
openPercentage: function(percentage) {
|
||||
var p = percentage / 100;
|
||||
|
||||
if(this.left && percentage >= 0) {
|
||||
this.openAmount(this.left.width * p);
|
||||
} else if(this.right && percentage < 0) {
|
||||
var maxRight = this.right.width;
|
||||
this.openAmount(this.right.width * p);
|
||||
}
|
||||
|
||||
if(percentage !== 0) {
|
||||
document.body.classList.add('menu-open');
|
||||
} else {
|
||||
document.body.classList.remove('menu-open');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the menu the given pixel amount.
|
||||
* @param {float} amount the pixel amount to open the menu. Positive value for left menu,
|
||||
* negative value for right menu (only one menu will be visible at a time).
|
||||
*/
|
||||
openAmount: function(amount) {
|
||||
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 && this.left.isEnabled) && amount > 0) {
|
||||
this.content.setTranslateX(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(this.right && this.right.isEnabled) && amount < 0) {
|
||||
this.content.setTranslateX(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(this._leftShowing && amount > maxLeft) {
|
||||
this.content.setTranslateX(maxLeft);
|
||||
return;
|
||||
}
|
||||
|
||||
if(this._rightShowing && amount < -maxRight) {
|
||||
this.content.setTranslateX(-maxRight);
|
||||
return;
|
||||
}
|
||||
|
||||
this.content.setTranslateX(amount);
|
||||
|
||||
if(amount >= 0) {
|
||||
this._leftShowing = true;
|
||||
this._rightShowing = false;
|
||||
|
||||
if(amount > 0) {
|
||||
// Push the z-index of the right menu down
|
||||
this.right && this.right.pushDown && this.right.pushDown();
|
||||
// Bring the z-index of the left menu up
|
||||
this.left && this.left.bringUp && this.left.bringUp();
|
||||
}
|
||||
} else {
|
||||
this._rightShowing = true;
|
||||
this._leftShowing = false;
|
||||
|
||||
// Bring the z-index of the right menu up
|
||||
this.right && this.right.bringUp && this.right.bringUp();
|
||||
// Push the z-index of the left menu down
|
||||
this.left && this.left.pushDown && this.left.pushDown();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Given an event object, find the final resting position of this side
|
||||
* menu. For example, if the user "throws" the content to the right and
|
||||
* releases the touch, the left menu should snap open (animated, of course).
|
||||
*
|
||||
* @param {Event} e the gesture event to use for snapping
|
||||
*/
|
||||
snapToRest: function(e) {
|
||||
// We want to animate at the end of this
|
||||
this.content.enableAnimation();
|
||||
this._isDragging = false;
|
||||
|
||||
// Check how much the panel is open after the drag, and
|
||||
// what the drag velocity is
|
||||
var ratio = this.getOpenRatio();
|
||||
|
||||
if(ratio === 0) {
|
||||
// Just to be safe
|
||||
this.openPercentage(0);
|
||||
return;
|
||||
}
|
||||
|
||||
var velocityThreshold = 0.3;
|
||||
var velocityX = e.gesture.velocityX;
|
||||
var direction = e.gesture.direction;
|
||||
|
||||
// Less than half, going left
|
||||
//if(ratio > 0 && ratio < 0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
||||
//this.openPercentage(0);
|
||||
//}
|
||||
|
||||
// Going right, less than half, too slow (snap back)
|
||||
if(ratio > 0 && ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
|
||||
this.openPercentage(0);
|
||||
}
|
||||
|
||||
// Going left, more than half, too slow (snap back)
|
||||
else if(ratio > 0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
||||
this.openPercentage(100);
|
||||
}
|
||||
|
||||
// Going left, less than half, too slow (snap back)
|
||||
else if(ratio < 0 && ratio > -0.5 && direction == 'left' && velocityX < velocityThreshold) {
|
||||
this.openPercentage(0);
|
||||
}
|
||||
|
||||
// Going right, more than half, too slow (snap back)
|
||||
else if(ratio < 0.5 && direction == 'right' && velocityX < velocityThreshold) {
|
||||
this.openPercentage(-100);
|
||||
}
|
||||
|
||||
// Going right, more than half, or quickly (snap open)
|
||||
else if(direction == 'right' && ratio >= 0 && (ratio >= 0.5 || velocityX > velocityThreshold)) {
|
||||
this.openPercentage(100);
|
||||
}
|
||||
|
||||
// Going left, more than half, or quickly (span open)
|
||||
else if(direction == 'left' && ratio <= 0 && (ratio <= -0.5 || velocityX > velocityThreshold)) {
|
||||
this.openPercentage(-100);
|
||||
}
|
||||
|
||||
// Snap back for safety
|
||||
else {
|
||||
this.openPercentage(0);
|
||||
}
|
||||
},
|
||||
|
||||
// End a drag with the given event
|
||||
_endDrag: function(e) {
|
||||
if(this._isDragging) {
|
||||
this.snapToRest(e);
|
||||
}
|
||||
this._startX = null;
|
||||
this._lastX = null;
|
||||
this._offsetX = null;
|
||||
},
|
||||
|
||||
// Handle a drag event
|
||||
_handleDrag: function(e) {
|
||||
|
||||
// If we don't have start coords, grab and store them
|
||||
if(!this._startX) {
|
||||
this._startX = e.gesture.touches[0].pageX;
|
||||
this._lastX = this._startX;
|
||||
} else {
|
||||
// Grab the current tap coords
|
||||
this._lastX = e.gesture.touches[0].pageX;
|
||||
}
|
||||
|
||||
// Calculate difference from the tap points
|
||||
if(!this._isDragging && Math.abs(this._lastX - this._startX) > this.dragThresholdX) {
|
||||
// if the difference is greater than threshold, start dragging using the current
|
||||
// point as the starting point
|
||||
this._startX = this._lastX;
|
||||
|
||||
this._isDragging = true;
|
||||
// Initialize dragging
|
||||
this.content.disableAnimation();
|
||||
this._offsetX = this.getOpenAmount();
|
||||
}
|
||||
|
||||
if(this._isDragging) {
|
||||
this.openAmount(this._offsetX + (this._lastX - this._startX));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
})(ionic);
|
||||
@@ -1,16 +0,0 @@
|
||||
(function(ionic) {
|
||||
'use strict';
|
||||
ionic.controllers.ViewController = function(options) {
|
||||
this.initialize.apply(this, arguments);
|
||||
};
|
||||
|
||||
ionic.controllers.ViewController.inherit = ionic.inherit;
|
||||
|
||||
ionic.extend(ionic.controllers.ViewController.prototype, {
|
||||
initialize: function() {},
|
||||
// Destroy this view controller, including all child views
|
||||
destroy: function() {
|
||||
}
|
||||
});
|
||||
|
||||
})(window.ionic);
|
||||
@@ -12,7 +12,6 @@
|
||||
this.isEnabled = (typeof opts.isEnabled === 'undefined') ? true : opts.isEnabled;
|
||||
this.setWidth(opts.width);
|
||||
},
|
||||
|
||||
getFullWidth: function() {
|
||||
return this.width;
|
||||
},
|
||||
@@ -37,12 +36,10 @@
|
||||
|
||||
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) {},
|
||||
onEndDrag: function(e) {}
|
||||
}, opts);
|
||||
|
||||
ionic.onGesture('drag', ionic.proxy(this._onDrag, this), this.el);
|
||||
|
||||
@@ -1,25 +1,224 @@
|
||||
describe('$ionicSideMenus controller', function() {
|
||||
var ctrl;
|
||||
|
||||
var Controller = function(opts) {
|
||||
this.el = opts.el;
|
||||
this.animateClass = opts.animateClass;
|
||||
};
|
||||
Controller.prototype = {
|
||||
getTranslateX: function() {
|
||||
var r = /translate3d\((-?.+)px/;
|
||||
var d = r.exec(this.el.style.webkitTransform);
|
||||
|
||||
if(d && d.length > 0) {
|
||||
return parseFloat(d[1]);
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
setTranslateX: function(amount) {
|
||||
this.el.style.webkitTransform = 'translate3d(' + amount + 'px, 0, 0)';
|
||||
},
|
||||
enableAnimation: function() {
|
||||
this.el.classList.add(this.animateClass);
|
||||
},
|
||||
disableAnimation: function() {
|
||||
this.el.classList.remove(this.animateClass);
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach(module('ionic'));
|
||||
|
||||
function setup(locals, props) {
|
||||
var ctrl;
|
||||
beforeEach(function(){
|
||||
|
||||
inject(function($controller, $rootScope) {
|
||||
var scope = $rootScope.$new();
|
||||
ctrl = $controller('$ionicSideMenus', angular.extend({
|
||||
$scope: scope,
|
||||
$attrs: {}
|
||||
}, locals || {}));
|
||||
angular.extend(ctrl, props || {});
|
||||
}, {}));
|
||||
angular.extend(ctrl, {});
|
||||
ctrl.left = new ionic.views.SideMenu({
|
||||
width: 270,
|
||||
el: document.createElement('div'),
|
||||
isEnabled: true
|
||||
});
|
||||
ctrl.right = new ionic.views.SideMenu({
|
||||
width: 270,
|
||||
el: document.createElement('div'),
|
||||
isEnabled: true
|
||||
});
|
||||
ctrl.setContent(new Controller({ el: document.createElement('div') }));
|
||||
});
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Menu enable/disable
|
||||
it('should set enabled/disabled', function() {
|
||||
ctrl.left.setIsEnabled(false);
|
||||
ctrl.right.setIsEnabled(false);
|
||||
expect(ctrl.left.isEnabled).toEqual(false);
|
||||
expect(ctrl.right.isEnabled).toEqual(false);
|
||||
ctrl.left.setIsEnabled(true);
|
||||
ctrl.right.setIsEnabled(true);
|
||||
expect(ctrl.left.isEnabled).toEqual(true);
|
||||
expect(ctrl.right.isEnabled).toEqual(true);
|
||||
});
|
||||
|
||||
// Menu widths
|
||||
it('should init widths', function() {
|
||||
expect(ctrl.left.width).toEqual(270);
|
||||
expect(ctrl.right.width).toEqual(270);
|
||||
});
|
||||
|
||||
it('should have amount and percentage correct', function() {
|
||||
ctrl.openAmount(ctrl.left.width/2);
|
||||
expect(ctrl.getOpenAmount()).toEqual(ctrl.left.width/2);
|
||||
expect(ctrl.getOpenPercentage()).toEqual(50);
|
||||
|
||||
ctrl.openAmount(ctrl.left.width/4);
|
||||
expect(ctrl.getOpenAmount()).toEqual(ctrl.left.width/4);
|
||||
expect(ctrl.getOpenPercentage()).toEqual(25);
|
||||
|
||||
ctrl.openAmount(-ctrl.right.width/2);
|
||||
expect(ctrl.getOpenAmount()).toEqual(-ctrl.right.width/2);
|
||||
expect(ctrl.getOpenPercentage()).toEqual(-50);
|
||||
});
|
||||
|
||||
// Open
|
||||
it('should toggle left', function() {
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(100);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(100);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
});
|
||||
|
||||
it('should toggle right', function() {
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(-100);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(-100);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
});
|
||||
|
||||
it('should isOpen', function() {
|
||||
expect(ctrl.isOpen()).toEqual(false);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpen()).toEqual(true);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpen()).toEqual(false);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpen()).toEqual(true);
|
||||
ctrl.toggleLeft();
|
||||
|
||||
expect(ctrl.isOpen()).toEqual(false);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpen()).toEqual(true);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpen()).toEqual(false);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpen()).toEqual(true);
|
||||
});
|
||||
|
||||
|
||||
it('should isOpenLeft', function() {
|
||||
expect(ctrl.isOpenLeft()).toEqual(false);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpenLeft()).toEqual(true);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpenLeft()).toEqual(false);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpenLeft()).toEqual(true);
|
||||
});
|
||||
|
||||
it('should isOpenRight', function() {
|
||||
expect(ctrl.isOpenRight()).toEqual(false);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpenRight()).toEqual(true);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpenRight()).toEqual(false);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpenRight()).toEqual(true);
|
||||
});
|
||||
|
||||
// Snap
|
||||
it('should snap', function() {
|
||||
|
||||
// Center to right, Going right, less than half, too slow (snap back)
|
||||
ctrl.openAmount(10);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 0,
|
||||
direction: 'right'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
|
||||
// Right to left, Going left, more than half, too slow (snap back)
|
||||
ctrl.openPercentage(51);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 0,
|
||||
direction: 'left'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(100);
|
||||
|
||||
// Right to left, Going left, less than half, too slow (snap back)
|
||||
ctrl.openAmount(10);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 0,
|
||||
direction: 'left'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
|
||||
// Left to right, Going right, more than half, too slow (snap back)
|
||||
ctrl.openPercentage(-51);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 0,
|
||||
direction: 'right'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(-100);
|
||||
|
||||
// Going right, more than half, or quickly (snap open)
|
||||
ctrl.openPercentage(-51);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 1,
|
||||
direction: 'right'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
|
||||
// Going left, more than half, or quickly (snap open)
|
||||
ctrl.openPercentage(-51);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 1,
|
||||
direction: 'left'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(-100);
|
||||
});
|
||||
|
||||
it('Should test content drag events', function() {
|
||||
});
|
||||
|
||||
it('should register with backButton on open and dereg on close', inject(function($ionicPlatform) {
|
||||
var openAmount = 0;
|
||||
var deregSpy = jasmine.createSpy('deregister');
|
||||
spyOn($ionicPlatform, 'registerBackButtonAction').andReturn(deregSpy);
|
||||
|
||||
var ctrl = setup();
|
||||
spyOn(ctrl, 'getOpenAmount').andCallFake(function() { return openAmount; });
|
||||
|
||||
expect($ionicPlatform.registerBackButtonAction).not.toHaveBeenCalled();
|
||||
@@ -40,7 +239,6 @@ describe('$ionicSideMenus controller', function() {
|
||||
var deregSpy = jasmine.createSpy('deregister');
|
||||
spyOn($ionicPlatform, 'registerBackButtonAction').andReturn(deregSpy);
|
||||
|
||||
var ctrl = setup();
|
||||
spyOn(ctrl, 'getOpenAmount').andCallFake(function() { return openAmount; });
|
||||
|
||||
expect($ionicPlatform.registerBackButtonAction).not.toHaveBeenCalled();
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
describe('SideMenuController', function() {
|
||||
var ctrl, l, r, c;
|
||||
|
||||
var Controller = function(opts) {
|
||||
this.el = opts.el;
|
||||
this.animateClass = opts.animateClass;
|
||||
};
|
||||
Controller.prototype = {
|
||||
getTranslateX: function() {
|
||||
var r = /translate3d\((-?.+)px/;
|
||||
var d = r.exec(this.el.style.webkitTransform);
|
||||
|
||||
if(d && d.length > 0) {
|
||||
return parseFloat(d[1]);
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
setTranslateX: function(amount) {
|
||||
this.el.style.webkitTransform = 'translate3d(' + amount + 'px, 0, 0)';
|
||||
},
|
||||
enableAnimation: function() {
|
||||
this.el.classList.add(this.animateClass);
|
||||
},
|
||||
disableAnimation: function() {
|
||||
this.el.classList.remove(this.animateClass);
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
l = new ionic.views.SideMenu({ el: document.createElement('div'), width: 270 });
|
||||
r = new ionic.views.SideMenu({ el: document.createElement('div'), width: 270 });
|
||||
c = new Controller({ el: document.createElement('div') });
|
||||
|
||||
ctrl = new ionic.controllers.SideMenuController({
|
||||
left: l,
|
||||
right: r,
|
||||
content: c
|
||||
});
|
||||
});
|
||||
|
||||
// Init
|
||||
it('Should init', function() {
|
||||
expect(ctrl.left).toBe(l);
|
||||
expect(ctrl.right).toBe(r);
|
||||
expect(ctrl.content).toBe(c);
|
||||
});
|
||||
|
||||
// Menu enable/disable
|
||||
it('Should set enabled/disabled', function() {
|
||||
var left = ctrl.left;
|
||||
var right = ctrl.right;
|
||||
left.setIsEnabled(false);
|
||||
right.setIsEnabled(false);
|
||||
expect(left.isEnabled).toEqual(false);
|
||||
expect(right.isEnabled).toEqual(false);
|
||||
left.setIsEnabled(true);
|
||||
right.setIsEnabled(true);
|
||||
expect(left.isEnabled).toEqual(true);
|
||||
expect(right.isEnabled).toEqual(true);
|
||||
});
|
||||
|
||||
// Menu widths
|
||||
it('Should init widths', function() {
|
||||
var left = ctrl.left;
|
||||
var right = ctrl.right;
|
||||
expect(left.width).toEqual(270);
|
||||
expect(right.width).toEqual(270);
|
||||
});
|
||||
|
||||
it('Should have amount and percentage correct', function() {
|
||||
ctrl.openAmount(l.width/2);
|
||||
expect(ctrl.getOpenAmount()).toEqual(l.width/2);
|
||||
expect(ctrl.getOpenPercentage()).toEqual(50);
|
||||
|
||||
ctrl.openAmount(l.width/4);
|
||||
expect(ctrl.getOpenAmount()).toEqual(l.width/4);
|
||||
expect(ctrl.getOpenPercentage()).toEqual(25);
|
||||
|
||||
ctrl.openAmount(-r.width/2);
|
||||
expect(ctrl.getOpenAmount()).toEqual(-r.width/2);
|
||||
expect(ctrl.getOpenPercentage()).toEqual(-50);
|
||||
});
|
||||
|
||||
// Open
|
||||
it('Should toggle left', function() {
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(100);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(100);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
});
|
||||
|
||||
it('should toggle right', function() {
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(-100);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(-100);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
});
|
||||
|
||||
it('should isOpen', function() {
|
||||
expect(ctrl.isOpen()).toEqual(false);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpen()).toEqual(true);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpen()).toEqual(false);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpen()).toEqual(true);
|
||||
ctrl.toggleLeft();
|
||||
|
||||
expect(ctrl.isOpen()).toEqual(false);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpen()).toEqual(true);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpen()).toEqual(false);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpen()).toEqual(true);
|
||||
});
|
||||
|
||||
it('should isOpenLeft', function() {
|
||||
expect(ctrl.isOpenLeft()).toEqual(false);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpenLeft()).toEqual(true);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpenLeft()).toEqual(false);
|
||||
ctrl.toggleLeft();
|
||||
expect(ctrl.isOpenLeft()).toEqual(true);
|
||||
});
|
||||
|
||||
it('should isOpenRight', function() {
|
||||
expect(ctrl.isOpenRight()).toEqual(false);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpenRight()).toEqual(true);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpenRight()).toEqual(false);
|
||||
ctrl.toggleRight();
|
||||
expect(ctrl.isOpenRight()).toEqual(true);
|
||||
});
|
||||
|
||||
// Snap
|
||||
it('Should snap', function() {
|
||||
|
||||
// Center to right, Going right, less than half, too slow (snap back)
|
||||
ctrl.openAmount(10);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 0,
|
||||
direction: 'right'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
|
||||
// Right to left, Going left, more than half, too slow (snap back)
|
||||
ctrl.openPercentage(51);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 0,
|
||||
direction: 'left'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(100);
|
||||
|
||||
// Right to left, Going left, less than half, too slow (snap back)
|
||||
ctrl.openAmount(10);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 0,
|
||||
direction: 'left'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
|
||||
// Left to right, Going right, more than half, too slow (snap back)
|
||||
ctrl.openPercentage(-51);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 0,
|
||||
direction: 'right'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(-100);
|
||||
|
||||
// Going right, more than half, or quickly (snap open)
|
||||
ctrl.openPercentage(-51);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 1,
|
||||
direction: 'right'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(0);
|
||||
|
||||
// Going left, more than half, or quickly (snap open)
|
||||
ctrl.openPercentage(-51);
|
||||
ctrl.snapToRest({
|
||||
gesture: {
|
||||
velocityX: 1,
|
||||
direction: 'left'
|
||||
}
|
||||
});
|
||||
expect(ctrl.getOpenPercentage()).toEqual(-100);
|
||||
});
|
||||
|
||||
it('Should test content drag events', function() {
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user