Lines 1-482
Link Here
|
1 |
/* |
|
|
2 |
Copyright (c) 2009, Yahoo! Inc. All rights reserved. |
3 |
Code licensed under the BSD License: |
4 |
http://developer.yahoo.net/yui/license.txt |
5 |
version: 2.8.0r4 |
6 |
*/ |
7 |
/** |
8 |
* Utilities for cookie management |
9 |
* @namespace YAHOO.util |
10 |
* @module cookie |
11 |
*/ |
12 |
YAHOO.namespace("util"); |
13 |
|
14 |
/** |
15 |
* Cookie utility. |
16 |
* @class Cookie |
17 |
* @static |
18 |
*/ |
19 |
YAHOO.util.Cookie = { |
20 |
|
21 |
//------------------------------------------------------------------------- |
22 |
// Private Methods |
23 |
//------------------------------------------------------------------------- |
24 |
|
25 |
/** |
26 |
* Creates a cookie string that can be assigned into document.cookie. |
27 |
* @param {String} name The name of the cookie. |
28 |
* @param {String} value The value of the cookie. |
29 |
* @param {Boolean} encodeValue True to encode the value, false to leave as-is. |
30 |
* @param {Object} options (Optional) Options for the cookie. |
31 |
* @return {String} The formatted cookie string. |
32 |
* @method _createCookieString |
33 |
* @private |
34 |
* @static |
35 |
*/ |
36 |
_createCookieString : function (name /*:String*/, value /*:Variant*/, encodeValue /*:Boolean*/, options /*:Object*/) /*:String*/ { |
37 |
|
38 |
//shortcut |
39 |
var lang = YAHOO.lang, |
40 |
text = encodeURIComponent(name) + "=" + (encodeValue ? encodeURIComponent(value) : value); |
41 |
|
42 |
|
43 |
if (lang.isObject(options)){ |
44 |
//expiration date |
45 |
if (options.expires instanceof Date){ |
46 |
text += "; expires=" + options.expires.toUTCString(); |
47 |
} |
48 |
|
49 |
//path |
50 |
if (lang.isString(options.path) && options.path !== ""){ |
51 |
text += "; path=" + options.path; |
52 |
} |
53 |
|
54 |
//domain |
55 |
if (lang.isString(options.domain) && options.domain !== ""){ |
56 |
text += "; domain=" + options.domain; |
57 |
} |
58 |
|
59 |
//secure |
60 |
if (options.secure === true){ |
61 |
text += "; secure"; |
62 |
} |
63 |
} |
64 |
|
65 |
return text; |
66 |
}, |
67 |
|
68 |
/** |
69 |
* Formats a cookie value for an object containing multiple values. |
70 |
* @param {Object} hash An object of key-value pairs to create a string for. |
71 |
* @return {String} A string suitable for use as a cookie value. |
72 |
* @method _createCookieHashString |
73 |
* @private |
74 |
* @static |
75 |
*/ |
76 |
_createCookieHashString : function (hash /*:Object*/) /*:String*/ { |
77 |
|
78 |
//shortcuts |
79 |
var lang = YAHOO.lang; |
80 |
|
81 |
if (!lang.isObject(hash)){ |
82 |
throw new TypeError("Cookie._createCookieHashString(): Argument must be an object."); |
83 |
} |
84 |
|
85 |
var text /*:Array*/ = []; |
86 |
|
87 |
for (var key in hash){ |
88 |
if (lang.hasOwnProperty(hash, key) && !lang.isFunction(hash[key]) && !lang.isUndefined(hash[key])){ |
89 |
text.push(encodeURIComponent(key) + "=" + encodeURIComponent(String(hash[key]))); |
90 |
} |
91 |
} |
92 |
|
93 |
return text.join("&"); |
94 |
}, |
95 |
|
96 |
/** |
97 |
* Parses a cookie hash string into an object. |
98 |
* @param {String} text The cookie hash string to parse. The string should already be URL-decoded. |
99 |
* @return {Object} An object containing entries for each cookie value. |
100 |
* @method _parseCookieHash |
101 |
* @private |
102 |
* @static |
103 |
*/ |
104 |
_parseCookieHash : function (text /*:String*/) /*:Object*/ { |
105 |
|
106 |
var hashParts /*:Array*/ = text.split("&"), |
107 |
hashPart /*:Array*/ = null, |
108 |
hash /*:Object*/ = {}; |
109 |
|
110 |
if (text.length > 0){ |
111 |
for (var i=0, len=hashParts.length; i < len; i++){ |
112 |
hashPart = hashParts[i].split("="); |
113 |
hash[decodeURIComponent(hashPart[0])] = decodeURIComponent(hashPart[1]); |
114 |
} |
115 |
} |
116 |
|
117 |
return hash; |
118 |
}, |
119 |
|
120 |
/** |
121 |
* Parses a cookie string into an object representing all accessible cookies. |
122 |
* @param {String} text The cookie string to parse. |
123 |
* @param {Boolean} decode (Optional) Indicates if the cookie values should be decoded or not. Default is true. |
124 |
* @return {Object} An object containing entries for each accessible cookie. |
125 |
* @method _parseCookieString |
126 |
* @private |
127 |
* @static |
128 |
*/ |
129 |
_parseCookieString : function (text /*:String*/, decode /*:Boolean*/) /*:Object*/ { |
130 |
|
131 |
var cookies /*:Object*/ = {}; |
132 |
|
133 |
if (YAHOO.lang.isString(text) && text.length > 0) { |
134 |
|
135 |
var decodeValue = (decode === false ? function(s){return s;} : decodeURIComponent); |
136 |
|
137 |
//if (/[^=]+=[^=;]?(?:; [^=]+=[^=]?)?/.test(text)){ |
138 |
var cookieParts /*:Array*/ = text.split(/;\s/g), |
139 |
cookieName /*:String*/ = null, |
140 |
cookieValue /*:String*/ = null, |
141 |
cookieNameValue /*:Array*/ = null; |
142 |
|
143 |
for (var i=0, len=cookieParts.length; i < len; i++){ |
144 |
|
145 |
//check for normally-formatted cookie (name-value) |
146 |
cookieNameValue = cookieParts[i].match(/([^=]+)=/i); |
147 |
if (cookieNameValue instanceof Array){ |
148 |
try { |
149 |
cookieName = decodeURIComponent(cookieNameValue[1]); |
150 |
cookieValue = decodeValue(cookieParts[i].substring(cookieNameValue[1].length+1)); |
151 |
} catch (ex){ |
152 |
//ignore the entire cookie - encoding is likely invalid |
153 |
} |
154 |
} else { |
155 |
//means the cookie does not have an "=", so treat it as a boolean flag |
156 |
cookieName = decodeURIComponent(cookieParts[i]); |
157 |
cookieValue = ""; |
158 |
} |
159 |
cookies[cookieName] = cookieValue; |
160 |
} |
161 |
//} |
162 |
} |
163 |
|
164 |
return cookies; |
165 |
}, |
166 |
|
167 |
//------------------------------------------------------------------------- |
168 |
// Public Methods |
169 |
//------------------------------------------------------------------------- |
170 |
|
171 |
/** |
172 |
* Determines if the cookie with the given name exists. This is useful for |
173 |
* Boolean cookies (those that do not follow the name=value convention). |
174 |
* @param {String} name The name of the cookie to check. |
175 |
* @return {Boolean} True if the cookie exists, false if not. |
176 |
* @method exists |
177 |
* @static |
178 |
*/ |
179 |
exists: function(name) { |
180 |
|
181 |
if (!YAHOO.lang.isString(name) || name === ""){ |
182 |
throw new TypeError("Cookie.exists(): Cookie name must be a non-empty string."); |
183 |
} |
184 |
|
185 |
var cookies /*:Object*/ = this._parseCookieString(document.cookie, true); |
186 |
|
187 |
return cookies.hasOwnProperty(name); |
188 |
}, |
189 |
|
190 |
/** |
191 |
* Returns the cookie value for the given name. |
192 |
* @param {String} name The name of the cookie to retrieve. |
193 |
* @param {Object|Function} options (Optional) An object containing one or more |
194 |
* cookie options: raw (true/false) and converter (a function). |
195 |
* The converter function is run on the value before returning it. The |
196 |
* function is not used if the cookie doesn't exist. The function can be |
197 |
* passed instead of the options object for backwards compatibility. |
198 |
* @return {Variant} If no converter is specified, returns a string or null if |
199 |
* the cookie doesn't exist. If the converter is specified, returns the value |
200 |
* returned from the converter or null if the cookie doesn't exist. |
201 |
* @method get |
202 |
* @static |
203 |
*/ |
204 |
get : function (name /*:String*/, options /*:Variant*/) /*:Variant*/{ |
205 |
|
206 |
var lang = YAHOO.lang, |
207 |
converter; |
208 |
|
209 |
if (lang.isFunction(options)) { |
210 |
converter = options; |
211 |
options = {}; |
212 |
} else if (lang.isObject(options)) { |
213 |
converter = options.converter; |
214 |
} else { |
215 |
options = {}; |
216 |
} |
217 |
|
218 |
var cookies /*:Object*/ = this._parseCookieString(document.cookie, !options.raw); |
219 |
|
220 |
if (!lang.isString(name) || name === ""){ |
221 |
throw new TypeError("Cookie.get(): Cookie name must be a non-empty string."); |
222 |
} |
223 |
|
224 |
if (lang.isUndefined(cookies[name])) { |
225 |
return null; |
226 |
} |
227 |
|
228 |
if (!lang.isFunction(converter)){ |
229 |
return cookies[name]; |
230 |
} else { |
231 |
return converter(cookies[name]); |
232 |
} |
233 |
}, |
234 |
|
235 |
/** |
236 |
* Returns the value of a subcookie. |
237 |
* @param {String} name The name of the cookie to retrieve. |
238 |
* @param {String} subName The name of the subcookie to retrieve. |
239 |
* @param {Function} converter (Optional) A function to run on the value before returning |
240 |
* it. The function is not used if the cookie doesn't exist. |
241 |
* @return {Variant} If the cookie doesn't exist, null is returned. If the subcookie |
242 |
* doesn't exist, null if also returned. If no converter is specified and the |
243 |
* subcookie exists, a string is returned. If a converter is specified and the |
244 |
* subcookie exists, the value returned from the converter is returned. |
245 |
* @method getSub |
246 |
* @static |
247 |
*/ |
248 |
getSub : function (name, subName, converter) { |
249 |
|
250 |
var lang = YAHOO.lang, |
251 |
hash = this.getSubs(name); |
252 |
|
253 |
if (hash !== null) { |
254 |
|
255 |
if (!lang.isString(subName) || subName === ""){ |
256 |
throw new TypeError("Cookie.getSub(): Subcookie name must be a non-empty string."); |
257 |
} |
258 |
|
259 |
if (lang.isUndefined(hash[subName])){ |
260 |
return null; |
261 |
} |
262 |
|
263 |
if (!lang.isFunction(converter)){ |
264 |
return hash[subName]; |
265 |
} else { |
266 |
return converter(hash[subName]); |
267 |
} |
268 |
} else { |
269 |
return null; |
270 |
} |
271 |
|
272 |
}, |
273 |
|
274 |
/** |
275 |
* Returns an object containing name-value pairs stored in the cookie with the given name. |
276 |
* @param {String} name The name of the cookie to retrieve. |
277 |
* @return {Object} An object of name-value pairs if the cookie with the given name |
278 |
* exists, null if it does not. |
279 |
* @method getSubs |
280 |
* @static |
281 |
*/ |
282 |
getSubs : function (name /*:String*/) /*:Object*/ { |
283 |
|
284 |
var isString = YAHOO.lang.isString; |
285 |
|
286 |
//check cookie name |
287 |
if (!isString(name) || name === ""){ |
288 |
throw new TypeError("Cookie.getSubs(): Cookie name must be a non-empty string."); |
289 |
} |
290 |
|
291 |
var cookies = this._parseCookieString(document.cookie, false); |
292 |
if (isString(cookies[name])){ |
293 |
return this._parseCookieHash(cookies[name]); |
294 |
} |
295 |
return null; |
296 |
}, |
297 |
|
298 |
/** |
299 |
* Removes a cookie from the machine by setting its expiration date to |
300 |
* sometime in the past. |
301 |
* @param {String} name The name of the cookie to remove. |
302 |
* @param {Object} options (Optional) An object containing one or more |
303 |
* cookie options: path (a string), domain (a string), |
304 |
* and secure (true/false). The expires option will be overwritten |
305 |
* by the method. |
306 |
* @return {String} The created cookie string. |
307 |
* @method remove |
308 |
* @static |
309 |
*/ |
310 |
remove : function (name /*:String*/, options /*:Object*/) /*:String*/ { |
311 |
|
312 |
//check cookie name |
313 |
if (!YAHOO.lang.isString(name) || name === ""){ |
314 |
throw new TypeError("Cookie.remove(): Cookie name must be a non-empty string."); |
315 |
} |
316 |
|
317 |
//set options - clone options so the original isn't affected |
318 |
options = YAHOO.lang.merge(options || {}, { |
319 |
expires: new Date(0) |
320 |
}); |
321 |
|
322 |
//set cookie |
323 |
return this.set(name, "", options); |
324 |
}, |
325 |
|
326 |
/** |
327 |
* Removes a subcookie with a given name. Removing the last subcookie |
328 |
* won't remove the entire cookie unless options.removeIfEmpty is true. |
329 |
* @param {String} name The name of the cookie in which the subcookie exists. |
330 |
* @param {String} subName The name of the subcookie to remove. |
331 |
* @param {Object} options (Optional) An object containing one or more |
332 |
* cookie options: path (a string), domain (a string), expires (a Date object), |
333 |
* removeIfEmpty (true/false), and secure (true/false). This must be the same |
334 |
* settings as the original subcookie. |
335 |
* @return {String} The created cookie string. |
336 |
* @method removeSub |
337 |
* @static |
338 |
*/ |
339 |
removeSub : function(name /*:String*/, subName /*:String*/, options /*:Object*/) /*:String*/ { |
340 |
|
341 |
var lang = YAHOO.lang; |
342 |
|
343 |
options = options || {}; |
344 |
|
345 |
//check cookie name |
346 |
if (!lang.isString(name) || name === ""){ |
347 |
throw new TypeError("Cookie.removeSub(): Cookie name must be a non-empty string."); |
348 |
} |
349 |
|
350 |
//check subcookie name |
351 |
if (!lang.isString(subName) || subName === ""){ |
352 |
throw new TypeError("Cookie.removeSub(): Subcookie name must be a non-empty string."); |
353 |
} |
354 |
|
355 |
//get all subcookies for this cookie |
356 |
var subs = this.getSubs(name); |
357 |
|
358 |
//delete the indicated subcookie |
359 |
if (lang.isObject(subs) && lang.hasOwnProperty(subs, subName)){ |
360 |
delete subs[subName]; |
361 |
|
362 |
if (!options.removeIfEmpty) { |
363 |
//reset the cookie |
364 |
|
365 |
return this.setSubs(name, subs, options); |
366 |
} else { |
367 |
//reset the cookie if there are subcookies left, else remove |
368 |
for (var key in subs){ |
369 |
if (lang.hasOwnProperty(subs, key) && !lang.isFunction(subs[key]) && !lang.isUndefined(subs[key])){ |
370 |
return this.setSubs(name, subs, options); |
371 |
} |
372 |
} |
373 |
|
374 |
return this.remove(name, options); |
375 |
} |
376 |
} else { |
377 |
return ""; |
378 |
} |
379 |
|
380 |
}, |
381 |
|
382 |
/** |
383 |
* Sets a cookie with a given name and value. |
384 |
* @param {String} name The name of the cookie to set. |
385 |
* @param {Variant} value The value to set for the cookie. |
386 |
* @param {Object} options (Optional) An object containing one or more |
387 |
* cookie options: path (a string), domain (a string), expires (a Date object), |
388 |
* raw (true/false), and secure (true/false). |
389 |
* @return {String} The created cookie string. |
390 |
* @method set |
391 |
* @static |
392 |
*/ |
393 |
set : function (name /*:String*/, value /*:Variant*/, options /*:Object*/) /*:String*/ { |
394 |
|
395 |
var lang = YAHOO.lang; |
396 |
|
397 |
options = options || {}; |
398 |
|
399 |
if (!lang.isString(name)){ |
400 |
throw new TypeError("Cookie.set(): Cookie name must be a string."); |
401 |
} |
402 |
|
403 |
if (lang.isUndefined(value)){ |
404 |
throw new TypeError("Cookie.set(): Value cannot be undefined."); |
405 |
} |
406 |
|
407 |
var text /*:String*/ = this._createCookieString(name, value, !options.raw, options); |
408 |
document.cookie = text; |
409 |
return text; |
410 |
}, |
411 |
|
412 |
/** |
413 |
* Sets a sub cookie with a given name to a particular value. |
414 |
* @param {String} name The name of the cookie to set. |
415 |
* @param {String} subName The name of the subcookie to set. |
416 |
* @param {Variant} value The value to set. |
417 |
* @param {Object} options (Optional) An object containing one or more |
418 |
* cookie options: path (a string), domain (a string), expires (a Date object), |
419 |
* and secure (true/false). |
420 |
* @return {String} The created cookie string. |
421 |
* @method setSub |
422 |
* @static |
423 |
*/ |
424 |
setSub : function (name /*:String*/, subName /*:String*/, value /*:Variant*/, options /*:Object*/) /*:String*/ { |
425 |
|
426 |
var lang = YAHOO.lang; |
427 |
|
428 |
if (!lang.isString(name) || name === ""){ |
429 |
throw new TypeError("Cookie.setSub(): Cookie name must be a non-empty string."); |
430 |
} |
431 |
|
432 |
if (!lang.isString(subName) || subName === ""){ |
433 |
throw new TypeError("Cookie.setSub(): Subcookie name must be a non-empty string."); |
434 |
} |
435 |
|
436 |
if (lang.isUndefined(value)){ |
437 |
throw new TypeError("Cookie.setSub(): Subcookie value cannot be undefined."); |
438 |
} |
439 |
|
440 |
var hash /*:Object*/ = this.getSubs(name); |
441 |
|
442 |
if (!lang.isObject(hash)){ |
443 |
hash = {}; |
444 |
} |
445 |
|
446 |
hash[subName] = value; |
447 |
|
448 |
return this.setSubs(name, hash, options); |
449 |
|
450 |
}, |
451 |
|
452 |
/** |
453 |
* Sets a cookie with a given name to contain a hash of name-value pairs. |
454 |
* @param {String} name The name of the cookie to set. |
455 |
* @param {Object} value An object containing name-value pairs. |
456 |
* @param {Object} options (Optional) An object containing one or more |
457 |
* cookie options: path (a string), domain (a string), expires (a Date object), |
458 |
* and secure (true/false). |
459 |
* @return {String} The created cookie string. |
460 |
* @method setSubs |
461 |
* @static |
462 |
*/ |
463 |
setSubs : function (name /*:String*/, value /*:Object*/, options /*:Object*/) /*:String*/ { |
464 |
|
465 |
var lang = YAHOO.lang; |
466 |
|
467 |
if (!lang.isString(name)){ |
468 |
throw new TypeError("Cookie.setSubs(): Cookie name must be a string."); |
469 |
} |
470 |
|
471 |
if (!lang.isObject(value)){ |
472 |
throw new TypeError("Cookie.setSubs(): Cookie value must be an object."); |
473 |
} |
474 |
|
475 |
var text /*:String*/ = this._createCookieString(name, this._createCookieHashString(value), false, options); |
476 |
document.cookie = text; |
477 |
return text; |
478 |
} |
479 |
|
480 |
}; |
481 |
|
482 |
YAHOO.register("cookie", YAHOO.util.Cookie, {version: "2.8.0r4", build: "2449"}); |