Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

feat(ngTouch): add optional ngSwipeDisableMouse attribute to ngSwipe... #7467

Merged
merged 1 commit into from
May 14, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/ngTouch/directive/ngSwipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
* Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag
* too.
*
* To disable the mouse click and drag functionality, add `ng-swipe-disable-mouse` to
* the `ng-swipe-left` or `ng-swipe-right` DOM Element.
*
* Requires the {@link ngTouch `ngTouch`} module to be installed.
*
* @element ANY
Expand Down Expand Up @@ -101,6 +104,10 @@ function makeSwipeDirective(directiveName, direction, eventName) {
deltaY / deltaX < MAX_VERTICAL_RATIO;
}

var pointerTypes = ['touch'];
if (!angular.isDefined(attr['ngSwipeDisableMouse'])) {
pointerTypes.push('mouse');
}
$swipe.bind(element, {
'start': function(coords, event) {
startCoords = coords;
Expand All @@ -117,7 +124,7 @@ function makeSwipeDirective(directiveName, direction, eventName) {
});
}
}
});
}, pointerTypes);
};
}]);
}
Expand Down
49 changes: 40 additions & 9 deletions src/ngTouch/swipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ ngTouch.factory('$swipe', [function() {
// The total distance in any direction before we make the call on swipe vs. scroll.
var MOVE_BUFFER_RADIUS = 10;

var POINTER_EVENTS = {
'mouse': {
start: 'mousedown',
move: 'mousemove',
end: 'mouseup'
},
'touch': {
start: 'touchstart',
move: 'touchmove',
end: 'touchend',
cancel: 'touchcancel'
}
};

function getCoordinates(event) {
var touches = event.touches && event.touches.length ? event.touches : [event];
var e = (event.changedTouches && event.changedTouches[0]) ||
Expand All @@ -38,6 +52,17 @@ ngTouch.factory('$swipe', [function() {
};
}

function getEvents(pointerTypes, eventType) {
var res = [];
angular.forEach(pointerTypes, function(pointerType) {
var eventName = POINTER_EVENTS[pointerType][eventType];
if (eventName) {
res.push(eventName);
}
});
return res.join(' ');
}

return {
/**
* @ngdoc method
Expand All @@ -46,6 +71,9 @@ ngTouch.factory('$swipe', [function() {
* @description
* The main method of `$swipe`. It takes an element to be watched for swipe motions, and an
* object containing event handlers.
* The pointer types that should be used can be specified via the optional
* third argument, which is an array of strings `'mouse'` and `'touch'`. By default,
* `$swipe` will listen for `mouse` and `touch` events.
*
* The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end`
* receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }`.
Expand All @@ -68,7 +96,7 @@ ngTouch.factory('$swipe', [function() {
* as described above.
*
*/
bind: function(element, eventHandlers) {
bind: function(element, eventHandlers, pointerTypes) {
// Absolute total movement, used to control swipe vs. scroll.
var totalX, totalY;
// Coordinates of the start position.
Expand All @@ -78,21 +106,24 @@ ngTouch.factory('$swipe', [function() {
// Whether a swipe is active.
var active = false;

element.on('touchstart mousedown', function(event) {
pointerTypes = pointerTypes || ['mouse', 'touch'];
element.on(getEvents(pointerTypes, 'start'), function(event) {
startCoords = getCoordinates(event);
active = true;
totalX = 0;
totalY = 0;
lastPos = startCoords;
eventHandlers['start'] && eventHandlers['start'](startCoords, event);
});
var events = getEvents(pointerTypes, 'cancel');
if (events) {
element.on(events, function(event) {
active = false;
eventHandlers['cancel'] && eventHandlers['cancel'](event);
});
}

element.on('touchcancel', function(event) {
active = false;
eventHandlers['cancel'] && eventHandlers['cancel'](event);
});

element.on('touchmove mousemove', function(event) {
element.on(getEvents(pointerTypes, 'move'), function(event) {
if (!active) return;

// Android will send a touchcancel if it thinks we're starting to scroll.
Expand Down Expand Up @@ -126,7 +157,7 @@ ngTouch.factory('$swipe', [function() {
}
});

element.on('touchend mouseup', function(event) {
element.on(getEvents(pointerTypes, 'end'), function(event) {
if (!active) return;
active = false;
eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event);
Expand Down
18 changes: 18 additions & 0 deletions test/ngTouch/directive/ngSwipeSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ var swipeTests = function(description, restrictBrowsers, startEvent, moveEvent,
expect($rootScope.swiped).toBe(true);
}));

it('should only swipe given ng-swipe-disable-mouse attribute for touch events', inject(function($rootScope, $compile) {
element = $compile('<div ng-swipe-left="swiped = true" ng-swipe-disable-mouse></div>')($rootScope);
$rootScope.$digest();
expect($rootScope.swiped).toBeUndefined();

browserTrigger(element, startEvent, {
keys : [],
x : 100,
y : 20
});
browserTrigger(element, endEvent,{
keys: [],
x: 20,
y: 20
});
expect(!!$rootScope.swiped).toBe(description !== 'mouse');
}));

it('should pass event object', inject(function($rootScope, $compile) {
element = $compile('<div ng-swipe-left="event = $event"></div>')($rootScope);
$rootScope.$digest();
Expand Down
Loading