cookies.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Cookies.js - 1.2.3
  3. * https://github.com/ScottHamper/Cookies
  4. *
  5. * This is free and unencumbered software released into the public domain.
  6. */
  7. (function (global, undefined) {
  8. 'use strict';
  9. var factory = function (window) {
  10. if (typeof window.document !== 'object') {
  11. throw new Error('Cookies.js requires a `window` with a `document` object');
  12. }
  13. var Cookies = function (key, value, options) {
  14. return arguments.length === 1 ?
  15. Cookies.get(key) : Cookies.set(key, value, options);
  16. };
  17. // Allows for setter injection in unit tests
  18. Cookies._document = window.document;
  19. // Used to ensure cookie keys do not collide with
  20. // built-in `Object` properties
  21. Cookies._cacheKeyPrefix = 'cookey.'; // Hurr hurr, :)
  22. Cookies._maxExpireDate = new Date('Fri, 31 Dec 9999 23:59:59 UTC');
  23. Cookies.defaults = {
  24. path: '/',
  25. secure: false
  26. };
  27. Cookies.get = function (key) {
  28. if (Cookies._cachedDocumentCookie !== Cookies._document.cookie) {
  29. Cookies._renewCache();
  30. }
  31. var value = Cookies._cache[Cookies._cacheKeyPrefix + key];
  32. return value === undefined ? undefined : decodeURIComponent(value);
  33. };
  34. Cookies.set = function (key, value, options) {
  35. options = Cookies._getExtendedOptions(options);
  36. options.expires = Cookies._getExpiresDate(value === undefined ? -1 : options.expires);
  37. Cookies._document.cookie = Cookies._generateCookieString(key, value, options);
  38. return Cookies;
  39. };
  40. Cookies.expire = function (key, options) {
  41. return Cookies.set(key, undefined, options);
  42. };
  43. Cookies._getExtendedOptions = function (options) {
  44. return {
  45. path: options && options.path || Cookies.defaults.path,
  46. domain: options && options.domain || Cookies.defaults.domain,
  47. expires: options && options.expires || Cookies.defaults.expires,
  48. secure: options && options.secure !== undefined ? options.secure : Cookies.defaults.secure
  49. };
  50. };
  51. Cookies._isValidDate = function (date) {
  52. return Object.prototype.toString.call(date) === '[object Date]' && !isNaN(date.getTime());
  53. };
  54. Cookies._getExpiresDate = function (expires, now) {
  55. now = now || new Date();
  56. if (typeof expires === 'number') {
  57. expires = expires === Infinity ?
  58. Cookies._maxExpireDate : new Date(now.getTime() + expires * 1000);
  59. } else if (typeof expires === 'string') {
  60. expires = new Date(expires);
  61. }
  62. if (expires && !Cookies._isValidDate(expires)) {
  63. throw new Error('`expires` parameter cannot be converted to a valid Date instance');
  64. }
  65. return expires;
  66. };
  67. Cookies._generateCookieString = function (key, value, options) {
  68. key = key.replace(/[^#$&+\^`|]/g, encodeURIComponent);
  69. key = key.replace(/\(/g, '%28').replace(/\)/g, '%29');
  70. value = (value + '').replace(/[^!#$&-+\--:<-\[\]-~]/g, encodeURIComponent);
  71. options = options || {};
  72. var cookieString = key + '=' + value;
  73. cookieString += options.path ? ';path=' + options.path : '';
  74. cookieString += options.domain ? ';domain=' + options.domain : '';
  75. cookieString += options.expires ? ';expires=' + options.expires.toUTCString() : '';
  76. cookieString += options.secure ? ';secure' : '';
  77. return cookieString;
  78. };
  79. Cookies._getCacheFromString = function (documentCookie) {
  80. var cookieCache = {};
  81. var cookiesArray = documentCookie ? documentCookie.split('; ') : [];
  82. for (var i = 0; i < cookiesArray.length; i++) {
  83. var cookieKvp = Cookies._getKeyValuePairFromCookieString(cookiesArray[i]);
  84. if (cookieCache[Cookies._cacheKeyPrefix + cookieKvp.key] === undefined) {
  85. cookieCache[Cookies._cacheKeyPrefix + cookieKvp.key] = cookieKvp.value;
  86. }
  87. }
  88. return cookieCache;
  89. };
  90. Cookies._getKeyValuePairFromCookieString = function (cookieString) {
  91. // "=" is a valid character in a cookie value according to RFC6265, so cannot `split('=')`
  92. var separatorIndex = cookieString.indexOf('=');
  93. // IE omits the "=" when the cookie value is an empty string
  94. separatorIndex = separatorIndex < 0 ? cookieString.length : separatorIndex;
  95. var key = cookieString.substr(0, separatorIndex);
  96. var decodedKey;
  97. try {
  98. decodedKey = decodeURIComponent(key);
  99. } catch (e) {
  100. if (console && typeof console.error === 'function') {
  101. console.error('Could not decode cookie with key "' + key + '"', e);
  102. }
  103. }
  104. return {
  105. key: decodedKey,
  106. value: cookieString.substr(separatorIndex + 1) // Defer decoding value until accessed
  107. };
  108. };
  109. Cookies._renewCache = function () {
  110. Cookies._cache = Cookies._getCacheFromString(Cookies._document.cookie);
  111. Cookies._cachedDocumentCookie = Cookies._document.cookie;
  112. };
  113. Cookies._areEnabled = function () {
  114. var testKey = 'cookies.js';
  115. var areEnabled = Cookies.set(testKey, 1).get(testKey) === '1';
  116. Cookies.expire(testKey);
  117. return areEnabled;
  118. };
  119. Cookies.enabled = Cookies._areEnabled();
  120. return Cookies;
  121. };
  122. var cookiesExport = (global && typeof global.document === 'object') ? factory(global) : factory;
  123. // AMD support
  124. if (typeof define === 'function' && define.amd) {
  125. define(function () { return cookiesExport; });
  126. // CommonJS/Node.js support
  127. } else if (typeof exports === 'object') {
  128. // Support Node.js specific `module.exports` (which can be a function)
  129. if (typeof module === 'object' && typeof module.exports === 'object') {
  130. exports = module.exports = cookiesExport;
  131. }
  132. // But always support CommonJS module 1.1.1 spec (`exports` cannot be a function)
  133. exports.Cookies = cookiesExport;
  134. } else {
  135. global.Cookies = cookiesExport;
  136. }
  137. })(typeof window === 'undefined' ? this : window);