pax_global_header00006660000000000000000000000064135222753060014517gustar00rootroot0000000000000052 comment=54962f884e9ae33f93e13ac903ffaf1d5a523598 js-cookie-2.2.1/000077500000000000000000000000001352227530600134045ustar00rootroot00000000000000js-cookie-2.2.1/.eslintignore000066400000000000000000000000231352227530600161020ustar00rootroot00000000000000build node_modules js-cookie-2.2.1/.eslintrc000066400000000000000000000017371352227530600152400ustar00rootroot00000000000000{ "env": { "commonjs": true }, "globals": { "Cookies": true }, "rules": { "curly": "error", "eqeqeq": "error", "no-unused-expressions": "error", "new-cap": "error", "no-caller": "error", "no-irregular-whitespace": "error", "no-undef": "error", "no-unused-vars": "error", "comma-style": ["error", "last"], "eol-last": "error", "semi": ["error", "always"], "keyword-spacing": ["error", {}], "spaced-comment": ["error", "always", {"exceptions": ["!"]}], "space-before-blocks": ["error", "always"], "key-spacing": ["error", {"afterColon": true}], "indent-legacy": ["error", "tab", {"SwitchCase": 1}], "linebreak-style": ["error", "unix"], "quotes": ["error", "single"], "array-bracket-spacing": ["error", "never", {}], "space-in-parens": ["error", "never"], "no-trailing-spaces": "error", "no-array-constructor": "error", "no-new-object": "error", "no-new-wrappers": "error" } } js-cookie-2.2.1/.gitignore000066400000000000000000000000521352227530600153710ustar00rootroot00000000000000node_modules build .sizecache.json *.log* js-cookie-2.2.1/.tm_properties000066400000000000000000000002451352227530600163020ustar00rootroot00000000000000softTabs = false tabSize = 2 [ text.plain ] softWrap = true wrapColumn = "Use Window Frame" softTabs = true tabSize = 4 [ "*.md" ] fileType = "text.plain" js-cookie-2.2.1/.travis.yml000066400000000000000000000013421352227530600155150ustar00rootroot00000000000000language: node_js node_js: - '6' - '8' - '10' cache: directories: - node_modules stages: - test - name: saucelabs if: fork IS false jobs: include: - stage: saucelabs node_js: '10' script: grunt saucelabs addons: sauce_connect: true env: # Encrypted SAUCE_USERNAME and SAUCE_ACCESS_KEY used by travis global: - secure: IkMOa/8r4sWyzUMxecsfqoPzZyIqVAMwPkQ6/HxXPbT8X7UnvqAdaicAMeHEKtOnOac+rx6pGB9HQvC8P/ZzkEBtsKLP4nEh9vsAInZvb3pXg+qbIgIK6/19X0kU4UkpDqVdWmBuFTamJvMDMstUTgEaM3869bB5vGp9taBgfVo= - secure: DKrQplF0CBiBh+cbQ8D7EKebCeklUWEELblIJdU4475Occ4G9b8ZFYO9HFwl1B8F/XapB7CsMyxbJCWor030FySeqn8bhJs9NoAVoYGg+MtWniv1EOHuZLWuOGfgQDv7qj5U0Af9Y655MmUpXSN2aDlCmQweWnYdpFTM9Dfsdd8= js-cookie-2.2.1/CONTRIBUTING.md000066400000000000000000000072461352227530600156460ustar00rootroot00000000000000## Issues - Report issues or feature requests on [GitHub Issues](https://github.com/js-cookie/js-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: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 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=`, where `` 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. ### Projects using it This hook is being used in the following projects: * [Java Cookie](https://github.com/js-cookie/java-cookie). js-cookie-2.2.1/Gruntfile.js000066400000000000000000000102431352227530600157010ustar00rootroot00000000000000/* eslint-env node */ 'use strict'; module.exports = function (grunt) { 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({ pkg: grunt.file.readJSON('package.json'), qunit: { all: { options: { urls: [ 'http://127.0.0.1:9998/', 'http://127.0.0.1:9998/amd.html', 'http://127.0.0.1:9998/environment-with-amd-and-umd.html', 'http://127.0.0.1:9998/encoding.html?integration_baseurl=http://127.0.0.1:9998/' ] } }, }, nodeunit: { all: 'test/node.js' }, eslint: { grunt: 'Gruntfile.js', source: 'src/**/*.js', tests: ['test/**/*.js', '!test/polyfill.js'] }, uglify: { options: { compress: { unsafe: true }, screwIE8: false, banner: '/*! <%= pkg.name %> v<%= pkg.version %> | <%= pkg.license %> */\n' }, build: { files: { 'build/js.cookie.min.js': 'src/js.cookie.js', 'build/js.cookie-<%= pkg.version %>.min.js': 'src/js.cookie.js' } } }, watch: { options: { livereload: true }, files: '{src,test}/**/*.js', tasks: 'default' }, compare_size: { files: [ 'build/js.cookie-<%= pkg.version %>.min.js', 'src/js.cookie.js' ], options: { compress: { gz: function (fileContents) { return require('gzip-js').zip(fileContents, {}).length; } } } }, connect: { 'build-qunit': { options: { port: 9998, base: ['.', 'test'], middleware: function (connect, options, middlewares) { middlewares.unshift(encodingMiddleware); return middlewares; } } }, 'build-sauce': { options: { port: 9999, base: ['.', 'test'] } }, tests: { options: { port: 10000, base: ['.', 'test'], open: 'http://127.0.0.1:10000', keepalive: true, livereload: true, middleware: function (connect, options, middlewares) { middlewares.unshift(encodingMiddleware); return middlewares; } } } }, 'saucelabs-qunit': { all: { options: { urls: ['http://127.0.0.1:9999'], testname: 'Sauce Test for js-cookie', build: process.env.TRAVIS_JOB_ID, statusCheckAttempts: -1, throttled: 3, browsers: [ { browserName: 'safari', platform: 'macOS 10.13', version: '12.0' }, { browserName: 'safari', platform: 'macOS 10.13', version: '11.1' }, { browserName: 'firefox', platform: 'macOS 10.13', version: '65.0' }, { browserName: 'chrome', platform: 'macOS 10.13', version: '72.0' }, { browserName: 'safari', platform: 'macOS 10.12', version: '11.0' }, { browserName: 'internet explorer', platform: 'Windows 10', version: '11.285' }, { 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: 'firefox', platform: 'Linux', version: '45.0' }, { browserName: 'chrome', platform: 'Linux', version: '48.0' } ] } } } }); // Loading dependencies for (var key in grunt.file.readJSON('package.json').devDependencies) { if (key !== 'grunt' && key.indexOf('grunt') === 0) { grunt.loadNpmTasks(key); } } grunt.registerTask('test', ['uglify', 'eslint', 'connect:build-qunit', 'qunit', 'nodeunit']); grunt.registerTask('saucelabs', ['uglify', 'connect:build-sauce', 'saucelabs-qunit']); grunt.registerTask('dev', ['test', 'compare_size']); grunt.registerTask('default', 'dev'); }; js-cookie-2.2.1/LICENSE000066400000000000000000000021361352227530600144130ustar00rootroot00000000000000MIT License Copyright (c) 2018 Copyright 2018 Klaus Hartl, Fagner Brack, GitHub Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 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. js-cookie-2.2.1/README.md000066400000000000000000000303751352227530600146730ustar00rootroot00000000000000

# 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) [![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/js-cookie/badge?style=rounded)](https://www.jsdelivr.com/package/npm/js-cookie) A simple, lightweight JavaScript API for handling cookies * Works in [all](https://saucelabs.com/u/js-cookie) browsers * Accepts [any](#encoding) character * [Heavily](test) tested * No dependency * [Unobtrusive](#json) JSON support * Supports AMD/CommonJS * [RFC 6265](https://tools.ietf.org/html/rfc6265) compliant * Useful [Wiki](https://github.com/js-cookie/js-cookie/wiki) * Enable [custom encoding/decoding](#converters) * **~900 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.](https://github.com/js-cookie/js-cookie/tree/latest#readme)** ## Build Status Matrix ([including active Pull Requests](https://github.com/js-cookie/js-cookie/issues/286)) [![Selenium Test Status](https://saucelabs.com/browser-matrix/js-cookie.svg)](https://saucelabs.com/u/js-cookie) ## Installation ### Direct download Download the script [here](https://github.com/js-cookie/js-cookie/blob/latest/src/js.cookie.js) and include it (unless you are packaging scripts somehow else): ```html ``` Or include it via [jsDelivr CDN](https://www.jsdelivr.com/package/npm/js-cookie): ```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. ### Package Managers JavaScript Cookie supports [npm](https://www.npmjs.com/package/js-cookie) and [Bower](http://bower.io/search/?q=js-cookie) under the name `js-cookie`. #### NPM ``` $ npm install js-cookie --save ``` ### Module Loaders JavaScript Cookie can also be loaded as an AMD or CommonJS module. ## Basic Usage Create a cookie, valid across the entire site: ```javascript Cookies.set('name', 'value'); ``` Create a cookie that expires 7 days from now, valid across the entire site: ```javascript Cookies.set('name', 'value', { expires: 7 }); ``` Create an expiring cookie, valid to the path of the current page: ```javascript Cookies.set('name', 'value', { expires: 7, path: '' }); ``` Read cookie: ```javascript Cookies.get('name'); // => 'value' Cookies.get('nothing'); // => undefined ``` Read all visible cookies: ```javascript Cookies.get(); // => { name: 'value' } ``` *Note: It is not possible to read a particular cookie by passing one of the cookie attributes (which may or may not have been used when writing the cookie in question):* ```javascript Cookies.get('foo', { domain: 'sub.example.com' }); // `domain` won't have any effect...! ``` The cookie with the name `foo` will only be available on `.get()` if it's visible from where the code is called; the domain and/or path attribute will not have an effect when reading. Delete cookie: ```javascript Cookies.remove('name'); ``` 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! ``` *IMPORTANT! When deleting a cookie and you're not relying on the [default attributes](#cookie-attributes), you must pass the exact same path and domain attributes that were used to set the cookie:* ```javascript Cookies.remove('name', { path: '', domain: '.yourdomain.com' }); ``` *Note: Removing a nonexistent cookie does not raise any exception nor return any value.* ## Namespace conflicts If there is any danger of a conflict with the namespace `Cookies`, the `noConflict` method will allow you to define a new namespace and preserve the original one. This is especially useful when running the script on third party sites e.g. as part of a widget or SDK. ```javascript // Assign the js-cookie api to a different variable and restore the original "window.Cookies" var Cookies2 = Cookies.noConflict(); Cookies2.set('name', 'value'); ``` *Note: The `.noConflict` method is not necessary when using AMD or CommonJS, thus it is not exposed in those environments.* ## JSON js-cookie provides unobtrusive JSON storage for cookies. 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.set('name', { foo: 'bar' }); ``` When reading a cookie with the default `Cookies.get` api, you receive the string representation stored in the cookie: ```javascript Cookies.get('name'); // => '{"foo":"bar"}' ``` ```javascript Cookies.get(); // => { name: '{"foo":"bar"}' } ``` 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`: ```javascript Cookies.getJSON('name'); // => { foo: 'bar' } ``` ```javascript Cookies.getJSON(); // => { name: { foo: 'bar' } } ``` *Note: To support IE6-7 ([and IE 8 compatibility mode](http://stackoverflow.com/questions/4715373/json-object-undefined-in-internet-explorer-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. Please note that the default encoding/decoding strategy is meant to be interoperable [only between cookies that are read/written by js-cookie](https://github.com/js-cookie/js-cookie/pull/200#discussion_r63270778). To override the default encoding/decoding strategy you need to use a [converter](#converters). *Note: According to [RFC 6265](https://tools.ietf.org/html/rfc6265#section-6.1), your cookies may get deleted if they are too big or there are too many cookies in the same domain, [more details here](https://github.com/js-cookie/js-cookie/wiki/Frequently-Asked-Questions#why-are-my-cookies-being-deleted).* ## 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 Define when the cookie will be removed. Value can be a [`Number`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number) which will be interpreted as days from time of creation or a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) instance. If omitted, the cookie becomes a session cookie. To create a cookie that expires in less than a day, you can check the [FAQ on the Wiki](https://github.com/js-cookie/js-cookie/wiki/Frequently-Asked-Questions#expire-cookies-in-less-than-a-day). **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 A [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) indicating the path where the cookie is visible. **Default:** `/` **Examples:** ```javascript Cookies.set('name', 'value', { path: '' }); Cookies.get('name'); // => 'value' Cookies.remove('name', { path: '' }); ``` **Note regarding Internet Explorer:** > Due to an obscure bug in the underlying WinINET InternetGetCookie implementation, IE’s document.cookie will not return a cookie if it was set with a path attribute containing a filename. (From [Internet Explorer Cookie Internals (FAQ)](http://blogs.msdn.com/b/ieinternals/archive/2009/08/20/wininet-ie-cookie-internals-faq.aspx)) This means one cannot set a path using `window.location.pathname` in case such pathname contains a filename like so: `/check.html` (or at least, such cookie cannot be read correctly). In fact, you should never allow untrusted input to set the cookie attributes or you might be exposed to a [XSS attack](https://github.com/js-cookie/js-cookie/issues/396). ### domain A [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) indicating a valid domain where the cookie should be visible. The cookie will also be visible to all subdomains. **Default:** Cookie is visible only to the domain or subdomain of the page where the cookie was created, except for Internet Explorer (see below). **Examples:** Assuming a cookie that is being created on `site.com`: ```javascript Cookies.set('name', 'value', { domain: 'subdomain.site.com' }); Cookies.get('name'); // => undefined (need to read at 'subdomain.site.com') ``` **Note regarding Internet Explorer default behavior:** > Q3: If I don’t specify a DOMAIN attribute (for) a cookie, IE sends it to all nested subdomains anyway? > A: Yes, a cookie set on example.com will be sent to sub2.sub1.example.com. > Internet Explorer differs from other browsers in this regard. (From [Internet Explorer Cookie Internals (FAQ)](http://blogs.msdn.com/b/ieinternals/archive/2009/08/20/wininet-ie-cookie-internals-faq.aspx)) This means that if you omit the `domain` attribute, it will be visible for a subdomain in IE. ### secure Either `true` or `false`, indicating if the cookie transmission requires a secure protocol (https). **Default:** No secure protocol requirement. **Examples:** ```javascript Cookies.set('name', 'value', { secure: true }); Cookies.get('name'); // => 'value' Cookies.remove('name'); ``` ## Converters ### Read Create a new instance of the api that overrides the default decoding implementation. All get methods that rely in a proper decoding to work, such as `Cookies.get()` and `Cookies.get('name')`, 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 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: '北' } ``` ### Write Create a new instance of the api that overrides the default encoding implementation: ```javascript Cookies.withConverter({ read: function (value, name) { // Read converter }, write: function (value, name) { // Write converter } }); ``` ## Server-side integration Check out the [Servers Docs](SERVER_SIDE.md) ## Contributing Check out the [Contributing Guidelines](CONTRIBUTING.md) ## Security For vulnerability reports, send an e-mail to `jscookieproject at gmail dot com` ## Manual release steps * Increment the "version" attribute of `package.json` * Increment the version number in the `src/js.cookie.js` file * If `major` bump, update jsDelivr CDN major version link on README * Commit with the message "Release version x.x.x" * Create version tag in git * Create a github release and upload the minified file * Change the `latest` tag pointer to the latest commit * `git tag -f latest` * `git push :refs/tags/latest` * `git push origin master --tags` * Release on npm ## Authors * [Klaus Hartl](https://github.com/carhartl) * [Fagner Brack](https://github.com/FagnerMartinsBrack) * And awesome [contributors](https://github.com/js-cookie/js-cookie/graphs/contributors) js-cookie-2.2.1/SERVER_SIDE.md000066400000000000000000000122731352227530600155450ustar00rootroot00000000000000# Server-side integration There are some servers that are not compliant with the [RFC 6265](http://tools.ietf.org/html/rfc6265). For those, some characters that are not encoded by JavaScript Cookie might be treated differently. Here we document the most important server-side peculiarities and their workarounds. Feel free to send a [Pull Request](https://github.com/js-cookie/js-cookie/blob/master/CONTRIBUTING.md#pull-requests) if you see something that can be improved. *Disclaimer: This documentation is entirely based on community provided information. The examples below should be used only as a reference.* ## PHP In PHP, `setcookie()` function encodes cookie values using `urlencode()` function, which applies `%`-encoding but also encodes spaces as `+` signs, [for historical reasons](http://php.net/manual/en/function.urlencode.php#function.urlencode). When cookies are read back via `$_COOKIE` or `filter_input(INPUT_COOKIE)`, they would go trough a decoding process which decodes `%`-encoded sequences and also converts `+` signs back to spaces. However, the plus (`+`) sign is valid cookie character by itself, which means that libraries that adhere to standards will interpret `+` signs differently to PHP. This presents two types of problems: 1. PHP writes a cookie via `setcookie()` and all spaces get converted to `+` signs. JavaScript Cookie read `+` signs and uses them literally, since it is a valid cookie character. 2. JavaScript Cookie writes a cookie with a value that contains `+` signs and stores it as is, since it is a valid cookie character. PHP read a cookie and converts `+` signs to spaces. To make both PHP and JavaScript Cookie play nicely together? **In PHP**, use `setrawcookie()` instead of `setcookie()`: ```php setrawcookie($name, rawurlencode($value)); ``` **In JavaScript**, use a custom converter. **Example**: ```javascript var PHPCookies = Cookies.withConverter({ write: function (value) { // Encode all characters according to the "encodeURIComponent" spec return encodeURIComponent(value) // Revert the characters that are unnecessarily encoded but are // allowed in a cookie value, except for the plus sign (%2B) .replace(/%(23|24|26|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); }, read: function (value) { return value // Decode the plus sign to spaces first, otherwise "legit" encoded pluses // will be replaced incorrectly .replace(/\+/g, ' ') // Decode all characters according to the "encodeURIComponent" spec .replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent); } }); ``` Rack seems to have [a similar problem](https://github.com/js-cookie/js-cookie/issues/70#issuecomment-132503017). ## Tomcat ### Version >= 7.x It seems that there is a situation where Tomcat does not [read the parens correctly](https://github.com/js-cookie/js-cookie/issues/92#issue-107743407). To fix this you need to write a custom write converter. **Example**: ```javascript var TomcatCookies = Cookies.withConverter({ write: function (value) { // Encode all characters according to the "encodeURIComponent" spec return encodeURIComponent(value) // Revert the characters that are unnecessarily encoded but are // allowed in a cookie value .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent) // Encode the parens that are interpreted incorrectly by Tomcat .replace(/[\(\)]/g, escape); } }); ``` ### Version >= 8.0.15 Since Tomcat 8.0.15, it is possible to configure RFC 6265 compliance by changing your `conf/context.xml` file and adding the new [CookieProcessor](https://tomcat.apache.org/tomcat-8.0-doc/config/cookie-processor.html) nested inside the Context element. It would be like this: ```xml ``` And you're all done. Alternatively, you can check the [Java Cookie](https://github.com/js-cookie/java-cookie) project, which integrates nicely with JavaScript Cookie. ## JBoss 7.1.1 It seems that the servlet implementation of JBoss 7.1.1 [does not read some characters correctly](https://github.com/js-cookie/js-cookie/issues/70#issuecomment-148944674), even though they are allowed as per [RFC 6265](https://tools.ietf.org/html/rfc6265#section-4.1.1). To fix this you need to write a custom converter to send those characters correctly. **Example**: ```javascript var JBossCookies = Cookies.withConverter({ write: function (value) { // Encode all characters according to the "encodeURIComponent" spec return encodeURIComponent(value) // Revert the characters that are unnecessarily encoded but are // allowed in a cookie value .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent) // Encode again the characters that are not allowed in JBoss 7.1.1, like "[" and "]": .replace(/[\[\]]/g, encodeURIComponent); } }); ``` Alternatively, you can check the [Java Cookie](https://github.com/js-cookie/java-cookie) project, which integrates nicely with JavaScript Cookie. js-cookie-2.2.1/bower.json000066400000000000000000000004001352227530600154070ustar00rootroot00000000000000{ "name": "js-cookie", "license": "MIT", "main": [ "src/js.cookie.js" ], "ignore": [ "test", "Gruntfile.js", "package.json", ".gitignore", ".eslintintignore", ".eslintrc", ".tm_properties", ".travis.yml" ] } js-cookie-2.2.1/package.json000066400000000000000000000017671352227530600157050ustar00rootroot00000000000000{ "name": "js-cookie", "version": "2.2.1", "description": "A simple, lightweight JavaScript API for handling cookies", "main": "src/js.cookie.js", "directories": { "test": "test" }, "keywords": [ "cookie", "cookies", "browser", "amd", "commonjs", "client", "js-cookie", "browserify" ], "scripts": { "test": "grunt test" }, "repository": { "type": "git", "url": "git://github.com/js-cookie/js-cookie.git" }, "files": [ "src/**/*.js", "SERVER_SIDE.md", "CONTRIBUTING.md" ], "author": "Klaus Hartl", "license": "MIT", "devDependencies": { "grunt": "1.0.3", "grunt-compare-size": "0.4.2", "grunt-contrib-connect": "2.0.0", "grunt-contrib-nodeunit": "2.0.0", "grunt-contrib-qunit": "2.0.0", "grunt-contrib-uglify": "2.3.0", "grunt-contrib-watch": "1.1.0", "grunt-eslint": "21.0.0", "grunt-saucelabs": "9.0.0", "gzip-js": "0.3.2", "qunitjs": "1.23.1", "requirejs": "2.3.5" } } js-cookie-2.2.1/src/000077500000000000000000000000001352227530600141735ustar00rootroot00000000000000js-cookie-2.2.1/src/.eslintrc000066400000000000000000000002001352227530600160070ustar00rootroot00000000000000{ "extends": "../.eslintrc", "env": { "browser": true, "amd": true }, "rules": { "camelcase": "error" } } js-cookie-2.2.1/src/js.cookie.js000066400000000000000000000074531352227530600164260ustar00rootroot00000000000000/*! * JavaScript Cookie v2.2.1 * https://github.com/js-cookie/js-cookie * * Copyright 2006, 2015 Klaus Hartl & Fagner Brack * Released under the MIT license */ ;(function (factory) { var registeredInModuleLoader; if (typeof define === 'function' && define.amd) { define(factory); registeredInModuleLoader = true; } if (typeof exports === 'object') { module.exports = factory(); registeredInModuleLoader = true; } if (!registeredInModuleLoader) { var OldCookies = window.Cookies; var api = window.Cookies = factory(); api.noConflict = function () { window.Cookies = OldCookies; return api; }; } }(function () { function extend () { var i = 0; var result = {}; for (; i < arguments.length; i++) { var attributes = arguments[ i ]; for (var key in attributes) { result[key] = attributes[key]; } } return result; } function decode (s) { return s.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent); } function init (converter) { function api() {} function set (key, value, attributes) { if (typeof document === 'undefined') { return; } attributes = extend({ path: '/' }, api.defaults, attributes); if (typeof attributes.expires === 'number') { attributes.expires = new Date(new Date() * 1 + attributes.expires * 864e+5); } // We're using "expires" because "max-age" is not supported by IE attributes.expires = attributes.expires ? attributes.expires.toUTCString() : ''; try { var result = JSON.stringify(value); if (/^[\{\[]/.test(result)) { value = result; } } catch (e) {} value = converter.write ? converter.write(value, key) : encodeURIComponent(String(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)) .replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent) .replace(/[\(\)]/g, escape); var stringifiedAttributes = ''; for (var attributeName in attributes) { if (!attributes[attributeName]) { continue; } stringifiedAttributes += '; ' + attributeName; if (attributes[attributeName] === true) { continue; } // Considers RFC 6265 section 5.2: // ... // 3. If the remaining unparsed-attributes contains a %x3B (";") // character: // Consume the characters of the unparsed-attributes up to, // not including, the first %x3B (";") character. // ... stringifiedAttributes += '=' + attributes[attributeName].split(';')[0]; } return (document.cookie = key + '=' + value + stringifiedAttributes); } function get (key, json) { if (typeof document === 'undefined') { return; } var jar = {}; // To prevent the for loop in the first place assign an empty array // in case there are no cookies at all. var cookies = document.cookie ? document.cookie.split('; ') : []; var i = 0; for (; i < cookies.length; i++) { var parts = cookies[i].split('='); var cookie = parts.slice(1).join('='); if (!json && cookie.charAt(0) === '"') { cookie = cookie.slice(1, -1); } try { var name = decode(parts[0]); cookie = (converter.read || converter)(cookie, name) || decode(cookie); if (json) { try { cookie = JSON.parse(cookie); } catch (e) {} } jar[name] = cookie; if (key === name) { break; } } catch (e) {} } return key ? jar[key] : jar; } api.set = set; api.get = function (key) { return get(key, false /* read as raw */); }; api.getJSON = function (key) { return get(key, true /* read as json */); }; api.remove = function (key, attributes) { set(key, '', extend(attributes, { expires: -1 })); }; api.defaults = {}; api.withConverter = init; return api; } return init(function () {}); })); js-cookie-2.2.1/test/000077500000000000000000000000001352227530600143635ustar00rootroot00000000000000js-cookie-2.2.1/test/.eslintrc000066400000000000000000000004221352227530600162050ustar00rootroot00000000000000{ "extends": "../.eslintrc", "env": { "browser": true, "qunit": true }, "globals": { "require": true, "unescape": true, "lifecycle": true, "using": true, "quoted": true, "addEvent": true, "loadFileSync": true }, "rules": {} } js-cookie-2.2.1/test/amd-config.js000066400000000000000000000001771352227530600167320ustar00rootroot00000000000000/* eslint-disable no-unused-vars */ var require = { paths: { 'qunit': [ '../node_modules/qunitjs/qunit/qunit' ] } }; js-cookie-2.2.1/test/amd.html000066400000000000000000000006311352227530600160120ustar00rootroot00000000000000 JavaScript Cookie Test Suite - AMD
js-cookie-2.2.1/test/amd.js000066400000000000000000000004651352227530600154670ustar00rootroot00000000000000require(['qunit'], function (QUnit) { QUnit.module('amd'); QUnit.start(); QUnit.test('module loading', function (assert) { assert.expect(1); var done = assert.async(); require(['/src/js.cookie.js'], function (Cookies) { assert.ok(!!Cookies.get, 'should load the api'); done(); }); }); }); js-cookie-2.2.1/test/encoding.html000066400000000000000000000007721352227530600170450ustar00rootroot00000000000000 JavaScript Cookie Test Suite - Encoding
js-cookie-2.2.1/test/encoding.js000066400000000000000000000544041352227530600165160ustar00rootroot00000000000000QUnit.module('cookie-value', lifecycle); QUnit.test('cookie-value with double quotes', function (assert) { assert.expect(1); using(assert) .setCookie('c', '"') .then(function (decodedValue) { assert.strictEqual(decodedValue, '"', 'should print the quote character'); }); }); QUnit.test('cookie-value with double quotes in the left', function (assert) { assert.expect(1); using(assert) .setCookie('c', '"content') .then(function (decodedValue) { assert.strictEqual(decodedValue, '"content', 'should print the quote character'); }); }); QUnit.test('cookie-value with double quotes in the right', function (assert) { assert.expect(1); using(assert) .setCookie('c', 'content"') .then(function (decodedValue) { assert.strictEqual(decodedValue, 'content"', 'should print the quote character'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-value " "', function (assert) { assert.expect(2); using(assert) .setCookie('c', ' ') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, ' ', 'should handle the whitespace character'); assert.strictEqual(plainValue, 'c=%20', 'whitespace is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-value ","', function (assert) { assert.expect(2); using(assert) .setCookie('c', ',') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, ',', 'should handle the comma character'); assert.strictEqual(plainValue, 'c=%2C', 'comma is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-value ";"', function (assert) { assert.expect(2); using(assert) .setCookie('c', ';') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, ';', 'should handle the semicolon character'); assert.strictEqual(plainValue, 'c=%3B', 'semicolon is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-value "\\"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '\\') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '\\', 'should handle the backslash character'); assert.strictEqual(plainValue, 'c=%5C', 'backslash is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - characters not allowed in the cookie-value should be replaced globally', function (assert) { assert.expect(2); using(assert) .setCookie('c', ';;') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, ';;', 'should handle multiple not allowed characters'); assert.strictEqual(plainValue, 'c=%3B%3B', 'should replace multiple not allowed characters'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "#"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '#') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '#', 'should handle the sharp character'); assert.strictEqual(plainValue, 'c=#', 'sharp is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "$"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '$') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '$', 'should handle the dollar sign character'); assert.strictEqual(plainValue, 'c=$', 'dollar sign is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "%"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '%') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '%', 'should handle the percent character'); assert.strictEqual(plainValue, 'c=%25', 'percent is allowed, but need to be escaped'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "&"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '&') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '&', 'should handle the ampersand character'); assert.strictEqual(plainValue, 'c=&', 'ampersand is allowed, should not encode'); }); }); // github.com/carhartl/jquery-cookie/pull/62 QUnit.test('RFC 6265 - character allowed in the cookie-value "+"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '+') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '+', 'should handle the plus character'); assert.strictEqual(plainValue, 'c=+', 'plus is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value ":"', function (assert) { assert.expect(2); using(assert) .setCookie('c', ':') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, ':', 'should handle the colon character'); assert.strictEqual(plainValue, 'c=:', 'colon is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "<"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '<') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '<', 'should handle the less-than character'); assert.strictEqual(plainValue, 'c=<', 'less-than is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value ">"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '>') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '>', 'should handle the greater-than character'); assert.strictEqual(plainValue, 'c=>', 'greater-than is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "="', function (assert) { assert.expect(2); using(assert) .setCookie('c', '=') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '=', 'should handle the equal sign character'); assert.strictEqual(plainValue, 'c==', 'equal sign is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "/"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '/') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '/', 'should handle the slash character'); assert.strictEqual(plainValue, 'c=/', 'slash is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "?"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '?') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '?', 'should handle the question mark character'); assert.strictEqual(plainValue, 'c=?', 'question mark is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "@"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '@') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '@', 'should handle the at character'); assert.strictEqual(plainValue, 'c=@', 'at is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "["', function (assert) { assert.expect(2); using(assert) .setCookie('c', '[') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '[', 'should handle the opening square bracket character'); assert.strictEqual(plainValue, 'c=[', 'opening square bracket is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "]"', function (assert) { assert.expect(2); using(assert) .setCookie('c', ']') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, ']', 'should handle the closing square bracket character'); assert.strictEqual(plainValue, 'c=]', 'closing square bracket is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "^"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '^') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '^', 'should handle the caret character'); assert.strictEqual(plainValue, 'c=^', 'caret is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "`"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '`') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '`', 'should handle the grave accent character'); assert.strictEqual(plainValue, 'c=`', 'grave accent is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "{"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '{') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '{', 'should handle the opening curly bracket character'); assert.strictEqual(plainValue, 'c={', 'opening curly bracket is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "}"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '}') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '}', 'should handle the closing curly bracket character'); assert.strictEqual(plainValue, 'c=}', 'closing curly bracket is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-value "|"', function (assert) { assert.expect(2); using(assert) .setCookie('c', '|') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '|', 'should handle the pipe character'); assert.strictEqual(plainValue, 'c=|', 'pipe is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - characters allowed in the cookie-value should globally not be encoded', function (assert) { assert.expect(1); using(assert) .setCookie('c', '{{') .then(function (decodedValue, plainValue) { assert.strictEqual(plainValue, 'c={{', 'should not encode all the character occurrences'); }); }); QUnit.test('cookie-value - 2 bytes character (ã)', function (assert) { assert.expect(2); using(assert) .setCookie('c', 'ã') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'ã', 'should handle the ã character'); assert.strictEqual(plainValue, 'c=%C3%A3', 'should encode the ã character'); }); }); QUnit.test('cookie-value - 3 bytes character (₯)', function (assert) { assert.expect(2); using(assert) .setCookie('c', '₯') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '₯', 'should handle the ₯ character'); assert.strictEqual(plainValue, 'c=%E2%82%AF', 'should encode the ₯ character'); }); }); QUnit.test('cookie-value - 4 bytes character (𩸽)', function (assert) { assert.expect(2); using(assert) .setCookie('c', '𩸽') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, '𩸽', 'should handle the 𩸽 character'); assert.strictEqual(plainValue, 'c=%F0%A9%B8%BD', 'should encode the 𩸽 character'); }); }); QUnit.module('cookie-name', lifecycle); QUnit.test('RFC 6265 - character not allowed in the cookie-name "("', function (assert) { assert.expect(2); using(assert) .setCookie('(', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the opening parens character'); assert.strictEqual(plainValue, '%28=v', 'opening parens is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name ")"', function (assert) { assert.expect(2); using(assert) .setCookie(')', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the closing parens character'); assert.strictEqual(plainValue, '%29=v', 'closing parens is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - should replace parens globally', function (assert) { assert.expect(1); using(assert) .setCookie('(())', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(plainValue, '%28%28%29%29=v', 'encode with global replace'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "<"', function (assert) { assert.expect(2); using(assert) .setCookie('<', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the less-than character'); assert.strictEqual(plainValue, '%3C=v', 'less-than is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name ">"', function (assert) { assert.expect(2); using(assert) .setCookie('>', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the greater-than character'); assert.strictEqual(plainValue, '%3E=v', 'greater-than is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "@"', function (assert) { assert.expect(2); using(assert) .setCookie('@', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the at character'); assert.strictEqual(plainValue, '%40=v', 'at is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name ","', function (assert) { assert.expect(2); using(assert) .setCookie(',', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the comma character'); assert.strictEqual(plainValue, '%2C=v', 'comma is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name ";"', function (assert) { assert.expect(2); using(assert) .setCookie(';', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the semicolon character'); assert.strictEqual(plainValue, '%3B=v', 'semicolon is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name ":"', function (assert) { assert.expect(2); using(assert) .setCookie(':', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the colon character'); assert.strictEqual(plainValue, '%3A=v', 'colon is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "\\"', function (assert) { assert.expect(2); using(assert) .setCookie('\\', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the backslash character'); assert.strictEqual(plainValue, '%5C=v', 'backslash is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "\""', function (assert) { assert.expect(2); using(assert) .setCookie('"', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the double quote character'); assert.strictEqual(plainValue, '%22=v', 'double quote is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "/"', function (assert) { assert.expect(2); using(assert) .setCookie('/', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the slash character'); assert.strictEqual(plainValue, '%2F=v', 'slash is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "["', function (assert) { assert.expect(2); using(assert) .setCookie('[', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the opening square brackets character'); assert.strictEqual(plainValue, '%5B=v', 'opening square brackets is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "]"', function (assert) { assert.expect(2); using(assert) .setCookie(']', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the closing square brackets character'); assert.strictEqual(plainValue, '%5D=v', 'closing square brackets is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "?"', function (assert) { assert.expect(2); using(assert) .setCookie('?', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the question mark character'); assert.strictEqual(plainValue, '%3F=v', 'question mark is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "="', function (assert) { assert.expect(2); using(assert) .setCookie('=', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the equal sign character'); assert.strictEqual(plainValue, '%3D=v', 'equal sign is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "{"', function (assert) { assert.expect(2); using(assert) .setCookie('{', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the opening curly brackets character'); assert.strictEqual(plainValue, '%7B=v', 'opening curly brackets is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "}"', function (assert) { assert.expect(2); using(assert) .setCookie('}', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the closing curly brackets character'); assert.strictEqual(plainValue, '%7D=v', 'closing curly brackets is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name "\\t"', function (assert) { assert.expect(2); using(assert) .setCookie(' ', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the horizontal tab character'); assert.strictEqual(plainValue, '%09=v', 'horizontal tab is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character not allowed in the cookie-name " "', function (assert) { assert.expect(2); using(assert) .setCookie(' ', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the whitespace character'); assert.strictEqual(plainValue, '%20=v', 'whitespace is not allowed, need to encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-name "#"', function (assert) { assert.expect(2); using(assert) .setCookie('#', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the sharp character'); assert.strictEqual(plainValue, '#=v', 'sharp is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-name "$"', function (assert) { assert.expect(2); using(assert) .setCookie('$', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the dollar sign character'); assert.strictEqual(plainValue, '$=v', 'dollar sign is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in cookie-name "%"', function (assert) { assert.expect(2); using(assert) .setCookie('%', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the percent character'); assert.strictEqual(plainValue, '%25=v', 'percent is allowed, but need to be escaped'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-name "&"', function (assert) { assert.expect(2); using(assert) .setCookie('&', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the ampersand character'); assert.strictEqual(plainValue, '&=v', 'ampersand is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-name "+"', function (assert) { assert.expect(2); using(assert) .setCookie('+', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the plus character'); assert.strictEqual(plainValue, '+=v', 'plus is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-name "^"', function (assert) { assert.expect(2); using(assert) .setCookie('^', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the caret character'); assert.strictEqual(plainValue, '^=v', 'caret is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-name "`"', function (assert) { assert.expect(2); using(assert) .setCookie('`', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the grave accent character'); assert.strictEqual(plainValue, '`=v', 'grave accent is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - character allowed in the cookie-name "|"', function (assert) { assert.expect(2); using(assert) .setCookie('|', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the pipe character'); assert.strictEqual(plainValue, '|=v', 'pipe is allowed, should not encode'); }); }); QUnit.test('RFC 6265 - characters allowed in the cookie-name should globally not be encoded', function (assert) { assert.expect(1); using(assert) .setCookie('||', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(plainValue, '||=v', 'should not encode all character occurrences'); }); }); QUnit.test('cookie-name - 2 bytes characters', function (assert) { assert.expect(2); using(assert) .setCookie('ã', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the ã character'); assert.strictEqual(plainValue, '%C3%A3=v', 'should encode the ã character'); }); }); QUnit.test('cookie-name - 3 bytes characters', function (assert) { assert.expect(2); using(assert) .setCookie('₯', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should handle the ₯ character'); assert.strictEqual(plainValue, '%E2%82%AF=v', 'should encode the ₯ character'); }); }); QUnit.test('cookie-name - 4 bytes characters', function (assert) { assert.expect(2); using(assert) .setCookie('𩸽', 'v') .then(function (decodedValue, plainValue) { assert.strictEqual(decodedValue, 'v', 'should_handle the 𩸽 character'); assert.strictEqual(plainValue, '%F0%A9%B8%BD=v', 'should encode the 𩸽 character'); }); }); js-cookie-2.2.1/test/environment-with-amd-and-umd.html000066400000000000000000000007131352227530600226510ustar00rootroot00000000000000 JavaScript Cookie Test Suite - Environment with AMD and UMD
js-cookie-2.2.1/test/environment-with-amd-and-umd.js000066400000000000000000000013441352227530600223220ustar00rootroot00000000000000require(['qunit'], function (QUnit) { QUnit.start(); QUnit.module('Environment with AMD and UMD', { beforeEach: function () { window.exports = {}; window.module = { exports: window.exports }; }, afterEach: function () { delete window.module; } }); QUnit.test('js-cookie need to register itself in AMD and UMD', function (assert) { assert.expect(2); var done = assert.async(); require(['/src/js.cookie.js'], function () { var actual = typeof window.module.exports; var expected = 'function'; assert.strictEqual(actual, expected, 'should register a function in module.exports'); assert.notOk(!!window.Cookies, 'should not register globally in AMD/UMD environments'); done(); }); }); }); js-cookie-2.2.1/test/index.html000066400000000000000000000010331352227530600163550ustar00rootroot00000000000000 JavaScript Cookie Test Suite
js-cookie-2.2.1/test/malformed_cookie.html000066400000000000000000000005541352227530600205540ustar00rootroot00000000000000 js-cookie-2.2.1/test/missing_semicolon.html000066400000000000000000000013061352227530600207720ustar00rootroot00000000000000 js-cookie-2.2.1/test/node.js000066400000000000000000000015001352227530600156420ustar00rootroot00000000000000/* eslint-env node */ exports.node = { should_load_js_cookie: function (test) { test.expect(1); var Cookies = require('../src/js.cookie'); test.ok(!!Cookies.get, 'should load the Cookies API'); test.done(); }, should_not_throw_error_for_set_call_in_node: function (test) { test.expect(0); var Cookies = require('../src/js.cookie'); Cookies.set('anything'); Cookies.set('anything', { path: '' }); test.done(); }, should_not_throw_error_for_get_call_in_node: function (test) { test.expect(0); var Cookies = require('../src/js.cookie'); Cookies.get('anything'); test.done(); }, should_not_throw_error_for_remove_call_in_node: function (test) { test.expect(0); var Cookies = require('../src/js.cookie'); Cookies.remove('anything'); Cookies.remove('anything', { path: '' }); test.done(); } }; js-cookie-2.2.1/test/polyfill.js000066400000000000000000000101111352227530600165450ustar00rootroot00000000000000// 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}}()); // 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++}}); // 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")})}();js-cookie-2.2.1/test/tests.js000066400000000000000000000430111352227530600160620ustar00rootroot00000000000000'use strict'; /* global lifecycle: true */ QUnit.module('read', lifecycle); QUnit.test('simple value', function (assert) { assert.expect(1); document.cookie = 'c=v'; assert.strictEqual(Cookies.get('c'), 'v', 'should return value'); }); 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', ''); assert.strictEqual(Cookies.get('c'), '', 'should return value'); }); QUnit.test('not existing', function (assert) { assert.expect(1); assert.strictEqual(Cookies.get('whatever'), undefined, 'return undefined'); }); // github.com/carhartl/jquery-cookie/issues/50 QUnit.test('equality sign in cookie value', function (assert) { assert.expect(1); Cookies.set('c', 'foo=bar'); assert.strictEqual(Cookies.get('c'), 'foo=bar', 'should include the entire value'); }); // 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'); }); 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'); }); // 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'); iframe.src = 'malformed_cookie.html'; addEvent(iframe, 'load', function () { if (iframe.contentWindow.ok) { assert.strictEqual(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+. assert.ok(true, 'N/A'); } done(); }); document.body.appendChild(iframe); }); // github.com/js-cookie/js-cookie/pull/171 QUnit.test('missing leading semicolon', 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 loadedSuccessfully = true; iframe.src = 'missing_semicolon.html'; addEvent(iframe, 'load', function () { iframe.contentWindow.onerror = function () { loadedSuccessfully = false; }; assert.strictEqual(loadedSuccessfully, true, 'can\'t throw Object is not a function error'); done(); }); document.body.appendChild(iframe); }); QUnit.test('Call to read all when there are cookies', function (assert) { Cookies.set('c', 'v'); Cookies.set('foo', 'bar'); assert.deepEqual(Cookies.get(), { c: 'v', foo: 'bar' }, 'returns object containing all cookies'); }); QUnit.test('Call to read all when there are no cookies at all', function (assert) { assert.deepEqual(Cookies.get(), {}, 'returns empty object'); }); 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'); }); // github.com/js-cookie/js-cookie/issues/196 QUnit.test('Call to read cookie when there is another unrelated cookie with malformed encoding in the name', function (assert) { assert.expect(2); document.cookie = 'BS%BS=1'; document.cookie = 'c=v'; assert.strictEqual(Cookies.get('c'), 'v', 'should not throw a URI malformed exception when retrieving a single cookie'); assert.deepEqual(Cookies.get(), { c: 'v' }, 'should not throw a URI malformed exception when retrieving all cookies'); document.cookie = 'BS%BS=1; expires=Thu, 01 Jan 1970 00:00:00 GMT'; }); // github.com/js-cookie/js-cookie/pull/62 QUnit.test('Call to read cookie when there is another unrelated cookie with malformed encoding in the value', function (assert) { assert.expect(2); document.cookie = 'invalid=%A1'; document.cookie = 'c=v'; assert.strictEqual(Cookies.get('c'), 'v', 'should not throw a URI malformed exception when retrieving a single cookie'); assert.deepEqual(Cookies.get(), { c: 'v' }, 'should not throw a URI malformed exception when retrieving all cookies'); Cookies.withConverter(unescape).remove('invalid'); }); // github.com/js-cookie/js-cookie/issues/145 QUnit.test('Call to read cookie when passing an Object Literal as the second argument', function (assert) { assert.expect(1); Cookies.get('name', { path: '' }); assert.strictEqual(document.cookie, '', 'should not create a cookie'); }); // github.com/js-cookie/js-cookie/issues/238 QUnit.test('Call to read cookie when there is a window.json variable globally', function (assert) { assert.expect(1); window.json = true; Cookies.set('boolean', true); assert.strictEqual(typeof Cookies.get('boolean'), 'string', 'should not change the returned type'); // IE 6-8 throw an exception if trying to delete a window property // See stackoverflow.com/questions/1073414/deleting-a-window-property-in-ie/1824228 try { delete window.json; } catch (e) {} }); QUnit.module('write', lifecycle); QUnit.test('String primitive', function (assert) { assert.expect(1); Cookies.set('c', 'v'); assert.strictEqual(Cookies.get('c'), 'v', 'should write value'); }); QUnit.test('String object', function (assert) { /* eslint-disable no-new-wrappers */ assert.expect(1); Cookies.set('c', new String('v')); assert.strictEqual(Cookies.get('c'), 'v', 'should write value'); }); QUnit.test('value "[object Object]"', function (assert) { assert.expect(1); Cookies.set('c', '[object Object]'); assert.strictEqual(Cookies.get('c'), '[object Object]', 'should write value'); }); QUnit.test('number', function (assert) { assert.expect(1); Cookies.set('c', 1234); assert.strictEqual(Cookies.get('c'), '1234', 'should write value'); }); QUnit.test('null', function (assert) { assert.expect(1); Cookies.set('c', null); assert.strictEqual(Cookies.get('c'), 'null', 'should write value'); }); QUnit.test('undefined', function (assert) { assert.expect(1); Cookies.set('c', undefined); assert.strictEqual(Cookies.get('c'), 'undefined', 'should write value'); }); QUnit.test('expires option as days from now', function (assert) { assert.expect(1); var days = 200; var expires = new Date(new Date().valueOf() + days * 24 * 60 * 60 * 1000); var expected = 'expires=' + expires.toUTCString(); var actual = Cookies.set('c', 'v', { expires: days }); assert.ok(actual.indexOf(expected) !== -1, quoted(actual) + ' includes ' + quoted(expected)); }); // github.com/carhartl/jquery-cookie/issues/246 QUnit.test('expires option as fraction of a day', function (assert) { assert.expect(1); var findValueForAttributeName = function (createdCookie, attributeName) { var pairs = createdCookie.split('; '); var foundAttributeValue; pairs.forEach(function (pair) { if (pair.split('=')[0] === attributeName) { foundAttributeValue = pair.split('=')[1]; } }); return foundAttributeValue; }; var now = new Date(); var stringifiedDate = findValueForAttributeName(Cookies.set('c', 'v', { expires: 0.5 }), 'expires'); var expires = new Date(stringifiedDate); // When we were using Date.setDate() fractions have been ignored // and expires resulted in the current date. Allow 1000 milliseconds // difference for execution time because new Date() can be different, // even when it's run synchronously. // See https://github.com/js-cookie/js-cookie/commit/ecb597b65e4c477baa2b30a2a5a67fdaee9870ea#commitcomment-20146048. var assertion = expires.getTime() > now.getTime() + 1000; var message = quoted(expires.getTime()) + ' should be greater than ' + quoted(now.getTime()); assert.ok(assertion, message); }); QUnit.test('expires option as Date instance', function (assert) { assert.expect(1); var sevenDaysFromNow = new Date(); sevenDaysFromNow.setDate(sevenDaysFromNow.getDate() + 7); var expected = 'expires=' + sevenDaysFromNow.toUTCString(); var actual = Cookies.set('c', 'v', { expires: sevenDaysFromNow }); assert.ok(actual.indexOf(expected) !== -1, quoted(actual) + ' includes ' + quoted(expected)); }); 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'); }); 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'; 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'); }); QUnit.test('true secure value', function (assert) { assert.expect(1); var expected = 'c=v; path=/; secure'; var actual = Cookies.set('c', 'v', {secure: true}); assert.strictEqual(actual, expected, 'should add secure attribute'); }); // github.com/js-cookie/js-cookie/pull/54 QUnit.test('false secure value', function (assert) { assert.expect(1); var expected = 'c=v; path=/'; var actual = Cookies.set('c', 'v', {secure: false}); assert.strictEqual(actual, expected, 'false should not modify path in cookie string'); }); // github.com/js-cookie/js-cookie/issues/276 QUnit.test('unofficial attribute', function (assert) { assert.expect(1); var expected = 'c=v; path=/; unofficial=anything'; var actual = Cookies.set('c', 'v', { unofficial: 'anything' }); assert.strictEqual(expected, actual, 'should write the cookie string with unofficial attribute'); }); QUnit.test('undefined attribute value', function (assert) { assert.expect(5); assert.strictEqual(Cookies.set('c', 'v', { expires: undefined }), 'c=v; path=/', 'should not write undefined expires attribute'); assert.strictEqual(Cookies.set('c', 'v', { path: undefined }), 'c=v', 'should not write undefined path attribute'); assert.strictEqual(Cookies.set('c', 'v', { domain: undefined }), 'c=v; path=/', 'should not write undefined domain attribute'); assert.strictEqual(Cookies.set('c', 'v', { secure: undefined }), 'c=v; path=/', 'should not write undefined secure attribute'); assert.strictEqual(Cookies.set('c', 'v', { unofficial: undefined }), 'c=v; path=/', 'should not write undefined unofficial attribute'); }); // github.com/js-cookie/js-cookie/issues/396 QUnit.test('sanitization of attributes to prevent XSS from untrusted input', function (assert) { assert.expect(1); assert.strictEqual(Cookies.set('c', 'v', { path: '/;domain=sub.domain.com', domain: 'site.com;remove_this', customAttribute: 'value;;remove_this' }), 'c=v; path=/; domain=site.com; customAttribute=value', 'should not allow semicolon in a cookie attribute'); }); 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'); }); 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'); }); 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); // 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'); }); 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: '' }); }); 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'); }); // github.com/js-cookie/js-cookie/issues/70 QUnit.test('should be able to create a write decoder', function (assert) { assert.expect(1); Cookies.withConverter({ write: function (value) { return value.replace('+', '%2B'); } }).set('c', '+'); assert.strictEqual(document.cookie, 'c=%2B', 'should call the write converter'); }); QUnit.test('should be able to use read and write decoder', function (assert) { assert.expect(1); document.cookie = 'c=%2B'; var cookies = Cookies.withConverter({ read: function (value) { return value.replace('%2B', '+'); } }); assert.strictEqual(cookies.get('c'), '+', 'should call the read converter'); }); 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'); }); 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'); }); 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'); }); QUnit.test('Array Constructor', function (assert) { /* eslint-disable no-array-constructor */ 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'); }); QUnit.test('Object Constructor', function (assert) { /* eslint-disable no-new-object */ 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'); }); 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, 4, 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'); }); 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'); }); QUnit.test('Cookies with escaped quotes in json using raw converters', function (assert) { Cookies.withConverter({ read: function (value) { return value; }, write: function (value) { return value; } }).set('c', '"{ \\"foo\\": \\"bar\\" }"'); assert.strictEqual(Cookies.getJSON('c'), '{ "foo": "bar" }', 'returns JSON parsed cookie'); assert.strictEqual(Cookies.get('c'), '{ \\"foo\\": \\"bar\\" }', 'returns unparsed cookie with enclosing quotes removed'); }); QUnit.test('Prevent accidentally writing cookie when passing unexpected argument', function (assert) { Cookies.getJSON('c', { foo: 'bar' }); assert.strictEqual(Cookies.get('c'), undefined, 'should not write any cookie'); }); QUnit.module('noConflict', lifecycle); QUnit.test('do not conflict with existent globals', function (assert) { assert.expect(2); var Cookies = window.Cookies.noConflict(); Cookies.set('c', 'v'); assert.strictEqual(Cookies.get('c'), 'v', 'should work correctly'); assert.strictEqual(window.Cookies, 'existent global', 'should restore the original global'); window.Cookies = Cookies; }); js-cookie-2.2.1/test/utils.js000066400000000000000000000065641352227530600160740ustar00rootroot00000000000000// https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit (function () { 'use strict'; var log = []; 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); } }); }); window.lifecycle = { afterEach: function () { // Remove the cookies created using js-cookie default attributes // Note: Using `Object.keys(Cookies.get()).forEach(Cookies.remove)` // would cause IE 6 + 7 to break with a "Object doesn't support // this property or method" error, thus wrapping it with a // function. Object.keys(Cookies.get()).forEach(function (cookie) { Cookies.remove(cookie); }); // Remove the cookies created using browser default attributes Object.keys(Cookies.get()).forEach(function (cookie) { Cookies.remove(cookie, { path: '' }); }); } }; window.addEvent = function (element, eventName, fn) { var method = 'addEventListener'; if (element.attachEvent) { eventName = 'on' + eventName; method = 'attachEvent'; } element[ method ](eventName, fn); }; window.using = function (assert) { function getQuery(key) { var queries = location.href.split('?')[1]; if (!queries) { return; } var pairs = queries.split(/&|=/); var indexBaseURL = pairs.indexOf(key); var result = pairs[indexBaseURL + 1]; if (result) { return decodeURIComponent(result); } } function setCookie(name, value) { return { then: function (callback) { var iframe = document.getElementById('request_target'); var serverURL = getQuery('integration_baseurl'); Cookies.set(name, value); if (!serverURL) { callback(Cookies.get(name), document.cookie); } else { var requestURL = [ serverURL, 'encoding?', 'name=' + encodeURIComponent(name), '&value=' + encodeURIComponent(value) ].join(''); var done = assert.async(); addEvent(iframe, 'load', function () { var iframeDocument = iframe.contentWindow.document; var root = iframeDocument.documentElement; var content = root.textContent; if (!content) { ok(false, [ '"' + requestURL + '"', 'content should not be empty' ].join(' ')); done(); return; } try { var result = JSON.parse(content); callback(result.value, iframeDocument.cookie); } finally { done(); } }); iframe.src = requestURL; } } }; } return { setCookie: setCookie }; }; window.loadFileSync = function (path) { var xhr = new XMLHttpRequest(); xhr.open('GET', path, false); xhr.send(null); return xhr.status === 200 ? xhr.responseText : null; }; window.quoted = function (input) { return '"' + input + '"'; }; }());