mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
feat(refresher): Allow refrsher to work with native scrolling
This update allows `<ion-refresher>` to work with native scrolling. Native scrolling can be enabled in the state deffinition, through the `$ionicConfigProvider` like `$ionicConfig.scrolling.jsScrolling(false);` or in the controller directly. It should function exactly the same as with JS scrolling enabled. This is a merge of the wip-scrolling branch.
This commit is contained in:
129
test/unit/angular/controller/refreshController.unit.js
Normal file
129
test/unit/angular/controller/refreshController.unit.js
Normal file
@@ -0,0 +1,129 @@
|
||||
describe('$ionicRefresh Controller', function() {
|
||||
|
||||
beforeEach(module('ionic'));
|
||||
beforeEach(inject(function($ionicConfig) {
|
||||
ionic.Platform.ready = function(cb) { cb(); };
|
||||
ionic.requestAnimationFrame = function(cb) { cb(); };
|
||||
$ionicConfig.scrolling.jsScrolling(false);
|
||||
}));
|
||||
|
||||
function setup(options) {
|
||||
options = options || {};
|
||||
options.el = options.el ||
|
||||
angular.element('<ion-refresher></ion-refresher><div class="list"></div>')[0];
|
||||
scrollEl = options.parent ||
|
||||
angular.element('<div class="ionic-scroll"><div class="scroll"></div></div>');
|
||||
scrollEl.find('.scroll').append(options.el);
|
||||
|
||||
inject(function($controller, $rootScope, $timeout, $compile) {
|
||||
scope = $rootScope.$new();
|
||||
|
||||
$compile(scrollEl)(scope);
|
||||
scope.$apply();
|
||||
scope.$onRefresh = jasmine.createSpy('onRefresh');
|
||||
scope.$onPulling = jasmine.createSpy('onPulling');
|
||||
refresher = scrollEl.find('.scroll-refresher')[0];
|
||||
ctrl = angular.element(refresher).controller('ionRefresher');
|
||||
timeout = $timeout;
|
||||
});
|
||||
}
|
||||
function evt(y) {
|
||||
return {
|
||||
touches: [
|
||||
{screenY:y}
|
||||
],
|
||||
preventDefault: function() {}
|
||||
};
|
||||
}
|
||||
|
||||
it('should error if not child of scroll view', function() {
|
||||
setup({parent: angular.element('<div></div>')});
|
||||
expect(ctrl).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should oversroll using CSS transforms', function() {
|
||||
setup();
|
||||
|
||||
ctrl.__handleTouchmove(evt(0));
|
||||
ctrl.__handleTouchmove(evt(10));
|
||||
ctrl.__handleTouchmove(evt(20));
|
||||
expect(ctrl.__getScrollChild().style[ionic.CSS.TRANSFORM]).toBe('translateY(10px)');
|
||||
expect(ctrl.__getScrollChild().classList.contains('overscroll')).toBe(true);
|
||||
expect(refresher.classList.contains('invisible')).toBe(false);
|
||||
});
|
||||
|
||||
it('should resume native scrolling when overscroll is done', function() {
|
||||
setup();
|
||||
var domMethods = ctrl.getRefresherDomMethods();
|
||||
spyOn(domMethods, 'activate');
|
||||
spyOn(domMethods, 'deactivate');
|
||||
|
||||
ctrl.__handleTouchmove(evt(0));
|
||||
ctrl.__handleTouchmove(evt(10));
|
||||
expect(refresher.classList.contains('invisible')).toBe(false);
|
||||
ctrl.__handleTouchmove(evt(0));
|
||||
expect(ctrl.__getScrollChild().style[ionic.CSS.TRANSFORM]).toBe('translateY(0px)');
|
||||
expect(ctrl.__getScrollChild().classList.contains('overscroll')).toBe(false);
|
||||
expect(refresher.classList.contains('invisible')).toBe(true);
|
||||
});
|
||||
|
||||
it('should activate and deactivate when dragging past activation threshold', function() {
|
||||
setup();
|
||||
var domMethods = ctrl.getRefresherDomMethods();
|
||||
spyOn(domMethods, 'activate');
|
||||
spyOn(domMethods, 'deactivate');
|
||||
|
||||
ctrl.__handleTouchmove(evt(0));
|
||||
ctrl.__handleTouchmove(evt(10));
|
||||
ctrl.__handleTouchmove(evt(100));
|
||||
expect(ctrl.__getScrollChild().style[ionic.CSS.TRANSFORM]).toBe('translateY(90px)');
|
||||
expect(ctrl.__getScrollChild().classList.contains('overscroll')).toBe(true);
|
||||
expect(refresher.classList.contains('invisible')).toBe(false);
|
||||
expect(refresher.classList.contains('active')).toBe(true);
|
||||
|
||||
ctrl.__handleTouchmove(evt(0));
|
||||
timeout.flush();
|
||||
expect(ctrl.__getScrollChild().style[ionic.CSS.TRANSFORM]).toBe('translateY(0px)');
|
||||
expect(ctrl.__getScrollChild().classList.contains('overscroll')).toBe(false);
|
||||
expect(refresher.classList.contains('invisible')).toBe(true);
|
||||
expect(refresher.classList.contains('active')).toBe(false);
|
||||
});
|
||||
|
||||
it('should update refresher class when shared methods fire', function() {
|
||||
setup();
|
||||
|
||||
scope.$onRefresh = jasmine.createSpy('onRefresh');
|
||||
scope.$onPulling = jasmine.createSpy('onPulling');
|
||||
|
||||
|
||||
expect(refresher.classList.contains('active')).toBe(false);
|
||||
expect(refresher.classList.contains('refreshing')).toBe(false);
|
||||
expect(refresher.classList.contains('invisible')).toBe(true);
|
||||
expect(scope.$onRefresh).not.toHaveBeenCalled();
|
||||
expect(scope.$onPulling).not.toHaveBeenCalled();
|
||||
|
||||
ctrl.getRefresherDomMethods().show();
|
||||
expect(refresher.classList.contains('invisible')).toBe(false);
|
||||
|
||||
ctrl.getRefresherDomMethods().activate();
|
||||
expect(refresher.classList.contains('active')).toBe(true);
|
||||
expect(refresher.classList.contains('refreshing')).toBe(false);
|
||||
expect(scope.$onPulling).toHaveBeenCalled();
|
||||
|
||||
ctrl.getRefresherDomMethods().start();
|
||||
expect(refresher.classList.contains('refreshing')).toBe(true);
|
||||
expect(scope.$onRefresh).toHaveBeenCalled();
|
||||
|
||||
ctrl.getRefresherDomMethods().tail();
|
||||
expect(refresher.classList.contains('refreshing-tail')).toBe(true);
|
||||
|
||||
ctrl.getRefresherDomMethods().deactivate();
|
||||
timeout.flush();
|
||||
expect(refresher.classList.contains('active')).toBe(false);
|
||||
expect(refresher.classList.contains('refreshing')).toBe(false);
|
||||
expect(refresher.classList.contains('refreshing-tail')).toBe(false);
|
||||
|
||||
ctrl.getRefresherDomMethods().hide();
|
||||
expect(refresher.classList.contains('invisible')).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -242,19 +242,41 @@ describe('$ionicScroll Controller', function() {
|
||||
expect(ctrl.scrollView.activatePullToRefresh).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should activatePullToRefresh and work when setRefresher', function() {
|
||||
var startCb, refreshingCb, doneCb, refresherEl;
|
||||
it('should activatePullToRefresh and work when setRefresher', inject(function($compile) {
|
||||
var refresherEl,
|
||||
activateCB,
|
||||
deactivateCB,
|
||||
startCB,
|
||||
showCB,
|
||||
hideCB,
|
||||
tailCB,
|
||||
onPullProgressCB;
|
||||
setup({
|
||||
el: angular.element('<div><div class="scroll-refresher"></div></div>')[0]
|
||||
el: angular.element('<div><ion-refresher class="refresher"></ion-refresher></div>')[0]
|
||||
});
|
||||
spyOn(ctrl.scrollView, 'activatePullToRefresh').andCallFake(function(height, start, refreshing, done, show, hide) {
|
||||
startCb = start;
|
||||
refreshingCb = refreshing;
|
||||
doneCb = done;
|
||||
showCb = show;
|
||||
hideCb = hide;
|
||||
|
||||
$compile(ctrl.element)(scope);
|
||||
scope.$apply();
|
||||
|
||||
spyOn(ctrl.scrollView, 'activatePullToRefresh').andCallFake(function(height, start, done, refreshing, show, hide, tail, onPull) {
|
||||
activateCB = start;
|
||||
deactivateCB = done;
|
||||
startCB = refreshing;
|
||||
showCB = show;
|
||||
hideCB = hide;
|
||||
tailCB = tail;
|
||||
onPullProgressCB = onPull;
|
||||
});
|
||||
ctrl._setRefresher(scope, ctrl.element);
|
||||
|
||||
var refresher = ctrl.refresher;
|
||||
var refreshCtrl = angular.element(refresher).controller('ionRefresher');
|
||||
var dm = refreshCtrl.getRefresherDomMethods()
|
||||
|
||||
ctrl._setRefresher(
|
||||
scope,
|
||||
ctrl.element,
|
||||
dm
|
||||
);
|
||||
|
||||
var scrollOnRefreshSpy = jasmine.createSpy('scroll.onRefresh');
|
||||
|
||||
@@ -262,31 +284,29 @@ describe('$ionicScroll Controller', function() {
|
||||
scope.$onPulling = jasmine.createSpy('onPulling');
|
||||
|
||||
timeout.flush();
|
||||
var refresher = ctrl.refresher;
|
||||
|
||||
expect(refresher.classList.contains('active')).toBe(false);
|
||||
expect(refresher.classList.contains('refreshing')).toBe(false);
|
||||
|
||||
startCb();
|
||||
dm.activate();
|
||||
expect(refresher.classList.contains('active')).toBe(true);
|
||||
expect(refresher.classList.contains('refreshing')).toBe(false);
|
||||
expect(scope.$onPulling).toHaveBeenCalled();
|
||||
|
||||
refreshingCb();
|
||||
expect(refresher.classList.contains('refreshing')).toBe(false);
|
||||
|
||||
expect(scope.$onRefresh).not.toHaveBeenCalled();
|
||||
|
||||
doneCb();
|
||||
dm.start();
|
||||
expect(refresher.classList.contains('refreshing')).toBe(true);
|
||||
expect(scope.$onRefresh).toHaveBeenCalled();
|
||||
|
||||
dm.deactivate();
|
||||
timeout.flush();
|
||||
expect(refresher.classList.contains('active')).toBe(false);
|
||||
|
||||
showCb();
|
||||
dm.show();
|
||||
expect(refresher.classList.contains('invisible')).toBe(false);
|
||||
|
||||
hideCb();
|
||||
dm.hide();
|
||||
expect(refresher.classList.contains('invisible')).toBe(true);
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user