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

fix($swipe): add pointer support #14791

Closed
wants to merge 1 commit into from
Closed
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
22 changes: 14 additions & 8 deletions src/ngTouch/swipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ ngTouch.factory('$swipe', [function() {
move: 'touchmove',
end: 'touchend',
cancel: 'touchcancel'
},
'pointer': {
start: 'pointerdown',
move: 'pointermove',
end: 'pointerup',
cancel: 'pointercancel'
}
};

Expand Down Expand Up @@ -69,28 +75,28 @@ ngTouch.factory('$swipe', [function() {
* 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.
* third argument, which is an array of strings `'mouse'`, `'touch'` and `'pointer'`. By default,
* `$swipe` will listen for `mouse`, `touch` and `pointer` 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 }` and the raw
* `event`. `cancel` receives the raw `event` as its single parameter.
*
* `start` is called on either `mousedown` or `touchstart`. After this event, `$swipe` is
* watching for `touchmove` or `mousemove` events. These events are ignored until the total
* `start` is called on either `mousedown`, `touchstart` or `pointerdown`. After this event, `$swipe` is
* watching for `touchmove`, `mousemove` or `pointermove` events. These events are ignored until the total
* distance moved in either dimension exceeds a small threshold.
*
* Once this threshold is exceeded, either the horizontal or vertical delta is greater.
* - If the horizontal distance is greater, this is a swipe and `move` and `end` events follow.
* - If the vertical distance is greater, this is a scroll, and we let the browser take over.
* A `cancel` event is sent.
*
* `move` is called on `mousemove` and `touchmove` after the above logic has determined that
* `move` is called on `mousemove`, `touchmove` and `pointermove` after the above logic has determined that
* a swipe is in progress.
*
* `end` is called when a swipe is successfully completed with a `touchend` or `mouseup`.
* `end` is called when a swipe is successfully completed with a `touchend`, `mouseup` or `pointerup`.
*
* `cancel` is called either on a `touchcancel` from the browser, or when we begin scrolling
* `cancel` is called either on a `touchcancel` or `pointercancel` from the browser, or when we begin scrolling
* as described above.
*
*/
Expand All @@ -104,7 +110,7 @@ ngTouch.factory('$swipe', [function() {
// Whether a swipe is active.
var active = false;

pointerTypes = pointerTypes || ['mouse', 'touch'];
pointerTypes = pointerTypes || ['mouse', 'touch', 'pointer'];
element.on(getEvents(pointerTypes, 'start'), function(event) {
startCoords = getCoordinates(event);
active = true;
Expand Down
26 changes: 24 additions & 2 deletions test/ngTouch/swipeSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ describe('$swipe', function() {
var usedEvents;
var MOUSE_EVENTS = ['mousedown','mousemove','mouseup'].sort();
var TOUCH_EVENTS = ['touchcancel','touchend','touchmove','touchstart'].sort();
var ALL_EVENTS = MOUSE_EVENTS.concat(TOUCH_EVENTS).sort();
var POINTER_EVENTS = ['pointerdown', 'pointermove', 'pointerup', 'pointercancel'].sort();
var ALL_EVENTS = MOUSE_EVENTS.concat(TOUCH_EVENTS, POINTER_EVENTS).sort();

beforeEach(function() {
usedEvents = [];
Expand All @@ -36,7 +37,7 @@ describe('$swipe', function() {
});
});

it('should use mouse and touch by default', inject(function($swipe) {
it('should use mouse, touch and pointer by default', inject(function($swipe) {
$swipe.bind(element, events);
expect(usedEvents.sort()).toEqual(ALL_EVENTS);
}));
Expand All @@ -51,14 +52,35 @@ describe('$swipe', function() {
expect(usedEvents.sort()).toEqual(TOUCH_EVENTS);
}));

it('should only use pointer events for pointerType "pointer"', inject(function($swipe) {
$swipe.bind(element, events, ['pointer']);
expect(usedEvents.sort()).toEqual(POINTER_EVENTS);
}));

it('should use mouse and touch if both are specified', inject(function($swipe) {
$swipe.bind(element, events, ['touch', 'mouse']);
expect(usedEvents.sort()).toEqual(MOUSE_EVENTS.concat(TOUCH_EVENTS).sort());
}));

it('should use mouse and pointer if both are specified', inject(function($swipe) {
$swipe.bind(element, events, ['mouse', 'pointer']);
expect(usedEvents.sort()).toEqual(MOUSE_EVENTS.concat(POINTER_EVENTS).sort());
}));

it('should use touch and pointer if both are specified', inject(function($swipe) {
$swipe.bind(element, events, ['touch', 'pointer']);
expect(usedEvents.sort()).toEqual(TOUCH_EVENTS.concat(POINTER_EVENTS).sort());
}));

it('should use mouse, touch and pointer if they are specified', inject(function($swipe) {
$swipe.bind(element, events, ['mouse', 'touch', 'pointer']);
expect(usedEvents.sort()).toEqual(ALL_EVENTS);
}));

});

swipeTests('touch', /* restrictBrowers */ true, 'touchstart', 'touchmove', 'touchend');
swipeTests('pointer', /* restrictBrowers */ true, 'pointerdown', 'pointermove', 'pointerup');
swipeTests('mouse', /* restrictBrowers */ false, 'mousedown', 'mousemove', 'mouseup');

// Wrapper to abstract over using touch events or mouse events.
Expand Down