cookie-debug.js 17 KB

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