| OLD | NEW |
| 1 part of angular.core.dom; | 1 part of angular.core.dom; |
| 2 | 2 |
| 3 /** | 3 /** |
| 4 * This class provides low-level acces to the browser's cookies. | 4 * This class provides low-level acces to the browser's cookies. |
| 5 * It is not meant to be used directly by applications. Instead | 5 * It is not meant to be used directly by applications. Instead |
| 6 * use the Cookies service. | 6 * use the Cookies service. |
| 7 * | 7 * |
| 8 */ | 8 */ |
| 9 @NgInjectableService() | 9 @NgInjectableService() |
| 10 class BrowserCookies { | 10 class BrowserCookies { |
| 11 ExceptionHandler _exceptionHandler; |
| 11 dom.Document _document; | 12 dom.Document _document; |
| 12 | 13 |
| 13 var lastCookies = {}; | 14 var lastCookies = {}; |
| 14 var lastCookieString = ''; | 15 var lastCookieString = ''; |
| 15 var cookiePath; | 16 var cookiePath; |
| 16 var baseElement; | 17 var baseElement; |
| 17 | 18 |
| 18 | 19 BrowserCookies(this._exceptionHandler) { |
| 19 BrowserCookies() { | |
| 20 // Injecting document produces the error 'Caught Compile-time error during m
irrored execution: | 20 // Injecting document produces the error 'Caught Compile-time error during m
irrored execution: |
| 21 // <'file:///mnt/data/b/build/slave/dartium-lucid32-full-trunk/build/src/out
/Release/gen/blink/ | 21 // <'file:///mnt/data/b/build/slave/dartium-lucid32-full-trunk/build/src/out
/Release/gen/blink/ |
| 22 // bindings/dart/dart/html/Document.dart': Error: line 7 pos 3: expression m
ust be a compile-time constant | 22 // bindings/dart/dart/html/Document.dart': Error: line 7 pos 3: expression m
ust be a compile-time constant |
| 23 // @ DocsEditable ' | 23 // @ DocsEditable ' |
| 24 // I have not had time to debug it yet. | 24 // I have not had time to debug it yet. |
| 25 _document = dom.document; | 25 _document = dom.document; |
| 26 | 26 |
| 27 var baseElementList = _document.getElementsByName('base'); | 27 var baseElementList = _document.getElementsByName('base'); |
| 28 if (baseElementList.isEmpty) return; | 28 if (baseElementList.isEmpty) return; |
| 29 baseElement = _document.getElementsByName('base').first; | 29 baseElement = baseElementList.first; |
| 30 cookiePath = _baseHref(); | 30 cookiePath = _baseHref(); |
| 31 } | 31 } |
| 32 | 32 |
| 33 var URL_PROTOCOL = new RegExp(r'^https?\:\/\/[^\/]*'); | 33 var URL_PROTOCOL = new RegExp(r'^https?\:\/\/[^\/]*'); |
| 34 _baseHref() { | 34 _baseHref() { |
| 35 var href = baseElement != null ? baseElement.attr('href') : null; | 35 var href = baseElement != null ? baseElement.attr('href') : null; |
| 36 return href != null ? href.replace(URL_PROTOCOL, '') : ''; | 36 return href != null ? href.replace(URL_PROTOCOL, '') : ''; |
| 37 } | 37 } |
| 38 | 38 |
| 39 // NOTE(deboer): This is sub-optimal, see dartbug.com/14281 | 39 // NOTE(deboer): This is sub-optimal, see dartbug.com/14281 |
| 40 _unescape(s) => Uri.decodeFull(s); | 40 _unescape(s) => Uri.decodeFull(s); |
| 41 _escape(s) => | 41 _escape(s) => |
| 42 Uri.encodeFull(s) | 42 Uri.encodeFull(s) |
| 43 .replaceAll('=', '%3D') | 43 .replaceAll('=', '%3D') |
| 44 .replaceAll(';', '%3B'); | 44 .replaceAll(';', '%3B'); |
| 45 | 45 |
| 46 | |
| 47 _updateLastCookies() { | 46 _updateLastCookies() { |
| 48 var cookieLength, cookieArray, cookie, i, index; | |
| 49 | |
| 50 if (_document.cookie != lastCookieString) { | 47 if (_document.cookie != lastCookieString) { |
| 51 lastCookieString = _document.cookie; | 48 lastCookieString = _document.cookie; |
| 52 cookieArray = lastCookieString.split("; "); | 49 List<String> cookieArray = lastCookieString.split("; "); |
| 53 lastCookies = {}; | 50 lastCookies = {}; |
| 54 | 51 |
| 55 for (i = 0; i < cookieArray.length; i++) { | 52 // The first value that is seen for a cookie is the most specific one. |
| 56 cookie = cookieArray[i]; | 53 // Values for the same cookie name that follow are for less specific paths
. |
| 57 index = cookie.indexOf('='); | 54 // Hence we reverse the array. |
| 55 cookieArray.reversed.forEach((cookie) { |
| 56 var index = cookie.indexOf('='); |
| 58 if (index > 0) { //ignore nameless cookies | 57 if (index > 0) { //ignore nameless cookies |
| 59 var name = _unescape(cookie.substring(0, index)); | 58 var name = _unescape(cookie.substring(0, index)); |
| 60 // the first value that is seen for a cookie is the most | 59 lastCookies[name] = _unescape(cookie.substring(index + 1)); |
| 61 // specific one. values for the same cookie name that | |
| 62 // follow are for less specific paths. | |
| 63 if (!lastCookies.containsKey(name)) { | |
| 64 lastCookies[name] = _unescape(cookie.substring(index + 1)); | |
| 65 } | |
| 66 } | 60 } |
| 67 } | 61 }); |
| 68 } | 62 } |
| 69 return lastCookies; | 63 return lastCookies; |
| 70 } | 64 } |
| 71 | 65 |
| 72 /** | 66 /** |
| 73 * Returns a cookie. | 67 * Returns a cookie. |
| 74 */ | 68 */ |
| 75 operator[](key) => _updateLastCookies()[key]; | 69 operator[](key) => _updateLastCookies()[key]; |
| 76 | 70 |
| 77 /** | 71 /** |
| 78 * Sets a cookie. Setting a cookie to [null] deletes the cookie. | 72 * Sets a cookie. Setting a cookie to [null] deletes the cookie. |
| 79 */ | 73 */ |
| 80 operator[]=(name, value) { | 74 operator[]=(name, value) { |
| 81 var cookieLength, cookieArray, cookie, i, index; | |
| 82 | |
| 83 if (identical(value, null)) { | 75 if (identical(value, null)) { |
| 84 _document.cookie = "${_escape(name)}=;path=$cookiePath;expires=Thu, 01 Jan
1970 00:00:00 GMT"; | 76 _document.cookie = "${_escape(name)}=;path=$cookiePath;expires=Thu, 01 Jan
1970 00:00:00 GMT"; |
| 85 } else { | 77 } else { |
| 86 if (value is String) { | 78 if (value is String) { |
| 87 cookieLength = (_document.cookie = "${_escape(name)}=${_escape(value)};p
ath=$cookiePath").length + 1; | 79 var cookieLength = (_document.cookie = "${_escape(name)}=${_escape(value
)};path=$cookiePath").length + 1; |
| 88 | 80 |
| 89 // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum
: | 81 // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum
: |
| 90 // - 300 cookies | 82 // - 300 cookies |
| 91 // - 20 cookies per unique domain | 83 // - 20 cookies per unique domain |
| 92 // - 4096 bytes per cookie | 84 // - 4096 bytes per cookie |
| 93 if (cookieLength > 4096) { | 85 if (cookieLength > 4096) { |
| 94 print("Cookie '$name' possibly not set or overflowed because it was "
+ | 86 _exceptionHandler("Cookie '$name' possibly not set or overflowed becau
se it was " + |
| 95 "too large ($cookieLength > 4096 bytes)!"); | 87 "too large ($cookieLength > 4096 bytes)!", null); |
| 96 } | 88 } |
| 97 } | 89 } |
| 98 } | 90 } |
| 99 | |
| 100 } | 91 } |
| 101 | 92 |
| 102 get all => _updateLastCookies(); | 93 get all => _updateLastCookies(); |
| 103 } | 94 } |
| 104 | 95 |
| 105 /** | 96 /** |
| 106 * Cookies service | 97 * Cookies service |
| 107 */ | 98 */ |
| 108 class Cookies { | 99 class Cookies { |
| 109 | |
| 110 BrowserCookies _browserCookies; | 100 BrowserCookies _browserCookies; |
| 111 | 101 Cookies(this._browserCookies); |
| 112 Cookies(BrowserCookies this._browserCookies); | |
| 113 | 102 |
| 114 /** | 103 /** |
| 115 * Returns the value of given cookie key | 104 * Returns the value of given cookie key |
| 116 */ | 105 */ |
| 117 operator[](name) => this._browserCookies[name]; | 106 operator[](name) => this._browserCookies[name]; |
| 118 | 107 |
| 119 /** | 108 /** |
| 120 * Sets a value for given cookie key | 109 * Sets a value for given cookie key |
| 121 */ | 110 */ |
| 122 operator[]=(name, value) { | 111 operator[]=(name, value) => this._browserCookies[name] = value; |
| 123 this._browserCookies[name] = value; | |
| 124 } | |
| 125 | 112 |
| 126 /** | 113 /** |
| 127 * Remove given cookie | 114 * Remove given cookie |
| 128 */ | 115 */ |
| 129 remove(name) { | 116 remove(name) => this._browserCookies[name] = null; |
| 130 this._browserCookies[name] = null; | |
| 131 } | |
| 132 } | 117 } |
| 133 | 118 |
| OLD | NEW |