mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
@@ -16,13 +16,15 @@ module.exports = {
|
||||
' *\n' +
|
||||
' * Licensed under the MIT license. Please see LICENSE for more information.\n'+
|
||||
' *\n' +
|
||||
' */\n\n',
|
||||
' */\n\n' +
|
||||
'(function() {\n',
|
||||
bundleBanner:
|
||||
'/*!\n' +
|
||||
' * ionic.bundle.js is a concatenation of:\n' +
|
||||
' * ionic.js, angular.js, angular-animate.js,\n'+
|
||||
' * angular-ui-router.js, and ionic-angular.js\n'+
|
||||
' */\n\n',
|
||||
footer: '\n})();',
|
||||
|
||||
ionicFiles: [
|
||||
// Base
|
||||
|
||||
@@ -1,8 +1,173 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular.module('ionic.ui.scroll')
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name $ionicScrollDelegate
|
||||
* @module ionic
|
||||
* @description
|
||||
* Delegate for controlling scrollViews (created by
|
||||
* {@link ionic.directive:ionContent} and
|
||||
* {@link ionic.directive:ionScroll} directives).
|
||||
*
|
||||
* Each method on $ionicScrollDelegate can be called on the service itself to control all scrollViews. Alternatively, one can control one specific scrollView using `withHandle` and `delegate-handle`. See the example below.
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* Basic Usage:
|
||||
*
|
||||
* ```html
|
||||
* <body ng-controller="MainCtrl">
|
||||
* <ion-content>
|
||||
* <button ng-click="scrollTop()">Scroll to Top!</button>
|
||||
* </ion-content>
|
||||
* </body>
|
||||
* ```
|
||||
* ```js
|
||||
* function MainCtrl($scope, $ionicScrollDelegate) {
|
||||
* $scope.scrollTop = function() {
|
||||
* $ionicScrollDelegate.scrollTop();
|
||||
* };
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Example of advanced usage, with two scroll areas using `delegate-handle`
|
||||
* for fine control.
|
||||
*
|
||||
* ```html
|
||||
* <body ng-controller="MainCtrl">
|
||||
* <ion-content delegate-handle="mainScroll">
|
||||
* <button ng-click="scrollMainToTop()">
|
||||
* Scroll content to top!
|
||||
* </button>
|
||||
* <ion-scroll delegate-handle="small" style="height: 100px;">
|
||||
* <button ng-click="scrollSmallToTop()">
|
||||
* Scroll small area to top!
|
||||
* </button>
|
||||
* </ion-scroll>
|
||||
* </ion-content>
|
||||
* </body>
|
||||
* ```
|
||||
* ```js
|
||||
* function MainCtrl($scope, $ionicScrollDelegate) {
|
||||
* $scope.scrollMainToTop = function() {
|
||||
* $ionicScrollDelegate.withHandle('mainScroll').scrollTop();
|
||||
* };
|
||||
* $scope.scrollSmallToTop = function() {
|
||||
* $ionicScrollDelegate.withHandle('small').scrollTop();
|
||||
* };
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicScrollDelegate#withHandle
|
||||
* @param {string} handle
|
||||
* @returns `delegateInstance` A delegate instance that controls only the
|
||||
* scrollView with delegate-handle matching the given handle.
|
||||
*/
|
||||
.service('$ionicScrollDelegate', delegateService([
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicScrollDelegate#resize
|
||||
* @description Tell the scrollView to recalculate the size of its container.
|
||||
*/
|
||||
'resize',
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicScrollDelegate#scrollTop
|
||||
* @param {boolean=} shouldAnimate Whether the scroll should animate.
|
||||
*/
|
||||
'scrollTop',
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicScrollDelegate#scrollBottom
|
||||
* @param {boolean=} shouldAnimate Whether the scroll should animate.
|
||||
*/
|
||||
'scrollBottom',
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicScrollDelegate#scroll
|
||||
* @param {number} left The x-value to scroll to.
|
||||
* @param {number} top The y-value to scroll to.
|
||||
* @param {boolean=} shouldAnimate Whether the scroll should animate.
|
||||
*/
|
||||
'scrollTo',
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicScrollDelegate#anchorScroll
|
||||
* @description Tell the scrollView to scroll to the element with an id
|
||||
* matching window.location.hash.
|
||||
*
|
||||
* If no matching element is found, it will scroll to top.
|
||||
*
|
||||
* @param {boolean=} shouldAnimate Whether the scroll should animate.
|
||||
*/
|
||||
'anchorScroll',
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicScrollDelegate#rememberScrollPosition
|
||||
* @description
|
||||
* Will make it so, when this scrollView is destroyed (user leaves the page),
|
||||
* the last scroll position the page was on will be saved, indexed by the
|
||||
* given id.
|
||||
*
|
||||
* Note: for pages associated with a view under an ion-nav-view,
|
||||
* rememberScrollPosition automatically saves their scroll.
|
||||
*
|
||||
* Related methods: scrollToRememberedPosition, forgetScrollPosition (below).
|
||||
*
|
||||
* In the following example, the scroll position of the ion-scroll element
|
||||
* will persist, even when the user changes the toggle switch.
|
||||
*
|
||||
* ```html
|
||||
* <ion-toggle ng-model="shouldShowScrollView"></ion-toggle>
|
||||
* <ion-scroll delegate-handle="myScroll" ng-if="shouldShowScrollView">
|
||||
* <div ng-controller="ScrollCtrl">
|
||||
* <ion-list>
|
||||
* <ion-item ng-repeat="i in items">{{i}}</ion-item>
|
||||
* </ion-list>
|
||||
* </div>
|
||||
* </ion-scroll>
|
||||
* ```
|
||||
* ```js
|
||||
* function ScrollCtrl($scope, $ionicScrollDelegate) {
|
||||
* var delegate = $ionicScrollDelegate.withHandle('myScroll');
|
||||
*
|
||||
* // Put any unique ID here. The point of this is: every time the controller is recreated
|
||||
* // we want to load the correct remembered scroll values.
|
||||
* delegate.rememberScrollPosition('my-scroll-id');
|
||||
* delegate.scrollToRememberedPosition();
|
||||
* $scope.items = [];
|
||||
* for (var i=0; i<100; i++) {
|
||||
* $scope.items.push(i);
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param {string} id The id to remember the scroll position of this
|
||||
* scrollView by.
|
||||
*/
|
||||
'rememberScrollPosition',
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicScrollDelegate#forgetScrollPosition
|
||||
* @description
|
||||
* Stop remembering the scroll position for this scrollView.
|
||||
*/
|
||||
'forgetScrollPosition',
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicScrollDelegate#scrollToRememberedPosition
|
||||
* @description
|
||||
* If this scrollView has an id associated with its scroll position,
|
||||
* (through calling rememberScrollPosition), and that position is remembered,
|
||||
* load the position and scroll to it.
|
||||
* @param {boolean=} shouldAnimate Whether to animate the scroll.
|
||||
*/
|
||||
'scrollToRememberedPosition'
|
||||
]))
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@@ -10,14 +175,6 @@ angular.module('ionic.ui.scroll')
|
||||
return {};
|
||||
})
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name ionicScroll
|
||||
* @module ionic
|
||||
* @description
|
||||
* Controller for the {@link ionic.directive:ionContent} and
|
||||
* {@link ionic.directive:ionScroll} directives.
|
||||
*/
|
||||
.controller('$ionicScroll', [
|
||||
'$scope',
|
||||
'scrollViewOptions',
|
||||
@@ -25,13 +182,18 @@ angular.module('ionic.ui.scroll')
|
||||
'$window',
|
||||
'$$scrollValueCache',
|
||||
'$location',
|
||||
'$parse',
|
||||
'$rootScope',
|
||||
'$document',
|
||||
function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $location, $parse, $rootScope, $document) {
|
||||
'$ionicScrollDelegate',
|
||||
'$parse', //DEPRECATED
|
||||
function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $location, $rootScope, $document, $ionicScrollDelegate, $parse) {
|
||||
|
||||
var self = this;
|
||||
|
||||
this._scrollViewOptions = scrollViewOptions; //for testing
|
||||
|
||||
$parse('$ionicScrollController').assign($scope.$parent || $scope, this);
|
||||
|
||||
var element = this.element = scrollViewOptions.el;
|
||||
var $element = this.$element = angular.element(element);
|
||||
var scrollView = this.scrollView = new ionic.views.Scroll(scrollViewOptions);
|
||||
@@ -42,8 +204,9 @@ function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $loca
|
||||
($element.parent().length ? $element.parent() : $element)
|
||||
.data('$$ionicScrollController', this);
|
||||
|
||||
$parse(scrollViewOptions.controllerBind || '$ionicScrollController')
|
||||
.assign($scope.$parent || $scope, this);
|
||||
var deregisterInstance = $ionicScrollDelegate._registerInstance(
|
||||
this, scrollViewOptions.delegateHandle
|
||||
);
|
||||
|
||||
if (!angular.isDefined(scrollViewOptions.bouncing)) {
|
||||
ionic.Platform.ready(function() {
|
||||
@@ -58,6 +221,7 @@ function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $loca
|
||||
var backListenDone = angular.noop;
|
||||
|
||||
$scope.$on('$destroy', function() {
|
||||
deregisterInstance();
|
||||
ionic.off('resize', resize, $window);
|
||||
$window.removeEventListener('resize', resize);
|
||||
backListenDone();
|
||||
@@ -101,31 +265,16 @@ function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $loca
|
||||
|
||||
this._rememberScrollId = null;
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ionicScroll#resize
|
||||
* @description Tell the scrollView to recalculate the size of its container.
|
||||
*/
|
||||
this.resize = function() {
|
||||
return $timeout(resize);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ionicScroll#scrollTop
|
||||
* @param {boolean=} shouldAnimate Whether the scroll should animate.
|
||||
*/
|
||||
this.scrollTop = function(shouldAnimate) {
|
||||
this.resize().then(function() {
|
||||
scrollView.scrollTo(0, 0, !!shouldAnimate);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ionicScroll#scrollBottom
|
||||
* @param {boolean=} shouldAnimate Whether the scroll should animate.
|
||||
*/
|
||||
this.scrollBottom = function(shouldAnimate) {
|
||||
this.resize().then(function() {
|
||||
var max = scrollView.getScrollMax();
|
||||
@@ -133,29 +282,12 @@ function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $loca
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ionicScroll#scroll
|
||||
* @param {number} left The x-value to scroll to.
|
||||
* @param {number} top The y-value to scroll to.
|
||||
* @param {boolean=} shouldAnimate Whether the scroll should animate.
|
||||
*/
|
||||
this.scrollTo = function(left, top, shouldAnimate) {
|
||||
this.resize().then(function() {
|
||||
scrollView.scrollTo(left, top, !!shouldAnimate);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ionicScroll#anchorScroll
|
||||
* @description Tell the scrollView to scroll to the element with an id
|
||||
* matching window.location.hash.
|
||||
*
|
||||
* If no matching element is found, it will scroll to top.
|
||||
*
|
||||
* @param {boolean=} shouldAnimate Whether the scroll should animate.
|
||||
*/
|
||||
this.anchorScroll = function(shouldAnimate) {
|
||||
this.resize().then(function() {
|
||||
var hash = $location.hash();
|
||||
@@ -169,75 +301,16 @@ function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $loca
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ionicScroll#rememberScrollPosition
|
||||
* @description
|
||||
* Will make it so, when this scrollView is destroyed (user leaves the page),
|
||||
* the last scroll position the page was on will be saved, indexed by the
|
||||
* given id.
|
||||
*
|
||||
* Note: for pages associated with a view under an ion-nav-view,
|
||||
* rememberScrollPosition automatically saves their scroll.
|
||||
*
|
||||
* Related methods: scrollToRememberedPosition, forgetScrollPosition (below).
|
||||
*
|
||||
* In the following example, the scroll position of the ion-scroll element
|
||||
* will persist, even when the user changes the toggle switch.
|
||||
*
|
||||
* ```html
|
||||
* <ion-toggle ng-model="shouldShowScrollView"></ion-toggle>
|
||||
* <ion-scroll ng-if="shouldShowScrollView">
|
||||
* <div ng-controller="ScrollCtrl">
|
||||
* <ion-list>
|
||||
* <ion-item ng-repeat="i in items">{{i}}</ion-item>
|
||||
* </ion-list>
|
||||
* </div>
|
||||
* </ion-scroll>
|
||||
* ```
|
||||
* ```js
|
||||
* function ScrollCtrl($scope) {
|
||||
* // Put any unique ID here. The point of this is: every time the controller is recreated
|
||||
* // we want to load the correct remembered scroll values.
|
||||
* $scope.$ionicScrollController.rememberScrollPosition('my-scroll-id');
|
||||
*
|
||||
* $scope.$ionicScrollController.scrollToRememberedPosition();
|
||||
|
||||
* $scope.items = [];
|
||||
* for (var i=0; i<100; i++) {
|
||||
* $scope.items.push(i);
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param {string} id The id to remember the scroll position of this
|
||||
* scrollView by.
|
||||
*/
|
||||
this.rememberScrollPosition = function(id) {
|
||||
if (!id) {
|
||||
throw new Error("Must supply an id to remember the scroll by!");
|
||||
}
|
||||
this._rememberScrollId = id;
|
||||
};
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ionicScroll#forgetScrollPosition
|
||||
* @description
|
||||
* Stop remembering the scroll position for this scrollView.
|
||||
*/
|
||||
this.forgetScrollPosition = function() {
|
||||
delete $$scrollValueCache[this._rememberScrollId];
|
||||
this._rememberScrollId = null;
|
||||
};
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ionicScroll#scrollToRememberedPosition
|
||||
* @description
|
||||
* If this scrollView has an id associated with its scroll position,
|
||||
* (through calling rememberScrollPosition), and that position is remembered,
|
||||
* load the position and scroll to it.
|
||||
* @param {boolean=} shouldAnimate Whether to animate the scroll.
|
||||
*/
|
||||
this.scrollToRememberedPosition = function(shouldAnimate) {
|
||||
var values = $$scrollValueCache[this._rememberScrollId];
|
||||
if (values) {
|
||||
@@ -268,4 +341,3 @@ function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $loca
|
||||
};
|
||||
}]);
|
||||
|
||||
})();
|
||||
|
||||
8
js/ext/angular/src/directive/ionicContent.js
vendored
8
js/ext/angular/src/directive/ionicContent.js
vendored
@@ -28,7 +28,6 @@ angular.module('ionic.ui.content', ['ionic.ui.scroll'])
|
||||
* @ngdoc directive
|
||||
* @name ionContent
|
||||
* @module ionic
|
||||
* @controller ionicScroll as $scope.$ionicScrollController
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
@@ -44,9 +43,8 @@ angular.module('ionic.ui.content', ['ionic.ui.scroll'])
|
||||
* directive, and infinite scrolling with the {@link ionic.directive:ionInfiniteScroll}
|
||||
* directive.
|
||||
*
|
||||
* @param {string=} controller-bind The scope variable to bind this element's scrollView's
|
||||
* {@link ionic.controller:ionicScroll ionicScroll controller} to.
|
||||
* Default: $scope.$ionicScrollController.
|
||||
* @param {string=} delegate-handle The handle used to identify this scrollView
|
||||
* with {@link ionic.service:$ionicScrollDelegate}.
|
||||
* @param {boolean=} padding Whether to add padding to the content.
|
||||
* of the content. Defaults to true on iOS, false on Android.
|
||||
* @param {boolean=} scroll Whether to allow scrolling of content. Defaults to true.
|
||||
@@ -122,7 +120,7 @@ function($parse, $timeout, $controller, $ionicBind) {
|
||||
$scope: $scope,
|
||||
scrollViewOptions: {
|
||||
el: $element[0],
|
||||
controllerBind: $attr.controllerBind,
|
||||
delegateHandle: attr.delegateHandle,
|
||||
bouncing: $scope.$eval($scope.hasBouncing),
|
||||
startX: $scope.$eval($scope.startX) || 0,
|
||||
startY: $scope.$eval($scope.startY) || 0,
|
||||
|
||||
8
js/ext/angular/src/directive/ionicScroll.js
vendored
8
js/ext/angular/src/directive/ionicScroll.js
vendored
@@ -7,15 +7,13 @@ angular.module('ionic.ui.scroll', [])
|
||||
* @ngdoc directive
|
||||
* @name ionScroll
|
||||
* @module ionic
|
||||
* @controller ionicScroll as $scope.$ionicScrollController
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* Creates a scrollable container for all content inside.
|
||||
*
|
||||
* @param {string=} controller-bind The scope variable to bind this element's scrollView's
|
||||
* {@link ionic.controller:ionicScroll ionicScroll controller} to.
|
||||
* Default: $scope.$ionicScrollController.
|
||||
* @param {string=} delegate-handle The handle used to identify this scrollView
|
||||
* with {@link ionic.service:$ionicScrollDelegate}.
|
||||
* @param {string=} direction Which way to scroll. 'x' or 'y'. Default 'y'.
|
||||
* @param {boolean=} paging Whether to scroll with paging.
|
||||
* @param {expression=} on-refresh Called on pull-to-refresh, triggered by an {@link ionic.directive:ionRefresher}.
|
||||
@@ -63,7 +61,7 @@ angular.module('ionic.ui.scroll', [])
|
||||
|
||||
var scrollViewOptions= {
|
||||
el: $element[0],
|
||||
controllerBind: $attr.controllerBind,
|
||||
delegateHandle: $attr.delegateHandle,
|
||||
paging: isPaging,
|
||||
scrollbarX: $scope.$eval($scope.scrollbarX) !== false,
|
||||
scrollbarY: $scope.$eval($scope.scrollbarY) !== false,
|
||||
|
||||
66
js/ext/angular/src/service/delegateFactory.js
vendored
Normal file
66
js/ext/angular/src/service/delegateFactory.js
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
|
||||
function delegateService(methodNames) {
|
||||
return ['$log', function($log) {
|
||||
var delegate = this;
|
||||
|
||||
this._instances = {};
|
||||
this._registerInstance = function(instance, handle) {
|
||||
handle || (handle = ionic.Utils.nextUid());
|
||||
delegate._instances[handle] = instance;
|
||||
|
||||
return function deregister() {
|
||||
delete delegate._instances[handle];
|
||||
};
|
||||
};
|
||||
|
||||
this.withHandle = function(handle) {
|
||||
if (!handle) {
|
||||
return delegate;
|
||||
}
|
||||
return new InstanceWithHandle(handle);
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a new object that will have all the methodNames given,
|
||||
* and call them on the given the controller instance matching given
|
||||
* handle.
|
||||
* The reason we don't just let withHandle return the controller instance
|
||||
* itself is that the controller instance might not exist yet.
|
||||
*
|
||||
* We want people to be able to do
|
||||
* `var instance = $ionicScrollDelegate.withHandle('foo')` on controller
|
||||
* instantiation, but on controller instantiation a child directive
|
||||
* may not have been compiled yet!
|
||||
*
|
||||
* So this is our way of solving this problem: we create an object
|
||||
* that will only try to fetch the controller with given handle
|
||||
* once the methods are actually called.
|
||||
*/
|
||||
function InstanceWithHandle(handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
methodNames.forEach(function(methodName) {
|
||||
InstanceWithHandle.prototype[methodName] = function() {
|
||||
var instance = delegate._instances[this.handle];
|
||||
if (!instance) {
|
||||
return $log.error(
|
||||
'Delegate with handle "'+this.handle+'" could not find a',
|
||||
'corresponding element with delegate-handle="'+this.handle+'"!',
|
||||
methodName, 'was not called!');
|
||||
}
|
||||
return instance[methodName].apply(instance, arguments);
|
||||
};
|
||||
delegate[methodName] = function() {
|
||||
var args = arguments;
|
||||
var returnValue;
|
||||
angular.forEach(delegate._instances, function(instance) {
|
||||
var result = instance[methodName].apply(instance, args);
|
||||
if (!angular.isDefined(returnValue)) {
|
||||
returnValue = result;
|
||||
}
|
||||
});
|
||||
return returnValue;
|
||||
};
|
||||
});
|
||||
}];
|
||||
}
|
||||
@@ -35,7 +35,7 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function MyCtrl($scope, $location) {
|
||||
function MyCtrl($scope, $location, $ionicScrollDelegate) {
|
||||
$scope.items = [];
|
||||
for (var i=0; i < 100; i++) {
|
||||
$scope.items.push({id:i});
|
||||
@@ -43,7 +43,7 @@ function MyCtrl($scope, $location) {
|
||||
|
||||
$scope.doScroll = function() {
|
||||
$location.hash('foo-50');
|
||||
$scope.$ionicScrollController.anchorScroll(true);
|
||||
$ionicScrollDelegate.anchorScroll(true);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -27,17 +27,28 @@ describe('$ionicScroll Controller', function() {
|
||||
});
|
||||
}
|
||||
|
||||
it('should set $scope.$ionicScrollController by default', function() {
|
||||
setup()
|
||||
expect(scope.$ionicScrollController).toBe(ctrl);
|
||||
});
|
||||
it('should register with no handle', inject(function($ionicScrollDelegate) {
|
||||
spyOn($ionicScrollDelegate, '_registerInstance');
|
||||
var el = setup();
|
||||
expect($ionicScrollDelegate._registerInstance)
|
||||
.toHaveBeenCalledWith(ctrl, undefined);
|
||||
}));
|
||||
|
||||
it('should set options.controllerBind to ctrl', function() {
|
||||
setup({
|
||||
controllerBind: 'something'
|
||||
it('should register with given handle and deregister on destroy', inject(function($ionicScrollDelegate) {
|
||||
var deregisterSpy = jasmine.createSpy('deregister');
|
||||
spyOn($ionicScrollDelegate, '_registerInstance').andCallFake(function() {
|
||||
return deregisterSpy;
|
||||
});
|
||||
expect(scope.something).toBe(ctrl);
|
||||
});
|
||||
setup({
|
||||
delegateHandle: 'something'
|
||||
});
|
||||
expect($ionicScrollDelegate._registerInstance)
|
||||
.toHaveBeenCalledWith(ctrl, 'something');
|
||||
|
||||
expect(deregisterSpy).not.toHaveBeenCalled();
|
||||
scope.$destroy();
|
||||
expect(deregisterSpy).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should set bouncing to option if given', function() {
|
||||
spyOn(ionic.Platform, 'isAndroid');
|
||||
|
||||
@@ -16,6 +16,12 @@ describe('Ionic Content directive', function() {
|
||||
expect(element.controller('$ionicScroll').element).toBe(element[0]);
|
||||
});
|
||||
|
||||
it('passes delegateHandle attribute', function() {
|
||||
var element = compile('<ion-content delegate-handle="handleMe">')(scope);
|
||||
expect(element.controller('$ionicScroll')._scrollViewOptions.delegateHandle)
|
||||
.toBe('handleMe');
|
||||
});
|
||||
|
||||
it('Has content class', function() {
|
||||
var element = compile('<ion-content></ion-content>')(scope);
|
||||
expect(element.hasClass('scroll-content')).toBe(true);
|
||||
@@ -46,18 +52,12 @@ describe('Ionic Content directive', function() {
|
||||
it('Should set start x and y', function() {
|
||||
var element = compile('<ion-content start-x="100" start-y="300"></ion-content>')(scope);
|
||||
scope.$apply();
|
||||
var scrollView = scope.$ionicScrollController.scrollView;
|
||||
var scrollView = element.controller('$ionicScroll').scrollView;
|
||||
var vals = scrollView.getValues();
|
||||
expect(vals.left).toBe(100);
|
||||
expect(vals.top).toBe(300);
|
||||
});
|
||||
|
||||
it('should pass attr.controllerBind ionicScrollController', function() {
|
||||
var element = compile('<ion-content controller-bind="scrolly">')(scope);
|
||||
scope.$apply();
|
||||
expect(scope.scrolly).toBe(element.controller('$ionicScroll'));
|
||||
});
|
||||
|
||||
});
|
||||
/* Tests #555 */
|
||||
describe('Ionic Content Directive scoping', function() {
|
||||
|
||||
@@ -14,9 +14,10 @@ describe('Ionic Scroll Directive', function() {
|
||||
});
|
||||
}));
|
||||
|
||||
it('Has $ionicScroll controller', function() {
|
||||
element = compile('<ion-scroll></ion-scroll>')(scope);
|
||||
expect(element.controller('$ionicScroll').element).toBe(element[0]);
|
||||
it('passes delegateHandle attribute', function() {
|
||||
var element = compile('<ion-scroll delegate-handle="handleThis">')(scope);
|
||||
expect(element.controller('$ionicScroll')._scrollViewOptions.delegateHandle)
|
||||
.toBe('handleThis');
|
||||
});
|
||||
|
||||
it('has $onScroll (used by $ionicScrollController)', function() {
|
||||
@@ -44,16 +45,10 @@ describe('Ionic Scroll Directive', function() {
|
||||
expect(scrollElement.hasClass('padding')).toEqual(true);
|
||||
});
|
||||
|
||||
it('should pass attr.controllerBind ionicScrollController', function() {
|
||||
var element = compile('<ion-scroll controller-bind="scrolly">')(scope);
|
||||
scope.$apply();
|
||||
expect(scope.scrolly).toBe(element.controller('$ionicScroll'));
|
||||
});
|
||||
|
||||
it('Should set start x and y', function() {
|
||||
element = compile('<ion-content start-x="100" start-y="300" has-header="true"></ion-scroll>')(scope);
|
||||
scope.$apply();
|
||||
var scrollView = scope.$ionicScrollController.scrollView;
|
||||
var scrollView = element.controller('$ionicScroll').scrollView;
|
||||
var vals = scrollView.getValues();
|
||||
expect(vals.left).toBe(100);
|
||||
expect(vals.top).toBe(300);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<ion-toggle ng-model="shouldShowScrollView"></ion-toggle>
|
||||
<ion-scroll ng-if="shouldShowScrollView">
|
||||
<ion-scroll delegate-handle="myScroll" ng-if="shouldShowScrollView">
|
||||
<div ng-controller="ScrollCtrl">
|
||||
<ion-list>
|
||||
<ion-item ng-repeat="i in items">{{i}}</ion-item>
|
||||
@@ -18,9 +18,11 @@
|
||||
</div>
|
||||
</ion-scroll>
|
||||
<script>
|
||||
function ScrollCtrl($scope) {
|
||||
$scope.$ionicScrollController.rememberScrollPosition('my-scroll-id');
|
||||
$scope.$ionicScrollController.scrollToRememberedPosition();
|
||||
function ScrollCtrl($scope, $ionicScrollDelegate) {
|
||||
var delegate = $ionicScrollDelegate.withHandle('myScroll');
|
||||
|
||||
delegate.rememberScrollPosition('my-scroll-id');
|
||||
delegate.scrollToRememberedPosition();
|
||||
|
||||
$scope.items = [];
|
||||
for (var i=0; i<100; i++) {
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
}
|
||||
})
|
||||
|
||||
.controller('ThisCtrl', function($scope) {
|
||||
.controller('ThisCtrl', function($scope, $ionicScrollDelegate) {
|
||||
var header = document.getElementById('header');
|
||||
var content = document.getElementById('container');
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
}
|
||||
$scope.scrollTo = function() {
|
||||
console.log('scrollTo');
|
||||
$scope.$ionicScrollController.scrollTo(0, 100, true);
|
||||
$ionicScrollDelegate.scrollTo(0, 100, true);
|
||||
};
|
||||
$scope.onScroll = function(event, scrollTop, scrollLeft) {
|
||||
/*
|
||||
|
||||
141
js/ext/angular/test/service/delegateFactory.unit.js
Normal file
141
js/ext/angular/test/service/delegateFactory.unit.js
Normal file
@@ -0,0 +1,141 @@
|
||||
describe('DelegateFactory', function() {
|
||||
function setup(methods) {
|
||||
var delegate;
|
||||
inject(function($log, $injector) {
|
||||
$log.error = jasmine.createSpy('error');
|
||||
delegate = $injector.instantiate(delegateService(methods || []));
|
||||
});
|
||||
return delegate;
|
||||
}
|
||||
|
||||
it('should have properties', function() {
|
||||
expect(setup()._instances).toEqual({});
|
||||
expect(setup()._registerInstance).toEqual(jasmine.any(Function));
|
||||
expect(setup().withHandle).toEqual(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it('should allow reg & dereg of instance with handle', function() {
|
||||
var delegate = setup();
|
||||
var instance = {};
|
||||
var deregister = delegate._registerInstance(instance, 'handle');
|
||||
expect(delegate._instances['handle']).toBe(instance);
|
||||
deregister();
|
||||
expect(delegate._instances['handle']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should allow reg & dereg of instance, and make its own handle', function() {
|
||||
spyOn(ionic.Utils, 'nextUid').andCallFake(function() {
|
||||
return 'uid';
|
||||
});
|
||||
var delegate = setup();
|
||||
var instance = {};
|
||||
var deregister = delegate._registerInstance(instance);
|
||||
expect(ionic.Utils.nextUid).toHaveBeenCalled();
|
||||
expect(delegate._instances['uid']).toBe(instance);
|
||||
deregister();
|
||||
expect(delegate._instances['uid']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should have given methodNames on root', function() {
|
||||
var delegate = setup(['foo', 'bar']);
|
||||
expect(delegate.foo).toEqual(jasmine.any(Function));
|
||||
expect(delegate.bar).toEqual(jasmine.any(Function));
|
||||
});
|
||||
|
||||
it('should call given methodNames on all instances with args', function() {
|
||||
var delegate = setup(['foo', 'bar']);
|
||||
var instance1 = {
|
||||
foo: jasmine.createSpy('foo1'),
|
||||
bar: jasmine.createSpy('bar1')
|
||||
};
|
||||
var instance2 = {
|
||||
foo: jasmine.createSpy('foo1'),
|
||||
bar: jasmine.createSpy('bar1')
|
||||
};
|
||||
delegate._registerInstance(instance1);
|
||||
delegate._registerInstance(instance2);
|
||||
|
||||
expect(instance1.foo).not.toHaveBeenCalled();
|
||||
expect(instance2.foo).not.toHaveBeenCalled();
|
||||
delegate.foo('a', 'b', 'c');
|
||||
expect(instance1.foo).toHaveBeenCalledWith('a', 'b', 'c');
|
||||
expect(instance2.foo).toHaveBeenCalledWith('a', 'b', 'c');
|
||||
|
||||
instance1.foo.reset();
|
||||
instance2.foo.reset();
|
||||
delegate.foo(1, 2, 3);
|
||||
expect(instance1.foo).toHaveBeenCalledWith(1, 2, 3);
|
||||
expect(instance2.foo).toHaveBeenCalledWith(1, 2, 3);
|
||||
|
||||
expect(instance1.bar).not.toHaveBeenCalled();
|
||||
expect(instance2.bar).not.toHaveBeenCalled();
|
||||
delegate.bar('something');
|
||||
expect(instance1.bar).toHaveBeenCalledWith('something');
|
||||
expect(instance2.bar).toHaveBeenCalledWith('something');
|
||||
});
|
||||
|
||||
it('should return the first return value from multiple instances', function() {
|
||||
var delegate = setup(['fn']);
|
||||
var instance1 = {
|
||||
fn: jasmine.createSpy('fn').andCallFake(function() {
|
||||
return 'ret1';
|
||||
})
|
||||
};
|
||||
var instance2 = {
|
||||
fn: jasmine.createSpy('fn').andCallFake(function() {
|
||||
return 'ret2';
|
||||
})
|
||||
};
|
||||
var deregister = delegate._registerInstance(instance1);
|
||||
delegate._registerInstance(instance2);
|
||||
|
||||
expect(delegate.fn()).toBe('ret1');
|
||||
deregister();
|
||||
expect(delegate.fn()).toBe('ret2');
|
||||
});
|
||||
|
||||
it('withHandle should return this for blank handle', function() {
|
||||
var delegate = setup();
|
||||
expect(delegate.withHandle()).toBe(delegate);
|
||||
});
|
||||
|
||||
describe('withHandle', function() {
|
||||
var delegate, instance1, instance2;
|
||||
beforeEach(function() {
|
||||
delegate = setup(['a']);
|
||||
instance1 = {
|
||||
a: jasmine.createSpy('a1').andCallFake(function() {
|
||||
return 'a1';
|
||||
}),
|
||||
};
|
||||
instance2 = {
|
||||
a: jasmine.createSpy('a2').andCallFake(function() {
|
||||
return 'a2';
|
||||
}),
|
||||
};
|
||||
});
|
||||
it('should return an InstanceWithHandle object with fields', function() {
|
||||
expect(delegate.withHandle('one').a).toEqual(jasmine.any(Function));
|
||||
expect(delegate.withHandle('two').a).toEqual(jasmine.any(Function));
|
||||
expect(delegate.withHandle('invalid').a).toEqual(jasmine.any(Function));
|
||||
});
|
||||
it('should do nothing if calling for a non-added instance', function() {
|
||||
expect(delegate.withHandle('one').a()).toBeUndefined();
|
||||
});
|
||||
it('should call an added instance\'s method', function() {
|
||||
delegate._registerInstance(instance1, '1');
|
||||
delegate._registerInstance(instance2, '2');
|
||||
|
||||
var result = delegate.withHandle('1').a(1,2,3);
|
||||
expect(instance1.a).toHaveBeenCalledWith(1,2,3);
|
||||
expect(instance2.a).not.toHaveBeenCalled();
|
||||
expect(result).toBe('a1');
|
||||
|
||||
instance1.a.reset();
|
||||
var result = delegate.withHandle('2').a(2,3,4);
|
||||
expect(instance2.a).toHaveBeenCalledWith(2,3,4);
|
||||
expect(instance1.a).not.toHaveBeenCalled();
|
||||
expect(result).toBe('a2');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user