diff --git a/README.md b/README.md index 301e356..cddae5b 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,11 @@ Read cookie: $.cookie('the_cookie'); // => "the_value" $.cookie('not_existing'); // => null -Delete cookie: +Read all cookies: + + $.cookie(); // => { "the_cookie": "the_value", "...remaining": "cookies" } + +Delete cookie (*): // Returns true when cookie was found, false when no cookie was found... $.removeCookie('the_cookie'); @@ -38,6 +42,14 @@ Delete cookie: // Same path as when the cookie was written... $.removeCookie('the_cookie', { path: '/' }); +Edit multiple cookies in batch: + + $.cookie({ set_me: 'to this', delete_me: null }); // => same object returned + // $.cookie('set_me'); // => "to this" + // $.cookie('delete_me'); // => null (*) + + $.cookie({ go: '?', you: '!' }, { path: '/' }); // options object, as above + *Note: when deleting a cookie, you must pass the exact same path, domain and secure options that were used to set the cookie, unless you're relying on the default options that is.* ## Configuration diff --git a/jquery.cookie.js b/jquery.cookie.js index 2d4c05a..f679b6b 100644 --- a/jquery.cookie.js +++ b/jquery.cookie.js @@ -21,6 +21,14 @@ var config = $.cookie = function (key, value, options) { + if (typeof key === 'object') { + for (var name in key) { + if (!key.hasOwnProperty(name)) continue; + $.cookie(name, key[name], value); // "options" is optional 2nd arg here + } + return key; + } + // write if (value !== undefined) { options = $.extend({}, config.defaults, options); @@ -46,17 +54,26 @@ } // read + var all = arguments.length ? null : {}; var decode = config.raw ? raw : decoded; var cookies = document.cookie.split('; '); for (var i = 0, l = cookies.length; i < l; i++) { var parts = cookies[i].split('='); - if (decode(parts.shift()) === key) { + if ((name = decode(parts.shift())) === key || all) { var cookie = decode(parts.join('=')); - return config.json ? JSON.parse(cookie) : cookie; + if (config.json) { + cookie = JSON.parse(cookie); + } + if (all) { + all[name] = cookie; + } + else { + return cookie; + } } } - return null; + return all; }; config.defaults = {}; diff --git a/test.js b/test.js index 82f7a5e..33d2cc0 100644 --- a/test.js +++ b/test.js @@ -1,6 +1,6 @@ var before = { setup: function () { - cookies = document.cookie.split('; ') + var cookies = document.cookie.split('; '); for (var i = 0, c; (c = (cookies)[i]) && (c = c.split('=')[0]); i++) { document.cookie = c + '=; expires=' + new Date(0).toUTCString(); } @@ -36,7 +36,7 @@ test('decode', 1, function () { }); test('decode pluses to space for server side written cookie', 1, function () { - document.cookie = 'c=foo+bar' + document.cookie = 'c=foo+bar'; equal($.cookie('c'), 'foo bar', 'should convert pluses back to space'); }); @@ -45,6 +45,16 @@ test('[] used in name', 1, function () { equal($.cookie('c[999]'), 'foo', 'should return value'); }); +test('no arguments', 3, function () { + document.cookie = 'x=y'; + var count = document.cookie.split(';').length; + var cookies = $.cookie(); + equal(typeof cookies, 'object', 'should return object'); + var found = 0; for (var key in cookies) found++; + equal(found, count, 'should find all cookies'); + equal(cookies.x, 'y', 'should decode cookies'); +}); + test('raw: true', 2, function () { $.cookie.raw = true; @@ -81,7 +91,7 @@ asyncTest('malformed cookie value in IE (#88, #117)', 1, function() { ok(true, 'N/A'); } }; - iframe.src = '/sandbox.html'; + iframe.src = 'sandbox.html'; document.body.appendChild(iframe); }); @@ -108,6 +118,27 @@ test('number', 1, function () { equal($.cookie('c'), '1234', 'should write value'); }); +test('editing cookies by object', 4, function() { + var edits = { a: 'a', c: null }; + var result = $.cookie(edits); + ok(result === edits, 'should return the object instance passed'); + deepEqual(result, { a: 'a', c: null }, 'should return the object unmodified'); + equal($.cookie('a'), 'a', 'should set all given cookies'); + equal($.cookie('c'), null, 'should remove nulled cookies'); +}); + +test('editing cookies by object with options', 4, function() { + $.cookie('a', 'something'); + $.cookie('c', 'something'); + var edits = { a: null, c: 'c' }; + var options = { expires: -1 }; + var result = $.cookie(edits, options); + ok(result === edits, 'should return the object instance passed'); + deepEqual(result, { a: null, c: 'c' }, 'should return the object unmodified'); + equal($.cookie('a'), null, 'should use the options object for all cookies'); + equal($.cookie('c'), null, 'should use the options object for all cookies'); +}); + test('expires option as days from now', 1, function() { var sevenDaysFromNow = new Date(); sevenDaysFromNow.setDate(sevenDaysFromNow.getDate() + 7); @@ -137,6 +168,8 @@ test('defaults', 2, function () { $.cookie.defaults.path = '/'; ok($.cookie('c', 'v').match(/path=\//), 'should use options from defaults'); ok($.cookie('c', 'v', { path: '/foo' }).match(/path=\/foo/), 'options argument has precedence'); + $.removeCookie('c', { path: '/foo' }); + $.removeCookie('c', { path: '/' }); }); test('raw: true', 1, function () { @@ -149,7 +182,8 @@ test('json: true', 1, function () { if ('JSON' in window) { $.cookie('c', { foo: 'bar' }); - equal(document.cookie, 'c=' + encodeURIComponent(JSON.stringify({ foo: 'bar' })), 'should stringify JSON'); + var first = document.cookie.split(';')[0]; + equal(first, 'c=' + encodeURIComponent(JSON.stringify({ foo: 'bar' })), 'should stringify JSON'); } else { ok(true); } @@ -159,18 +193,20 @@ test('json: true', 1, function () { module('delete', before); test('delete (deprecated)', 1, function () { + var original_cookie = document.cookie; document.cookie = 'c=v'; $.cookie('c', null); - equal(document.cookie, '', 'should delete the cookie'); + equal(document.cookie, original_cookie, 'should delete the cookie'); }); module('removeCookie', before); test('delete', 1, function() { + var original_cookie = document.cookie; document.cookie = 'c=v'; $.removeCookie('c'); - equal(document.cookie, '', 'should delete the cookie'); + equal(document.cookie, original_cookie, 'should delete the cookie'); }); test('return', 2, function() {