Skip to content

Commit

Permalink
feat(scrolling): add native scroll delegate
Browse files Browse the repository at this point in the history
  • Loading branch information
perrygovier committed Mar 26, 2015
1 parent 893fcbe commit bda4de1
Show file tree
Hide file tree
Showing 13 changed files with 706 additions and 258 deletions.
1 change: 1 addition & 0 deletions config/build.config.js
Expand Up @@ -55,6 +55,7 @@ module.exports = {
// Views
'js/views/view.js',
'js/views/scrollView.js',
'js/views/scrollViewNative.js',
'js/views/listView.js',
'js/views/modalView.js',
'js/views/sideMenuView.js',
Expand Down
4 changes: 2 additions & 2 deletions js/angular/controller/refresherController.js
Expand Up @@ -238,8 +238,8 @@ IonicModule
scrollParent = $element.parent().parent()[0];
scrollChild = $element.parent()[0];

if (!scrollParent.classList.contains('ionic-scroll') ||
!scrollChild.classList.contains('scroll')) {
if (!scrollParent || !scrollParent.classList.contains('ionic-scroll') ||
!scrollChild || !scrollChild.classList.contains('scroll')) {
throw new Error('Refresher must be immediate child of ion-content or ion-scroll');
}

Expand Down
11 changes: 10 additions & 1 deletion js/angular/controller/scrollController.js
Expand Up @@ -26,10 +26,19 @@ function($scope,
self.__timeout = $timeout;

self._scrollViewOptions = scrollViewOptions; //for testing
self.isNative = function() {
return !!scrollViewOptions.nativeScrolling;
};

var element = self.element = scrollViewOptions.el;
var $element = self.$element = jqLite(element);
var scrollView = self.scrollView = new ionic.views.Scroll(scrollViewOptions);
var scrollView;
if (self.isNative()) {
scrollView = self.scrollView = new ionic.views.ScrollNative(scrollViewOptions);
} else {
scrollView = self.scrollView = new ionic.views.Scroll(scrollViewOptions);
}


//Attach self to element as a controller so other directives can require this controller
//through `require: '$ionicScroll'
Expand Down
66 changes: 42 additions & 24 deletions js/angular/directive/content.js
Expand Up @@ -109,37 +109,55 @@ function($timeout, $controller, $ionicBind, $ionicConfig) {

if ($attr.scroll === "false") {
//do nothing
} else if (attr.overflowScroll === "true" || !$ionicConfig.scrolling.jsScrolling()) {
// use native scrolling
$element.addClass('overflow-scroll');
} else {
var scrollViewOptions = {
el: $element[0],
delegateHandle: attr.delegateHandle,
locking: (attr.locking || 'true') === 'true',
bouncing: $scope.$eval($scope.hasBouncing),
startX: $scope.$eval($scope.startX) || 0,
startY: $scope.$eval($scope.startY) || 0,
scrollbarX: $scope.$eval($scope.scrollbarX) !== false,
scrollbarY: $scope.$eval($scope.scrollbarY) !== false,
scrollingX: $scope.direction.indexOf('x') >= 0,
scrollingY: $scope.direction.indexOf('y') >= 0,
scrollEventInterval: parseInt($scope.scrollEventInterval, 10) || 10,
scrollingComplete: function() {
$scope.$onScrollComplete({
scrollTop: this.__scrollTop,
scrollLeft: this.__scrollLeft
});
}
};
var scrollViewOptions = {};

if (attr.overflowScroll === "true" || !$ionicConfig.scrolling.jsScrolling()) {
// use native scrolling
$element.addClass('overflow-scroll');

scrollViewOptions = {
el: $element[0],
delegateHandle: attr.delegateHandle,
startX: $scope.$eval($scope.startX) || 0,
startY: $scope.$eval($scope.startY) || 0,
nativeScrolling:true
};

} else {
// Use JS scrolling
scrollViewOptions = {
el: $element[0],
delegateHandle: attr.delegateHandle,
locking: (attr.locking || 'true') === 'true',
bouncing: $scope.$eval($scope.hasBouncing),
startX: $scope.$eval($scope.startX) || 0,
startY: $scope.$eval($scope.startY) || 0,
scrollbarX: $scope.$eval($scope.scrollbarX) !== false,
scrollbarY: $scope.$eval($scope.scrollbarY) !== false,
scrollingX: $scope.direction.indexOf('x') >= 0,
scrollingY: $scope.direction.indexOf('y') >= 0,
scrollEventInterval: parseInt($scope.scrollEventInterval, 10) || 10,
scrollingComplete: function() {
$scope.$onScrollComplete({
scrollTop: this.__scrollTop,
scrollLeft: this.__scrollLeft
});
}
};
}

// init scroll controller with appropriate options
$controller('$ionicScroll', {
$scope: $scope,
scrollViewOptions: scrollViewOptions
});

$scope.$on('$destroy', function() {
scrollViewOptions.scrollingComplete = noop;
delete scrollViewOptions.el;
if (scrollViewOptions) {
scrollViewOptions.scrollingComplete = noop;
delete scrollViewOptions.el;
}
innerElement = null;
$element = null;
attr.$$element = null;
Expand Down
14 changes: 7 additions & 7 deletions js/angular/directive/infiniteScroll.js
Expand Up @@ -79,10 +79,14 @@ IonicModule
link: function($scope, $element, $attrs, ctrls) {
var infiniteScrollCtrl = ctrls[1];
var scrollCtrl = infiniteScrollCtrl.scrollCtrl = ctrls[0];
var jsScrolling = infiniteScrollCtrl.jsScrolling = !!scrollCtrl;
var jsScrolling = infiniteScrollCtrl.jsScrolling = !scrollCtrl.isNative();

// if this view is not beneath a scrollCtrl, it can't be injected, proceed w/ native scrolling
if (jsScrolling) {
infiniteScrollCtrl.scrollView = scrollCtrl.scrollView;
$scope.scrollingType = 'js-scrolling';
//bind to JS scroll events
scrollCtrl.$element.on('scroll', infiniteScrollCtrl.checkBounds);
} else {
// grabbing the scrollable element, to determine dimensions, and current scroll pos
var scrollEl = ionic.DomUtil.getParentOrSelfWithClass($element[0].parentNode,'overflow-scroll');
Expand All @@ -91,14 +95,10 @@ IonicModule
if (!scrollEl) {
throw 'Infinite scroll must be used inside a scrollable div';
}
}
//bind to appropriate scroll event
if (jsScrolling) {
$scope.scrollingType = 'js-scrolling';
scrollCtrl.$element.on('scroll', infiniteScrollCtrl.checkBounds);
} else {
//bind to native scroll events
infiniteScrollCtrl.scrollEl.addEventListener('scroll', infiniteScrollCtrl.checkBounds);
}

// Optionally check bounds on start after scrollView is fully rendered
var doImmediateCheck = isDefined($attrs.immediateCheck) ? $scope.$eval($attrs.immediateCheck) : true;
if (doImmediateCheck) {
Expand Down
11 changes: 4 additions & 7 deletions js/angular/directive/refresher.js
Expand Up @@ -87,10 +87,11 @@ IonicModule
// JS Scrolling uses the scroll controller
var scrollCtrl = ctrls[0],
refresherCtrl = ctrls[1];

if (!!scrollCtrl) {
if (!scrollCtrl || scrollCtrl.isNative()) {
// Kick off native scrolling
refresherCtrl.init();
} else {
$element[0].classList.add('js-scrolling');

scrollCtrl._setRefresher(
$scope,
$element[0],
Expand All @@ -102,10 +103,6 @@ IonicModule
scrollCtrl.scrollView.finishPullToRefresh();
});
});

} else {
// Kick off native scrolling
refresherCtrl.init();
}

}
Expand Down

0 comments on commit bda4de1

Please sign in to comment.