Comparing version 1.5.1 to 2.0.0-pre
{ | ||
"name": "js-cookie", | ||
"version": "1.5.1", | ||
"main": [ | ||
"src/js.cookie.js" | ||
], | ||
"ignore": [ | ||
"test", | ||
".*", | ||
"*.json", | ||
"*.md", | ||
"*.txt", | ||
"Gruntfile.js" | ||
] | ||
"ignore": [] | ||
} |
@@ -1,2 +0,2 @@ | ||
##Issues | ||
## Issues | ||
@@ -6,3 +6,3 @@ - Report issues or feature requests on [GitHub Issues](https://github.com/js-cookie/js-cookie/issues). | ||
##Pull requests | ||
## Pull requests | ||
- Create a new topic branch for every separate change you make. | ||
@@ -14,3 +14,3 @@ - Create a test case if you are fixing a bug or implementing an important feature. | ||
###Tools | ||
### Tools | ||
We use the following tools for development: | ||
@@ -22,3 +22,3 @@ | ||
###Getting started | ||
### Getting started | ||
Install [NodeJS](http://nodejs.org/). | ||
@@ -41,3 +41,3 @@ Install globally grunt-cli using the following command: | ||
###Tests | ||
### Tests | ||
You can also run the tests in the browser. | ||
@@ -48,9 +48,31 @@ Start a test server from the project root: | ||
This will automatically open the test suite at http://127.0.0.1:9998 in the default browser, with livereload enabled. | ||
This will automatically open the test suite at http://127.0.0.1:10000 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 | ||
### Automatic build | ||
You can build automatically after a file change using the following command: | ||
$ grunt watch | ||
## Integration with server-side | ||
js-cookie allows integrating the encoding test suite with solutions written in other server-side languages. To integrate successfully, the server-side solution need to execute the `test/encoding.html` file in it's integration testing routine with a web automation tool, like [Selenium](http://www.seleniumhq.org/). js-cookie test suite exposes an API to make this happen. | ||
### ?integration_baseurl | ||
Specify the base url to pass the cookies into the server through a query string. If `integration_baseurl` query is not present, then js-cookie will assume there's no server. | ||
### window.global_test_results | ||
After the test suite has finished, js-cookie exposes the global `window.global_test_results` property containing an Object Literal that represents the [QUnit's details](http://api.qunitjs.com/QUnit.done/). js-cookie also adds an additional property representing an Array containing the tests data. | ||
### Handling requests | ||
When js-cookie encoding tests are executed, it will request a url in the server through an iframe representing each test being run. js-cookie expects the server to handle the input and return the proper `Set-Cookie` headers in the response. js-cookie will then read the response and verify if the encoding is consistent with js-cookie default encoding mechanism | ||
js-cookie will send some requests to the server from the baseurl in the format `/encoding?name=<cookie>`, where `<cookie>` represents the cookie-name to be read from the request. | ||
The server should handle those requests, internally parsing the cookie from the request and writing it again. It must set an `application/json` content type containing an object literal in the content body with `name` and `value` keys, each representing the cookie-name and cookie-value decoded by the server-side implementation. | ||
If the server fails to respond with this specification in any request, the related QUnit test will fail. This is to make sure the server-side implementation will always be in sync with js-cookie encoding tests for maximum compatibility. |
253
Gruntfile.js
@@ -1,2 +0,2 @@ | ||
/*jshint node:true, quotmark:single */ | ||
/*jshint node:true */ | ||
'use strict'; | ||
@@ -6,2 +6,22 @@ | ||
function encodingMiddleware(request, response, next) { | ||
var url = require('url').parse(request.url, true, true); | ||
var query = url.query; | ||
var pathname = url.pathname; | ||
if (pathname !== '/encoding') { | ||
next(); | ||
return; | ||
} | ||
var cookieName = query.name; | ||
var cookieValue = query.value; | ||
response.setHeader('content-type', 'application/json'); | ||
response.end(JSON.stringify({ | ||
name: cookieName, | ||
value: cookieValue | ||
})); | ||
} | ||
grunt.initConfig({ | ||
@@ -12,9 +32,12 @@ pkg: grunt.file.readJSON('package.json'), | ||
options: { | ||
httpBase: 'http://127.0.0.1:9998' | ||
}, | ||
src: ['test/index.html', 'test/amd.html'] | ||
} | ||
urls: [ | ||
'http://127.0.0.1:9998/', | ||
'http://127.0.0.1:9998/amd.html', | ||
'http://127.0.0.1:9998/encoding.html?integration_baseurl=http://127.0.0.1:9998/' | ||
] | ||
} | ||
}, | ||
}, | ||
nodeunit: { | ||
all: 'test/node.js' | ||
all: 'test/commonjs.js' | ||
}, | ||
@@ -27,4 +50,25 @@ jshint: { | ||
source: 'src/**/*.js', | ||
tests: 'test/**/*.js' | ||
tests: ['test/**/*.js', '!test/polyfill.js'] | ||
}, | ||
jscs: { | ||
options: { | ||
requireCommaBeforeLineBreak: true, | ||
requireLineFeedAtFileEnd: true, | ||
requireSemicolons: true, | ||
requireSpaceBeforeKeywords: ['else', 'while', 'catch'], | ||
requireSpaceAfterKeywords: true, | ||
requireSpaceAfterLineComment: true, | ||
requireSpaceBeforeBlockStatements: true, | ||
requireSpaceBeforeObjectValues: true, | ||
validateIndentation: '\t', | ||
validateLineBreaks: 'LF', | ||
validateQuoteMarks: true, | ||
disallowSpacesInsideArrayBrackets: 'all', | ||
disallowSpacesInsideParentheses: true, | ||
disallowTrailingWhitespace: true | ||
}, | ||
grunt: 'Gruntfile.js', | ||
source: 'src/**/*.js', | ||
tests: ['test/**/*.js', '!test/polyfill.js'] | ||
}, | ||
uglify: { | ||
@@ -61,11 +105,15 @@ options: { | ||
connect: { | ||
saucelabs: { | ||
'build-qunit': { | ||
options: { | ||
port: 9999, | ||
base: ['.', 'test'] | ||
port: 9998, | ||
base: ['.', 'test'], | ||
middleware: function (connect, options, middlewares) { | ||
middlewares.unshift(encodingMiddleware); | ||
return middlewares; | ||
} | ||
} | ||
}, | ||
build: { | ||
'build-sauce': { | ||
options: { | ||
port: 9998, | ||
port: 9999, | ||
base: ['.', 'test'] | ||
@@ -76,7 +124,11 @@ } | ||
options: { | ||
port: 9998, | ||
port: 10000, | ||
base: ['.', 'test'], | ||
open: 'http://127.0.0.1:9998', | ||
open: 'http://127.0.0.1:10000', | ||
keepalive: true, | ||
livereload: true | ||
livereload: true, | ||
middleware: function (connect, options, middlewares) { | ||
middlewares.unshift(encodingMiddleware); | ||
return middlewares; | ||
} | ||
} | ||
@@ -91,85 +143,88 @@ } | ||
build: process.env.TRAVIS_JOB_ID, | ||
pollInterval: 5000, | ||
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' | ||
pollInterval: 10000, | ||
statusCheckAttempts: 90, | ||
throttled: 3, | ||
browsers: (function () { | ||
var browsers = { | ||
'iOS': [{ | ||
browserName: 'iphone', | ||
platform: 'OS X 10.10', | ||
version: '8.2', | ||
deviceName: 'iPhone Simulator' | ||
}, { | ||
browserName: 'iphone', | ||
platform: 'OS X 10.10', | ||
version: '8.2', | ||
deviceName: 'iPad Simulator' | ||
}], | ||
'android': [{ | ||
browserName: 'android', | ||
platform: 'Linux', | ||
version: '5.1', | ||
deviceName: 'Android Emulator' | ||
}], | ||
'mac': [{ | ||
browserName: 'safari', | ||
platform: 'OS X 10.10', | ||
version: '8.0' | ||
}, { | ||
browserName: 'firefox', | ||
platform: 'OS X 10.10', | ||
version: '36.0' | ||
}, { | ||
browserName: 'chrome', | ||
platform: 'OS X 10.10', | ||
versiono: '41.0' | ||
}], | ||
'windows7': [{ | ||
browserName: 'internet explorer', | ||
platform: 'Windows 7', | ||
version: '11.0' | ||
}, { | ||
browserName: 'internet explorer', | ||
platform: 'Windows 7', | ||
version: '10.0' | ||
}, { | ||
browserName: 'internet explorer', | ||
platform: 'Windows 7', | ||
version: '9.0' | ||
}, { | ||
browserName: 'opera', | ||
platform: 'Windows 7', | ||
version: '12.12' | ||
}], | ||
'windowsXP': [{ | ||
browserName: 'internet explorer', | ||
platform: 'Windows XP', | ||
version: '8.0' | ||
}, { | ||
browserName: 'internet explorer', | ||
platform: 'Windows XP', | ||
version: '7.0' | ||
}, { | ||
browserName: 'internet explorer', | ||
platform: 'Windows XP', | ||
version: '6.0' | ||
}], | ||
'linux': [{ | ||
browserName: 'opera', | ||
platform: 'Linux', | ||
version: '12.15' | ||
}, { | ||
browserName: 'firefox', | ||
platform: 'Linux', | ||
version: '37.0' | ||
}, { | ||
browserName: 'chrome', | ||
platform: 'Linux', | ||
version: '41.0' | ||
}] | ||
}; | ||
var matrix = []; | ||
for (var os in browsers) { | ||
matrix = matrix.concat(browsers[os]); | ||
} | ||
] | ||
return matrix; | ||
}()) | ||
} | ||
@@ -187,4 +242,4 @@ } | ||
grunt.registerTask('saucelabs', ['connect:saucelabs', 'saucelabs-qunit']); | ||
grunt.registerTask('test', ['jshint', 'connect:build', 'qunit', 'nodeunit']); | ||
grunt.registerTask('saucelabs', ['connect:build-sauce', 'saucelabs-qunit']); | ||
grunt.registerTask('test', ['jshint', 'jscs', 'connect:build-qunit', 'qunit', 'nodeunit']); | ||
@@ -191,0 +246,0 @@ grunt.registerTask('dev', ['test', 'uglify', 'compare_size']); |
{ | ||
"name": "js-cookie", | ||
"version": "1.5.1", | ||
"version": "2.0.0-pre", | ||
"description": "A simple, lightweight JavaScript API for handling cookies", | ||
@@ -38,23 +38,8 @@ "main": "src/js.cookie.js", | ||
"grunt-contrib-watch": "0.6.1", | ||
"grunt-jscs": "1.6.0", | ||
"grunt-saucelabs": "8.6.0", | ||
"gzip-js": "0.3.2", | ||
"jquery": "2.1.3", | ||
"qunitjs": "1.18.0", | ||
"requirejs": "2.1.17" | ||
}, | ||
"jspm": { | ||
"main": "js.cookie", | ||
"files": [ | ||
"src/js.cookie.js" | ||
], | ||
"buildConfig": { | ||
"uglify": true | ||
} | ||
}, | ||
"jam": { | ||
"main": "src/js.cookie.js", | ||
"include": [ | ||
"src/js.cookie.js" | ||
] | ||
} | ||
} |
188
README.md
@@ -1,11 +0,1 @@ | ||
# Migrating from jquery-cookie | ||
JavaScript Cookie 1.x internal behavior is totally backward compatible with jquery-cookie. | ||
To start migrating from jquery-cookie to JavaScript Cookie, just rename the API accordingly: | ||
`$.cookie('name', 'value')` === `Cookies.set('name', 'value')` | ||
`$.cookie('name')` === `Cookies.get('name')` | ||
`$.removeCookie('name')` === `Cookies.remove('name')` | ||
`$.cookie()` === `Cookies.get()` | ||
# JavaScript Cookie [![Build Status](https://travis-ci.org/js-cookie/js-cookie.svg?branch=master)](https://travis-ci.org/js-cookie/js-cookie) [![Code Climate](https://codeclimate.com/github/js-cookie/js-cookie.svg)](https://codeclimate.com/github/js-cookie/js-cookie) | ||
@@ -15,6 +5,15 @@ | ||
* Works in [all](https://saucelabs.com/u/js-cookie) browsers | ||
* [Heavily](test) tested | ||
* No dependency | ||
* [Unobstrusive](#json) JSON support | ||
* Supports AMD/CommonJS | ||
* [RFC 6265](http://www.rfc-editor.org/rfc/rfc6265.txt) compliant | ||
* Enable [custom decoding](#converter) | ||
* **~800 bytes** gzipped! | ||
**If you're viewing this at https://github.com/js-cookie/js-cookie, you're reading the documentation for the master branch. | ||
[View documentation for the latest release (1.5.0).](https://github.com/js-cookie/js-cookie/tree/v1.5.0)** | ||
[View documentation for the latest release (1.5.1).](https://github.com/js-cookie/js-cookie/tree/v1.5.1)** | ||
## Build Status Matrix | ||
## Build Status Matrix (master branch) | ||
@@ -34,8 +33,10 @@ [![Selenium Test Status](https://saucelabs.com/browser-matrix/js-cookie.svg)](https://saucelabs.com/u/js-cookie) | ||
The plugin can also be loaded as AMD or CommonJS module. | ||
js-cookie supports [npm](https://www.npmjs.com/package/js-cookie) and [Bower](http://bower.io/search/?q=js-cookie) under the name `js-cookie` | ||
## Usage | ||
It can also be loaded as an AMD or CommonJS module. | ||
Create session cookie: | ||
## Basic Usage | ||
Create a cookie, valid across the entire site: | ||
```javascript | ||
@@ -45,3 +46,3 @@ Cookies.set('name', 'value'); | ||
Create expiring cookie, 7 days from then: | ||
Create a cookie that expires 7 days from now, valid across the entire site: | ||
@@ -52,6 +53,6 @@ ```javascript | ||
Create expiring cookie, valid across entire site: | ||
Create an expiring cookie, valid to the path of the current page: | ||
```javascript | ||
Cookies.set('name', 'value', { expires: 7, path: '/' }); | ||
Cookies.set('name', 'value', { expires: 7, path: '' }); | ||
``` | ||
@@ -62,3 +63,3 @@ | ||
```javascript | ||
Cookies.get('name'); // => "value" | ||
Cookies.get('name'); // => 'value' | ||
Cookies.get('nothing'); // => undefined | ||
@@ -70,3 +71,3 @@ ``` | ||
```javascript | ||
Cookies.get(); // => { "name": "value" } | ||
Cookies.get(); // => { name: 'value' } | ||
``` | ||
@@ -77,15 +78,14 @@ | ||
```javascript | ||
// Returns true when cookie was successfully deleted, otherwise false | ||
Cookies.remove('name'); // => true | ||
Cookies.remove('nothing'); // => false | ||
Cookies.remove('name'); | ||
``` | ||
// Need to use the same attributes (path, domain) as what the cookie was written with | ||
Cookies.set('name', 'value', { path: '/' }); | ||
// This won't work! | ||
Cookies.remove('name'); // => false | ||
// This will work! | ||
Cookies.remove('name', { path: '/' }); // => true | ||
Delete a cookie valid to the path of the current page: | ||
```javascript | ||
Cookies.set('name', 'value', { path: '' }); | ||
Cookies.remove('name'); // fail! | ||
Cookies.remove('name', { path: '' }); // removed! | ||
``` | ||
*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.* | ||
*IMPORTANT! when deleting a cookie, you must pass the exact same path, domain and secure attributes that were used to set the cookie, unless you're relying on the [default attributes](#cookie-attributes).* | ||
@@ -104,36 +104,72 @@ ## Namespace conflicts | ||
## Configuration | ||
## JSON | ||
### raw | ||
js-cookie provides unobstrusive JSON storage for cookies. | ||
By default the cookie value is encoded/decoded when writing/reading, using `encodeURIComponent`/`decodeURIComponent`. Bypass this by setting raw to true: | ||
When creating a cookie you can pass an Array or Object Literal instead of a string in the value. If you do so, js-cookie will store the string representation of the object according to `JSON.stringify`: | ||
```javascript | ||
Cookies.raw = true; | ||
Cookies.set('name', { foo: 'bar' }); | ||
``` | ||
### json | ||
When reading a cookie with the default `Cookies.get` api, you receive the string representation stored in the cookie: | ||
Turn on automatic storage of JSON objects passed as the cookie value. Assumes `JSON.stringify` and `JSON.parse`: | ||
```javascript | ||
Cookies.get('name'); // => '{"foo":"bar"}' | ||
``` | ||
```javascript | ||
Cookies.json = true; | ||
Cookies.get(); // => { name: '{"foo":"bar"}' } | ||
``` | ||
## Cookie Options | ||
When reading a cookie with the `Cookies.getJSON` api, you receive the parsed representation of the string stored in the cookie according to `JSON.parse`: | ||
Cookie attributes can be set globally by setting properties of the `Cookies.defaults` object or individually for each call to `Cookies.set()` by passing a plain object to the options argument. Per-call options override the default options. | ||
```javascript | ||
Cookies.getJSON('name'); // => { foo: 'bar' } | ||
``` | ||
```javascript | ||
Cookies.getJSON(); // => { name: { foo: 'bar' } } | ||
``` | ||
*Note: To support IE6-8 you need to include the JSON-js polyfill: https://github.com/douglascrockford/JSON-js* | ||
## Encoding | ||
This project is [RFC 6265](http://tools.ietf.org/html/rfc6265#section-4.1.1) compliant. All special characters that are not allowed in the cookie-name or cookie-value are encoded with each one's UTF-8 Hex equivalent using [percent-encoding](http://en.wikipedia.org/wiki/Percent-encoding). | ||
The only character in cookie-name or cookie-value that is allowed and still encoded is the percent `%` character, it is escaped in order to interpret percent input as literal. | ||
To override the default cookie decoding you need to use a [converter](#converter). | ||
## Cookie Attributes | ||
Cookie attributes defaults can be set globally by setting properties of the `Cookies.defaults` object or individually for each call to `Cookies.set(...)` by passing a plain object in the last argument. Per-call attributes override the default attributes. | ||
### expires | ||
expires: 365 | ||
Define when the cookie will be removed. Value can be a `Number` which will be interpreted as days from time of creation or a `Date` instance. If omitted, the cookie becomes a session cookie. | ||
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. | ||
**Default:** Cookie is removed when the user closes the browser. | ||
**Examples:** | ||
```javascript | ||
Cookies.set('name', 'value', { expires: 365 }); | ||
Cookies.get('name'); // => 'value' | ||
Cookies.remove('name'); | ||
``` | ||
### path | ||
path: '/' | ||
Define the path where the cookie is available. | ||
Define the path where the cookie is valid. *By default the path of the cookie is the path of the page where the cookie was created (standard browser behavior).* If you want to make it available for instance across the entire domain use `path: '/'`. Default: path of page where the cookie was created. | ||
**Default:** `/` | ||
**Examples:** | ||
```javascript | ||
Cookies.set('name', 'value', { path: '' }); | ||
Cookies.get('name'); // => 'value' | ||
Cookies.remove('name', { path: '' }); | ||
``` | ||
**Note regarding Internet Explorer:** | ||
@@ -149,33 +185,57 @@ | ||
domain: 'example.com' | ||
Define the domain where the cookie is available | ||
Define the domain where the cookie is valid. Default: domain of page where the cookie was created. | ||
**Default:** Domain of the page where the cookie was created | ||
**Examples:** | ||
```javascript | ||
Cookies.set('name', 'value', { domain: 'sub.domain.com' }); | ||
Cookies.get('name'); // => undefined (need to read at 'sub.domain.com') | ||
``` | ||
### secure | ||
secure: true | ||
A `Boolean` indicating if the cookie transmission requires a secure protocol (https) | ||
If true, the cookie transmission requires a secure protocol (https). Default: `false`. | ||
**Default:** No secure protocol requirement | ||
## Converters | ||
**Examples:** | ||
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. | ||
```javascript | ||
Cookies.set('name', 'value', { secure: true }); | ||
Cookies.get('name'); // => 'value' | ||
Cookies.remove('name', { secure: true }); | ||
``` | ||
Example for parsing a value into a number: | ||
## Converter | ||
Create a new instance of the api that overrides the default decoding implementation. | ||
All methods that rely in a proper decoding to work, such as `Cookies.remove()` and `Cookies.get()`, will run the converter first for each cookie. | ||
The returning String will be used as the cookie value. | ||
Example from reading one of the cookies that can only be decoded using the `escape` function: | ||
```javascript | ||
Cookies.set('foo', '42'); | ||
Cookies.get('foo', Number); // => 42 | ||
document.cookie = 'escaped=%u5317'; | ||
document.cookie = 'default=%E5%8C%97'; | ||
var cookies = Cookies.withConverter(function (value, name) { | ||
if ( name === 'escaped' ) { | ||
return unescape(value); | ||
} | ||
}); | ||
cookies.get('escaped'); // 北 | ||
cookies.get('default'); // 北 | ||
cookies.get(); // { escaped: '北', default: '北' } | ||
``` | ||
Dealing with cookies that have been encoded using `escape` (3rd party cookies): | ||
Example for parsing the value from a cookie generated with PHP's `setcookie()` method: | ||
```javascript | ||
Cookies.raw = true; | ||
Cookies.get('foo', unescape); | ||
// 'cookie+with+space' => 'cookie with space' | ||
Cookies.withConverter(function (value) { | ||
return value.replace(/\+/g, ' '); | ||
}).get('foo'); | ||
``` | ||
You can pass an arbitrary conversion function. | ||
## Contributing | ||
@@ -187,4 +247,4 @@ | ||
* Remove the "-pre" suffix of the "version" attribute of `bower.json`, `package.json` and `component.json` | ||
* Remove the "-pre" suffix of the version number in the `CHANGELOG.md` and `src/js.cookie.js` files | ||
* Remove the "-pre" suffix of the "version" attribute of `package.json` | ||
* Remove the "-pre" suffix of the version number in the `src/js.cookie.js` file | ||
* Commit with the message "Release version x.x.x" | ||
@@ -194,4 +254,4 @@ * Create version tag in git | ||
* Release on npm | ||
* Increment and add the "-pre" suffix to the "version" attribute of `bower.json`, `package.json` and `component.json` | ||
* Increment and add the "-pre" suffix to the version number in the `CHANGELOG.md` and `src/js.cookie.js` files | ||
* Increment and add the "-pre" suffix to the "version" attribute of `package.json` | ||
* Increment and add the "-pre" suffix to the version number in the `src/js.cookie.js` file | ||
* Link the documentation of the latest release tag in the `README.md` | ||
@@ -202,2 +262,4 @@ * Commit with the message "Prepare for the next development iteration" | ||
[Klaus Hartl](https://github.com/carhartl) | ||
* [Klaus Hartl](https://github.com/carhartl) | ||
* [Fagner Brack](https://github.com/FagnerMartinsBrack) | ||
* And awesome [contributors](https://github.com/js-cookie/js-cookie/graphs/contributors) |
/*! | ||
* Javascript Cookie v1.5.1 | ||
* JavaScript Cookie v2.0.0-pre | ||
* https://github.com/js-cookie/js-cookie | ||
* | ||
* Copyright 2006, 2014 Klaus Hartl | ||
* Copyright 2006, 2015 Klaus Hartl | ||
* Released under the MIT license | ||
*/ | ||
(function (factory) { | ||
var jQuery; | ||
if (typeof define === 'function' && define.amd) { | ||
// AMD (Register as an anonymous module) | ||
define(['jquery'], factory); | ||
define(factory); | ||
} else if (typeof exports === 'object') { | ||
// Node/CommonJS | ||
try { | ||
jQuery = require('jquery'); | ||
} catch(e) {} | ||
module.exports = factory(jQuery); | ||
module.exports = factory(); | ||
} else { | ||
// Browser globals | ||
var _OldCookies = window.Cookies; | ||
var api = window.Cookies = factory(window.jQuery); | ||
api.noConflict = function() { | ||
api.noConflict = function () { | ||
window.Cookies = _OldCookies; | ||
@@ -28,46 +21,10 @@ return api; | ||
} | ||
}(function ($) { | ||
var pluses = /\+/g; | ||
function encode(s) { | ||
return api.raw ? s : encodeURIComponent(s); | ||
} | ||
function decode(s) { | ||
return api.raw ? s : decodeURIComponent(s); | ||
} | ||
function stringifyCookieValue(value) { | ||
return encode(api.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 api.json ? JSON.parse(s) : s; | ||
} catch(e) {} | ||
} | ||
function read(s, converter) { | ||
var value = api.raw ? s : parseCookieValue(s); | ||
return isFunction(converter) ? converter(value) : value; | ||
} | ||
function extend() { | ||
var key, options; | ||
}(function () { | ||
function extend () { | ||
var i = 0; | ||
var result = {}; | ||
for (; i < arguments.length; i++) { | ||
options = arguments[ i ]; | ||
for (key in options) { | ||
result[key] = options[key]; | ||
var attributes = arguments[ i ]; | ||
for (var key in attributes) { | ||
result[key] = attributes[key]; | ||
} | ||
@@ -78,72 +35,105 @@ } | ||
function isFunction(obj) { | ||
return Object.prototype.toString.call(obj) === '[object Function]'; | ||
} | ||
function init (converter) { | ||
function api (key, value, attributes) { | ||
var result; | ||
var api = function (key, value, options) { | ||
// Write | ||
// Write | ||
if (arguments.length > 1) { | ||
attributes = extend({ | ||
path: '/' | ||
}, api.defaults, attributes); | ||
if (arguments.length > 1 && !isFunction(value)) { | ||
options = extend(api.defaults, options); | ||
if (typeof attributes.expires === 'number') { | ||
var expires = new Date(); | ||
expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5); | ||
attributes.expires = expires; | ||
} | ||
if (typeof options.expires === 'number') { | ||
var days = options.expires, t = options.expires = new Date(); | ||
t.setMilliseconds(t.getMilliseconds() + days * 864e+5); | ||
try { | ||
result = JSON.stringify(value); | ||
if (/^[\{\[]/.test(result)) { | ||
value = result; | ||
} | ||
} catch (e) {} | ||
value = encodeURIComponent(String(value)); | ||
value = value.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); | ||
key = encodeURIComponent(String(key)); | ||
key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent); | ||
key = key.replace(/[\(\)]/g, escape); | ||
return (document.cookie = [ | ||
key, '=', value, | ||
attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE | ||
attributes.path && '; path=' + attributes.path, | ||
attributes.domain && '; domain=' + attributes.domain, | ||
attributes.secure && '; secure' | ||
].join('')); | ||
} | ||
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 | ||
// Read | ||
if (!key) { | ||
result = {}; | ||
} | ||
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 "get()". | ||
cookies = document.cookie ? document.cookie.split('; ') : [], | ||
i = 0, | ||
l = cookies.length; | ||
// calling "get()" | ||
var cookies = document.cookie ? document.cookie.split('; ') : []; | ||
var rdecode = /(%[0-9A-Z]{2})+/g; | ||
var i = 0; | ||
for (; i < l; i++) { | ||
var parts = cookies[i].split('='), | ||
name = decode(parts.shift()), | ||
cookie = parts.join('='); | ||
for (; i < cookies.length; i++) { | ||
var parts = cookies[i].split('='); | ||
var name = parts[0].replace(rdecode, decodeURIComponent); | ||
var cookie = parts.slice(1).join('='); | ||
if (key === name) { | ||
// If second argument (value) is a function it's a converter... | ||
result = read(cookie, value); | ||
break; | ||
if (cookie.charAt(0) === '"') { | ||
cookie = cookie.slice(1, -1); | ||
} | ||
cookie = converter && converter(cookie, name) || cookie.replace(rdecode, decodeURIComponent); | ||
if (this.json) { | ||
try { | ||
cookie = JSON.parse(cookie); | ||
} catch (e) {} | ||
} | ||
if (key === name) { | ||
result = cookie; | ||
break; | ||
} | ||
if (!key) { | ||
result[name] = cookie; | ||
} | ||
} | ||
// Prevent storing a cookie that we couldn't decode. | ||
if (!key && (cookie = read(cookie)) !== undefined) { | ||
result[name] = cookie; | ||
} | ||
return result; | ||
} | ||
return result; | ||
}; | ||
api.get = api.set = api; | ||
api.getJSON = function () { | ||
return api.apply({ | ||
json: true | ||
}, [].slice.call(arguments)); | ||
}; | ||
api.defaults = {}; | ||
api.get = api.set = api; | ||
api.defaults = {}; | ||
api.remove = function (key, attributes) { | ||
api(key, '', extend(attributes, { | ||
expires: -1 | ||
})); | ||
}; | ||
api.remove = function (key, options) { | ||
// Must not alter options, thus extending a fresh object... | ||
api(key, '', extend(options, { expires: -1 })); | ||
return !api(key); | ||
}; | ||
api.withConverter = init; | ||
if ( $ ) { | ||
$.cookie = api; | ||
$.removeCookie = api.remove; | ||
return api; | ||
} | ||
return api; | ||
return init(); | ||
})); |
@@ -5,5 +5,2 @@ /*jshint unused:false */ | ||
paths: { | ||
'jquery': [ | ||
'../node_modules/jquery/dist/jquery' | ||
], | ||
'qunit': [ | ||
@@ -10,0 +7,0 @@ '../node_modules/qunitjs/qunit/qunit' |
@@ -5,9 +5,7 @@ require(['qunit'], function (QUnit) { | ||
QUnit.start(); | ||
QUnit.test('with jquery dependency', function (assert) { | ||
QUnit.expect(3); | ||
QUnit.test('module loading', function (assert) { | ||
QUnit.expect(1); | ||
var done = assert.async(); | ||
require(['jquery', '/src/js.cookie.js'], function ($, Cookies) { | ||
assert.ok(!!$.cookie, 'Loaded $.cookie'); | ||
assert.ok(!!$.removeCookie, 'Loaded $.removeCookie'); | ||
assert.ok(!!Cookies.get, 'Loaded Cookies api'); | ||
require(['/src/js.cookie.js'], function (Cookies) { | ||
assert.ok(!!Cookies.get, 'should load the api'); | ||
done(); | ||
@@ -14,0 +12,0 @@ }); |
@@ -1,96 +0,11 @@ | ||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys | ||
Object.keys = Object.keys || (function() { | ||
'use strict'; | ||
var hasOwnProperty = Object.prototype.hasOwnProperty, | ||
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'), | ||
dontEnums = [ | ||
'toString', | ||
'toLocaleString', | ||
'valueOf', | ||
'hasOwnProperty', | ||
'isPrototypeOf', | ||
'propertyIsEnumerable', | ||
'constructor' | ||
], | ||
dontEnumsLength = dontEnums.length; | ||
// Object.keys() | ||
// developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys | ||
Object.keys||(Object.keys=function(){"use strict";var a=Object.prototype.hasOwnProperty,b=!{toString:null}.propertyIsEnumerable("toString"),c=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],d=c.length;return function(e){if("object"!=typeof e&&("function"!=typeof e||null===e))throw new TypeError("Object.keys called on non-object");var g,h,f=[];for(g in e)a.call(e,g)&&f.push(g);if(b)for(h=0;d>h;h++)a.call(e,c[h])&&f.push(c[h]);return f}}()); | ||
return function(obj) { | ||
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { | ||
throw new TypeError('Object.keys called on non-object'); | ||
} | ||
// Array.forEach() | ||
// developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach | ||
Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c,d;if(null==this)throw new TypeError(" this is null or not defined");var e=Object(this),f=e.length>>>0;if("function"!=typeof a)throw new TypeError(a+" is not a function");for(arguments.length>1&&(c=b),d=0;f>d;){var g;d in e&&(g=e[d],a.call(c,g,d,e)),d++}}); | ||
var result = [], prop, i; | ||
for (prop in obj) { | ||
if (hasOwnProperty.call(obj, prop)) { | ||
result.push(prop); | ||
} | ||
} | ||
if (hasDontEnumBug) { | ||
for (i = 0; i < dontEnumsLength; i++) { | ||
if (hasOwnProperty.call(obj, dontEnums[i])) { | ||
result.push(dontEnums[i]); | ||
} | ||
} | ||
} | ||
return result; | ||
}; | ||
}()); | ||
// Reproducing steps of ECMA-262, Edition 5, 15.4.4.18 | ||
// Reference: http://es5.github.com/#x15.4.4.18 | ||
Array.prototype.forEach = Array.prototype.forEach || function( callback, thisArg ) { | ||
var T, k; | ||
if ( this === null || this === undefined ) { | ||
throw new TypeError( "this is null or not defined" ); | ||
} | ||
// 1. Let O be the result of calling ToObject passing the |this| value as the argument. | ||
var O = Object(this); | ||
// 2. Let lenValue be the result of calling the Get internal method of O with the argument | ||
// "length". | ||
// 3. Let len be ToUint32(lenValue). | ||
var len = O.length >>> 0; // Hack to convert O.length to a UInt32 | ||
// 4. If IsCallable(callback) is false, throw a TypeError exception. | ||
// See: http://es5.github.com/#x9.11 | ||
if ( {}.toString.call(callback) !== "[object Function]" ) { | ||
throw new TypeError( callback + " is not a function" ); | ||
} | ||
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined. | ||
if ( thisArg ) { | ||
T = thisArg; | ||
} | ||
// 6. Let k be 0 | ||
k = 0; | ||
// 7. Repeat, while k < len | ||
while( k < len ) { | ||
var kValue; | ||
// a. Let Pk be ToString(k). | ||
// This is implicit for LHS operands of the in operator | ||
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk. | ||
// This step can be combined with c | ||
// c. If kPresent is true, then | ||
if ( Object.prototype.hasOwnProperty.call(O, k) ) { | ||
// i. Let kValue be the result of calling the Get internal method of O with argument Pk. | ||
kValue = O[ k ]; | ||
// ii. Call the Call internal method of callback with T as the this value and | ||
// argument list containing kValue, k, and O. | ||
callback.call( T, kValue, k, O ); | ||
} | ||
// d. Increase k by 1. | ||
k++; | ||
} | ||
// 8. return undefined | ||
}; | ||
// JSON | ||
// github.com/douglascrockford/JSON-js/tree/c07c287e39ab5a1726818e0436490bf071b7c838 | ||
"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(a){return 10>a?"0"+a:a}function this_value(){return this.valueOf()}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return"string"==typeof b?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,h,g=gap,i=b[a];switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(a)),"function"==typeof rep&&(i=rep.call(b,a,i)),typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";if(gap+=indent,h=[],"[object Array]"===Object.prototype.toString.apply(i)){for(f=i.length,c=0;f>c;c+=1)h[c]=str(c,i)||"null";return e=0===h.length?"[]":gap?"[\n"+gap+h.join(",\n"+gap)+"\n"+g+"]":"["+h.join(",")+"]",gap=g,e}if(rep&&"object"==typeof rep)for(f=rep.length,c=0;f>c;c+=1)"string"==typeof rep[c]&&(d=rep[c],e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e));else for(d in i)Object.prototype.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e));return e=0===h.length?"{}":gap?"{\n"+gap+h.join(",\n"+gap)+"\n"+g+"}":"{"+h.join(",")+"}",gap=g,e}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},Boolean.prototype.toJSON=this_value,Number.prototype.toJSON=this_value,String.prototype.toJSON=this_value);var cx,escapable,gap,indent,meta,rep;"function"!=typeof JSON.stringify&&(escapable=/[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(a,b,c){var d;if(gap="",indent="","number"==typeof c)for(d=0;c>d;d+=1)indent+=" ";else"string"==typeof c&&(indent=c);if(rep=b,b&&"function"!=typeof b&&("object"!=typeof b||"number"!=typeof b.length))throw new Error("JSON.stringify");return str("",{"":a})}),"function"!=typeof JSON.parse&&(cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&"object"==typeof e)for(c in e)Object.prototype.hasOwnProperty.call(e,c)&&(d=walk(e,c),void 0!==d?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;if(text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}(); |
@@ -1,170 +0,55 @@ | ||
// https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit | ||
(function() { | ||
"use strict"; | ||
/*global lifecycle: true*/ | ||
var log = []; | ||
QUnit.module('read', lifecycle); | ||
QUnit.done(function (test_results) { | ||
var tests = []; | ||
for (var i = 0, len = log.length; i < len; i++) { | ||
var details = log[i]; | ||
tests.push({ | ||
name: details.name, | ||
result: details.result, | ||
expected: details.expected, | ||
actual: details.actual, | ||
source: details.source | ||
}); | ||
} | ||
test_results.tests = tests; | ||
// Required for exposing test results to the Sauce Labs API. | ||
// Can be removed when the following issue is fixed: | ||
// https://github.com/axemclion/grunt-saucelabs/issues/84 | ||
window.global_test_results = test_results; | ||
}); | ||
QUnit.testStart(function (testDetails) { | ||
QUnit.log(function (details) { | ||
if (!details.result) { | ||
details.name = testDetails.name; | ||
log.push(details); | ||
} | ||
}); | ||
}); | ||
}()); | ||
var lifecycle = { | ||
teardown: function () { | ||
Cookies.defaults = {}; | ||
delete Cookies.raw; | ||
delete Cookies.json; | ||
Object.keys(Cookies.get()).forEach(Cookies.remove); | ||
} | ||
}; | ||
module('read', lifecycle); | ||
test('simple value', function () { | ||
expect(1); | ||
QUnit.test('simple value', function (assert) { | ||
assert.expect(1); | ||
document.cookie = 'c=v'; | ||
strictEqual(Cookies.get('c'), 'v', 'should return value'); | ||
assert.strictEqual(Cookies.get('c'), 'v', 'should return value'); | ||
}); | ||
test('empty value', function () { | ||
expect(1); | ||
QUnit.test('empty value', function (assert) { | ||
assert.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. | ||
Cookies.set('c', ''); | ||
strictEqual(Cookies.get('c'), '', 'should return value'); | ||
assert.strictEqual(Cookies.get('c'), '', 'should return value'); | ||
}); | ||
test('not existing', function () { | ||
expect(1); | ||
strictEqual(Cookies.get('whatever'), undefined, 'return undefined'); | ||
QUnit.test('not existing', function (assert) { | ||
assert.expect(1); | ||
assert.strictEqual(Cookies.get('whatever'), undefined, 'return undefined'); | ||
}); | ||
test('RFC 2068 quoted string', function () { | ||
expect(1); | ||
document.cookie = 'c="v@address.com\\"\\\\\\""'; | ||
strictEqual(Cookies.get('c'), 'v@address.com"\\"', 'should decode RFC 2068 quoted string'); | ||
}); | ||
test('decode', function () { | ||
expect(1); | ||
document.cookie = encodeURIComponent(' c') + '=' + encodeURIComponent(' v'); | ||
strictEqual(Cookies.get(' 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'; | ||
strictEqual(Cookies.get('c'), 'foo bar', 'should convert pluses back to space'); | ||
}); | ||
test('raw = true', function () { | ||
expect(2); | ||
Cookies.raw = true; | ||
document.cookie = 'c=%20v'; | ||
strictEqual(Cookies.get('c'), '%20v', 'should not decode value'); | ||
// see https://github.com/carhartl/jquery-cookie/issues/50 | ||
// github.com/carhartl/jquery-cookie/issues/50 | ||
QUnit.test('equality sign in cookie value', function (assert) { | ||
assert.expect(1); | ||
Cookies.set('c', 'foo=bar'); | ||
strictEqual(Cookies.get('c'), 'foo=bar', 'should include the entire value'); | ||
assert.strictEqual(Cookies.get('c'), 'foo=bar', 'should include the entire value'); | ||
}); | ||
test('json = true', function () { | ||
expect(1); | ||
if ('JSON' in window) { | ||
Cookies.json = true; | ||
Cookies.set('c', { foo: 'bar' }); | ||
deepEqual(Cookies.get('c'), { foo: 'bar' }, 'should parse JSON'); | ||
} else { | ||
ok(true); | ||
} | ||
// github.com/carhartl/jquery-cookie/issues/215 | ||
QUnit.test('percent character in cookie value', function (assert) { | ||
assert.expect(1); | ||
document.cookie = 'bad=foo%'; | ||
assert.strictEqual(Cookies.get('bad'), 'foo%', 'should read the percent character'); | ||
}); | ||
test('not existing with json = true', function () { | ||
expect(1); | ||
if ('JSON' in window) { | ||
Cookies.json = true; | ||
strictEqual(Cookies.get('whatever'), undefined, "won't throw exception"); | ||
} else { | ||
ok(true); | ||
} | ||
QUnit.test('percent character in cookie value mixed with encoded values', function (assert) { | ||
assert.expect(1); | ||
document.cookie = 'bad=foo%bar%22baz%bax%3D'; | ||
assert.strictEqual(Cookies.get('bad'), 'foo%bar"baz%bax=', 'should read the percent character'); | ||
}); | ||
test('string with json = true', function () { | ||
expect(1); | ||
if ('JSON' in window) { | ||
Cookies.json = true; | ||
Cookies.set('c', 'v'); | ||
strictEqual(Cookies.get('c'), 'v', 'should return value'); | ||
} else { | ||
ok(true); | ||
} | ||
}); | ||
test('invalid JSON string with json = true', function () { | ||
expect(1); | ||
if ('JSON' in window) { | ||
Cookies.set('c', 'v'); | ||
Cookies.json = true; | ||
strictEqual(Cookies.get('c'), undefined, "won't throw exception, returns undefined"); | ||
} else { | ||
ok(true); | ||
} | ||
}); | ||
test('invalid URL encoding', function () { | ||
expect(1); | ||
document.cookie = 'bad=foo%'; | ||
strictEqual(Cookies.get('bad'), undefined, "won't throw exception, returns undefined"); | ||
// Delete manually here because it requires raw === true... | ||
Cookies.raw = true; | ||
Cookies.remove('bad'); | ||
}); | ||
asyncTest('malformed cookie value in IE (#88, #117)', function () { | ||
expect(1); | ||
// github.com/carhartl/jquery-cookie/pull/88 | ||
// github.com/carhartl/jquery-cookie/pull/117 | ||
QUnit.test('malformed cookie value in IE', function (assert) { | ||
assert.expect(1); | ||
var done = assert.async(); | ||
// Sandbox in an iframe so that we can poke around with document.cookie. | ||
var iframe = document.createElement('iframe'); | ||
var addEvent = function (element, eventName, fn) { | ||
var method = "addEventListener"; | ||
if (element.attachEvent) { | ||
eventName = 'on' + eventName; | ||
method = "attachEvent"; | ||
} | ||
element[ method ](eventName, fn); | ||
}; | ||
iframe.src = 'malformed_cookie.html'; | ||
addEvent(iframe, 'load', function () { | ||
start(); | ||
if (iframe.contentWindow.ok) { | ||
strictEqual(iframe.contentWindow.testValue, 'two', 'reads all cookie values, skipping duplicate occurences of "; "'); | ||
assert.strictEqual(iframe.contentWindow.testValue, 'two', 'reads all cookie values, skipping duplicate occurences of "; "'); | ||
} else { | ||
@@ -174,4 +59,5 @@ // Skip the test where we can't stub document.cookie using | ||
// Chrome, Firefox and IE 8+. | ||
ok(true, 'N/A'); | ||
assert.ok(true, 'N/A'); | ||
} | ||
done(); | ||
}); | ||
@@ -181,80 +67,71 @@ document.body.appendChild(iframe); | ||
test('Call to read all when there are cookies', function () { | ||
QUnit.test('Call to read all when there are cookies', function (assert) { | ||
Cookies.set('c', 'v'); | ||
Cookies.set('foo', 'bar'); | ||
deepEqual(Cookies.get(), { c: 'v', foo: 'bar' }, 'returns object containing all cookies'); | ||
assert.deepEqual(Cookies.get(), { c: 'v', foo: 'bar' }, 'returns object containing all cookies'); | ||
}); | ||
test('Call to read all when there are no cookies at all', function () { | ||
deepEqual(Cookies.get(), {}, 'returns empty object'); | ||
QUnit.test('Call to read all when there are no cookies at all', function (assert) { | ||
assert.deepEqual(Cookies.get(), {}, 'returns empty object'); | ||
}); | ||
test('Call to read all with json: true', function () { | ||
Cookies.json = true; | ||
Cookies.set('c', { foo: 'bar' }); | ||
deepEqual(Cookies.get(), { c: { foo: 'bar' } }, 'returns JSON parsed cookies'); | ||
QUnit.test('RFC 6265 - reading cookie-octet enclosed in DQUOTE', function (assert) { | ||
assert.expect(1); | ||
document.cookie = 'c="v"'; | ||
assert.strictEqual(Cookies.get('c'), 'v', 'should simply ignore quoted strings'); | ||
}); | ||
test('Call to read all with a badly encoded cookie', function () { | ||
expect(1); | ||
document.cookie = 'bad=foo%'; | ||
document.cookie = 'good=foo'; | ||
deepEqual(Cookies.get(), { good: 'foo' }, 'returns object containing all decodable cookies'); | ||
// Delete manually here because it requires raw === true... | ||
Cookies.raw = true; | ||
Cookies.remove('bad'); | ||
}); | ||
QUnit.module('write', lifecycle); | ||
module('write', lifecycle); | ||
test('String primitive', function () { | ||
expect(1); | ||
QUnit.test('String primitive', function (assert) { | ||
assert.expect(1); | ||
Cookies.set('c', 'v'); | ||
strictEqual(Cookies.get('c'), 'v', 'should write value'); | ||
assert.strictEqual(Cookies.get('c'), 'v', 'should write value'); | ||
}); | ||
test('String object', function () { | ||
expect(1); | ||
QUnit.test('String object', function (assert) { | ||
assert.expect(1); | ||
Cookies.set('c', new String('v')); | ||
strictEqual(Cookies.get('c'), 'v', 'should write value'); | ||
assert.strictEqual(Cookies.get('c'), 'v', 'should write value'); | ||
}); | ||
test('value "[object Object]"', function () { | ||
expect(1); | ||
QUnit.test('value "[object Object]"', function (assert) { | ||
assert.expect(1); | ||
Cookies.set('c', '[object Object]'); | ||
strictEqual(Cookies.get('c'), '[object Object]', 'should write value'); | ||
assert.strictEqual(Cookies.get('c'), '[object Object]', 'should write value'); | ||
}); | ||
test('number', function () { | ||
expect(1); | ||
QUnit.test('number', function (assert) { | ||
assert.expect(1); | ||
Cookies.set('c', 1234); | ||
strictEqual(Cookies.get('c'), '1234', 'should write value'); | ||
assert.strictEqual(Cookies.get('c'), '1234', 'should write value'); | ||
}); | ||
test('null', function () { | ||
expect(1); | ||
QUnit.test('null', function (assert) { | ||
assert.expect(1); | ||
Cookies.set('c', null); | ||
strictEqual(Cookies.get('c'), 'null', 'should write value'); | ||
assert.strictEqual(Cookies.get('c'), 'null', 'should write value'); | ||
}); | ||
test('undefined', function () { | ||
expect(1); | ||
QUnit.test('undefined', function (assert) { | ||
assert.expect(1); | ||
Cookies.set('c', undefined); | ||
strictEqual(Cookies.get('c'), 'undefined', 'should write value'); | ||
assert.strictEqual(Cookies.get('c'), 'undefined', 'should write value'); | ||
}); | ||
test('expires option as days from now', function () { | ||
expect(1); | ||
QUnit.test('expires option as days from now', function (assert) { | ||
assert.expect(1); | ||
var sevenDaysFromNow = new Date(); | ||
sevenDaysFromNow.setDate(sevenDaysFromNow.getDate() + 21); | ||
strictEqual(Cookies.set('c', 'v', { expires: 21 }), 'c=v; expires=' + sevenDaysFromNow.toUTCString(), | ||
'should write the cookie string with expires'); | ||
var expected = 'c=v; expires=' + sevenDaysFromNow.toUTCString(); | ||
var actual = Cookies.set('c', 'v', { expires: 21 }).substring(0, expected.length); | ||
assert.strictEqual(actual, expected, 'should write the cookie string with expires'); | ||
}); | ||
test('expires option as fraction of a day', function () { | ||
expect(1); | ||
QUnit.test('expires option as fraction of a day', function (assert) { | ||
assert.expect(1); | ||
var now = new Date().getTime(); | ||
var expires = Date.parse(Cookies.set('c', 'v', { expires: 0.5 }).replace(/.+expires=/, '')); | ||
var stringifiedDate = Cookies.set('c', 'v', { expires: 0.5 }).split('; ')[1].split('=')[1]; | ||
var expires = Date.parse(stringifiedDate); | ||
@@ -264,116 +141,184 @@ // When we were using Date.setDate() fractions have been ignored | ||
// difference for execution time. | ||
ok(expires > now + 1000, 'should write expires attribute with the correct date'); | ||
assert.ok(expires > now + 1000, 'should write expires attribute with the correct date'); | ||
}); | ||
test('expires option as Date instance', function () { | ||
expect(1); | ||
QUnit.test('expires option as Date instance', function (assert) { | ||
assert.expect(1); | ||
var sevenDaysFromNow = new Date(); | ||
sevenDaysFromNow.setDate(sevenDaysFromNow.getDate() + 7); | ||
strictEqual(Cookies.set('c', 'v', { expires: sevenDaysFromNow }), 'c=v; expires=' + sevenDaysFromNow.toUTCString(), | ||
'should write the cookie string with expires'); | ||
var expected = 'c=v; expires=' + sevenDaysFromNow.toUTCString(); | ||
var actual = Cookies.set('c', 'v', { expires: sevenDaysFromNow }).substring(0, expected.length); | ||
assert.strictEqual(actual, expected, 'should write the cookie string with expires'); | ||
}); | ||
test('return value', function () { | ||
expect(1); | ||
strictEqual(Cookies.set('c', 'v'), 'c=v', 'should return written cookie string'); | ||
QUnit.test('return value', function (assert) { | ||
assert.expect(1); | ||
var expected = 'c=v'; | ||
var actual = Cookies.set('c', 'v').substring(0, expected.length); | ||
assert.strictEqual(actual, expected, 'should return written cookie string'); | ||
}); | ||
test('defaults', function () { | ||
expect(2); | ||
QUnit.test('default path attribute', function (assert) { | ||
assert.expect(1); | ||
assert.ok(Cookies.set('c', 'v').match(/path=\//), 'should read the default path'); | ||
}); | ||
QUnit.test('API for changing defaults', function (assert) { | ||
assert.expect(3); | ||
Cookies.defaults.path = '/foo'; | ||
ok(Cookies.set('c', 'v').match(/path=\/foo/), 'should use options from defaults'); | ||
ok(Cookies.set('c', 'v', { path: '/bar' }).match(/path=\/bar/), 'options argument has precedence'); | ||
assert.ok(Cookies.set('c', 'v').match(/path=\/foo/), 'should use attributes from defaults'); | ||
Cookies.remove('c', { path: '/foo' }); | ||
assert.ok(Cookies.set('c', 'v', { path: '/bar' }).match(/path=\/bar/), 'attributes argument has precedence'); | ||
Cookies.remove('c', { path: '/bar' }); | ||
delete Cookies.defaults.path; | ||
assert.ok(Cookies.set('c', 'v').match(/path=\//), 'should roll back to the default path'); | ||
}); | ||
test('raw = true', function () { | ||
expect(1); | ||
Cookies.raw = true; | ||
strictEqual(Cookies.set('c[1]', 'v[1]'), 'c[1]=v[1]', 'should not encode'); | ||
// Delete manually here because it requires raw === true... | ||
Cookies.remove('c[1]'); | ||
QUnit.module('remove', lifecycle); | ||
QUnit.test('deletion', function (assert) { | ||
assert.expect(1); | ||
Cookies.set('c', 'v'); | ||
Cookies.remove('c'); | ||
assert.strictEqual(document.cookie, '', 'should delete the cookie'); | ||
}); | ||
test('json = true', function () { | ||
expect(1); | ||
Cookies.json = true; | ||
QUnit.test('with attributes', function (assert) { | ||
assert.expect(1); | ||
var attributes = { path: '/' }; | ||
Cookies.set('c', 'v', attributes); | ||
Cookies.remove('c', attributes); | ||
assert.strictEqual(document.cookie, '', 'should delete the cookie'); | ||
}); | ||
if ('JSON' in window) { | ||
Cookies.set('c', { foo: 'bar' }); | ||
strictEqual(document.cookie, 'c=' + encodeURIComponent(JSON.stringify({ foo: 'bar' })), 'should stringify JSON'); | ||
} else { | ||
ok(true); | ||
} | ||
QUnit.test('passing attributes reference', function (assert) { | ||
assert.expect(1); | ||
var attributes = { path: '/' }; | ||
Cookies.set('c', 'v', attributes); | ||
Cookies.remove('c', attributes); | ||
assert.deepEqual(attributes, { path: '/' }, 'won\'t alter attributes object'); | ||
}); | ||
QUnit.module('converters', lifecycle); | ||
module('removeCookie', lifecycle); | ||
// github.com/carhartl/jquery-cookie/pull/166 | ||
QUnit.test('provide a way for decoding characters encoded by the escape function', function (assert) { | ||
assert.expect(1); | ||
document.cookie = 'c=%u5317%u4eac'; | ||
assert.strictEqual(Cookies.withConverter(unescape).get('c'), '北京', 'should convert chinese characters correctly'); | ||
}); | ||
test('deletion', function () { | ||
expect(1); | ||
Cookies.set('c', 'v'); | ||
Cookies.remove('c'); | ||
strictEqual(document.cookie, '', 'should delete the cookie'); | ||
QUnit.test('should decode a malformed char that matches the decodeURIComponent regex', function (assert) { | ||
assert.expect(1); | ||
document.cookie = 'c=%E3'; | ||
var cookies = Cookies.withConverter(unescape); | ||
assert.strictEqual(cookies.get('c'), 'ã', 'should convert the character correctly'); | ||
cookies.remove('c', { | ||
path: '' | ||
}); | ||
}); | ||
test('when sucessfully deleted', function () { | ||
expect(1); | ||
Cookies.set('c', 'v'); | ||
strictEqual(Cookies.remove('c'), true, 'returns true'); | ||
QUnit.test('should be able to conditionally decode a single malformed cookie', function (assert) { | ||
assert.expect(4); | ||
var cookies = Cookies.withConverter(function (value, name) { | ||
if (name === 'escaped') { | ||
return unescape(value); | ||
} | ||
}); | ||
document.cookie = 'escaped=%u5317'; | ||
assert.strictEqual(cookies.get('escaped'), '北', 'should use a custom method for escaped cookie'); | ||
document.cookie = 'encoded=%E4%BA%AC'; | ||
assert.strictEqual(cookies.get('encoded'), '京', 'should use the default encoding for the rest'); | ||
assert.deepEqual(cookies.get(), { | ||
escaped: '北', | ||
encoded: '京' | ||
}, 'should retrieve everything'); | ||
Object.keys(cookies.get()).forEach(function (name) { | ||
cookies.remove(name, { | ||
path: '' | ||
}); | ||
}); | ||
assert.strictEqual(document.cookie, '', 'should remove everything'); | ||
}); | ||
test('when cookie does not exist', function () { | ||
expect(1); | ||
strictEqual(Cookies.remove('c'), true, 'returns true'); | ||
QUnit.module('JSON handling', lifecycle); | ||
QUnit.test('Number', function (assert) { | ||
assert.expect(2); | ||
Cookies.set('c', 1); | ||
assert.strictEqual(Cookies.getJSON('c'), 1, 'should handle a Number'); | ||
assert.strictEqual(Cookies.get('c'), '1', 'should return a String'); | ||
}); | ||
test('with options', function () { | ||
expect(1); | ||
var options = { path: '/' }; | ||
Cookies.set('c', 'v', options); | ||
Cookies.remove('c', options); | ||
strictEqual(document.cookie, '', 'should delete the cookie'); | ||
QUnit.test('Boolean', function (assert) { | ||
assert.expect(2); | ||
Cookies.set('c', true); | ||
assert.strictEqual(Cookies.getJSON('c'), true, 'should handle a Boolean'); | ||
assert.strictEqual(Cookies.get('c'), 'true', 'should return a Boolean'); | ||
}); | ||
test('passing options reference', function () { | ||
expect(1); | ||
var options = { path: '/' }; | ||
Cookies.set('c', 'v', options); | ||
Cookies.remove('c', options); | ||
deepEqual(options, { path: '/' }, "won't alter options object"); | ||
QUnit.test('Array Literal', function (assert) { | ||
assert.expect(2); | ||
Cookies.set('c', ['v']); | ||
assert.deepEqual(Cookies.getJSON('c'), ['v'], 'should handle Array Literal'); | ||
assert.strictEqual(Cookies.get('c'), '["v"]', 'should return a String'); | ||
}); | ||
test('[] used in name', function () { | ||
expect(1); | ||
Cookies.raw = true; | ||
document.cookie = 'c[1]=foo'; | ||
Cookies.remove('c[1]'); | ||
strictEqual(document.cookie, '', 'delete the cookie'); | ||
QUnit.test('Array Constructor', function (assert) { | ||
/*jshint -W009 */ | ||
assert.expect(2); | ||
var value = new Array(); | ||
value[0] = 'v'; | ||
Cookies.set('c', value); | ||
assert.deepEqual(Cookies.getJSON('c'), ['v'], 'should handle Array Constructor'); | ||
assert.strictEqual(Cookies.get('c'), '["v"]', 'should return a String'); | ||
}); | ||
QUnit.test('Object Literal', function (assert) { | ||
assert.expect(2); | ||
Cookies.set('c', {k: 'v'}); | ||
assert.deepEqual(Cookies.getJSON('c'), {k: 'v'}, 'should handle Object Literal'); | ||
assert.strictEqual(Cookies.get('c'), '{"k":"v"}', 'should return a String'); | ||
}); | ||
module('conversion', lifecycle); | ||
QUnit.test('Object Constructor', function (assert) { | ||
/*jshint -W010 */ | ||
assert.expect(2); | ||
var value = new Object(); | ||
value.k = 'v'; | ||
Cookies.set('c', value); | ||
assert.deepEqual(Cookies.getJSON('c'), {k: 'v'}, 'should handle Object Constructor'); | ||
assert.strictEqual(Cookies.get('c'), '{"k":"v"}', 'should return a String'); | ||
}); | ||
test('read converter', function() { | ||
expect(1); | ||
Cookies.set('c', '1'); | ||
strictEqual(Cookies.get('c', Number), 1, 'converts read value'); | ||
QUnit.test('Use String(value) for unsupported objects that do not stringify into JSON', function (assert) { | ||
assert.expect(2); | ||
Cookies.set('date', new Date(2015, 04, 13, 0, 0, 0, 0)); | ||
assert.strictEqual(Cookies.get('date').indexOf('"'), -1, 'should not quote the stringified Date object'); | ||
assert.strictEqual(Cookies.getJSON('date').indexOf('"'), -1, 'should not quote the stringified Date object'); | ||
}); | ||
test('read converter with raw = true', function() { | ||
expect(1); | ||
Cookies.raw = true; | ||
Cookies.set('c', '1'); | ||
strictEqual(Cookies.get('c', Number), 1, 'does not decode, but converts read value'); | ||
QUnit.test('Call to read all cookies with mixed json', function (assert) { | ||
Cookies.set('c', { foo: 'bar' }); | ||
Cookies.set('c2', 'v'); | ||
assert.deepEqual(Cookies.getJSON(), { c: { foo: 'bar' }, c2: 'v' }, 'returns JSON parsed cookies'); | ||
assert.deepEqual(Cookies.get(), { c: '{"foo":"bar"}', c2: 'v' }, 'returns unparsed cookies'); | ||
}); | ||
module('noConflict', lifecycle); | ||
QUnit.module('noConflict', lifecycle); | ||
test('do not conflict with existent globals', function() { | ||
expect(2); | ||
QUnit.test('do not conflict with existent globals', function (assert) { | ||
assert.expect(2); | ||
var Cookies = window.Cookies.noConflict(); | ||
Cookies.set('c', 'v'); | ||
strictEqual(Cookies.get('c'), 'v', 'should work correctly'); | ||
strictEqual(window.Cookies, 'existent global', 'should restore the original global'); | ||
assert.strictEqual(Cookies.get('c'), 'v', 'should work correctly'); | ||
assert.strictEqual(window.Cookies, 'existent global', 'should restore the original global'); | ||
window.Cookies = Cookies; | ||
}); | ||
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
69528
27
1333
254
2
1