|
|
@@ -1,141 +1,172 @@
|
|
|
-/*!
|
|
|
- * Cookies.js - 0.3.1
|
|
|
- * Wednesday, April 24 2013 @ 2:28 AM EST
|
|
|
+/*
|
|
|
+ * Cookies.js - 1.2.3
|
|
|
+ * https://github.com/ScottHamper/Cookies
|
|
|
*
|
|
|
- * Copyright (c) 2013, Scott Hamper
|
|
|
- * Licensed under the MIT license,
|
|
|
- * http://www.opensource.org/licenses/MIT
|
|
|
+ * This is free and unencumbered software released into the public domain.
|
|
|
*/
|
|
|
-(function (undefined) {
|
|
|
+(function (global, undefined) {
|
|
|
'use strict';
|
|
|
|
|
|
- var Cookies = function (key, value, options) {
|
|
|
- return arguments.length === 1 ?
|
|
|
- Cookies.get(key) : Cookies.set(key, value, options);
|
|
|
- };
|
|
|
+ var factory = function (window) {
|
|
|
+ if (typeof window.document !== 'object') {
|
|
|
+ throw new Error('Cookies.js requires a `window` with a `document` object');
|
|
|
+ }
|
|
|
|
|
|
- // Allows for setter injection in unit tests
|
|
|
- Cookies._document = document;
|
|
|
- Cookies._navigator = navigator;
|
|
|
+ var Cookies = function (key, value, options) {
|
|
|
+ return arguments.length === 1 ?
|
|
|
+ Cookies.get(key) : Cookies.set(key, value, options);
|
|
|
+ };
|
|
|
|
|
|
- Cookies.defaults = {
|
|
|
- path: '/'
|
|
|
- };
|
|
|
+ // Allows for setter injection in unit tests
|
|
|
+ Cookies._document = window.document;
|
|
|
|
|
|
- Cookies.get = function (key) {
|
|
|
- if (Cookies._cachedDocumentCookie !== Cookies._document.cookie) {
|
|
|
- Cookies._renewCache();
|
|
|
- }
|
|
|
+ // Used to ensure cookie keys do not collide with
|
|
|
+ // built-in `Object` properties
|
|
|
+ Cookies._cacheKeyPrefix = 'cookey.'; // Hurr hurr, :)
|
|
|
|
|
|
- return Cookies._cache[key];
|
|
|
- };
|
|
|
+ Cookies._maxExpireDate = new Date('Fri, 31 Dec 9999 23:59:59 UTC');
|
|
|
|
|
|
- Cookies.set = function (key, value, options) {
|
|
|
- options = Cookies._getExtendedOptions(options);
|
|
|
- options.expires = Cookies._getExpiresDate(value === undefined ? -1 : options.expires);
|
|
|
+ Cookies.defaults = {
|
|
|
+ path: '/',
|
|
|
+ secure: false
|
|
|
+ };
|
|
|
|
|
|
- Cookies._document.cookie = Cookies._generateCookieString(key, value, options);
|
|
|
+ Cookies.get = function (key) {
|
|
|
+ if (Cookies._cachedDocumentCookie !== Cookies._document.cookie) {
|
|
|
+ Cookies._renewCache();
|
|
|
+ }
|
|
|
|
|
|
- return Cookies;
|
|
|
- };
|
|
|
+ var value = Cookies._cache[Cookies._cacheKeyPrefix + key];
|
|
|
|
|
|
- Cookies.expire = function (key, options) {
|
|
|
- return Cookies.set(key, undefined, options);
|
|
|
- };
|
|
|
+ return value === undefined ? undefined : decodeURIComponent(value);
|
|
|
+ };
|
|
|
+
|
|
|
+ Cookies.set = function (key, value, options) {
|
|
|
+ options = Cookies._getExtendedOptions(options);
|
|
|
+ options.expires = Cookies._getExpiresDate(value === undefined ? -1 : options.expires);
|
|
|
+
|
|
|
+ Cookies._document.cookie = Cookies._generateCookieString(key, value, options);
|
|
|
|
|
|
- Cookies._getExtendedOptions = function (options) {
|
|
|
- return {
|
|
|
- path: options && options.path || Cookies.defaults.path,
|
|
|
- domain: options && options.domain || Cookies.defaults.domain,
|
|
|
- expires: options && options.expires || Cookies.defaults.expires,
|
|
|
- secure: options && options.secure !== undefined ? options.secure : Cookies.defaults.secure
|
|
|
+ return Cookies;
|
|
|
};
|
|
|
- };
|
|
|
|
|
|
- Cookies._isValidDate = function (date) {
|
|
|
- return Object.prototype.toString.call(date) === '[object Date]' && !isNaN(date.getTime());
|
|
|
- };
|
|
|
+ Cookies.expire = function (key, options) {
|
|
|
+ return Cookies.set(key, undefined, options);
|
|
|
+ };
|
|
|
|
|
|
- Cookies._getExpiresDate = function (expires, now) {
|
|
|
- now = now || new Date();
|
|
|
- switch (typeof expires) {
|
|
|
- case 'number': expires = new Date(now.getTime() + expires * 1000); break;
|
|
|
- case 'string': expires = new Date(expires); break;
|
|
|
- }
|
|
|
+ Cookies._getExtendedOptions = function (options) {
|
|
|
+ return {
|
|
|
+ path: options && options.path || Cookies.defaults.path,
|
|
|
+ domain: options && options.domain || Cookies.defaults.domain,
|
|
|
+ expires: options && options.expires || Cookies.defaults.expires,
|
|
|
+ secure: options && options.secure !== undefined ? options.secure : Cookies.defaults.secure
|
|
|
+ };
|
|
|
+ };
|
|
|
|
|
|
- if (expires && !Cookies._isValidDate(expires)) {
|
|
|
- throw new Error('`expires` parameter cannot be converted to a valid Date instance');
|
|
|
- }
|
|
|
+ Cookies._isValidDate = function (date) {
|
|
|
+ return Object.prototype.toString.call(date) === '[object Date]' && !isNaN(date.getTime());
|
|
|
+ };
|
|
|
|
|
|
- return expires;
|
|
|
- };
|
|
|
+ Cookies._getExpiresDate = function (expires, now) {
|
|
|
+ now = now || new Date();
|
|
|
|
|
|
- Cookies._generateCookieString = function (key, value, options) {
|
|
|
- key = encodeURIComponent(key);
|
|
|
- value = (value + '').replace(/[^!#$&-+\--:<-\[\]-~]/g, encodeURIComponent);
|
|
|
- options = options || {};
|
|
|
+ if (typeof expires === 'number') {
|
|
|
+ expires = expires === Infinity ?
|
|
|
+ Cookies._maxExpireDate : new Date(now.getTime() + expires * 1000);
|
|
|
+ } else if (typeof expires === 'string') {
|
|
|
+ expires = new Date(expires);
|
|
|
+ }
|
|
|
|
|
|
- var cookieString = key + '=' + value;
|
|
|
- cookieString += options.path ? ';path=' + options.path : '';
|
|
|
- cookieString += options.domain ? ';domain=' + options.domain : '';
|
|
|
- cookieString += options.expires ? ';expires=' + options.expires.toGMTString() : '';
|
|
|
- cookieString += options.secure ? ';secure' : '';
|
|
|
+ if (expires && !Cookies._isValidDate(expires)) {
|
|
|
+ throw new Error('`expires` parameter cannot be converted to a valid Date instance');
|
|
|
+ }
|
|
|
|
|
|
- return cookieString;
|
|
|
- };
|
|
|
+ return expires;
|
|
|
+ };
|
|
|
|
|
|
- Cookies._getCookieObjectFromString = function (documentCookie) {
|
|
|
- var cookieObject = {};
|
|
|
- var cookiesArray = documentCookie ? documentCookie.split('; ') : [];
|
|
|
+ Cookies._generateCookieString = function (key, value, options) {
|
|
|
+ key = key.replace(/[^#$&+\^`|]/g, encodeURIComponent);
|
|
|
+ key = key.replace(/\(/g, '%28').replace(/\)/g, '%29');
|
|
|
+ value = (value + '').replace(/[^!#$&-+\--:<-\[\]-~]/g, encodeURIComponent);
|
|
|
+ options = options || {};
|
|
|
|
|
|
- for (var i = 0; i < cookiesArray.length; i++) {
|
|
|
- var cookieKvp = Cookies._getKeyValuePairFromCookieString(cookiesArray[i]);
|
|
|
+ var cookieString = key + '=' + value;
|
|
|
+ cookieString += options.path ? ';path=' + options.path : '';
|
|
|
+ cookieString += options.domain ? ';domain=' + options.domain : '';
|
|
|
+ cookieString += options.expires ? ';expires=' + options.expires.toUTCString() : '';
|
|
|
+ cookieString += options.secure ? ';secure' : '';
|
|
|
|
|
|
- if (cookieObject[cookieKvp.key] === undefined) {
|
|
|
- cookieObject[cookieKvp.key] = cookieKvp.value;
|
|
|
+ return cookieString;
|
|
|
+ };
|
|
|
+
|
|
|
+ Cookies._getCacheFromString = function (documentCookie) {
|
|
|
+ var cookieCache = {};
|
|
|
+ var cookiesArray = documentCookie ? documentCookie.split('; ') : [];
|
|
|
+
|
|
|
+ for (var i = 0; i < cookiesArray.length; i++) {
|
|
|
+ var cookieKvp = Cookies._getKeyValuePairFromCookieString(cookiesArray[i]);
|
|
|
+
|
|
|
+ if (cookieCache[Cookies._cacheKeyPrefix + cookieKvp.key] === undefined) {
|
|
|
+ cookieCache[Cookies._cacheKeyPrefix + cookieKvp.key] = cookieKvp.value;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- return cookieObject;
|
|
|
- };
|
|
|
+ return cookieCache;
|
|
|
+ };
|
|
|
|
|
|
- Cookies._getKeyValuePairFromCookieString = function (cookieString) {
|
|
|
- // "=" is a valid character in a cookie value according to RFC6265, so cannot `split('=')`
|
|
|
- var separatorIndex = cookieString.indexOf('=');
|
|
|
+ Cookies._getKeyValuePairFromCookieString = function (cookieString) {
|
|
|
+ // "=" is a valid character in a cookie value according to RFC6265, so cannot `split('=')`
|
|
|
+ var separatorIndex = cookieString.indexOf('=');
|
|
|
+
|
|
|
+ // IE omits the "=" when the cookie value is an empty string
|
|
|
+ separatorIndex = separatorIndex < 0 ? cookieString.length : separatorIndex;
|
|
|
+
|
|
|
+ var key = cookieString.substr(0, separatorIndex);
|
|
|
+ var decodedKey;
|
|
|
+ try {
|
|
|
+ decodedKey = decodeURIComponent(key);
|
|
|
+ } catch (e) {
|
|
|
+ if (console && typeof console.error === 'function') {
|
|
|
+ console.error('Could not decode cookie with key "' + key + '"', e);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // IE omits the "=" when the cookie value is an empty string
|
|
|
- separatorIndex = separatorIndex < 0 ? cookieString.length : separatorIndex;
|
|
|
+ return {
|
|
|
+ key: decodedKey,
|
|
|
+ value: cookieString.substr(separatorIndex + 1) // Defer decoding value until accessed
|
|
|
+ };
|
|
|
+ };
|
|
|
|
|
|
- return {
|
|
|
- key: decodeURIComponent(cookieString.substr(0, separatorIndex)),
|
|
|
- value: decodeURIComponent(cookieString.substr(separatorIndex + 1))
|
|
|
+ Cookies._renewCache = function () {
|
|
|
+ Cookies._cache = Cookies._getCacheFromString(Cookies._document.cookie);
|
|
|
+ Cookies._cachedDocumentCookie = Cookies._document.cookie;
|
|
|
};
|
|
|
- };
|
|
|
|
|
|
- Cookies._renewCache = function () {
|
|
|
- Cookies._cache = Cookies._getCookieObjectFromString(Cookies._document.cookie);
|
|
|
- Cookies._cachedDocumentCookie = Cookies._document.cookie;
|
|
|
- };
|
|
|
+ Cookies._areEnabled = function () {
|
|
|
+ var testKey = 'cookies.js';
|
|
|
+ var areEnabled = Cookies.set(testKey, 1).get(testKey) === '1';
|
|
|
+ Cookies.expire(testKey);
|
|
|
+ return areEnabled;
|
|
|
+ };
|
|
|
|
|
|
- Cookies._areEnabled = function () {
|
|
|
- return Cookies._navigator.cookieEnabled ||
|
|
|
- Cookies.set('cookies.js', 1).get('cookies.js') === '1';
|
|
|
- };
|
|
|
+ Cookies.enabled = Cookies._areEnabled();
|
|
|
|
|
|
- Cookies.enabled = Cookies._areEnabled();
|
|
|
+ return Cookies;
|
|
|
+ };
|
|
|
+ var cookiesExport = (global && typeof global.document === 'object') ? factory(global) : factory;
|
|
|
|
|
|
// AMD support
|
|
|
if (typeof define === 'function' && define.amd) {
|
|
|
- define(function () { return Cookies; });
|
|
|
- // CommonJS and Node.js module support.
|
|
|
- } else if (typeof exports !== 'undefined') {
|
|
|
+ define(function () { return cookiesExport; });
|
|
|
+ // CommonJS/Node.js support
|
|
|
+ } else if (typeof exports === 'object') {
|
|
|
// Support Node.js specific `module.exports` (which can be a function)
|
|
|
- if (typeof module !== 'undefined' && module.exports) {
|
|
|
- exports = module.exports = Cookies;
|
|
|
+ if (typeof module === 'object' && typeof module.exports === 'object') {
|
|
|
+ exports = module.exports = cookiesExport;
|
|
|
}
|
|
|
// But always support CommonJS module 1.1.1 spec (`exports` cannot be a function)
|
|
|
- exports.Cookies = Cookies;
|
|
|
+ exports.Cookies = cookiesExport;
|
|
|
} else {
|
|
|
- window.Cookies = Cookies;
|
|
|
+ global.Cookies = cookiesExport;
|
|
|
}
|
|
|
-})();
|
|
|
+})(typeof window === 'undefined' ? this : window);
|