From 984acdc6270df1dee5796ed44efebfb9ff6706c7 Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Sun, 26 Sep 2010 23:45:05 -0700 Subject: Reworked the cookie synchronization between cookie service, $browser and document.cookie. Now we finally correctly handle situations when browser refuses to set a cookie, due to storage quota or other (file:// protocol) limitations. --- src/Browser.js | 3 +-- src/services.js | 65 +++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/Browser.js b/src/Browser.js index e3c768ca..aa80ef47 100644 --- a/src/Browser.js +++ b/src/Browser.js @@ -138,11 +138,10 @@ function Browser(location, document, head, XHR, $log) { if (name) { if (value === _undefined) { - delete lastCookies[name]; rawDocument.cookie = escape(name) + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT"; } else { if (isString(value)) { - rawDocument.cookie = escape(name) + '=' + escape(lastCookies[name] = value); + rawDocument.cookie = escape(name) + '=' + escape(value); cookieLength = name.length + value.length + 1; if (cookieLength > 4096) { diff --git a/src/services.js b/src/services.js index 56637573..9bf3d1ed 100644 --- a/src/services.js +++ b/src/services.js @@ -405,52 +405,71 @@ angularService('$resource', function($xhr){ * cookies are created or deleted from the browser at the end of the current eval. */ angularService('$cookies', function($browser) { - var cookies = {}, - rootScope = this, - lastCookies; + var rootScope = this, + cookies = {}, + lastCookies = {}, + lastBrowserCookies; //creates a poller fn that copies all cookies from the $browser to service & inits the service $browser.addPollFn(function() { var currentCookies = $browser.cookies(); - if (lastCookies != currentCookies) { - lastCookies = currentCookies; + if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl + lastBrowserCookies = currentCookies; + copy(currentCookies, lastCookies); copy(currentCookies, cookies); rootScope.$eval(); } })(); //at the end of each eval, push cookies - this.$onEval(PRIORITY_LAST, update); + this.$onEval(PRIORITY_LAST, push); return cookies; - function update(){ + + /** + * Pushes all the cookies from the service to the browser and verifies if all cookies were stored. + */ + function push(){ var name, - browserCookies = $browser.cookies(); + browserCookies, + updated; + + //delete any cookies deleted in $cookies + for (name in lastCookies) { + if (isUndefined(cookies[name])) { + $browser.cookies(name, _undefined); + } + } - //$cookies -> $browser + //update all cookies updated in $cookies for(name in cookies) { - if (cookies[name] !== browserCookies[name]) { + if (cookies[name] !== lastCookies[name]) { $browser.cookies(name, cookies[name]); + updated = true; } } - //get what was actually stored in the browser - browserCookies = $browser.cookies(); + //verify what was actually stored + if (updated){ + updated = !updated; + 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; + } - //$browser -> $cookies - for(name in browserCookies) { - if (isUndefined(cookies[name])) { - $browser.cookies(name, _undefined); - } else { - cookies[name] = browserCookies[name]; } - } - //drop cookies in $cookies for cookies that $browser or real browser dropped - for (name in cookies) { - if (isUndefined(browserCookies[name])) { - delete cookies[name]; + if (updated) { + rootScope.$eval(); } } } -- cgit v1.2.3