Skip to content

Commit eff91c5

Browse files
Portugal, Marcelomportuga
authored andcommitted
refactor(custom-scrolling.js): Update scroller logic and unit tests.
1 parent b2e4c8d commit eff91c5

File tree

2 files changed

+83
-65
lines changed

2 files changed

+83
-65
lines changed

src/features/custom-scrolling/js/custom-scrolling.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,14 @@
6262
*/
6363
module.factory('uiGridScroller', ['$window', 'gridUtil', 'uiGridScrollerConstants',
6464
function($window, gridUtil, uiGridScrollerConstants) {
65-
var isAnimating;
65+
66+
/**
67+
* @ngdoc object
68+
* @name isAnimating
69+
* @propertyOf ui.grid.customScrolling.service:uiGridScroller
70+
* @description Keeps track of whether or not the scrolling is animating.
71+
*/
72+
uiGridScroller.isAnimating = false;
6673

6774
/**
6875
* @ngdoc object
@@ -124,7 +131,7 @@
124131
startTime = (new Date()).getTime();
125132
startX = element[0].scrollLeft;
126133
startY = element[0].scrollTop;
127-
isAnimating = false;
134+
uiGridScroller.isAnimating = false;
128135
}
129136

130137
/**
@@ -311,7 +318,7 @@
311318
startY = element[0].scrollTop,
312319
destTime = startTime + duration;
313320

314-
isAnimating = true;
321+
uiGridScroller.isAnimating = true;
315322

316323
next();
317324

@@ -320,7 +327,7 @@
320327
relPoint, easeRes, newX, newY;
321328

322329
if (now >= destTime) {
323-
isAnimating = false;
330+
uiGridScroller.isAnimating = false;
324331
translate(destX, destY, element);
325332
element.on('scroll', callback);
326333
return;
@@ -337,7 +344,7 @@
337344

338345
callback.call();
339346

340-
if (isAnimating) {
347+
if (uiGridScroller.isAnimating && angular.isFunction(window.requestAnimationFrame)) {
341348
window.requestAnimationFrame(next);
342349
} else {
343350
element.on('scroll', callback);

src/features/custom-scrolling/test/ui-grid-custom-scroller.factory.spec.js

Lines changed: 71 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,31 @@
22
'use strict';
33

44
describe('uiGridScroller', function() {
5-
var element, scrollHandler, gridUtil, uiGridScroller, uiGridScrollerConstants;
5+
var element, scrollHandler, gridUtil, uiGridScroller, uiGridScrollerConstants,
6+
callbacks = {};
67

78
beforeEach(function() {
89
element = {
910
0: {
11+
scrollTop: 0,
12+
scrollLeft: 0,
13+
clientWidth: 300,
14+
clientHeight: 300,
1015
children: {
11-
0: {}
16+
0: {
17+
offsetWidth: 300,
18+
offsetHeight: 300
19+
}
1220
}
1321
},
14-
on: jasmine.createSpy('on'),
15-
off: jasmine.createSpy('off')
22+
on: jasmine.createSpy('on').and.callFake(function(eventName, callback) {
23+
callbacks[eventName] = callback;
24+
}),
25+
off: jasmine.createSpy('off'),
26+
trigger: function(eventName, args) {
27+
args.type = eventName;
28+
callbacks[eventName](args);
29+
}
1630
};
1731
scrollHandler = jasmine.createSpy('scrollHandler');
1832

@@ -23,6 +37,8 @@
2337
uiGridScrollerConstants = _uiGridScrollerConstants_;
2438
gridUtil = _gridUtil_;
2539
});
40+
41+
spyOn(window, 'requestAnimationFrame').and.callFake(jasmine.createSpy('requestAnimationFrame'));
2642
});
2743

2844
describe('when gridUtils.isTouchEnabled returns true', function() {
@@ -45,48 +61,42 @@
4561
it('should initialize touchcancel', function() {
4662
expect(element.on).toHaveBeenCalledWith('touchcancel', jasmine.any(Function));
4763
});
48-
xdescribe('events', function() {
64+
describe('events', function() {
4965
describe('on touchstart', function() {
5066
beforeEach(function() {
51-
element.on.and.callFake(function(eventName, callback) {
52-
if (eventName === 'touchstart') {
53-
callback({
54-
type: eventName,
55-
touches: [true]
56-
});
57-
}
67+
element.trigger('touchstart', {
68+
touches: [{
69+
pageX: 0,
70+
pageY: 0
71+
}]
5872
});
59-
uiGridScroller(element, scrollHandler);
6073
});
6174
it('should remove the scroll event from the element', function() {
6275
expect(element.off).toHaveBeenCalledWith('scroll', scrollHandler);
6376
});
6477
it('should update the uiGridScroller.initiated value to TOUCHABLE', function() {
6578
expect(uiGridScroller.initiated).toEqual(uiGridScrollerConstants.scrollType.TOUCHABLE);
6679
});
67-
afterEach(function() {
68-
element.on.and.callFake(angular.noop);
80+
it('should update the uiGridScroller.isAnimating value to false', function() {
81+
expect(uiGridScroller.isAnimating).toBe(false);
6982
});
7083
});
7184
describe('on touchmove', function() {
7285
var preventDefaultSpy;
7386

7487
beforeEach(function() {
7588
preventDefaultSpy = jasmine.createSpy('preventDefault');
76-
element.on.and.callFake(function(eventName, callback) {
77-
if (eventName === 'touchmove') {
78-
callback({
79-
type: eventName,
80-
touches: [true],
81-
preventDefault: preventDefaultSpy
82-
});
83-
}
84-
});
8589
});
8690
describe('when the uiGridScroller has been initiated with a touch event', function() {
8791
beforeEach(function() {
8892
uiGridScroller.initiated = uiGridScrollerConstants.scrollType.TOUCHABLE;
89-
uiGridScroller(element, scrollHandler);
93+
element.trigger('touchmove', {
94+
touches: [{
95+
pageX: 0,
96+
pageY: 0
97+
}],
98+
preventDefault: preventDefaultSpy
99+
});
90100
});
91101
it('should prevent the default behavior', function() {
92102
expect(preventDefaultSpy).toHaveBeenCalled();
@@ -98,7 +108,13 @@
98108
describe('when the uiGridScroller has not been initiated with a touch event', function() {
99109
beforeEach(function() {
100110
uiGridScroller.initiated = uiGridScrollerConstants.scrollType.NONE;
101-
uiGridScroller(element, scrollHandler);
111+
element.trigger('touchmove', {
112+
touches: [{
113+
pageX: 0,
114+
pageY: 0
115+
}],
116+
preventDefault: preventDefaultSpy
117+
});
102118
});
103119
it('should prevent the default behavior', function() {
104120
expect(preventDefaultSpy).toHaveBeenCalled();
@@ -107,61 +123,56 @@
107123
expect(scrollHandler).not.toHaveBeenCalled();
108124
});
109125
});
110-
afterEach(function() {
111-
element.on.and.callFake(angular.noop);
112-
});
113126
});
114-
function testEndFunction() {
127+
function testEndFunction(eventName) {
115128
describe('when the uiGridScroller has been initiated with a touch event', function() {
116129
beforeEach(function() {
130+
uiGridScroller.isAnimating = false;
117131
uiGridScroller.initiated = uiGridScrollerConstants.scrollType.TOUCHABLE;
118-
uiGridScroller(element, scrollHandler);
132+
element.trigger(eventName, {
133+
touches: [{
134+
pageX: 0,
135+
pageY: 0
136+
}]
137+
});
119138
});
120139
it('should update the uiGridScroller.initiated value to NONE', function() {
121140
expect(uiGridScroller.initiated).toEqual(uiGridScrollerConstants.scrollType.NONE);
122141
});
142+
it('should update the uiGridScroller.isAnimating value to true', function() {
143+
expect(uiGridScroller.isAnimating).toBe(true);
144+
});
145+
it('should call requestAnimationFrame in the window', function() {
146+
expect(window.requestAnimationFrame).toHaveBeenCalled();
147+
});
123148
});
124149
describe('when the uiGridScroller has not been initiated with a touch event', function() {
125150
beforeEach(function() {
151+
uiGridScroller.isAnimating = false;
126152
uiGridScroller.initiated = uiGridScrollerConstants.scrollType.MOUSE;
127-
uiGridScroller(element, scrollHandler);
153+
element.trigger(eventName, {
154+
touches: [{
155+
pageX: 0,
156+
pageY: 0
157+
}]
158+
});
128159
});
129160
it('should not update the uiGridScroller.initiated value', function() {
130161
expect(uiGridScroller.initiated).toEqual(uiGridScrollerConstants.scrollType.MOUSE);
131162
});
132-
});
133-
afterEach(function() {
134-
element.on.and.callFake(angular.noop);
163+
it('should not update the uiGridScroller.isAnimating value', function() {
164+
expect(uiGridScroller.isAnimating).toBe(false);
165+
});
166+
it('should not call requestAnimationFrame in the window', function() {
167+
expect(window.requestAnimationFrame).not.toHaveBeenCalled();
168+
});
135169
});
136170
}
137171
describe('on touchend', function() {
138-
beforeEach(function() {
139-
element.on.and.callFake(function(eventName, callback) {
140-
if (eventName === 'touchend') {
141-
callback({
142-
type: eventName,
143-
touches: [true]
144-
});
145-
}
146-
});
147-
});
148-
testEndFunction();
172+
testEndFunction('touchend');
149173
});
150174
describe('on touchcancel', function() {
151-
beforeEach(function() {
152-
element.on.and.callFake(function(eventName, callback) {
153-
if (eventName === 'touchcancel') {
154-
callback({
155-
type: eventName,
156-
touches: [true]
157-
});
158-
}
159-
});
160-
});
161-
it('should be initialized', function() {
162-
expect(element.on).toHaveBeenCalledWith('touchcancel', jasmine.any(Function));
163-
});
164-
testEndFunction();
175+
testEndFunction('touchcancel');
165176
});
166177
});
167178
afterEach(function() {

0 commit comments

Comments
 (0)