PageRenderTime 44ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/files/yui/3.17.2/cookie/cookie.js

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