Skip to content

Commit

Permalink
refactor(custom-scrolling.js): Update scroller logic and unit tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Portugal, Marcelo authored and mportuga committed Dec 9, 2016
1 parent b2e4c8d commit eff91c5
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 65 deletions.
17 changes: 12 additions & 5 deletions src/features/custom-scrolling/js/custom-scrolling.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,14 @@
*/
module.factory('uiGridScroller', ['$window', 'gridUtil', 'uiGridScrollerConstants',
function($window, gridUtil, uiGridScrollerConstants) {
var isAnimating;

/**
* @ngdoc object
* @name isAnimating
* @propertyOf ui.grid.customScrolling.service:uiGridScroller
* @description Keeps track of whether or not the scrolling is animating.
*/
uiGridScroller.isAnimating = false;

/**
* @ngdoc object
Expand Down Expand Up @@ -124,7 +131,7 @@
startTime = (new Date()).getTime();
startX = element[0].scrollLeft;
startY = element[0].scrollTop;
isAnimating = false;
uiGridScroller.isAnimating = false;
}

/**
Expand Down Expand Up @@ -311,7 +318,7 @@
startY = element[0].scrollTop,
destTime = startTime + duration;

isAnimating = true;
uiGridScroller.isAnimating = true;

next();

Expand All @@ -320,7 +327,7 @@
relPoint, easeRes, newX, newY;

if (now >= destTime) {
isAnimating = false;
uiGridScroller.isAnimating = false;
translate(destX, destY, element);
element.on('scroll', callback);
return;
Expand All @@ -337,7 +344,7 @@

callback.call();

if (isAnimating) {
if (uiGridScroller.isAnimating && angular.isFunction(window.requestAnimationFrame)) {
window.requestAnimationFrame(next);
} else {
element.on('scroll', callback);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,31 @@
'use strict';

describe('uiGridScroller', function() {
var element, scrollHandler, gridUtil, uiGridScroller, uiGridScrollerConstants;
var element, scrollHandler, gridUtil, uiGridScroller, uiGridScrollerConstants,
callbacks = {};

beforeEach(function() {
element = {
0: {
scrollTop: 0,
scrollLeft: 0,
clientWidth: 300,
clientHeight: 300,
children: {
0: {}
0: {
offsetWidth: 300,
offsetHeight: 300
}
}
},
on: jasmine.createSpy('on'),
off: jasmine.createSpy('off')
on: jasmine.createSpy('on').and.callFake(function(eventName, callback) {
callbacks[eventName] = callback;
}),
off: jasmine.createSpy('off'),
trigger: function(eventName, args) {
args.type = eventName;
callbacks[eventName](args);
}
};
scrollHandler = jasmine.createSpy('scrollHandler');

Expand All @@ -23,6 +37,8 @@
uiGridScrollerConstants = _uiGridScrollerConstants_;
gridUtil = _gridUtil_;
});

spyOn(window, 'requestAnimationFrame').and.callFake(jasmine.createSpy('requestAnimationFrame'));
});

describe('when gridUtils.isTouchEnabled returns true', function() {
Expand All @@ -45,48 +61,42 @@
it('should initialize touchcancel', function() {
expect(element.on).toHaveBeenCalledWith('touchcancel', jasmine.any(Function));
});
xdescribe('events', function() {
describe('events', function() {
describe('on touchstart', function() {
beforeEach(function() {
element.on.and.callFake(function(eventName, callback) {
if (eventName === 'touchstart') {
callback({
type: eventName,
touches: [true]
});
}
element.trigger('touchstart', {
touches: [{
pageX: 0,
pageY: 0
}]
});
uiGridScroller(element, scrollHandler);
});
it('should remove the scroll event from the element', function() {
expect(element.off).toHaveBeenCalledWith('scroll', scrollHandler);
});
it('should update the uiGridScroller.initiated value to TOUCHABLE', function() {
expect(uiGridScroller.initiated).toEqual(uiGridScrollerConstants.scrollType.TOUCHABLE);
});
afterEach(function() {
element.on.and.callFake(angular.noop);
it('should update the uiGridScroller.isAnimating value to false', function() {
expect(uiGridScroller.isAnimating).toBe(false);
});
});
describe('on touchmove', function() {
var preventDefaultSpy;

beforeEach(function() {
preventDefaultSpy = jasmine.createSpy('preventDefault');
element.on.and.callFake(function(eventName, callback) {
if (eventName === 'touchmove') {
callback({
type: eventName,
touches: [true],
preventDefault: preventDefaultSpy
});
}
});
});
describe('when the uiGridScroller has been initiated with a touch event', function() {
beforeEach(function() {
uiGridScroller.initiated = uiGridScrollerConstants.scrollType.TOUCHABLE;
uiGridScroller(element, scrollHandler);
element.trigger('touchmove', {
touches: [{
pageX: 0,
pageY: 0
}],
preventDefault: preventDefaultSpy
});
});
it('should prevent the default behavior', function() {
expect(preventDefaultSpy).toHaveBeenCalled();
Expand All @@ -98,7 +108,13 @@
describe('when the uiGridScroller has not been initiated with a touch event', function() {
beforeEach(function() {
uiGridScroller.initiated = uiGridScrollerConstants.scrollType.NONE;
uiGridScroller(element, scrollHandler);
element.trigger('touchmove', {
touches: [{
pageX: 0,
pageY: 0
}],
preventDefault: preventDefaultSpy
});
});
it('should prevent the default behavior', function() {
expect(preventDefaultSpy).toHaveBeenCalled();
Expand All @@ -107,61 +123,56 @@
expect(scrollHandler).not.toHaveBeenCalled();
});
});
afterEach(function() {
element.on.and.callFake(angular.noop);
});
});
function testEndFunction() {
function testEndFunction(eventName) {
describe('when the uiGridScroller has been initiated with a touch event', function() {
beforeEach(function() {
uiGridScroller.isAnimating = false;
uiGridScroller.initiated = uiGridScrollerConstants.scrollType.TOUCHABLE;
uiGridScroller(element, scrollHandler);
element.trigger(eventName, {
touches: [{
pageX: 0,
pageY: 0
}]
});
});
it('should update the uiGridScroller.initiated value to NONE', function() {
expect(uiGridScroller.initiated).toEqual(uiGridScrollerConstants.scrollType.NONE);
});
it('should update the uiGridScroller.isAnimating value to true', function() {
expect(uiGridScroller.isAnimating).toBe(true);
});
it('should call requestAnimationFrame in the window', function() {
expect(window.requestAnimationFrame).toHaveBeenCalled();
});
});
describe('when the uiGridScroller has not been initiated with a touch event', function() {
beforeEach(function() {
uiGridScroller.isAnimating = false;
uiGridScroller.initiated = uiGridScrollerConstants.scrollType.MOUSE;
uiGridScroller(element, scrollHandler);
element.trigger(eventName, {
touches: [{
pageX: 0,
pageY: 0
}]
});
});
it('should not update the uiGridScroller.initiated value', function() {
expect(uiGridScroller.initiated).toEqual(uiGridScrollerConstants.scrollType.MOUSE);
});
});
afterEach(function() {
element.on.and.callFake(angular.noop);
it('should not update the uiGridScroller.isAnimating value', function() {
expect(uiGridScroller.isAnimating).toBe(false);
});
it('should not call requestAnimationFrame in the window', function() {
expect(window.requestAnimationFrame).not.toHaveBeenCalled();
});
});
}
describe('on touchend', function() {
beforeEach(function() {
element.on.and.callFake(function(eventName, callback) {
if (eventName === 'touchend') {
callback({
type: eventName,
touches: [true]
});
}
});
});
testEndFunction();
testEndFunction('touchend');
});
describe('on touchcancel', function() {
beforeEach(function() {
element.on.and.callFake(function(eventName, callback) {
if (eventName === 'touchcancel') {
callback({
type: eventName,
touches: [true]
});
}
});
});
it('should be initialized', function() {
expect(element.on).toHaveBeenCalledWith('touchcancel', jasmine.any(Function));
});
testEndFunction();
testEndFunction('touchcancel');
});
});
afterEach(function() {
Expand Down

0 comments on commit eff91c5

Please sign in to comment.