From 7b22d59b4a16d5c50c2eee054178ba17f8038880 Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Mon, 26 Mar 2012 16:22:06 -0700 Subject: chore(ngCookies): moved to module --- Rakefile | 4 + angularFiles.js | 7 +- docs/src/templates/docs.js | 2 +- docs/src/templates/index.html | 1 + example/personalLog/test/personalLogSpec.js | 2 +- src/AngularPublic.js | 2 - src/ng/cookieStore.js | 64 ----------- src/ng/cookies.js | 94 ---------------- src/ngCookies/cookies.js | 163 ++++++++++++++++++++++++++++ test/ng/cookieStoreSpec.js | 30 ----- test/ng/cookiesSpec.js | 97 ----------------- test/ngCookies/cookiesSpec.js | 128 ++++++++++++++++++++++ 12 files changed, 303 insertions(+), 291 deletions(-) delete mode 100644 src/ng/cookieStore.js delete mode 100644 src/ng/cookies.js create mode 100644 src/ngCookies/cookies.js delete mode 100644 test/ng/cookieStoreSpec.js delete mode 100644 test/ng/cookiesSpec.js create mode 100644 test/ngCookies/cookiesSpec.js diff --git a/Rakefile b/Rakefile index 2748d1d1..c6a55c73 100644 --- a/Rakefile +++ b/Rakefile @@ -81,9 +81,11 @@ task :compile => [:init, :compile_scenario, :compile_jstd_scenario_adapter] do FileUtils.cp 'src/ngMock/angular-mocks.js', path_to('angular-mocks.js') FileUtils.cp 'src/ngResource/resource.js', path_to('angular-resource.js') + FileUtils.cp 'src/ngCookies/cookies.js', path_to('angular-cookies.js') closureCompile('angular.js') + closureCompile('angular-cookies.js') closureCompile('angular-loader.js') closureCompile('angular-resource.js') @@ -115,6 +117,8 @@ task :package => [:clean, :compile, :docs] do path_to('angular-loader.js'), path_to('angular-loader.min.js'), path_to('angular-mocks.js'), + path_to('angular-cookies.js'), + path_to('angular-cookies.min.js'), path_to('angular-resource.js'), path_to('angular-resource.min.js'), path_to('angular-scenario.js'), diff --git a/angularFiles.js b/angularFiles.js index d8fe5d06..18cc8d61 100644 --- a/angularFiles.js +++ b/angularFiles.js @@ -14,8 +14,6 @@ angularFiles = { 'src/ng/cacheFactory.js', 'src/ng/compiler.js', 'src/ng/controller.js', - 'src/ng/cookieStore.js', - 'src/ng/cookies.js', 'src/ng/defer.js', 'src/ng/document.js', 'src/ng/exceptionHandler.js', @@ -66,6 +64,7 @@ angularFiles = { ], 'angularSrcModules': [ + 'src/ngCookies/cookies.js', 'src/ngResource/resource.js', 'src/ngMock/angular-mocks.js' ], @@ -98,6 +97,7 @@ angularFiles = { 'test/ng/*.js', 'test/ng/directive/*.js', 'test/ng/filter/*.js', + 'test/ngCookies/*.js', 'test/ngResource/*.js', 'test/ngMock/*.js' ], @@ -135,9 +135,11 @@ angularFiles = { 'lib/jasmine-jstd-adapter/JasmineAdapter.js', 'build/angular.js', 'src/ngMock/angular-mocks.js', + 'src/ngCookies/cookies.js', 'src/ngResource/resource.js', 'test/matchers.js', 'test/ngMock/*.js', + 'test/ngCookies/*.js', 'test/ngResource/*.js' ], @@ -169,6 +171,7 @@ angularFiles = { 'src/ngScenario/jstd-scenario-adapter/Adapter.js', '@angularTest', 'example/personalLog/*.js', + 'example/personalLog/test/*.js' ], diff --git a/docs/src/templates/docs.js b/docs/src/templates/docs.js index 9627dc60..9d91c233 100644 --- a/docs/src/templates/docs.js +++ b/docs/src/templates/docs.js @@ -146,7 +146,7 @@ function TutorialInstructionsCtrl($cookieStore) { }; } -angular.module('ngdocs', ['ngdocs.directives', 'ngResource'], function($locationProvider, $filterProvider, $compileProvider) { +angular.module('ngdocs', ['ngdocs.directives', 'ngResource', 'ngCookies'], function($locationProvider, $filterProvider, $compileProvider) { $locationProvider.html5Mode(true).hashPrefix('!'); $filterProvider.register('title', function(){ diff --git a/docs/src/templates/index.html b/docs/src/templates/index.html index ccd8f108..d7470461 100644 --- a/docs/src/templates/index.html +++ b/docs/src/templates/index.html @@ -29,6 +29,7 @@ if (jQuery) addTag('script', {src: 'jquery.min.js'}); addTag('script', {src: path('angular.js')}, sync); addTag('script', {src: path('angular-resource.js') }, sync); + addTag('script', {src: path('angular-cookies.js') }, sync); addTag('script', {src: 'docs-combined.js'}, sync); addTag('script', {src: 'docs-keywords.js'}, sync); diff --git a/example/personalLog/test/personalLogSpec.js b/example/personalLog/test/personalLogSpec.js index ab2d98c9..ee4fb687 100644 --- a/example/personalLog/test/personalLogSpec.js +++ b/example/personalLog/test/personalLogSpec.js @@ -2,7 +2,7 @@ describe('example.personalLog.LogCtrl', function() { var logScope; beforeEach(function() { - var injector = angular.injector(['ng', 'ngMock']); + var injector = angular.injector(['ng', 'ngMock', 'ngCookies']); logScope = injector.get('$rootScope'); logScope.$cookies = injector.get('$cookies'); injector.instantiate(example.personalLog.LogCtrl, {$scope: logScope}); diff --git a/src/AngularPublic.js b/src/AngularPublic.js index ec307962..8597de9c 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -110,8 +110,6 @@ function publishExternalAPI(angular){ $browser: $BrowserProvider, $cacheFactory: $CacheFactoryProvider, $controller: $ControllerProvider, - $cookies: $CookiesProvider, - $cookieStore: $CookieStoreProvider, $defer: $DeferProvider, $document: $DocumentProvider, $exceptionHandler: $ExceptionHandlerProvider, diff --git a/src/ng/cookieStore.js b/src/ng/cookieStore.js deleted file mode 100644 index e6b7cd21..00000000 --- a/src/ng/cookieStore.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict'; - -/** - * @ngdoc object - * @name angular.module.ng.$cookieStore - * @requires $cookies - * - * @description - * Provides a key-value (string-object) storage, that is backed by session cookies. - * Objects put or retrieved from this storage are automatically serialized or - * deserialized by angular's toJson/fromJson. - * @example - */ -function $CookieStoreProvider(){ - this.$get = ['$cookies', function($cookies) { - - return { - /** - * @ngdoc method - * @name angular.module.ng.$cookieStore#get - * @methodOf angular.module.ng.$cookieStore - * - * @description - * Returns the value of given cookie key - * - * @param {string} key Id to use for lookup. - * @returns {Object} Deserialized cookie value. - */ - get: function(key) { - return fromJson($cookies[key]); - }, - - /** - * @ngdoc method - * @name angular.module.ng.$cookieStore#put - * @methodOf angular.module.ng.$cookieStore - * - * @description - * Sets a value for given cookie key - * - * @param {string} key Id for the `value`. - * @param {Object} value Value to be stored. - */ - put: function(key, value) { - $cookies[key] = toJson(value); - }, - - /** - * @ngdoc method - * @name angular.module.ng.$cookieStore#remove - * @methodOf angular.module.ng.$cookieStore - * - * @description - * Remove given cookie - * - * @param {string} key Id of the key-value pair to delete. - */ - remove: function(key) { - delete $cookies[key]; - } - }; - - }]; -} diff --git a/src/ng/cookies.js b/src/ng/cookies.js deleted file mode 100644 index cd953eb1..00000000 --- a/src/ng/cookies.js +++ /dev/null @@ -1,94 +0,0 @@ -'use strict'; - -/** - * @ngdoc object - * @name angular.module.ng.$cookies - * @requires $browser - * - * @description - * Provides read/write access to browser's cookies. - * - * Only a simple Object is exposed and by adding or removing properties to/from - * this object, new cookies are created/deleted at the end of current $eval. - * - * @example - */ -function $CookiesProvider() { - this.$get = ['$rootScope', '$browser', function ($rootScope, $browser) { - var cookies = {}, - lastCookies = {}, - lastBrowserCookies, - runEval = false; - - //creates a poller fn that copies all cookies from the $browser to service & inits the service - $browser.addPollFn(function() { - var currentCookies = $browser.cookies(); - if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl - lastBrowserCookies = currentCookies; - copy(currentCookies, lastCookies); - copy(currentCookies, cookies); - if (runEval) $rootScope.$apply(); - } - })(); - - runEval = true; - - //at the end of each eval, push cookies - //TODO: this should happen before the "delayed" watches fire, because if some cookies are not - // strings or browser refuses to store some cookies, we update the model in the push fn. - $rootScope.$watch(push); - - return cookies; - - - /** - * Pushes all the cookies from the service to the browser and verifies if all cookies were stored. - */ - function push() { - var name, - value, - browserCookies, - updated; - - //delete any cookies deleted in $cookies - for (name in lastCookies) { - if (isUndefined(cookies[name])) { - $browser.cookies(name, undefined); - } - } - - //update all cookies updated in $cookies - for(name in cookies) { - value = cookies[name]; - if (!isString(value)) { - if (isDefined(lastCookies[name])) { - cookies[name] = lastCookies[name]; - } else { - delete cookies[name]; - } - } else if (value !== lastCookies[name]) { - $browser.cookies(name, value); - updated = true; - } - } - - //verify what was actually stored - if (updated){ - updated = false; - browserCookies = $browser.cookies(); - - for (name in cookies) { - if (cookies[name] !== browserCookies[name]) { - //delete or reset all cookies that the browser dropped from $cookies - if (isUndefined(browserCookies[name])) { - delete cookies[name]; - } else { - cookies[name] = browserCookies[name]; - } - updated = true; - } - } - } - } - }]; -} diff --git a/src/ngCookies/cookies.js b/src/ngCookies/cookies.js new file mode 100644 index 00000000..f6446db1 --- /dev/null +++ b/src/ngCookies/cookies.js @@ -0,0 +1,163 @@ +'use strict'; + +/** + * @ngdoc overview + * @name angular.module.ngCookies + */ + + +angular.module('ngCookies', ['ng']). + /** + * @ngdoc object + * @name angular.module.ng.$cookies + * @requires $browser + * + * @description + * Provides read/write access to browser's cookies. + * + * Only a simple Object is exposed and by adding or removing properties to/from + * this object, new cookies are created/deleted at the end of current $eval. + * + * @example + */ + factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) { + var cookies = {}, + lastCookies = {}, + lastBrowserCookies, + runEval = false, + copy = angular.copy, + isUndefined = angular.isUndefined; + + //creates a poller fn that copies all cookies from the $browser to service & inits the service + $browser.addPollFn(function() { + var currentCookies = $browser.cookies(); + if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl + lastBrowserCookies = currentCookies; + copy(currentCookies, lastCookies); + copy(currentCookies, cookies); + if (runEval) $rootScope.$apply(); + } + })(); + + runEval = true; + + //at the end of each eval, push cookies + //TODO: this should happen before the "delayed" watches fire, because if some cookies are not + // strings or browser refuses to store some cookies, we update the model in the push fn. + $rootScope.$watch(push); + + return cookies; + + + /** + * Pushes all the cookies from the service to the browser and verifies if all cookies were stored. + */ + function push() { + var name, + value, + browserCookies, + updated; + + //delete any cookies deleted in $cookies + for (name in lastCookies) { + if (isUndefined(cookies[name])) { + $browser.cookies(name, undefined); + } + } + + //update all cookies updated in $cookies + for(name in cookies) { + value = cookies[name]; + if (!angular.isString(value)) { + if (angular.isDefined(lastCookies[name])) { + cookies[name] = lastCookies[name]; + } else { + delete cookies[name]; + } + } else if (value !== lastCookies[name]) { + $browser.cookies(name, value); + updated = true; + } + } + + //verify what was actually stored + if (updated){ + updated = false; + browserCookies = $browser.cookies(); + + for (name in cookies) { + if (cookies[name] !== browserCookies[name]) { + //delete or reset all cookies that the browser dropped from $cookies + if (isUndefined(browserCookies[name])) { + delete cookies[name]; + } else { + cookies[name] = browserCookies[name]; + } + updated = true; + } + } + } + } + }]). + + + /** + * @ngdoc object + * @name angular.module.ng.$cookieStore + * @requires $cookies + * + * @description + * Provides a key-value (string-object) storage, that is backed by session cookies. + * Objects put or retrieved from this storage are automatically serialized or + * deserialized by angular's toJson/fromJson. + * @example + */ + factory('$cookieStore', ['$cookies', function($cookies) { + + return { + /** + * @ngdoc method + * @name angular.module.ng.$cookieStore#get + * @methodOf angular.module.ng.$cookieStore + * + * @description + * Returns the value of given cookie key + * + * @param {string} key Id to use for lookup. + * @returns {Object} Deserialized cookie value. + */ + get: function(key) { + return angular.fromJson($cookies[key]); + }, + + /** + * @ngdoc method + * @name angular.module.ng.$cookieStore#put + * @methodOf angular.module.ng.$cookieStore + * + * @description + * Sets a value for given cookie key + * + * @param {string} key Id for the `value`. + * @param {Object} value Value to be stored. + */ + put: function(key, value) { + $cookies[key] = angular.toJson(value); + }, + + /** + * @ngdoc method + * @name angular.module.ng.$cookieStore#remove + * @methodOf angular.module.ng.$cookieStore + * + * @description + * Remove given cookie + * + * @param {string} key Id of the key-value pair to delete. + */ + remove: function(key) { + delete $cookies[key]; + } + }; + + }]); diff --git a/test/ng/cookieStoreSpec.js b/test/ng/cookieStoreSpec.js deleted file mode 100644 index 50ac7797..00000000 --- a/test/ng/cookieStoreSpec.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict'; - -describe('$cookieStore', function() { - - - it('should serialize objects to json', inject(function($cookieStore, $browser, $rootScope) { - $cookieStore.put('objectCookie', {id: 123, name: 'blah'}); - $rootScope.$digest(); - expect($browser.cookies()).toEqual({'objectCookie': '{"id":123,"name":"blah"}'}); - })); - - - it('should deserialize json to object', inject(function($cookieStore, $browser) { - $browser.cookies('objectCookie', '{"id":123,"name":"blah"}'); - $browser.poll(); - expect($cookieStore.get('objectCookie')).toEqual({id: 123, name: 'blah'}); - })); - - - it('should delete objects from the store when remove is called', inject(function($cookieStore, $browser, $rootScope) { - $cookieStore.put('gonner', { "I'll":"Be Back"}); - $rootScope.$digest(); //force eval in test - $browser.poll(); - expect($browser.cookies()).toEqual({'gonner': '{"I\'ll":"Be Back"}'}); - - $cookieStore.remove('gonner'); - $rootScope.$digest(); - expect($browser.cookies()).toEqual({}); - })); -}); diff --git a/test/ng/cookiesSpec.js b/test/ng/cookiesSpec.js deleted file mode 100644 index 5427ac36..00000000 --- a/test/ng/cookiesSpec.js +++ /dev/null @@ -1,97 +0,0 @@ -'use strict'; - -describe('$cookies', function() { - beforeEach(module(function($provide) { - $provide.factory('$browser', function(){ - return angular.extend(new angular.mock.$Browser(), {cookieHash: {preexisting:'oldCookie'}}); - }); - })); - - - it('should provide access to existing cookies via object properties and keep them in sync', - inject(function($cookies, $browser, $rootScope) { - expect($cookies).toEqual({'preexisting': 'oldCookie'}); - - // access internal cookie storage of the browser mock directly to simulate behavior of - // document.cookie - $browser.cookieHash['brandNew'] = 'cookie'; - $browser.poll(); - - expect($cookies).toEqual({'preexisting': 'oldCookie', 'brandNew':'cookie'}); - - $browser.cookieHash['brandNew'] = 'cookie2'; - $browser.poll(); - expect($cookies).toEqual({'preexisting': 'oldCookie', 'brandNew':'cookie2'}); - - delete $browser.cookieHash['brandNew']; - $browser.poll(); - expect($cookies).toEqual({'preexisting': 'oldCookie'}); - })); - - - it('should create or update a cookie when a value is assigned to a property', - inject(function($cookies, $browser, $rootScope) { - $cookies.oatmealCookie = 'nom nom'; - $rootScope.$digest(); - - expect($browser.cookies()). - toEqual({'preexisting': 'oldCookie', 'oatmealCookie':'nom nom'}); - - $cookies.oatmealCookie = 'gone'; - $rootScope.$digest(); - - expect($browser.cookies()). - toEqual({'preexisting': 'oldCookie', 'oatmealCookie': 'gone'}); - })); - - - it('should drop or reset any cookie that was set to a non-string value', - inject(function($cookies, $browser, $rootScope) { - $cookies.nonString = [1, 2, 3]; - $cookies.nullVal = null; - $cookies.undefVal = undefined; - $cookies.preexisting = function() {}; - $rootScope.$digest(); - expect($browser.cookies()).toEqual({'preexisting': 'oldCookie'}); - expect($cookies).toEqual({'preexisting': 'oldCookie'}); - })); - - - it('should remove a cookie when a $cookies property is deleted', - inject(function($cookies, $browser, $rootScope) { - $cookies.oatmealCookie = 'nom nom'; - $rootScope.$digest(); - $browser.poll(); - expect($browser.cookies()). - toEqual({'preexisting': 'oldCookie', 'oatmealCookie':'nom nom'}); - - delete $cookies.oatmealCookie; - $rootScope.$digest(); - - expect($browser.cookies()).toEqual({'preexisting': 'oldCookie'}); - })); - - - it('should drop or reset cookies that browser refused to store', - inject(function($cookies, $browser, $rootScope) { - var i, longVal; - - for (i=0; i<5000; i++) { - longVal += '*'; - } - - //drop if no previous value - $cookies.longCookie = longVal; - $rootScope.$digest(); - expect($cookies).toEqual({'preexisting': 'oldCookie'}); - - - //reset if previous value existed - $cookies.longCookie = 'shortVal'; - $rootScope.$digest(); - expect($cookies).toEqual({'preexisting': 'oldCookie', 'longCookie': 'shortVal'}); - $cookies.longCookie = longVal; - $rootScope.$digest(); - expect($cookies).toEqual({'preexisting': 'oldCookie', 'longCookie': 'shortVal'}); - })); -}); diff --git a/test/ngCookies/cookiesSpec.js b/test/ngCookies/cookiesSpec.js new file mode 100644 index 00000000..435f40b4 --- /dev/null +++ b/test/ngCookies/cookiesSpec.js @@ -0,0 +1,128 @@ +'use strict'; + +describe('$cookies', function() { + beforeEach(module('ngCookies', function($provide) { + $provide.factory('$browser', function(){ + return angular.extend(new angular.mock.$Browser(), {cookieHash: {preexisting:'oldCookie'}}); + }); + })); + + + it('should provide access to existing cookies via object properties and keep them in sync', + inject(function($cookies, $browser, $rootScope) { + expect($cookies).toEqual({'preexisting': 'oldCookie'}); + + // access internal cookie storage of the browser mock directly to simulate behavior of + // document.cookie + $browser.cookieHash['brandNew'] = 'cookie'; + $browser.poll(); + + expect($cookies).toEqual({'preexisting': 'oldCookie', 'brandNew':'cookie'}); + + $browser.cookieHash['brandNew'] = 'cookie2'; + $browser.poll(); + expect($cookies).toEqual({'preexisting': 'oldCookie', 'brandNew':'cookie2'}); + + delete $browser.cookieHash['brandNew']; + $browser.poll(); + expect($cookies).toEqual({'preexisting': 'oldCookie'}); + })); + + + it('should create or update a cookie when a value is assigned to a property', + inject(function($cookies, $browser, $rootScope) { + $cookies.oatmealCookie = 'nom nom'; + $rootScope.$digest(); + + expect($browser.cookies()). + toEqual({'preexisting': 'oldCookie', 'oatmealCookie':'nom nom'}); + + $cookies.oatmealCookie = 'gone'; + $rootScope.$digest(); + + expect($browser.cookies()). + toEqual({'preexisting': 'oldCookie', 'oatmealCookie': 'gone'}); + })); + + + it('should drop or reset any cookie that was set to a non-string value', + inject(function($cookies, $browser, $rootScope) { + $cookies.nonString = [1, 2, 3]; + $cookies.nullVal = null; + $cookies.undefVal = undefined; + $cookies.preexisting = function() {}; + $rootScope.$digest(); + expect($browser.cookies()).toEqual({'preexisting': 'oldCookie'}); + expect($cookies).toEqual({'preexisting': 'oldCookie'}); + })); + + + it('should remove a cookie when a $cookies property is deleted', + inject(function($cookies, $browser, $rootScope) { + $cookies.oatmealCookie = 'nom nom'; + $rootScope.$digest(); + $browser.poll(); + expect($browser.cookies()). + toEqual({'preexisting': 'oldCookie', 'oatmealCookie':'nom nom'}); + + delete $cookies.oatmealCookie; + $rootScope.$digest(); + + expect($browser.cookies()).toEqual({'preexisting': 'oldCookie'}); + })); + + + it('should drop or reset cookies that browser refused to store', + inject(function($cookies, $browser, $rootScope) { + var i, longVal; + + for (i=0; i<5000; i++) { + longVal += '*'; + } + + //drop if no previous value + $cookies.longCookie = longVal; + $rootScope.$digest(); + expect($cookies).toEqual({'preexisting': 'oldCookie'}); + + + //reset if previous value existed + $cookies.longCookie = 'shortVal'; + $rootScope.$digest(); + expect($cookies).toEqual({'preexisting': 'oldCookie', 'longCookie': 'shortVal'}); + $cookies.longCookie = longVal; + $rootScope.$digest(); + expect($cookies).toEqual({'preexisting': 'oldCookie', 'longCookie': 'shortVal'}); + })); +}); + + +describe('$cookieStore', function() { + + beforeEach(module('ngCookies')); + + it('should serialize objects to json', inject(function($cookieStore, $browser, $rootScope) { + $cookieStore.put('objectCookie', {id: 123, name: 'blah'}); + $rootScope.$digest(); + expect($browser.cookies()).toEqual({'objectCookie': '{"id":123,"name":"blah"}'}); + })); + + + it('should deserialize json to object', inject(function($cookieStore, $browser) { + $browser.cookies('objectCookie', '{"id":123,"name":"blah"}'); + $browser.poll(); + expect($cookieStore.get('objectCookie')).toEqual({id: 123, name: 'blah'}); + })); + + + it('should delete objects from the store when remove is called', inject(function($cookieStore, $browser, $rootScope) { + $cookieStore.put('gonner', { "I'll":"Be Back"}); + $rootScope.$digest(); //force eval in test + $browser.poll(); + expect($browser.cookies()).toEqual({'gonner': '{"I\'ll":"Be Back"}'}); + + $cookieStore.remove('gonner'); + $rootScope.$digest(); + expect($browser.cookies()).toEqual({}); + })); +}); -- cgit v1.2.3