diff --git a/src/calendar.js b/src/calendar.js index 8663967..45a318b 100644 --- a/src/calendar.js +++ b/src/calendar.js @@ -11,10 +11,8 @@ angular.module('ui.calendar', []) .constant('uiCalendarConfig', {calendars: {}}) .controller('uiCalendarCtrl', ['$scope', - '$timeout', '$locale', function( $scope, - $timeout, $locale){ var sourceSerialId = 1, @@ -23,22 +21,19 @@ angular.module('ui.calendar', []) extraEventSignature = $scope.calendarWatchEvent ? $scope.calendarWatchEvent : angular.noop, wrapFunctionWithScopeApply = function(functionToWrap){ - var wrapper; - - if (functionToWrap){ - wrapper = function(){ - // This happens outside of angular context so we need to wrap it in a timeout which has an implied apply. - // In this way the function will be safely executed on the next digest. + return function(){ + // This may happen outside of angular context, so create one if outside. + if ($scope.$root.$$phase) { + return functionToWrap.apply(this, arguments); + } else { var args = arguments; - var _this = this; - $timeout(function(){ - functionToWrap.apply(_this, args); + var self = this; + return $scope.$root.$apply(function(){ + return functionToWrap.apply(self, args); }); - }; - } - - return wrapper; + } + }; }; this.eventsFingerprint = function(e) { diff --git a/test/calendar.spec.js b/test/calendar.spec.js index 76b4e01..a39744b 100644 --- a/test/calendar.spec.js +++ b/test/calendar.spec.js @@ -352,73 +352,41 @@ describe('uiCalendar', function () { scope.$apply(); }); - it('should make sure that all config functions are called in an angular context', inject(function($timeout, $rootScope){ - var functionCount = 0; - scope.uiConfig = { - calendar:{ - height: 200, - weekends: false, - defaultView: 'month', - dayClick: function(){}, - eventClick: function(){}, - eventDrop: function(){}, - eventResize: function(){}, - eventMouseover: function(){} - } - }; + it('should make sure that all config functions are called in an angular context', inject(function($rootScope){ + scope.uiConfig = { + calendar:{ + height: 200, + weekends: false, + defaultView: 'month' + } + }; - spyOn($rootScope,'$apply'); + var keys = ['dayClick', 'eventClick', 'eventDrop', 'eventResize', 'eventMouseover']; + angular.forEach(keys, function(key) { + scope.uiConfig.calendar[key] = jasmine.createSpy().andReturn(key); + }); - angular.forEach(scope.uiConfig.calendar, function(value,key){ - if (typeof value === 'function'){ - functionCount++; - spyOn(scope.uiConfig.calendar, key); + var fullCalendarConfig = calendarCtrl.getFullCalendarConfig(scope.uiConfig.calendar, {}); - var fullCalendarConfig = calendarCtrl.getFullCalendarConfig(scope.uiConfig.calendar, {}); + spyOn($rootScope,'$apply').andCallThrough(); - fullCalendarConfig[key](); - $timeout.flush(); - expect($rootScope.$apply.callCount).toBe(functionCount); - expect(scope.uiConfig.calendar[key]).toHaveBeenCalled(); - $rootScope.$apply.isSpy = false; - } - }); - })); + angular.forEach(keys, function(key){ + $rootScope.$apply.reset(); - it('should make sure that any function that already has an apply in it does not break the calendar (backwards compatible)', inject(function($timeout, $rootScope){ - - var functionCount = 0; - scope.uiConfig = { - calendar:{ - height: 200, - weekends: false, - defaultView: 'month', - dayClick: function(){scope.$apply();}, - eventClick: function(){scope.$apply();}, - eventDrop: function(){scope.$apply();}, - eventResize: function(){scope.$apply();}, - eventMouseover: function(){scope.$apply();} - } - }; - - spyOn($rootScope,'$apply'); - - angular.forEach(scope.uiConfig.calendar, function(value,key){ - if (typeof value === 'function'){ - functionCount++; - spyOn(scope.uiConfig.calendar, key); - - var fullCalendarConfig = calendarCtrl.getFullCalendarConfig(scope.uiConfig.calendar, {}); - - fullCalendarConfig[key](); - - scope.$apply(); - $timeout.flush(); - expect($rootScope.$apply.callCount).toBe(functionCount*2); - expect(scope.uiConfig.calendar[key]).toHaveBeenCalled(); - } - }); + var fn = fullCalendarConfig[key]; + + expect(fn()).toBe(key); + expect($rootScope.$apply.callCount).toBe(1); + expect(scope.uiConfig.calendar[key].callCount).toBe(1); + + expect($rootScope.$apply(function(){ + expect($rootScope.$apply.callCount).toBe(2); + return fn(); + })).toBe(key); + expect($rootScope.$apply.callCount).toBe(2); + expect(scope.uiConfig.calendar[key].callCount).toBe(2); + }); })); }); -}); \ No newline at end of file +});