SHINDIG-1056 by lipeng, BasicRemoteContentTest doesn't depend on static private key...
[shindig.git] / javascript / container / cookies.js
blob20d808a5f11be7a2b703134699dece1866b89d40
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations under the License.
19 /**
20 * @fileoverview Functions for setting, getting and deleting cookies
23 /**
24 * Namespace for cookie functions
27 // TODO: find the official solution for a cookies library
28 var shindig = shindig || {};
29 shindig.cookies = shindig.cookies || {};
32 shindig.cookies.JsType_ = {
33 UNDEFINED: 'undefined'
36 shindig.cookies.isDef = function(val) {
37 return typeof val != shindig.cookies.JsType_.UNDEFINED;
41 /**
42 * Sets a cookie.
43 * The max_age can be -1 to set a session cookie. To remove and expire cookies,
44 * use remove() instead.
46 * @param {string} name The cookie name.
47 * @param {string} value The cookie value.
48 * @param {number} opt_maxAge The max age in seconds (from now). Use -1 to set
49 * a session cookie. If not provided, the default is
50 * -1 (i.e. set a session cookie).
51 * @param {string} opt_path The path of the cookie, or null to not specify a
52 * path attribute (browser will use the full request
53 * path). If not provided, the default is '/' (i.e.
54 * path=/).
55 * @param {string} opt_domain The domain of the cookie, or null to not specify
56 * a domain attribute (browser will use the full
57 * request host name). If not provided, the default
58 * is null (i.e. let browser use full request host
59 * name).
61 shindig.cookies.set = function(name, value, opt_maxAge, opt_path, opt_domain) {
62 // we do not allow '=' or ';' in the name
63 if (/;=/g.test(name)) {
64 throw new Error('Invalid cookie name "' + name + '"');
66 // we do not allow ';' in value
67 if (/;/g.test(value)) {
68 throw new Error('Invalid cookie value "' + value + '"');
71 if (!shindig.cookies.isDef(opt_maxAge)) {
72 opt_maxAge = -1;
75 var domainStr = opt_domain ? ';domain=' + opt_domain : '';
76 var pathStr = opt_path ? ';path=' + opt_path : '';
78 var expiresStr;
80 // Case 1: Set a session cookie.
81 if (opt_maxAge < 0) {
82 expiresStr = '';
84 // Case 2: Expire the cookie.
85 // Note: We don't tell people about this option in the function doc because
86 // we prefer people to use ExpireCookie() to expire cookies.
87 } else if (opt_maxAge === 0) {
88 // Note: Don't use Jan 1, 1970 for date because NS 4.76 will try to convert
89 // it to local time, and if the local time is before Jan 1, 1970, then the
90 // browser will ignore the Expires attribute altogether.
91 var pastDate = new Date(1970, 1 /*Feb*/, 1); // Feb 1, 1970
92 expiresStr = ';expires=' + pastDate.toUTCString();
94 // Case 3: Set a persistent cookie.
95 } else {
96 var futureDate = new Date((new Date).getTime() + opt_maxAge * 1000);
97 expiresStr = ';expires=' + futureDate.toUTCString();
100 document.cookie = name + '=' + value + domainStr + pathStr + expiresStr;
105 * Returns the value for the first cookie with the given name
106 * @param {string} name The name of the cookie to get
107 * @param {string} opt_default If not found this is returned instead.
108 * @return {string|undefined} The value of the cookie. If no cookie is set this
109 * returns opt_default or undefined if opt_default is
110 * not provided.
112 shindig.cookies.get = function(name, opt_default) {
113 var nameEq = name + "=";
114 var cookie = String(document.cookie);
115 for (var pos = -1; (pos = cookie.indexOf(nameEq, pos + 1)) >= 0;) {
116 var i = pos;
117 // walk back along string skipping whitespace and looking for a ; before
118 // the name to make sure that we don't match cookies whose name contains
119 // the given name as a suffix.
120 while (--i >= 0) {
121 var ch = cookie.charAt(i);
122 if (ch == ';') {
123 i = -1; // indicate success
124 break;
127 if (i == -1) { // first cookie in the string or we found a ;
128 var end = cookie.indexOf(';', pos);
129 if (end < 0) {
130 end = cookie.length;
132 return cookie.substring(pos + nameEq.length, end);
135 return opt_default;
140 * Removes and expires a cookie.
142 * @param {string} name The cookie name.
143 * @param {string} opt_path The path of the cookie, or null to expire a cookie
144 * set at the full request path. If not provided, the
145 * default is '/' (i.e. path=/).
146 * @param {string} opt_domain The domain of the cookie, or null to expire a
147 * cookie set at the full request host name. If not
148 * provided, the default is null (i.e. cookie at
149 * full request host name).
151 shindig.cookies.remove = function(name, opt_path, opt_domain) {
152 var rv = shindig.cookies.containsKey(name);
153 shindig.cookies.set(name, '', 0, opt_path, opt_domain);
154 return rv;
159 * Gets the names and values for all the cookies
160 * @private
161 * @return {Object} An object with keys and values
163 shindig.cookies.getKeyValues_ = function() {
164 var cookie = String(document.cookie);
165 var parts = cookie.split(/\s*;\s*/);
166 var keys = [], values = [], index, part;
167 for (var i = 0; part = parts[i]; i++) {
168 index = part.indexOf('=');
170 if (index == -1) { // empty name
171 keys.push('');
172 values.push(part);
173 } else {
174 keys.push(part.substring(0, index));
175 values.push(part.substring(index + 1));
178 return {keys: keys, values: values};
183 * Gets the names for all the cookies
184 * @return {Array} An array with the names of the cookies
186 shindig.cookies.getKeys = function() {
187 return shindig.cookies.getKeyValues_().keys;
192 * Gets the values for all the cookies
193 * @return {Array} An array with the values of the cookies
195 shindig.cookies.getValues = function() {
196 return shindig.cookies.getKeyValues_().values;
201 * Whether there are any cookies for this document
202 * @return {boolean}
204 shindig.cookies.isEmpty = function() {
205 return document.cookie === '';
210 * Returns the number of cookies for this document
211 * @return {number}
213 shindig.cookies.getCount = function() {
214 var cookie = String(document.cookie);
215 if (cookie === '') {
216 return 0;
218 var parts = cookie.split(/\s*;\s*/);
219 return parts.length;
224 * Returns whether there is a cookie with the given name
225 * @param {string} key The name of the cookie to test for
226 * @return {boolean}
228 shindig.cookies.containsKey = function(key) {
229 var sentinel = {};
230 // if get does not find the key it returns the default value. We therefore
231 // compare the result with an object to ensure we do not get any false
232 // positives.
233 return shindig.cookies.get(key, sentinel) !== sentinel;
238 * Returns whether there is a cookie with the given value. (This is an O(n)
239 * operation.)
240 * @param {string} value The value to check for
241 * @return {boolean}
243 shindig.cookies.containsValue = function(value) {
244 // this O(n) in any case so lets do the trivial thing.
245 var values = shindig.cookies.getKeyValues_().values;
246 for (var i = 0; i < values.length; i++) {
247 if (values[i] == value) {
248 return true;
251 return false;
256 * Removes all cookies for this document
258 shindig.cookies.clear = function() {
259 var keys = shindig.cookies.getKeyValues_().keys;
260 for (var i = keys.length - 1; i >= 0; i--) {
261 shindig.cookies.remove(keys[i]);
266 * Static constant for the size of cookies. Per the spec, there's a 4K limit
267 * to the size of a cookie. To make sure users can't break this limit, we
268 * should truncate long cookies at 3950 bytes, to be extra careful with dumb
269 * browsers/proxies that interpret 4K as 4000 rather than 4096
270 * @type number
272 shindig.cookies.MAX_COOKIE_LENGTH = 3950;