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

Commit 76b1b2b

Browse files
shahatapetebacondarwin
authored andcommitted
refactor($browser): split cookie access into $$cookieReader and $$cookieWriter services
1 parent c62fa6b commit 76b1b2b

13 files changed

+425
-399
lines changed

angularFiles.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ var angularFiles = {
4040
'src/ng/timeout.js',
4141
'src/ng/urlUtils.js',
4242
'src/ng/window.js',
43+
'src/ng/cookieReader.js',
4344

4445
'src/ng/filter.js',
4546
'src/ng/filter/filter.js',
@@ -89,7 +90,8 @@ var angularFiles = {
8990
'src/ngAnimate/animate.js'
9091
],
9192
'ngCookies': [
92-
'src/ngCookies/cookies.js'
93+
'src/ngCookies/cookies.js',
94+
'src/ngCookies/cookieWriter.js'
9395
],
9496
'ngMessages': [
9597
'src/ngMessages/messages.js'
@@ -162,7 +164,7 @@ var angularFiles = {
162164
'src/publishExternalApis.js',
163165
'@angularSrcModules',
164166
'@angularScenario',
165-
'@angularTest',
167+
'@angularTest'
166168
],
167169

168170
'karmaExclude': [
@@ -197,7 +199,7 @@ var angularFiles = {
197199
'src/publishExternalApis.js',
198200
'@angularSrcModules',
199201
'@angularScenario',
200-
'@angularTest',
202+
'@angularTest'
201203
],
202204

203205
'karmaJqueryExclude': [

src/AngularPublic.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@
8484
$$RAFProvider,
8585
$$AsyncCallbackProvider,
8686
$WindowProvider,
87-
$$jqLiteProvider
87+
$$jqLiteProvider,
88+
$$CookieReaderProvider
8889
*/
8990

9091

@@ -238,7 +239,8 @@ function publishExternalAPI(angular) {
238239
$window: $WindowProvider,
239240
$$rAF: $$RAFProvider,
240241
$$asyncCallback: $$AsyncCallbackProvider,
241-
$$jqLite: $$jqLiteProvider
242+
$$jqLite: $$jqLiteProvider,
243+
$$cookieReader: $$CookieReaderProvider
242244
});
243245
}
244246
]);

src/ng/browser.js

-83
Original file line numberDiff line numberDiff line change
@@ -332,89 +332,6 @@ function Browser(window, document, $log, $sniffer) {
332332
return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
333333
};
334334

335-
//////////////////////////////////////////////////////////////
336-
// Cookies API
337-
//////////////////////////////////////////////////////////////
338-
var lastCookies = {};
339-
var lastCookieString = '';
340-
var cookiePath = self.baseHref();
341-
342-
function safeDecodeURIComponent(str) {
343-
try {
344-
return decodeURIComponent(str);
345-
} catch (e) {
346-
return str;
347-
}
348-
}
349-
350-
/**
351-
* @name $browser#cookies
352-
*
353-
* @param {string=} name Cookie name
354-
* @param {string=} value Cookie value
355-
*
356-
* @description
357-
* The cookies method provides a 'private' low level access to browser cookies.
358-
* It is not meant to be used directly, use the $cookie service instead.
359-
*
360-
* The return values vary depending on the arguments that the method was called with as follows:
361-
*
362-
* - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify
363-
* it
364-
* - cookies(name, value) -> set name to value, if value is undefined delete the cookie
365-
* - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that
366-
* way)
367-
*
368-
* @returns {Object} Hash of all cookies (if called without any parameter)
369-
*/
370-
self.cookies = function(name, value) {
371-
var cookieLength, cookieArray, cookie, i, index;
372-
373-
if (name) {
374-
if (value === undefined) {
375-
rawDocument.cookie = encodeURIComponent(name) + "=;path=" + cookiePath +
376-
";expires=Thu, 01 Jan 1970 00:00:00 GMT";
377-
} else {
378-
if (isString(value)) {
379-
cookieLength = (rawDocument.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) +
380-
';path=' + cookiePath).length + 1;
381-
382-
// per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
383-
// - 300 cookies
384-
// - 20 cookies per unique domain
385-
// - 4096 bytes per cookie
386-
if (cookieLength > 4096) {
387-
$log.warn("Cookie '" + name +
388-
"' possibly not set or overflowed because it was too large (" +
389-
cookieLength + " > 4096 bytes)!");
390-
}
391-
}
392-
}
393-
} else {
394-
if (rawDocument.cookie !== lastCookieString) {
395-
lastCookieString = rawDocument.cookie;
396-
cookieArray = lastCookieString.split("; ");
397-
lastCookies = {};
398-
399-
for (i = 0; i < cookieArray.length; i++) {
400-
cookie = cookieArray[i];
401-
index = cookie.indexOf('=');
402-
if (index > 0) { //ignore nameless cookies
403-
name = safeDecodeURIComponent(cookie.substring(0, index));
404-
// the first value that is seen for a cookie is the most
405-
// specific one. values for the same cookie name that
406-
// follow are for less specific paths.
407-
if (lastCookies[name] === undefined) {
408-
lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));
409-
}
410-
}
411-
}
412-
}
413-
return lastCookies;
414-
}
415-
};
416-
417-
418335
/**
419336
* @name $browser#defer
420337
* @param {function()} fn A function, who's execution should be deferred.

src/ng/cookieReader.js

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
'use strict';
2+
3+
/**
4+
* @name $$cookieReader
5+
* @requires $document
6+
*
7+
* @description
8+
* This is a private service for reading cookies used by $http and ngCookies
9+
*
10+
* @return {Object} a key/value map of the current cookies
11+
*/
12+
function $$CookieReader($document) {
13+
var rawDocument = $document[0];
14+
var lastCookies = {};
15+
var lastCookieString = '';
16+
17+
function safeDecodeURIComponent(str) {
18+
try {
19+
return decodeURIComponent(str);
20+
} catch (e) {
21+
return str;
22+
}
23+
}
24+
25+
return function() {
26+
var cookieArray, cookie, i, index, name;
27+
28+
if (rawDocument.cookie !== lastCookieString) {
29+
lastCookieString = rawDocument.cookie;
30+
cookieArray = lastCookieString.split('; ');
31+
lastCookies = {};
32+
33+
for (i = 0; i < cookieArray.length; i++) {
34+
cookie = cookieArray[i];
35+
index = cookie.indexOf('=');
36+
if (index > 0) { //ignore nameless cookies
37+
name = safeDecodeURIComponent(cookie.substring(0, index));
38+
// the first value that is seen for a cookie is the most
39+
// specific one. values for the same cookie name that
40+
// follow are for less specific paths.
41+
if (lastCookies[name] === undefined) {
42+
lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));
43+
}
44+
}
45+
}
46+
}
47+
return lastCookies;
48+
};
49+
}
50+
51+
$$CookieReader.$inject = ['$document'];
52+
53+
function $$CookieReaderProvider() {
54+
this.$get = $$CookieReader;
55+
}

src/ng/http.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ function $HttpProvider() {
220220
**/
221221
var interceptorFactories = this.interceptors = [];
222222

223-
this.$get = ['$httpBackend', '$browser', '$cacheFactory', '$rootScope', '$q', '$injector',
224-
function($httpBackend, $browser, $cacheFactory, $rootScope, $q, $injector) {
223+
this.$get = ['$httpBackend', '$$cookieReader', '$cacheFactory', '$rootScope', '$q', '$injector',
224+
function($httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector) {
225225

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

@@ -1066,7 +1066,7 @@ function $HttpProvider() {
10661066
// send the request to the backend
10671067
if (isUndefined(cachedResp)) {
10681068
var xsrfValue = urlIsSameOrigin(config.url)
1069-
? $browser.cookies()[config.xsrfCookieName || defaults.xsrfCookieName]
1069+
? $$cookieReader()[config.xsrfCookieName || defaults.xsrfCookieName]
10701070
: undefined;
10711071
if (xsrfValue) {
10721072
reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;

src/ngCookies/cookieWriter.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use strict';
2+
3+
/**
4+
* @name $$cookieWriter
5+
* @requires $document
6+
*
7+
* @description
8+
* This is a private service for writing cookies
9+
*
10+
* @param {string} name Cookie name
11+
* @param {string=} value Cookie value (if undefined, cookie will be deleted)
12+
*/
13+
function $$CookieWriter($document, $log, $browser) {
14+
var cookiePath = $browser.baseHref();
15+
var rawDocument = $document[0];
16+
17+
return function(name, value) {
18+
if (value === undefined) {
19+
rawDocument.cookie = encodeURIComponent(name) + "=;path=" + cookiePath +
20+
";expires=Thu, 01 Jan 1970 00:00:00 GMT";
21+
} else {
22+
if (angular.isString(value)) {
23+
var cookieLength = (rawDocument.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) +
24+
';path=' + cookiePath).length + 1;
25+
26+
// per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
27+
// - 300 cookies
28+
// - 20 cookies per unique domain
29+
// - 4096 bytes per cookie
30+
if (cookieLength > 4096) {
31+
$log.warn("Cookie '" + name +
32+
"' possibly not set or overflowed because it was too large (" +
33+
cookieLength + " > 4096 bytes)!");
34+
}
35+
}
36+
}
37+
};
38+
}
39+
40+
$$CookieWriter.$inject = ['$document', '$log', '$browser'];
41+
42+
angular.module('ngCookies').provider('$$cookieWriter', function $$CookieWriterProvider() {
43+
this.$get = $$CookieWriter;
44+
});

src/ngCookies/cookies.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ angular.module('ngCookies', ['ng']).
4343
* }]);
4444
* ```
4545
*/
46-
factory('$cookies', ['$rootScope', '$browser', function($rootScope, $browser) {
46+
factory('$cookies', ['$rootScope', '$browser', '$$cookieReader', '$$cookieWriter', function($rootScope, $browser, $$cookieReader, $$cookieWriter) {
4747
var cookies = {},
4848
lastCookies = {},
4949
lastBrowserCookies,
@@ -53,7 +53,7 @@ angular.module('ngCookies', ['ng']).
5353

5454
//creates a poller fn that copies all cookies from the $browser to service & inits the service
5555
$browser.addPollFn(function() {
56-
var currentCookies = $browser.cookies();
56+
var currentCookies = $$cookieReader();
5757
if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl
5858
lastBrowserCookies = currentCookies;
5959
copy(currentCookies, lastCookies);
@@ -85,7 +85,7 @@ angular.module('ngCookies', ['ng']).
8585
//delete any cookies deleted in $cookies
8686
for (name in lastCookies) {
8787
if (isUndefined(cookies[name])) {
88-
$browser.cookies(name, undefined);
88+
$$cookieWriter(name, undefined);
8989
}
9090
}
9191

@@ -97,15 +97,15 @@ angular.module('ngCookies', ['ng']).
9797
cookies[name] = value;
9898
}
9999
if (value !== lastCookies[name]) {
100-
$browser.cookies(name, value);
100+
$$cookieWriter(name, value);
101101
updated = true;
102102
}
103103
}
104104

105105
//verify what was actually stored
106106
if (updated) {
107107
updated = false;
108-
browserCookies = $browser.cookies();
108+
browserCookies = $$cookieReader();
109109

110110
for (name in cookies) {
111111
if (cookies[name] !== browserCookies[name]) {

src/ngMock/angular-mocks.js

-21
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ angular.mock.$Browser = function() {
5959

6060
self.$$checkUrlChange = angular.noop;
6161

62-
self.cookieHash = {};
63-
self.lastCookieHash = {};
6462
self.deferredFns = [];
6563
self.deferredNextId = 0;
6664

@@ -163,25 +161,6 @@ angular.mock.$Browser.prototype = {
163161
return this.$$state;
164162
},
165163

166-
cookies: function(name, value) {
167-
if (name) {
168-
if (angular.isUndefined(value)) {
169-
delete this.cookieHash[name];
170-
} else {
171-
if (angular.isString(value) && //strings only
172-
value.length <= 4096) { //strict cookie storage limits
173-
this.cookieHash[name] = value;
174-
}
175-
}
176-
} else {
177-
if (!angular.equals(this.cookieHash, this.lastCookieHash)) {
178-
this.lastCookieHash = angular.copy(this.cookieHash);
179-
this.cookieHash = angular.copy(this.cookieHash);
180-
}
181-
return this.cookieHash;
182-
}
183-
},
184-
185164
notifyWhenNoOutstandingRequests: function(fn) {
186165
fn();
187166
}

0 commit comments

Comments
 (0)