From ef019dba1de16d2a05975abe46d4b557727f1340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20Bo=CC=88hm?= Date: Mon, 10 Mar 2014 00:42:03 +0100 Subject: [PATCH] feat(ngTouch): add optional ngSwipeDisableMouse attribute to ngSwipe directives to ignore mouse events --- src/ngTouch/directive/ngSwipe.js | 4 ++ src/ngTouch/swipe.js | 18 +++++- test/ngTouch/directive/ngSwipeSpec.js | 47 ++++++++++++++++ test/ngTouch/swipeSpec.js | 81 +++++++++++++++++++++++++++ 4 files changed, 147 insertions(+), 3 deletions(-) diff --git a/src/ngTouch/directive/ngSwipe.js b/src/ngTouch/directive/ngSwipe.js index f19883294385..c31a2df95c4e 100644 --- a/src/ngTouch/directive/ngSwipe.js +++ b/src/ngTouch/directive/ngSwipe.js @@ -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 @@ -96,6 +99,7 @@ function makeSwipeDirective(directiveName, direction, eventName) { } $swipe.bind(element, { + 'disableMouseEvents': angular.isDefined(attr['ngSwipeDisableMouse']), 'start': function(coords, event) { startCoords = coords; valid = true; diff --git a/src/ngTouch/swipe.js b/src/ngTouch/swipe.js index ea79a96c37ec..0fe65a5a874f 100644 --- a/src/ngTouch/swipe.js +++ b/src/ngTouch/swipe.js @@ -78,7 +78,11 @@ ngTouch.factory('$swipe', [function() { // Whether a swipe is active. var active = false; - element.on('touchstart mousedown', function(event) { + var optionalMouseEventStart = ''; + if(!eventHandlers.disableMouseEvents){ + optionalMouseEventStart += ' mousedown'; + } + element.on('touchstart' + optionalMouseEventStart, function(event) { startCoords = getCoordinates(event); active = true; totalX = 0; @@ -92,7 +96,11 @@ ngTouch.factory('$swipe', [function() { eventHandlers['cancel'] && eventHandlers['cancel'](event); }); - element.on('touchmove mousemove', function(event) { + var optionalMouseEventMove = ''; + if(!eventHandlers.disableMouseEvents){ + optionalMouseEventMove += ' mousemove'; + } + element.on('touchmove' + optionalMouseEventMove, function(event) { if (!active) return; // Android will send a touchcancel if it thinks we're starting to scroll. @@ -126,7 +134,11 @@ ngTouch.factory('$swipe', [function() { } }); - element.on('touchend mouseup', function(event) { + var optionalMouseEventEnd = ''; + if(!eventHandlers.disableMouseEvents){ + optionalMouseEventEnd += ' mouseup'; + } + element.on('touchend' + optionalMouseEventEnd, function(event) { if (!active) return; active = false; eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event); diff --git a/test/ngTouch/directive/ngSwipeSpec.js b/test/ngTouch/directive/ngSwipeSpec.js index b46a9384e5f9..626ddb02ca7f 100644 --- a/test/ngTouch/directive/ngSwipeSpec.js +++ b/test/ngTouch/directive/ngSwipeSpec.js @@ -66,6 +66,53 @@ var swipeTests = function(description, restrictBrowsers, startEvent, moveEvent, expect($rootScope.swiped).toBe(true); })); + it('should not swipe to the left if ng-swipe-disable-mouse attribute is set', inject(function($rootScope, $compile) { + element = $compile('
')($rootScope); + $rootScope.$digest(); + expect($rootScope.swiped).toBeUndefined(); + + browserTrigger(element, startEvent, { + keys : [], + x : 100, + y : 20 + }); + browserTrigger(element, endEvent,{ + keys: [], + x: 20, + y: 20 + }); + if(description === 'mouse'){ + expect($rootScope.swiped).toBeUndefined(); + } + else{ + expect($rootScope.swiped).toBe(true); + } + })); + + + it('should not swipe to the left if ng-swipe-disable-mouse attribute is set', inject(function($rootScope, $compile) { + element = $compile('
')($rootScope); + $rootScope.$digest(); + expect($rootScope.swiped).toBeUndefined(); + + browserTrigger(element, startEvent, { + keys : [], + x : 100, + y : 20 + }); + browserTrigger(element, endEvent,{ + keys: [], + x: 20, + y: 20 + }); + if(description === 'mouse'){ + expect($rootScope.swiped).toBeUndefined(); + } + else{ + expect($rootScope.swiped).toBe(true); + } + })); + it('should pass event object', inject(function($rootScope, $compile) { element = $compile('
')($rootScope); $rootScope.$digest(); diff --git a/test/ngTouch/swipeSpec.js b/test/ngTouch/swipeSpec.js index 1eb53e45d619..a635637c61d8 100644 --- a/test/ngTouch/swipeSpec.js +++ b/test/ngTouch/swipeSpec.js @@ -239,6 +239,87 @@ var swipeTests = function(description, restrictBrowsers, startEvent, moveEvent, expect(events.cancel).not.toHaveBeenCalled(); })); + it('should not trigger a "start", many "move"s and an "end" for mouse if "disableMouseEvents" is set to "true"', inject(function($rootScope, $swipe, $compile) { + element = $compile('
')($rootScope); + var events = { + disableMouseEvents: 'true', + start: jasmine.createSpy('startSpy'), + move: jasmine.createSpy('moveSpy'), + cancel: jasmine.createSpy('cancelSpy'), + end: jasmine.createSpy('endSpy') + }; + + $swipe.bind(element, events); + + expect(events.start).not.toHaveBeenCalled(); + expect(events.move).not.toHaveBeenCalled(); + expect(events.cancel).not.toHaveBeenCalled(); + expect(events.end).not.toHaveBeenCalled(); + + browserTrigger(element, startEvent,{ + keys: [], + x: 100, + y: 40 + }); + + browserTrigger(element, moveEvent,{ + keys: [], + x: 120, + y: 40 + }); + browserTrigger(element, moveEvent,{ + keys: [], + x: 130, + y: 40 + }); + browserTrigger(element, moveEvent,{ + keys: [], + x: 140, + y: 40 + }); + browserTrigger(element, moveEvent,{ + keys: [], + x: 150, + y: 40 + }); + browserTrigger(element, moveEvent,{ + keys: [], + x: 160, + y: 40 + }); + browserTrigger(element, moveEvent,{ + keys: [], + x: 170, + y: 40 + }); + browserTrigger(element, moveEvent,{ + keys: [], + x: 180, + y: 40 + }); + + browserTrigger(element, endEvent,{ + keys: [], + x: 200, + y: 40 + }); + + + if(description === 'mouse'){ + expect(events.start).not.toHaveBeenCalled(); + expect(events.move).not.toHaveBeenCalled(); + expect(events.cancel).not.toHaveBeenCalled(); + expect(events.end).not.toHaveBeenCalled(); + } + else{ + expect(events.start).toHaveBeenCalled(); + expect(events.move.calls.length).toBe(7); + expect(events.end).toHaveBeenCalled(); + + expect(events.cancel).not.toHaveBeenCalled(); + } + })); + it('should not start sending "move"s until enough horizontal motion is accumulated', inject(function($rootScope, $swipe, $compile) { element = $compile('
')($rootScope); var events = {