diff --git a/js/angular/controller/infiniteScrollController.js b/js/angular/controller/infiniteScrollController.js
index 9f7dce5307..e1b0a2c7da 100644
--- a/js/angular/controller/infiniteScrollController.js
+++ b/js/angular/controller/infiniteScrollController.js
@@ -9,7 +9,11 @@ IonicModule
self.isLoading = false;
$scope.icon = function() {
- return angular.isDefined($attrs.icon) ? $attrs.icon : 'ion-loading-d';
+ return angular.isDefined($attrs.icon) ? $attrs.icon : 'ion-load-d';
+ };
+
+ $scope.spinner = function() {
+ return angular.isDefined($attrs.spinner) ? $attrs.spinner : '';
};
$scope.$on('scroll.infiniteScrollComplete', function() {
diff --git a/js/angular/directive/infiniteScroll.js b/js/angular/directive/infiniteScroll.js
index 163186af5a..2425861c97 100644
--- a/js/angular/directive/infiniteScroll.js
+++ b/js/angular/directive/infiniteScroll.js
@@ -18,7 +18,10 @@
* bottom.
* @param {string=} distance The distance from the bottom that the scroll must
* reach to trigger the on-infinite expression. Default: 1%.
- * @param {string=} icon The icon to show while loading. Default: 'ion-loading-d'.
+ * @param {string=} spinner The {@link ionic.directive:ionSpinner} to show while loading. The SVG
+ * {@link ionic.directive:ionSpinner} is now the default, replacing rotating font icons.
+ * @param {string=} icon The icon to show while loading. Default: 'ion-load-d'. This is depreicated
+ * in favor of the SVG {@link ionic.directive:ionSpinner}.
* @param {boolean=} immediate-check Whether to check the infinite scroll bounds immediately on load.
*
* @usage
@@ -67,7 +70,10 @@ IonicModule
return {
restrict: 'E',
require: ['?^$ionicScroll', 'ionInfiniteScroll'],
- template: '',
+ template: function($element, $attrs){
+ if ($attrs.icon) return '';
+ return '';
+ },
scope: true,
controller: '$ionInfiniteScroll',
link: function($scope, $element, $attrs, ctrls) {
diff --git a/scss/_scaffolding.scss b/scss/_scaffolding.scss
index 533d180b45..bdbaa8b209 100644
--- a/scss/_scaffolding.scss
+++ b/scss/_scaffolding.scss
@@ -160,37 +160,31 @@ body.grade-c {
ion-infinite-scroll {
height: 60px;
width: 100%;
-
display: block;
-// @include transition(opacity 0.25s);
@include display-flex();
@include flex-direction(row);
@include justify-content(center);
@include align-items(center);
.icon {
-
color: #666666;
font-size: 30px;
color: $scroll-refresh-icon-color;
- &:before{
- -webkit-transform: translate3d(0,0,0);
- transform: translate3d(0,0,0);
- }
}
- &:not(.active) .icon:before{
+ .icon:before,
+ .spinner{
+ -webkit-transform: translate3d(0,0,0);
+ transform: translate3d(0,0,0);
+ }
+ &:not(.active){
+ .spinner,
+ .icon:before{
-webkit-transform: translate3d(-1000px,0,0);
transform: translate3d(-1000px,0,0);
-
+ }
}
}
-// removing the animation when the spinner isn't shown
-// this breaks up animations on iOS, so they are left with unnecessary reflows
-body:not(.platform-ios) ion-infinite-scroll:not(.active) .icon{
- -webkit-animation: none;
- animation:none;
-}
.overflow-scroll {
overflow-x: hidden;
diff --git a/test/unit/angular/directive/infiniteScroll.unit.js b/test/unit/angular/directive/infiniteScroll.unit.js
index 1cfded6455..5b2eacb972 100644
--- a/test/unit/angular/directive/infiniteScroll.unit.js
+++ b/test/unit/angular/directive/infiniteScroll.unit.js
@@ -1,6 +1,5 @@
describe('ionicInfiniteScroll directive', function() {
beforeEach(module('ionic'));
-
var scrollTopValue = 50;
var scrollTopMaxValue = 60;
var scrollLeftValue = 101;
@@ -37,6 +36,7 @@ describe('ionicInfiniteScroll directive', function() {
$element: angular.element('
')
});
$compile(element)(scope);
+ ionic.requestAnimationFrame = function() {};
ctrl = element.controller('ionInfiniteScroll');
scope.$apply();
});
@@ -55,6 +55,7 @@ describe('ionicInfiniteScroll directive', function() {
element = parent.find('ion-infinite-scroll');
ionic.animationFrameThrottle = function(cb) { return function() { cb(); }; };
$compile(element)(scope);
+ ionic.requestAnimationFrame = function() {};
ctrl = element.controller('ionInfiniteScroll');
// create a fake scrollEl since they can't be faked if we're passing in scroll data
if (options) {
@@ -85,6 +86,7 @@ describe('ionicInfiniteScroll directive', function() {
});
it('should not have class or be loading by default', function() {
+ ionic.requestAnimationFrame = function() {};
var el = setupJS();
expect(el.hasClass('active')).toBe(false);
expect(ctrl.isLoading).toBe(false);
@@ -107,22 +109,30 @@ describe('ionicInfiniteScroll directive', function() {
});
describe('icon', function() {
- it('should have default icon ion-loading-d', function() {
+ it('should have platform appropriate default spinner', function() {
var el = setupJS();
- var icon = angular.element(el[0].querySelector('.icon'));
- expect(icon.hasClass('ion-loading-d')).toBe(true);
+ var icon = angular.element(el[0].querySelector('.spinner'));
+ if (ionic.Platform.isAndroid()) {
+ expect(icon[0].className.indexOf('spinner-android')).not.toBe(-1);
+ }else {
+ expect(icon[0].className.indexOf('spinner-ios')).not.toBe(-1);
+ }
});
it('should allow icon attr blank', function() {
var el = setupJS('icon=""');
- var icon = angular.element(el[0].querySelector('.icon'));
- expect(icon.hasClass('ion-loading-d')).toBe(false);
+ var icon = angular.element(el[0].querySelector('.spinner'));
+ if (ionic.Platform.isAndroid()) {
+ expect(icon[0].className.indexOf('spinner-android')).not.toBe(-1);
+ }else {
+ expect(icon[0].className.indexOf('spinner-ios')).not.toBe(-1);
+ }
});
it('should allow interpolated icon attr', function() {
var el = setupJS('icon="{{someIcon}}"');
var icon = angular.element(el[0].querySelector('.icon'));
- expect(icon.hasClass('ion-loading-d')).toBe(false);
+ expect(icon.hasClass('ion-load-d')).toBe(false);
el.scope().$apply('someIcon = "super-icon"');
expect(icon.hasClass('super-icon')).toBe(true);
});
@@ -194,42 +204,52 @@ describe('ionicInfiniteScroll directive', function() {
var el = setupNative('on-infinite="foo=1"');
var evObj = document.createEvent('HTMLEvents');
evObj.initEvent('scroll', true, true, window, 1, 12, 345, 7, 220, false, false, true, false, 0, null);
+ ionic.requestAnimationFrame = function(cb) { cb(); };
ctrl.scrollEl.dispatchEvent(evObj);
expect(el.hasClass('active')).toBe(false);
+ ionic.requestAnimationFrame = function() {};
expect(ctrl.isLoading).toBe(false);
expect(el.scope().foo).not.toBe(1);
});
it('should add active and call attr.onInfinite if >= top', function() {
var el = setupJS('on-infinite="foo=1"');
scrollTopValue = scrollTopMaxValue;
+ ionic.requestAnimationFrame = function(cb) { cb(); };
el.controller('$ionicScroll').$element.triggerHandler('scroll');
expect(el.hasClass('active')).toBe(true);
+ ionic.requestAnimationFrame = function() {};
expect(ctrl.isLoading).toBe(true);
expect(el.scope().foo).toBe(1);
scrollTopValue = scrollTopMaxValue;
var el = setupNative('on-infinite="foo=1"', {}, { scrollingX: true, scrollingY: true });
+ ionic.requestAnimationFrame = function(cb) { cb(); };
ctrl.checkBounds();
expect(el.hasClass('active')).toBe(true);
+ ionic.requestAnimationFrame = function() {};
expect(ctrl.isLoading).toBe(true);
expect(el.scope().foo).toBe(1);
});
it('should add active and call attr.onInfinite if >= left', function() {
var el = setupJS('on-infinite="foo=1"');
scrollLeftValue = scrollLeftMaxValue;
+ ionic.requestAnimationFrame = function(cb) { cb(); };
el.controller('$ionicScroll').$element.triggerHandler('scroll');
expect(el.hasClass('active')).toBe(true);
+ ionic.requestAnimationFrame = function() {};
expect(ctrl.isLoading).toBe(true);
expect(el.scope().foo).toBe(1);
scrollLeftValue = scrollLeftMaxValue;
var el = setupNative('on-infinite="foo=1"', {}, { scrollingX: true, scrollingY: true });
+ ionic.requestAnimationFrame = function(cb) { cb(); };
ctrl.checkBounds();
expect(el.hasClass('active')).toBe(true);
+ ionic.requestAnimationFrame = function() {};
expect(ctrl.isLoading).toBe(true);
expect(el.scope().foo).toBe(1);
});
@@ -237,6 +257,7 @@ describe('ionicInfiniteScroll directive', function() {
var onScrollSpy = jasmine.createSpy('onInfiniteScroll');
var el = setupJS('', { $onInfiniteScroll: onScrollSpy });
scrollTopValue = scrollTopMaxValue;
+ ionic.requestAnimationFrame = function(cb) { cb(); };
el.controller('$ionicScroll').$element.triggerHandler('scroll');
expect(el.hasClass('active')).toBe(true);
@@ -245,6 +266,7 @@ describe('ionicInfiniteScroll directive', function() {
el.controller('$ionicScroll').$element.triggerHandler('scroll');
expect(el.hasClass('active')).toBe(false);
+ ionic.requestAnimationFrame = function() {};
});
});
@@ -269,9 +291,11 @@ describe('ionicInfiniteScroll directive', function() {
var el = setupJS();
ctrl.isLoading = true;
el.addClass('active');
+ ionic.requestAnimationFrame = function(cb) { cb(); };
el.scope().$broadcast('scroll.infiniteScrollComplete');
expect(ctrl.isLoading).toBe(false);
expect(el.hasClass('active')).toBe(false);
+ ionic.requestAnimationFrame = function() {};
expect(el.controller('$ionicScroll').scrollView.resize).not.toHaveBeenCalled();
$timeout.flush();
expect(el.controller('$ionicScroll').scrollView.resize).toHaveBeenCalled();