diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..15812b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules +build +.sizecache.json +*.log* diff --git a/.jshintignore b/.jshintignore new file mode 100644 index 0000000..e3fbd98 --- /dev/null +++ b/.jshintignore @@ -0,0 +1,2 @@ +build +node_modules diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..fd016db --- /dev/null +++ b/.jshintrc @@ -0,0 +1,12 @@ +{ + "curly": true, + "eqeqeq": true, + "expr": true, + // "maxlen": 130, + "newcap": true, + "noarg": true, + "nonbsp": true, + "trailing": true, + "undef": true, + "unused": true +} diff --git a/.travis.yml b/.travis.yml index a532afb..bfd8ca1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,10 @@ language: node_js node_js: - - 0.8 + - 0.10 before_script: - - npm install grunt -script: grunt ci --verbose \ No newline at end of file + - npm install -g grunt-cli +script: grunt ci --verbose +env: + global: + - secure: HRae0kyIDDuhonvMi2SfEl1WJb4K/wX8WmzT9YkxFbmWwLjiOMkmqyuEyi76DbTC1cb9o7WwGVgbP1DhSm6n6m0Lz+PSzpprBN4QZuJc56jcc+tBA6gM81hyUufaTT0yUWz112Bu06kWIAs44w5PtG0FYZR0CuIN8fQvZi8fXCQ= + - secure: c+M5ECIfxDcVrr+ZlqgpGjv8kVM/hxiz3ACMCn4ZkDiaeq4Rw0wWIGZYL6aV5fhsoHgzEQ/XQPca8xKs3Umr7R3b6Vr3AEyFnW+LP67K/1Qbz4Pi3PvhDH/h4rvK7fOoTqTDCVVDEH3v4pefsz2VaKemG4iBKxrcof5aR4Rjopk= diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c58125..59d868f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,56 @@ +HEAD +----- + +1.4.1 +----- +- Added support for CommonJS. + +- Added support for package managers: Jam (http://jamjs.org), volo (http://volojs.org), Component (http://component.io), jspm (http://jspm.io). + +- The expires option now interpretes fractions of numbers (e.g. days) correctly. + +1.4.0 +----- +- Support for AMD. + +- Removed deprecated method `$.cookie('name', null)` for deleting a cookie, + use `$.removeCookie('name')`. + +- `$.cookie('name')` now returns `undefined` in case such cookie does not exist + (was `null`). Because the return value is still falsy, testing for existence + of a cookie like `if ( $.cookie('foo') )` keeps working without change. + +- Renamed bower package definition (component.json -> bower.json) for usage + with up-to-date bower. + +- Badly encoded cookies no longer throw exception upon reading but do return + undefined (similar to how we handle JSON parse errors with json = true). + +- Added conversion function as optional last argument for reading, + so that values can be changed to a different representation easily on the fly. + Useful for parsing numbers for instance: + + ```javascript + $.cookie('foo', '42'); + $.cookie('foo', Number); // => 42 + ``` + +1.3.1 +----- +- Fixed issue where it was no longer possible to check for an arbitrary cookie, + while json is set to true, there was a SyntaxError thrown from JSON.parse. + +- Fixed issue where RFC 2068 decoded cookies were not properly read. + 1.3.0 ----- +----- - Configuration options: `raw`, `json`. Replaces raw option, becomes config: ```javascript $.cookie.raw = true; // bypass encoding/decoding the cookie value $.cookie.json = true; // automatically JSON stringify/parse value ``` - + Thus the default options now cleanly contain cookie attributes only. - Removing licensing under GPL Version 2, the plugin is now released under MIT License only diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..608c33e --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,51 @@ +##Issues + +- Report issues or feature requests on [GitHub Issues](https://github.com/carhartl/jquery-cookie/issues). +- If reporting a bug, please add a [simplified example](http://sscce.org/). + +##Pull requests +- Create a new topic branch for every separate change you make. +- Create a test case if you are fixing a bug or implementing an important feature. +- Make sure the build runs successfully. + +## Development + +###Tools +We use the following tools for development: + +- [Qunit](http://qunitjs.com/) for tests. +- [NodeJS](http://nodejs.org/download/) required to run grunt. +- [Grunt](http://gruntjs.com/getting-started) for task management. + +###Getting started +Install [NodeJS](http://nodejs.org/). +Install globally grunt-cli using the following command: + + $ npm install -g grunt-cli + +Browse to the project root directory and install the dev dependencies: + + $ npm install -d + +To execute the build and tests run the following command in the root of the project: + + $ grunt + +You should see a green message in the console: + + Done, without errors. + +###Tests +You can also run the tests in the browser. +Start a test server from the project root: + + $ grunt connect:tests + +This will automatically open the test suite at http://127.0.0.1:9998 in the default browser, with livereload enabled. + +_Note: we recommend cleaning all the browser cookies before running the tests, that can avoid false positive failures._ + +###Automatic build +You can build automatically after a file change using the following command: + + $ grunt watch diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..5ac9db5 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,168 @@ +/*jshint node:true, quotmark:single */ +'use strict'; + +module.exports = function (grunt) { + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + qunit: { + all: 'test/index.html' + }, + jshint: { + options: { + jshintrc: true + }, + grunt: 'Gruntfile.js', + source: 'src/**/*.js', + tests: 'test/**/*.js' + }, + uglify: { + options: { + banner: '/*! <%= pkg.name %> v<%= pkg.version %> | <%= pkg.license %> */\n' + }, + build: { + files: { + 'build/jquery.cookie-<%= pkg.version %>.min.js': 'src/jquery.cookie.js' + } + } + }, + watch: { + options: { + livereload: true + }, + files: '{src,test}/**/*.js', + tasks: 'default' + }, + compare_size: { + files: [ + 'build/jquery.cookie-<%= pkg.version %>.min.js', + 'src/jquery.cookie.js' + ], + options: { + compress: { + gz: function (fileContents) { + return require('gzip-js').zip(fileContents, {}).length; + } + } + } + }, + connect: { + saucelabs: { + options: { + port: 9999, + base: ['.', 'test'] + } + }, + tests: { + options: { + port: 9998, + base: ['.', 'test'], + open: 'http://127.0.0.1:9998', + keepalive: true, + livereload: true + } + } + }, + 'saucelabs-qunit': { + all: { + options: { + urls: ['http://127.0.0.1:9999'], + build: process.env.TRAVIS_JOB_ID, + browsers: [ + // iOS + { + browserName: 'iphone', + platform: 'OS X 10.9', + version: '7.1' + }, + { + browserName: 'ipad', + platform: 'OS X 10.9', + version: '7.1' + }, + // Android + { + browserName: 'android', + platform: 'Linux', + version: '4.3' + }, + // OS X + { + browserName: 'safari', + platform: 'OS X 10.9', + version: '7' + }, + { + browserName: 'safari', + platform: 'OS X 10.8', + version: '6' + }, + { + browserName: 'firefox', + platform: 'OS X 10.9', + version: '28' + }, + // Windows + { + browserName: 'internet explorer', + platform: 'Windows 8.1', + version: '11' + }, + { + browserName: 'internet explorer', + platform: 'Windows 8', + version: '10' + }, + { + browserName: 'internet explorer', + platform: 'Windows 7', + version: '11' + }, + { + browserName: 'internet explorer', + platform: 'Windows 7', + version: '10' + }, + { + browserName: 'internet explorer', + platform: 'Windows 7', + version: '9' + }, + { + browserName: 'internet explorer', + platform: 'Windows 7', + version: '8' + }, + { + browserName: 'firefox', + platform: 'Windows 7', + version: '29' + }, + { + browserName: 'chrome', + platform: 'Windows 7', + version: '34' + }, + // Linux + { + browserName: 'firefox', + platform: 'Linux', + version: '29' + } + ] + } + } + } + }); + + // Loading dependencies + for (var key in grunt.file.readJSON('package.json').devDependencies) { + if (key !== 'grunt' && key.indexOf('grunt') === 0) { + grunt.loadNpmTasks(key); + } + } + + grunt.registerTask('default', ['jshint', 'qunit', 'uglify', 'compare_size']); + grunt.registerTask('saucelabs', ['connect:saucelabs', 'saucelabs-qunit']); + grunt.registerTask('ci', ['jshint', 'qunit', 'saucelabs']); +}; diff --git a/MIT-LICENSE.txt b/MIT-LICENSE.txt index 8ae647b..7a631e8 100644 --- a/MIT-LICENSE.txt +++ b/MIT-LICENSE.txt @@ -1,4 +1,4 @@ -Copyright 2013 Klaus Hartl +Copyright 2014 Klaus Hartl Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 91e8592..3100800 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,80 @@ -# jquery.cookie [![Build Status](https://travis-ci.org/carhartl/jquery-cookie.png?branch=master)](https://travis-ci.org/carhartl/jquery-cookie) +# IMPORTANT! + +This project was moved to https://github.com/js-cookie/js-cookie, check [the discussion](https://github.com/carhartl/jquery-cookie/issues/349). + +New issues should be opened at https://github.com/js-cookie/js-cookie/issues + +# jquery.cookie [![Build Status](https://travis-ci.org/carhartl/jquery-cookie.png?branch=master)](https://travis-ci.org/carhartl/jquery-cookie) [![Code Climate](https://codeclimate.com/github/carhartl/jquery-cookie.png)](https://codeclimate.com/github/carhartl/jquery-cookie) A simple, lightweight jQuery plugin for reading, writing and deleting cookies. +**If you're viewing this, you're reading the documentation for the old repository. +[View documentation for the latest backwards compatible release (1.5.1).](https://github.com/js-cookie/js-cookie/tree/v1.5.1)** + +## Build Status Matrix + +[![Selenium Test Status](https://saucelabs.com/browser-matrix/jquery-cookie.svg)](https://saucelabs.com/u/jquery-cookie) + ## Installation Include script *after* the jQuery library (unless you are packaging scripts somehow else): - +```html + +``` **Do not include the script directly from GitHub (http://raw.github.com/...).** The file is being served as text/plain and as such being blocked in Internet Explorer on Windows 7 for instance (because of the wrong MIME type). Bottom line: GitHub is not a CDN. +The plugin can also be loaded as AMD or CommonJS module. + ## Usage Create session cookie: - $.cookie('the_cookie', 'the_value'); +```javascript +$.cookie('name', 'value'); +``` Create expiring cookie, 7 days from then: - $.cookie('the_cookie', 'the_value', { expires: 7 }); +```javascript +$.cookie('name', 'value', { expires: 7 }); +``` Create expiring cookie, valid across entire site: - $.cookie('the_cookie', 'the_value', { expires: 7, path: '/' }); +```javascript +$.cookie('name', 'value', { expires: 7, path: '/' }); +``` Read cookie: - $.cookie('the_cookie'); // => "the_value" - $.cookie('not_existing'); // => null +```javascript +$.cookie('name'); // => "value" +$.cookie('nothing'); // => undefined +``` Read all available cookies: - $.cookie(); // => { "the_cookie": "the_value", "...remaining": "cookies" } +```javascript +$.cookie(); // => { "name": "value" } +``` Delete cookie: - // Returns true when cookie was found, false when no cookie was found... - $.removeCookie('the_cookie'); +```javascript +// Returns true when cookie was successfully deleted, otherwise false +$.removeCookie('name'); // => true +$.removeCookie('nothing'); // => false - // Same path as when the cookie was written... - $.removeCookie('the_cookie', { path: '/' }); +// Need to use the same attributes (path, domain) as what the cookie was written with +$.cookie('name', 'value', { path: '/' }); +// This won't work! +$.removeCookie('name'); // => false +// This will work! +$.removeCookie('name', { path: '/' }); // => true +``` *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.* @@ -50,20 +84,24 @@ Delete cookie: By default the cookie value is encoded/decoded when writing/reading, using `encodeURIComponent`/`decodeURIComponent`. Bypass this by setting raw to true: - $.cookie.raw = true; +```javascript +$.cookie.raw = true; +``` ### json Turn on automatic storage of JSON objects passed as the cookie value. Assumes `JSON.stringify` and `JSON.parse`: - $.cookie.json = true; +```javascript +$.cookie.json = true; +``` ## Cookie Options -### expires - Cookie attributes can be set globally by setting properties of the `$.cookie.defaults` object or individually for each call to `$.cookie()` by passing a plain object to the options argument. Per-call options override the default options. +### expires + expires: 365 Define lifetime of the cookie. Value can be a `Number` which will be interpreted as days from time of creation or a `Date` object. If omitted, the cookie becomes a session cookie. @@ -94,26 +132,30 @@ Define the domain where the cookie is valid. Default: domain of page where the c If true, the cookie transmission requires a secure protocol (https). Default: `false`. -## Tests - -Requires Node. Startup server: +## Converters - $ node server.js +Provide a conversion function as optional last argument for reading, in order to change the cookie's value +to a different representation on the fly. -Open in browser: +Example for parsing a value into a number: - $ open http://0.0.0.0:8124/test.html +```javascript +$.cookie('foo', '42'); +$.cookie('foo', Number); // => 42 +``` -For quick *non cross-browser* testing use grunt: +Dealing with cookies that have been encoded using `escape` (3rd party cookies): - $ grunt +```javascript +$.cookie.raw = true; +$.cookie('foo', unescape); +``` -## Development +You can pass an arbitrary conversion function. -- Source hosted at [GitHub](https://github.com/carhartl/jquery-cookie) -- Report issues, questions, feature requests on [GitHub Issues](https://github.com/carhartl/jquery-cookie/issues) +## Contributing -Pull requests are very welcome! Make sure your patches are well tested. Please create a topic branch for every separate change you make. +Check out the [Contributing Guidelines](CONTRIBUTING.md) ## Authors diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..3862b74 --- /dev/null +++ b/bower.json @@ -0,0 +1,18 @@ +{ + "name": "jquery.cookie", + "version": "1.4.1", + "main": [ + "src/jquery.cookie.js" + ], + "dependencies": { + "jquery": ">=1.2" + }, + "ignore": [ + "test", + ".*", + "*.json", + "*.md", + "*.txt", + "Gruntfile.js" + ] +} diff --git a/component.json b/component.json index 9f8f2bc..0fad480 100644 --- a/component.json +++ b/component.json @@ -1,10 +1,14 @@ { "name": "jquery.cookie", - "version": "1.3.0", - "main": [ - "./jquery.cookie.js" - ], - "dependencies": { - "jquery": ">=1.0" - } + "repo": "carhartl/jquery-cookie", + "description": "A simple, lightweight jQuery plugin for reading, writing and deleting cookies", + "version": "1.4.1", + "keywords": [], + "dependencies": {}, + "development": {}, + "license": "MIT", + "main": "src/jquery.cookie.js", + "scripts": [ + "src/jquery.cookie.js" + ] } diff --git a/cookie.jquery.json b/cookie.jquery.json index 96d3584..69d5748 100644 --- a/cookie.jquery.json +++ b/cookie.jquery.json @@ -1,6 +1,6 @@ { "name": "cookie", - "version": "1.3.0", + "version": "1.4.1", "title": "jQuery Cookie", "description": "A simple, lightweight jQuery plugin for reading, writing and deleting cookies.", "author": { @@ -8,6 +8,10 @@ "url": "https://github.com/carhartl" }, "maintainers": [ + { + "name": "Klaus Hartl", + "url": "https://github.com/carhartl" + }, { "name": "Fagner Martins", "url": "https://github.com/FagnerMartinsBrack" @@ -20,7 +24,7 @@ } ], "dependencies": { - "jquery": ">=1.0" + "jquery": ">=1.2" }, "bugs": "https://github.com/carhartl/jquery-cookie/issues", "homepage": "https://github.com/carhartl/jquery-cookie", diff --git a/grunt.js b/grunt.js deleted file mode 100644 index fa9aff0..0000000 --- a/grunt.js +++ /dev/null @@ -1,38 +0,0 @@ -/*global module */ -module.exports = function (grunt) { - 'use strict'; - - grunt.initConfig({ - qunit: { - files: ['test.html'] - }, - lint: { - files: [ - 'grunt.js', - 'jquery.cookie.js' - ] - }, - jshint: { - options: { - boss: true, - browser: true, - curly: true, - eqeqeq: true, - eqnull: true, - expr: true, - evil: true, - newcap: true, - noarg: true, - undef: true - }, - globals: { - jQuery: true - } - } - }); - - grunt.registerTask('default', 'lint qunit'); - - // Travis CI task. - grunt.registerTask('ci', 'default'); -}; diff --git a/jquery.cookie.js b/jquery.cookie.js deleted file mode 100644 index 9fee964..0000000 --- a/jquery.cookie.js +++ /dev/null @@ -1,90 +0,0 @@ -/*! - * jQuery Cookie Plugin v1.3.0 - * https://github.com/carhartl/jquery-cookie - * - * Copyright 2013 Klaus Hartl - * Released under the MIT license - */ -(function ($, document, undefined) { - - var pluses = /\+/g; - - function raw(s) { - return s; - } - - function decoded(s) { - return unRfc2068(decodeURIComponent(s.replace(pluses, ' '))); - } - - function unRfc2068(value) { - if (value.indexOf('"') === 0) { - // This is a quoted cookie as according to RFC2068, unescape - value = value.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); - } - return value; - } - - var config = $.cookie = function (key, value, options) { - - // write - if (value !== undefined) { - options = $.extend({}, config.defaults, options); - - if (value === null) { - options.expires = -1; - } - - if (typeof options.expires === 'number') { - var days = options.expires, t = options.expires = new Date(); - t.setDate(t.getDate() + days); - } - - value = config.json ? JSON.stringify(value) : String(value); - - return (document.cookie = [ - encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value), - options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE - options.path ? '; path=' + options.path : '', - options.domain ? '; domain=' + options.domain : '', - options.secure ? '; secure' : '' - ].join('')); - } - - // read - var decode = config.raw ? raw : decoded; - var cookies = document.cookie.split('; '); - var result = key ? null : {}; - for (var i = 0, l = cookies.length; i < l; i++) { - var parts = cookies[i].split('='); - var name = decode(parts.shift()); - var cookie = decode(parts.join('=')); - - if (config.json) { - cookie = JSON.parse(cookie); - } - - if (key && key === name) { - result = cookie; - break; - } - - if (!key) { - result[name] = cookie; - } - } - - return result; - }; - - config.defaults = {}; - - $.removeCookie = function (key, options) { - if ($.cookie(key) !== null) { - $.cookie(key, null, options); - return true; - } - return false; - }; - -})(jQuery, document); diff --git a/package.json b/package.json new file mode 100644 index 0000000..38abffe --- /dev/null +++ b/package.json @@ -0,0 +1,50 @@ +{ + "name": "jquery.cookie", + "version": "1.4.1", + "description": "A simple, lightweight jQuery plugin for reading, writing and deleting cookies.", + "main": "src/jquery.cookie.js", + "directories": { + "test": "test" + }, + "scripts": { + "test": "grunt" + }, + "repository": { + "type": "git", + "url": "git://github.com/carhartl/jquery-cookie.git" + }, + "author": "Klaus Hartl", + "license": "MIT", + "gitHead": "bd3c9713222bace68d25fe2128c0f8633cad1269", + "readmeFilename": "README.md", + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-jshint": "~0.10.0", + "grunt-contrib-uglify": "~0.2.0", + "grunt-contrib-qunit": "~0.2.0", + "grunt-contrib-watch": "~0.6.1", + "grunt-compare-size": "~0.4.0", + "grunt-saucelabs": "~7.0.0", + "grunt-contrib-connect": "~0.7.1", + "gzip-js": "~0.3.0" + }, + "volo": { + "url": "https://raw.github.com/carhartl/jquery-cookie/v{version}/src/jquery.cookie.js" + }, + "jspm": { + "main": "jquery.cookie", + "files": ["src/jquery.cookie.js"], + "buildConfig": { + "uglify": true + } + }, + "jam": { + "dependencies": { + "jquery": ">=1.2" + }, + "main": "src/jquery.cookie.js", + "include": [ + "src/jquery.cookie.js" + ] + } +} diff --git a/server.js b/server.js deleted file mode 100644 index 8136795..0000000 --- a/server.js +++ /dev/null @@ -1,24 +0,0 @@ -var http = require('http'); -var url = require('url'); -var path = require('path'); -var fs = require('fs'); - -http.createServer(function(request, response) { - var uri = url.parse(request.url).pathname; - var filename = path.join(process.cwd(), uri); - - fs.readFile(filename, 'binary', function(err, file) { - if (err) { - response.writeHead(500, { 'Content-Type': 'text/plain' }); - response.write(err + '\n'); - response.end(); - return; - } - - response.writeHead(200, filename.match(/\.js$/) ? { 'Content-Type': 'text/javascript' } : {}); - response.write(file, 'utf-8'); - response.end(); - }); -}).listen(8124, '0.0.0.0'); - -console.log('Test suite at http://0.0.0.0:8124/test.html'); diff --git a/src/.jshintrc b/src/.jshintrc new file mode 100644 index 0000000..241dd9f --- /dev/null +++ b/src/.jshintrc @@ -0,0 +1,13 @@ +{ + "browser": true, + "camelcase": true, + "jquery": true, + "quotmark": "single", + "globals": { + "define": true, + "module": true, + "require": true + }, + + "extends": "../.jshintrc" +} diff --git a/src/jquery.cookie.js b/src/jquery.cookie.js new file mode 100644 index 0000000..8218817 --- /dev/null +++ b/src/jquery.cookie.js @@ -0,0 +1,114 @@ +/*! + * jQuery Cookie Plugin v1.4.1 + * https://github.com/carhartl/jquery-cookie + * + * Copyright 2006, 2014 Klaus Hartl + * Released under the MIT license + */ +(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD (Register as an anonymous module) + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS + module.exports = factory(require('jquery')); + } else { + // Browser globals + factory(jQuery); + } +}(function ($) { + + var pluses = /\+/g; + + function encode(s) { + return config.raw ? s : encodeURIComponent(s); + } + + function decode(s) { + return config.raw ? s : decodeURIComponent(s); + } + + function stringifyCookieValue(value) { + return encode(config.json ? JSON.stringify(value) : String(value)); + } + + function parseCookieValue(s) { + if (s.indexOf('"') === 0) { + // This is a quoted cookie as according to RFC2068, unescape... + s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); + } + + try { + // Replace server-side written pluses with spaces. + // If we can't decode the cookie, ignore it, it's unusable. + // If we can't parse the cookie, ignore it, it's unusable. + s = decodeURIComponent(s.replace(pluses, ' ')); + return config.json ? JSON.parse(s) : s; + } catch(e) {} + } + + function read(s, converter) { + var value = config.raw ? s : parseCookieValue(s); + return $.isFunction(converter) ? converter(value) : value; + } + + var config = $.cookie = function (key, value, options) { + + // Write + + if (arguments.length > 1 && !$.isFunction(value)) { + options = $.extend({}, config.defaults, options); + + if (typeof options.expires === 'number') { + var days = options.expires, t = options.expires = new Date(); + t.setMilliseconds(t.getMilliseconds() + days * 864e+5); + } + + return (document.cookie = [ + encode(key), '=', stringifyCookieValue(value), + options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE + options.path ? '; path=' + options.path : '', + options.domain ? '; domain=' + options.domain : '', + options.secure ? '; secure' : '' + ].join('')); + } + + // Read + + var result = key ? undefined : {}, + // To prevent the for loop in the first place assign an empty array + // in case there are no cookies at all. Also prevents odd result when + // calling $.cookie(). + cookies = document.cookie ? document.cookie.split('; ') : [], + i = 0, + l = cookies.length; + + for (; i < l; i++) { + var parts = cookies[i].split('='), + name = decode(parts.shift()), + cookie = parts.join('='); + + if (key === name) { + // If second argument (value) is a function it's a converter... + result = read(cookie, value); + break; + } + + // Prevent storing a cookie that we couldn't decode. + if (!key && (cookie = read(cookie)) !== undefined) { + result[name] = cookie; + } + } + + return result; + }; + + config.defaults = {}; + + $.removeCookie = function (key, options) { + // Must not alter options, thus extending a fresh object... + $.cookie(key, '', $.extend({}, options, { expires: -1 })); + return !$.cookie(key); + }; + +})); diff --git a/test.html b/test.html deleted file mode 100644 index bf5a08f..0000000 --- a/test.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - jquery.cookie Test Suite - - - - - - - -

jquery.cookie Test Suite

-

-
-

-
    - - diff --git a/test.js b/test.js deleted file mode 100644 index 6991760..0000000 --- a/test.js +++ /dev/null @@ -1,238 +0,0 @@ -var before = { - setup: function () { - 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(); - } - - $.cookie.defaults = {}; - delete $.cookie.raw; - delete $.cookie.json; - } -}; - - -module('read', before); - -test('simple value', function () { - expect(1); - document.cookie = 'c=v'; - equal($.cookie('c'), 'v', 'should return value'); -}); - -test('empty value', function () { - expect(1); - // IE saves cookies with empty string as "c; ", e.g. without "=" as opposed to EOMB, which - // resulted in a bug while reading such a cookie. - $.cookie('c', ''); - equal($.cookie('c'), '', 'should return value'); -}); - -test('not existing', function () { - expect(1); - equal($.cookie('whatever'), null, 'should return null'); -}); - -test('rfc2068 quoted string', function () { - expect(1); - document.cookie = 'c="v@address.com\\"\\\\\\""'; - equal($.cookie('c'), 'v@address.com"\\"', 'should decode rfc2068 quoted string'); -}); - -test('decode', function () { - expect(1); - document.cookie = encodeURIComponent(' c') + '=' + encodeURIComponent(' v'); - equal($.cookie(' c'), ' v', 'should decode key and value'); -}); - -test('decode pluses to space for server side written cookie', function () { - expect(1); - document.cookie = 'c=foo+bar'; - equal($.cookie('c'), 'foo bar', 'should convert pluses back to space'); -}); - -test('[] used in name', function () { - expect(1); - document.cookie = 'c[999]=foo'; - equal($.cookie('c[999]'), 'foo', 'should return value'); -}); - -test('raw: true', function () { - expect(2); - $.cookie.raw = true; - - document.cookie = 'c=%20v'; - equal($.cookie('c'), '%20v', 'should not decode value'); - - // see https://github.com/carhartl/jquery-cookie/issues/50 - $.cookie('c', 'foo=bar'); - equal($.cookie('c'), 'foo=bar', 'should include the entire value'); -}); - -test('json: true', function () { - expect(1); - $.cookie.json = true; - - if ('JSON' in window) { - document.cookie = 'c=' + JSON.stringify({ foo: 'bar' }); - deepEqual($.cookie('c'), { foo: 'bar'}, 'should parse JSON'); - } else { - ok(true); - } -}); - -asyncTest('malformed cookie value in IE (#88, #117)', function() { - expect(1); - // Sandbox in an iframe so that we can poke around with document.cookie. - var iframe = $('')[0]; - $(iframe).on('load', function() { - start(); - if (iframe.contentWindow.ok) { - equal(iframe.contentWindow.testValue, 'two', 'reads all cookie values, skipping duplicate occurences of "; "'); - } else { - // Skip the test where we can't stub document.cookie using - // Object.defineProperty. Seems to work fine in - // Chrome, Firefox and IE 8+. - ok(true, 'N/A'); - } - }); - document.body.appendChild(iframe); -}); - -test('should return all cookies', function() { - document.cookie = 'c=v'; - document.cookie = 'foo=bar'; - deepEqual($.cookie(), { - c: 'v', - foo: 'bar' - }, 'should return all cookies'); -}); - - -module('write', before); - -test('String primitive', function () { - expect(1); - $.cookie('c', 'v'); - equal($.cookie('c'), 'v', 'should write value'); -}); - -test('String object', function () { - expect(1); - $.cookie('c', new String('v')); - equal($.cookie('c'), 'v', 'should write value'); -}); - -test('value "[object Object]"', function () { - expect(1); - $.cookie('c', '[object Object]'); - equal($.cookie('c'), '[object Object]', 'should write value'); -}); - -test('number', function () { - expect(1); - $.cookie('c', 1234); - equal($.cookie('c'), '1234', 'should write value'); -}); - -test('expires option as days from now', function() { - expect(1); - var sevenDaysFromNow = new Date(); - sevenDaysFromNow.setDate(sevenDaysFromNow.getDate() + 7); - equal($.cookie('c', 'v', { expires: 7 }), 'c=v; expires=' + sevenDaysFromNow.toUTCString(), - 'should write the cookie string with expires'); -}); - -test('expires option as Date instance', function() { - expect(1); - var sevenDaysFromNow = new Date(); - sevenDaysFromNow.setDate(sevenDaysFromNow.getDate() + 7); - equal($.cookie('c', 'v', { expires: sevenDaysFromNow }), 'c=v; expires=' + sevenDaysFromNow.toUTCString(), - 'should write the cookie string with expires'); -}); - -test('invalid expires option (in the past)', function() { - expect(1); - var yesterday = new Date(); - yesterday.setDate(yesterday.getDate() - 1); - $.cookie('c', 'v', { expires: yesterday }); - equal($.cookie('c'), null, 'should not save already expired cookie'); -}); - -test('return value', function () { - expect(1); - equal($.cookie('c', 'v'), 'c=v', 'should return written cookie string'); -}); - -test('defaults', function () { - expect(2); - $.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'); -}); - -test('raw: true', function () { - expect(1); - $.cookie.raw = true; - equal($.cookie('c', ' v').split('=')[1], ' v', 'should not encode'); -}); - -test('json: true', function () { - expect(1); - $.cookie.json = true; - - if ('JSON' in window) { - $.cookie('c', { foo: 'bar' }); - equal(document.cookie, 'c=' + encodeURIComponent(JSON.stringify({ foo: 'bar' })), 'should stringify JSON'); - } else { - ok(true); - } -}); - - -module('delete', before); - -test('delete (deprecated)', function () { - expect(1); - document.cookie = 'c=v'; - $.cookie('c', null); - equal(document.cookie, '', 'should delete the cookie'); -}); - - -module('removeCookie', before); - -test('delete', function() { - expect(1); - document.cookie = 'c=v'; - $.removeCookie('c'); - equal(document.cookie, '', 'should delete the cookie'); -}); - -test('return', function() { - expect(2); - equal($.removeCookie('c'), false, "should return false if a cookie wasn't found"); - - document.cookie = 'c=v'; - equal($.removeCookie('c'), true, 'should return true if the cookie was found'); -}); - -test('with options', function() { - expect(2); - var oldCookie = $.cookie; - - $.cookie = function(arg0, arg1, arg2) { - if (arg1 === null) { - equal(arg2.foo, 'bar', 'should pass options when deleting cookie'); - } else { - // see https://github.com/carhartl/jquery-cookie/issues/99 - equal(arguments.length, 1, "should look up cookie instead of writing a new"); - } - }; - - document.cookie = 'c=v'; - $.removeCookie('c', { foo: 'bar' }); - - $.cookie = oldCookie; -}); diff --git a/test/.jshintrc b/test/.jshintrc new file mode 100644 index 0000000..bc52b0a --- /dev/null +++ b/test/.jshintrc @@ -0,0 +1,9 @@ +{ + "browser": true, + "jquery": true, + "qunit": true, + + "-W053": true, + + "extends": "../.jshintrc" +} diff --git a/test/index.html b/test/index.html new file mode 100644 index 0000000..ade6830 --- /dev/null +++ b/test/index.html @@ -0,0 +1,16 @@ + + + + + jquery.cookie Test Suite + + + + + + + +
    +
    + + diff --git a/sandbox.html b/test/malformed_cookie.html similarity index 68% rename from sandbox.html rename to test/malformed_cookie.html index 1f65de7..74178d4 100644 --- a/sandbox.html +++ b/test/malformed_cookie.html @@ -1,9 +1,9 @@ - + - - + +