diff --git a/src/AngularPublic.js b/src/AngularPublic.js index 777943a80260..1c5cf8a2b55d 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -150,7 +150,7 @@ function publishExternalAPI(angular) { 'isDate': isDate, 'lowercase': lowercase, 'uppercase': uppercase, - 'callbacks': {counter: 0}, + 'callbacks': {$$counter: 0}, 'getTestability': getTestability, '$$minErr': minErr, '$$csp': csp, diff --git a/src/ng/jsonpCallbacks.js b/src/ng/jsonpCallbacks.js index 180990516308..654b2c327331 100644 --- a/src/ng/jsonpCallbacks.js +++ b/src/ng/jsonpCallbacks.js @@ -11,8 +11,7 @@ */ var $jsonpCallbacksProvider = function() { this.$get = ['$window', function($window) { - var counter = 0; - $window.angular.callbacks = {}; + var callbacks = $window.angular.callbacks; var callbackMap = {}; function createCallback(callbackId) { @@ -35,10 +34,10 @@ var $jsonpCallbacksProvider = function() { * to pass to the server, which will be used to call the callback with its payload in the JSONP response. */ createCallback: function(url) { - var callbackId = '_' + (counter++).toString(36); + var callbackId = '_' + (callbacks.$$counter++).toString(36); var callbackPath = 'angular.callbacks.' + callbackId; var callback = createCallback(callbackId); - callbackMap[callbackPath] = $window.angular.callbacks[callbackId] = callback; + callbackMap[callbackPath] = callbacks[callbackId] = callback; return callbackPath; }, /** @@ -75,7 +74,7 @@ var $jsonpCallbacksProvider = function() { */ removeCallback: function(callbackPath) { var callback = callbackMap[callbackPath]; - delete $window.angular.callbacks[callback.id]; + delete callbacks[callback.id]; delete callbackMap[callbackPath]; } }; diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index 3e0f63333606..cb11ca38745b 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -2954,7 +2954,7 @@ angular.mock.$RootScopeDecorator = ['$delegate', function($delegate) { angular.forEach(angular.callbacks, function(val, key) { delete angular.callbacks[key]; }); - angular.callbacks.counter = 0; + angular.callbacks.$$counter = 0; }; (window.beforeEach || window.setup)(module.$$beforeEach); diff --git a/test/ng/jsonpCallbacksSpec.js b/test/ng/jsonpCallbacksSpec.js index 75d421857552..9e77703743c0 100644 --- a/test/ng/jsonpCallbacksSpec.js +++ b/test/ng/jsonpCallbacksSpec.js @@ -2,11 +2,6 @@ describe('$jsonpCallbacks', function() { - beforeEach(module(function($provide) { - // mock out the $window object - $provide.value('$window', { angular: {} }); - })); - describe('createCallback(url)', function() { it('should return a new unique path to a callback function on each call', inject(function($jsonpCallbacks) { @@ -36,6 +31,19 @@ describe('$jsonpCallbacks', function() { $jsonpCallbacks.createCallback('http://some.dummy.com/jsonp/request'); expect($window.angular.callbacks._3).toEqual(jasmine.any(Function)); })); + + it('should produce unique callback paths across multiple instances', function() { + var $jsonpCallbacks1 = angular.injector(['ng', 'ngMock']).get('$jsonpCallbacks'); + var $jsonpCallbacks2 = angular.injector(['ng', 'ngMock']).get('$jsonpCallbacks'); + + var path1 = $jsonpCallbacks1.createCallback('http://some.dummy.com/jsonp/request'); + var path2 = $jsonpCallbacks2.createCallback('http://some.dummy.com/jsonp/request'); + + expect(path1).toBe('angular.callbacks._0'); + expect(path2).toBe('angular.callbacks._1'); + expect(angular.callbacks._0).toBeDefined(); + expect(angular.callbacks._1).toBeDefined(); + }); }); @@ -62,6 +70,7 @@ describe('$jsonpCallbacks', function() { })); }); + describe('removeCallback(calbackPath)', function() { it('should remove the callback', inject(function($window, $jsonpCallbacks) {