Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

ng-cookies squashed #11222

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
refactor($browser): split cookie access into $$cookieReader and $$coo…
…kieWriter services
  • Loading branch information
shahata committed Mar 2, 2015
commit f4c1295c7bed9f0f90a60b6c9c7d2f05fe3e4105
8 changes: 5 additions & 3 deletions angularFiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ var angularFiles = {
'src/ng/timeout.js',
'src/ng/urlUtils.js',
'src/ng/window.js',
'src/ng/cookieReader.js',

'src/ng/filter.js',
'src/ng/filter/filter.js',
Expand Down Expand Up @@ -89,7 +90,8 @@ var angularFiles = {
'src/ngAnimate/animate.js'
],
'ngCookies': [
'src/ngCookies/cookies.js'
'src/ngCookies/cookies.js',
'src/ngCookies/cookieWriter.js'
],
'ngMessages': [
'src/ngMessages/messages.js'
Expand Down Expand Up @@ -162,7 +164,7 @@ var angularFiles = {
'src/publishExternalApis.js',
'@angularSrcModules',
'@angularScenario',
'@angularTest',
'@angularTest'
],

'karmaExclude': [
Expand Down Expand Up @@ -197,7 +199,7 @@ var angularFiles = {
'src/publishExternalApis.js',
'@angularSrcModules',
'@angularScenario',
'@angularTest',
'@angularTest'
],

'karmaJqueryExclude': [
Expand Down
6 changes: 4 additions & 2 deletions src/AngularPublic.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@
$$RAFProvider,
$$AsyncCallbackProvider,
$WindowProvider,
$$jqLiteProvider
$$jqLiteProvider,
$$CookieReaderProvider
*/


Expand Down Expand Up @@ -238,7 +239,8 @@ function publishExternalAPI(angular) {
$window: $WindowProvider,
$$rAF: $$RAFProvider,
$$asyncCallback: $$AsyncCallbackProvider,
$$jqLite: $$jqLiteProvider
$$jqLite: $$jqLiteProvider,
$$cookieReader: $$CookieReaderProvider
});
}
]);
Expand Down
83 changes: 0 additions & 83 deletions src/ng/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -324,89 +324,6 @@ function Browser(window, document, $log, $sniffer) {
return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
};

//////////////////////////////////////////////////////////////
// Cookies API
//////////////////////////////////////////////////////////////
var lastCookies = {};
var lastCookieString = '';
var cookiePath = self.baseHref();

function safeDecodeURIComponent(str) {
try {
return decodeURIComponent(str);
} catch (e) {
return str;
}
}

/**
* @name $browser#cookies
*
* @param {string=} name Cookie name
* @param {string=} value Cookie value
*
* @description
* The cookies method provides a 'private' low level access to browser cookies.
* It is not meant to be used directly, use the $cookie service instead.
*
* The return values vary depending on the arguments that the method was called with as follows:
*
* - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify
* it
* - cookies(name, value) -> set name to value, if value is undefined delete the cookie
* - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that
* way)
*
* @returns {Object} Hash of all cookies (if called without any parameter)
*/
self.cookies = function(name, value) {
var cookieLength, cookieArray, cookie, i, index;

if (name) {
if (value === undefined) {
rawDocument.cookie = encodeURIComponent(name) + "=;path=" + cookiePath +
";expires=Thu, 01 Jan 1970 00:00:00 GMT";
} else {
if (isString(value)) {
cookieLength = (rawDocument.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) +
';path=' + cookiePath).length + 1;

// per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
// - 300 cookies
// - 20 cookies per unique domain
// - 4096 bytes per cookie
if (cookieLength > 4096) {
$log.warn("Cookie '" + name +
"' possibly not set or overflowed because it was too large (" +
cookieLength + " > 4096 bytes)!");
}
}
}
} else {
if (rawDocument.cookie !== lastCookieString) {
lastCookieString = rawDocument.cookie;
cookieArray = lastCookieString.split("; ");
lastCookies = {};

for (i = 0; i < cookieArray.length; i++) {
cookie = cookieArray[i];
index = cookie.indexOf('=');
if (index > 0) { //ignore nameless cookies
name = safeDecodeURIComponent(cookie.substring(0, index));
// the first value that is seen for a cookie is the most
// specific one. values for the same cookie name that
// follow are for less specific paths.
if (lastCookies[name] === undefined) {
lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));
}
}
}
}
return lastCookies;
}
};


/**
* @name $browser#defer
* @param {function()} fn A function, who's execution should be deferred.
Expand Down
55 changes: 55 additions & 0 deletions src/ng/cookieReader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict';

/**
* @name $$cookieReader
* @requires $document
*
* @description
* This is a private service for reading cookies used by $http and ngCookies
*
* @return {Object} a key/value map of the current cookies
*/
function $$CookieReader($document) {
var rawDocument = $document[0];
var lastCookies = {};
var lastCookieString = '';

function safeDecodeURIComponent(str) {
try {
return decodeURIComponent(str);
} catch (e) {
return str;
}
}

return function() {
var cookieArray, cookie, i, index, name;

if (rawDocument.cookie !== lastCookieString) {
lastCookieString = rawDocument.cookie;
cookieArray = lastCookieString.split('; ');
lastCookies = {};

for (i = 0; i < cookieArray.length; i++) {
cookie = cookieArray[i];
index = cookie.indexOf('=');
if (index > 0) { //ignore nameless cookies
name = safeDecodeURIComponent(cookie.substring(0, index));
// the first value that is seen for a cookie is the most
// specific one. values for the same cookie name that
// follow are for less specific paths.
if (lastCookies[name] === undefined) {
lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));
}
}
}
}
return lastCookies;
};
}

$$CookieReader.$inject = ['$document'];

function $$CookieReaderProvider() {
this.$get = $$CookieReader;
}
6 changes: 3 additions & 3 deletions src/ng/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ function $HttpProvider() {
**/
var interceptorFactories = this.interceptors = [];

this.$get = ['$httpBackend', '$browser', '$cacheFactory', '$rootScope', '$q', '$injector',
function($httpBackend, $browser, $cacheFactory, $rootScope, $q, $injector) {
this.$get = ['$httpBackend', '$$cookieReader', '$cacheFactory', '$rootScope', '$q', '$injector',
function($httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector) {

var defaultCache = $cacheFactory('$http');

Expand Down Expand Up @@ -1066,7 +1066,7 @@ function $HttpProvider() {
// send the request to the backend
if (isUndefined(cachedResp)) {
var xsrfValue = urlIsSameOrigin(config.url)
? $browser.cookies()[config.xsrfCookieName || defaults.xsrfCookieName]
? $$cookieReader()[config.xsrfCookieName || defaults.xsrfCookieName]
: undefined;
if (xsrfValue) {
reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;
Expand Down
44 changes: 44 additions & 0 deletions src/ngCookies/cookieWriter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict';

/**
* @name $$cookieWriter
* @requires $document
*
* @description
* This is a private service for writing cookies
*
* @param {string} name Cookie name
* @param {string=} value Cookie value (if undefined, cookie will be deleted)
*/
function $$CookieWriter($document, $log, $browser) {
var cookiePath = $browser.baseHref();
var rawDocument = $document[0];

return function(name, value) {
if (value === undefined) {
rawDocument.cookie = encodeURIComponent(name) + "=;path=" + cookiePath +
";expires=Thu, 01 Jan 1970 00:00:00 GMT";
} else {
if (angular.isString(value)) {
var cookieLength = (rawDocument.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) +
';path=' + cookiePath).length + 1;

// per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
// - 300 cookies
// - 20 cookies per unique domain
// - 4096 bytes per cookie
if (cookieLength > 4096) {
$log.warn("Cookie '" + name +
"' possibly not set or overflowed because it was too large (" +
cookieLength + " > 4096 bytes)!");
}
}
}
};
}

$$CookieWriter.$inject = ['$document', '$log', '$browser'];

angular.module('ngCookies').provider('$$cookieWriter', function $$CookieWriterProvider() {
this.$get = $$CookieWriter;
});
10 changes: 5 additions & 5 deletions src/ngCookies/cookies.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ angular.module('ngCookies', ['ng']).
* }]);
* ```
*/
factory('$cookies', ['$rootScope', '$browser', function($rootScope, $browser) {
factory('$cookies', ['$rootScope', '$browser', '$$cookieReader', '$$cookieWriter', function($rootScope, $browser, $$cookieReader, $$cookieWriter) {
var cookies = {},
lastCookies = {},
lastBrowserCookies,
Expand All @@ -53,7 +53,7 @@ angular.module('ngCookies', ['ng']).

//creates a poller fn that copies all cookies from the $browser to service & inits the service
$browser.addPollFn(function() {
var currentCookies = $browser.cookies();
var currentCookies = $$cookieReader();
if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl
lastBrowserCookies = currentCookies;
copy(currentCookies, lastCookies);
Expand Down Expand Up @@ -85,7 +85,7 @@ angular.module('ngCookies', ['ng']).
//delete any cookies deleted in $cookies
for (name in lastCookies) {
if (isUndefined(cookies[name])) {
$browser.cookies(name, undefined);
$$cookieWriter(name, undefined);
}
}

Expand All @@ -97,15 +97,15 @@ angular.module('ngCookies', ['ng']).
cookies[name] = value;
}
if (value !== lastCookies[name]) {
$browser.cookies(name, value);
$$cookieWriter(name, value);
updated = true;
}
}

//verify what was actually stored
if (updated) {
updated = false;
browserCookies = $browser.cookies();
browserCookies = $$cookieReader();

for (name in cookies) {
if (cookies[name] !== browserCookies[name]) {
Expand Down
21 changes: 0 additions & 21 deletions src/ngMock/angular-mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ angular.mock.$Browser = function() {

self.$$checkUrlChange = angular.noop;

self.cookieHash = {};
self.lastCookieHash = {};
self.deferredFns = [];
self.deferredNextId = 0;

Expand Down Expand Up @@ -163,25 +161,6 @@ angular.mock.$Browser.prototype = {
return this.$$state;
},

cookies: function(name, value) {
if (name) {
if (angular.isUndefined(value)) {
delete this.cookieHash[name];
} else {
if (angular.isString(value) && //strings only
value.length <= 4096) { //strict cookie storage limits
this.cookieHash[name] = value;
}
}
} else {
if (!angular.equals(this.cookieHash, this.lastCookieHash)) {
this.lastCookieHash = angular.copy(this.cookieHash);
this.cookieHash = angular.copy(this.cookieHash);
}
return this.cookieHash;
}
},

notifyWhenNoOutstandingRequests: function(fn) {
fn();
}
Expand Down
Loading