pax_global_header00006660000000000000000000000064141136544320014515gustar00rootroot0000000000000052 comment=0ba77141dd215782cc7770347a457906908c66ff js-cookie-3.0.1/000077500000000000000000000000001411365443200134015ustar00rootroot00000000000000js-cookie-3.0.1/.eslintignore000066400000000000000000000000301411365443200160750ustar00rootroot00000000000000examples/**/node_modulesjs-cookie-3.0.1/.eslintrc.json000066400000000000000000000006441411365443200162010ustar00rootroot00000000000000{ "extends": "standard", "rules": { "no-undef": "off", "no-unused-vars": "off", "no-var": "off", "space-before-function-paren": "error" }, "plugins": ["html", "markdown"], "overrides": [ { "files": ["**/*.md"], "processor": "markdown/markdown" }, { "files": ["**/*.md/*.javascript"], "rules": { "comma-dangle": ["error", "never"] } } ] } js-cookie-3.0.1/.github/000077500000000000000000000000001411365443200147415ustar00rootroot00000000000000js-cookie-3.0.1/.github/ISSUE_TEMPLATE/000077500000000000000000000000001411365443200171245ustar00rootroot00000000000000js-cookie-3.0.1/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000017121411365443200216170ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve title: '' labels: 'bug' assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. iOS] - Browser [e.g. chrome, safari] - Version [e.g. 22] **Smartphone (please complete the following information):** - Device: [e.g. iPhone6] - OS: [e.g. iOS8.1] - Browser [e.g. stock browser, safari] - Version [e.g. 22] **Additional context** Add any other context about the problem here. js-cookie-3.0.1/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000013531411365443200226530ustar00rootroot00000000000000--- name: Feature request about: Suggest an idea for this project title: '' labels: 'feature request' assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. js-cookie-3.0.1/.github/dependabot.yml000066400000000000000000000011241411365443200175670ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: 'npm' # See documentation for possible values directory: '/' # Location of package manifests schedule: interval: 'daily' ignore: - dependency-name: '*' update-types: ['version-update:semver-patch'] js-cookie-3.0.1/.gitignore000066400000000000000000000000511411365443200153650ustar00rootroot00000000000000node_modules dist .sizecache.json *.log* js-cookie-3.0.1/.prettierignore000066400000000000000000000000251411365443200164410ustar00rootroot00000000000000dist .sizecache.json js-cookie-3.0.1/.release-it.json000066400000000000000000000012451411365443200164060ustar00rootroot00000000000000{ "git": { "commitMessage": "Craft v${version} release", "requireCleanWorkingDir": true, "tagAnnotation": "Release v${version}", "tagName": "v${version}" }, "github": { "assets": ["dist/*.mjs", "dist/*.js"], "draft": true, "release": true, "releaseName": "v${version}" }, "hooks": { "after:bump": "npm run dist", "after:git:release": "if [ \"${isPreRelease}\" != \"true\" ]; then git tag -f latest && git push -f origin latest; fi", "after:release": "echo Successfully created a release draft v${version} for ${repo.repository}. Please add release notes when necessary and publish it!", "before:init": "npm test" } } js-cookie-3.0.1/.travis.yml000066400000000000000000000005661411365443200155210ustar00rootroot00000000000000addons: browserstack: username: ${BROWSERSTACK_USERNAME} access_key: ${BROWSERSTACK_ACCESS_KEY} forcelocal: true language: node_js node_js: - 12 - 14 - 16 cache: directories: - node_modules stages: - test - name: browserstack if: fork IS false jobs: include: - stage: browserstack node_js: '14' script: grunt browserstack js-cookie-3.0.1/CONTRIBUTING.md000066400000000000000000000072521411365443200156400ustar00rootroot00000000000000## 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-3.0.1/Gruntfile.js000066400000000000000000000052201411365443200156750ustar00rootroot00000000000000function encodingMiddleware (request, response, next) { const URL = require('url').URL const url = new URL(request.url, 'http://localhost') if (url.pathname !== '/encoding') { next() return } const cookieName = url.searchParams.get('name') const cookieValue = url.searchParams.get('value') response.setHeader('content-type', 'application/json') response.end( JSON.stringify({ name: cookieName, value: cookieValue }) ) } const config = { qunit: { all: { options: { urls: [ 'http://127.0.0.1:9998/', 'http://127.0.0.1:9998/module.html', 'http://127.0.0.1:9998/encoding.html?integration_baseurl=http://127.0.0.1:9998/' ] } } }, nodeunit: { all: 'test/node.js' }, watch: { options: { livereload: true }, files: ['src/**/*.mjs', 'test/**/*.js'], tasks: 'default' }, compare_size: { files: [ 'dist/js.cookie.mjs', 'dist/js.cookie.min.mjs', 'dist/js.cookie.js', 'dist/js.cookie.min.js' ], options: { compress: { gz: (fileContents) => require('gzip-js').zip(fileContents, {}).length } } }, connect: { 'build-qunit': { options: { port: 9998, base: ['.', 'test'], middleware: function (connect, options, middlewares) { middlewares.unshift(encodingMiddleware) return middlewares } } }, 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 } } } }, exec: { rollup: 'npx rollup -c', lint: 'npx standard', format: 'npx prettier -l --write --single-quote --no-semi "**/*.{html,js,json,md,mjs,yml}" && npx eslint "**/*.{html,md}" --fix && npx standard --fix', 'browserstack-runner': 'node_modules/.bin/browserstack-runner --verbose' } } module.exports = function (grunt) { grunt.initConfig(config) // Load dependencies Object.keys(grunt.file.readJSON('package.json').devDependencies) .filter((key) => key !== 'grunt' && key.startsWith('grunt')) .forEach(grunt.loadNpmTasks) grunt.registerTask('test', [ 'exec:lint', 'exec:rollup', 'connect:build-qunit', 'qunit', 'nodeunit' ]) grunt.registerTask('browserstack', [ 'exec:rollup', 'exec:browserstack-runner' ]) grunt.registerTask('dev', ['exec:format', 'test', 'compare_size']) grunt.registerTask('default', 'dev') } js-cookie-3.0.1/LICENSE000066400000000000000000000021361411365443200144100ustar00rootroot00000000000000MIT 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-3.0.1/README.md000066400000000000000000000326741411365443200146740ustar00rootroot00000000000000

# JavaScript Cookie [![Build Status](https://travis-ci.com/js-cookie/js-cookie.svg?branch=master)](https://travis-ci.com/js-cookie/js-cookie) [![BrowserStack Status](https://www.browserstack.com/automate/badge.svg?badge_key=b3VDaHAxVDg0NDdCRmtUOWg0SlQzK2NsRVhWTjlDQS9qdGJoak1GMzJiVT0tLVhwZHNvdGRoY284YVRrRnI3eU1JTnc9PQ==--5e88ffb3ca116001d7ef2cfb97a4128ac31174c2)](https://www.browserstack.com/automate/public-build/b3VDaHAxVDg0NDdCRmtUOWg0SlQzK2NsRVhWTjlDQS9qdGJoak1GMzJiVT0tLVhwZHNvdGRoY284YVRrRnI3eU1JTnc9PQ==--5e88ffb3ca116001d7ef2cfb97a4128ac31174c2) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) [![Code Climate](https://codeclimate.com/github/js-cookie/js-cookie.svg)](https://codeclimate.com/github/js-cookie/js-cookie) [![npm](https://img.shields.io/github/package-json/v/js-cookie/js-cookie)](https://www.npmjs.com/package/js-cookie) [![size](https://img.shields.io/bundlephobia/minzip/js-cookie/3)](https://www.npmjs.com/package/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://www.browserstack.com/automate/public-build/b3VDaHAxVDg0NDdCRmtUOWg0SlQzK2NsRVhWTjlDQS9qdGJoak1GMzJiVT0tLVhwZHNvdGRoY284YVRrRnI3eU1JTnc9PQ==--5e88ffb3ca116001d7ef2cfb97a4128ac31174c2) browsers - Accepts [any](#encoding) character - [Heavily](test) tested - No dependency - Supports ES modules - 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) - **< 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.](https://github.com/js-cookie/js-cookie/tree/latest#readme) 👈👈** ## Installation ### NPM JavaScript Cookie supports [npm](https://www.npmjs.com/package/js-cookie) under the name `js-cookie`. ``` $ npm i js-cookie ``` The npm package has a `module` field pointing to an ES module variant of the library, mainly to provide support for ES module aware bundlers, whereas its `browser` field points to an UMD module for full backward compatibility. ### Direct download Starting with version 3 [releases](https://github.com/js-cookie/js-cookie/releases) are distributed with two variants of this library, an ES module as well as an UMD module. Note the different extensions: `.mjs` denotes the ES module, whereas `.js` is the UMD one. Example for how to load the ES module in a browser: ```html ``` _Not all browsers support ES modules natively yet_. For this reason the npm package/release provides both the ES and UMD module variant and you may want to include the ES module along with the UMD fallback to account for this: ```html ``` Here we're loading the nomodule script in a deferred fashion, because ES modules are deferred by default. This may not be strictly necessary depending on how you're using the library. ### CDN Alternatively, include it via [jsDelivr CDN](https://www.jsdelivr.com/package/npm/js-cookie). ## ES Module Example for how to import the ES module from another module: ```javascript import Cookies from 'js-cookie' Cookies.set('foo', 'bar') ``` ## 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 neither raises any exception nor returns 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._ ## 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 attribute defaults can be set globally by creating an instance of the api via `withAttributes()`, or individually for each call to `Cookies.set(...)` by passing a plain object as the last argument. Per-call attributes override the default attributes. ### expires Define when the cookie will be removed. Value must 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') ``` ### sameSite A [`String`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String), allowing to control whether the browser is sending a cookie along with cross-site requests. Default: not set. **Note that more recent browsers are making "Lax" the default value even without specifiying anything here.** **Examples:** ```javascript Cookies.set('name', 'value', { sameSite: 'strict' }) Cookies.get('name') // => 'value' Cookies.remove('name') ``` ### Setting up defaults ```javascript const api = Cookies.withAttributes({ path: '/', domain: '.example.com' }) ``` ## 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 given converter for each cookie. The returned value 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({ read: function (value, name) { if (name === 'escaped') { return unescape(value) } // Fall back to default for all other cookies return Cookies.converter.read(value, name) } }) 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({ write: function (value, name) { return value.toUpperCase() } }) ``` ## TypeScript declarations ``` $ npm i @types/js-cookie ``` ## 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 `js-cookie at googlegroups dot com` ## Releasing We are using [release-it](https://www.npmjs.com/package/release-it) for automated releasing. Start a dry run to see what would happen: ``` $ npm run release minor -- --dry-run ``` Do a real release (publishes both to npm as well as create a new release on GitHub): ``` $ npm run release minor ``` _GitHub releases are created as a draft and need to be published manually! (This is so we are able to craft suitable release notes before publishing.)_ ## Supporters

Many thanks to [BrowserStack](https://www.browserstack.com/) for providing unlimited browser testing free of cost. ## 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-3.0.1/SERVER_SIDE.md000066400000000000000000000133121411365443200155350ustar00rootroot00000000000000# 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: Cookies.converter.write, read: function (value) { // Decode the plus sign to spaces first, otherwise "legit" encoded pluses // will be replaced incorrectly value = value.replace(/\+/g, ' ') // Decode all characters according to the "encodeURIComponent" spec return Cookies.converter.read(value) } }) ``` 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) { return ( Cookies.converter .write(value) // Encode the parens that are interpreted incorrectly by Tomcat .replace(/[()]/g, escape) ) }, read: Cookies.converter.read }) ``` ### 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) { return ( Cookies.converter .write(value) // Encode again the characters that are not allowed in JBoss 7.1.1, like "[" and "]": .replace(/[[\]]/g, encodeURIComponent) ) }, read: Cookies.converter.read }) ``` Alternatively, you can check the [Java Cookie](https://github.com/js-cookie/java-cookie) project, which integrates nicely with JavaScript Cookie. ## Express [Express](https://github.com/expressjs/express) handles cookies with JSON by [prepending](https://github.com/expressjs/express/blob/master/lib/response.js#L827) a `j:` prefix to [verify](https://github.com/expressjs/cookie-parser/blob/master/index.js#L83) if it contains a JSON value later. An example to solve this: **Write** ```js // Client Cookies.set('name', 'j:' + JSON.stringify({ key: value })) // Or in Express server to prevent prepending of j: prefix res.cookie('name', JSON.stringify({ key: value })) ``` **Read** ```js // Client JSON.parse(Cookies.get('name').slice(2)) // Express already parses JSON cookies if `cookie-parser` middleware is installed. // If you used the solution for Express above: JSON.parse(req.cookies.name) ``` However, it's still quite a handful to do. To avoid that situation, writing a custom converter is recommended. **Example**: ```js var ExpressCookies = Cookies.withConverter({ write: function (value) { // Prepend j: prefix if it is JSON object try { var tmp = JSON.parse(value) if (typeof tmp !== 'object') { throw new Error() } value = 'j:' + JSON.stringify(tmp) } catch (e) {} return Cookies.converter.write(value) }, read: function (value) { value = Cookies.converter.read(value) // Check if the value contains j: prefix otherwise return as is return value.slice(0, 2) === 'j:' ? value.slice(2) : value } }) ``` js-cookie-3.0.1/browserstack.json000066400000000000000000000012741411365443200170110ustar00rootroot00000000000000{ "test_framework": "qunit", "test_path": ["test/index.html"], "exit_with_fail": true, "browsers": [ "chrome_latest", "chrome_previous", "firefox_latest", "firefox_previous", "ie_11", "ie_10", "opera_latest", { "browser": "safari", "browser_version": "latest", "os": "OS X", "os_version": "Big Sur" }, { "browser": "safari", "browser_version": "latest", "os": "OS X", "os_version": "Catalina" }, { "device": "iPhone 11", "real_mobile": "true", "os": "ios", "os_version": "13", "browserstack.local": "false", "browserstack.appium_version": "1.14.0" } ] } js-cookie-3.0.1/examples/000077500000000000000000000000001411365443200152175ustar00rootroot00000000000000js-cookie-3.0.1/examples/es-module/000077500000000000000000000000001411365443200171115ustar00rootroot00000000000000js-cookie-3.0.1/examples/es-module/package.json000066400000000000000000000005571411365443200214060ustar00rootroot00000000000000{ "name": "js-cookie-es-module-example", "version": "1.0.0", "description": "", "type": "module", "private": true, "scripts": { "start": "node src/main.js", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": {}, "dependencies": { "js-cookie": "^3.0.0" } } js-cookie-3.0.1/examples/es-module/src/000077500000000000000000000000001411365443200177005ustar00rootroot00000000000000js-cookie-3.0.1/examples/es-module/src/main.js000066400000000000000000000000721411365443200211610ustar00rootroot00000000000000import Cookies from 'js-cookie' console.log(Cookies.get) js-cookie-3.0.1/examples/webpack/000077500000000000000000000000001411365443200166335ustar00rootroot00000000000000js-cookie-3.0.1/examples/webpack/.gitignore000066400000000000000000000000171411365443200206210ustar00rootroot00000000000000!dist dist/*.jsjs-cookie-3.0.1/examples/webpack/dist/000077500000000000000000000000001411365443200175765ustar00rootroot00000000000000js-cookie-3.0.1/examples/webpack/dist/index.html000066400000000000000000000002061411365443200215710ustar00rootroot00000000000000 webpack Example js-cookie-3.0.1/examples/webpack/package.json000066400000000000000000000007121411365443200211210ustar00rootroot00000000000000{ "name": "js-cookie-webpack-example", "version": "1.0.0", "description": "", "private": true, "scripts": { "start": "node server.js", "build": "npx webpack", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "node-static": "^0.7.11", "webpack": "^4.41.0", "webpack-cli": "^3.3.9" }, "dependencies": { "js-cookie": "^3.0.0" } } js-cookie-3.0.1/examples/webpack/server.js000066400000000000000000000005571411365443200205060ustar00rootroot00000000000000const nodeStatic = require('node-static') const file = new nodeStatic.Server('./dist') const port = 8080 require('http') .createServer(function (request, response) { request .addListener('end', function () { file.serve(request, response) }) .resume() }) .listen(port) console.log(`Example available at http://localhost:${port}`) js-cookie-3.0.1/examples/webpack/src/000077500000000000000000000000001411365443200174225ustar00rootroot00000000000000js-cookie-3.0.1/examples/webpack/src/index.js000066400000000000000000000001001411365443200210560ustar00rootroot00000000000000import Cookies from 'js-cookie' Cookies.set('test', 'example') js-cookie-3.0.1/index.js000066400000000000000000000000551411365443200150460ustar00rootroot00000000000000module.exports = require('./dist/js.cookie') js-cookie-3.0.1/package.json000066400000000000000000000033241411365443200156710ustar00rootroot00000000000000{ "name": "js-cookie", "version": "3.0.1", "description": "A simple, lightweight JavaScript API for handling cookies", "browser": "dist/js.cookie.js", "module": "dist/js.cookie.mjs", "unpkg": "dist/js.cookie.min.js", "jsdelivr": "dist/js.cookie.min.js", "exports": { ".": { "import": "./dist/js.cookie.mjs", "require": "./dist/js.cookie.js" }, "./package.json": "./package.json" }, "directories": { "test": "test" }, "keywords": [ "cookie", "cookies", "browser", "amd", "commonjs", "client", "js-cookie", "browserify" ], "scripts": { "test": "grunt test", "format": "grunt exec:format", "dist": "rm -rf dist/* && rollup -c", "release": "release-it" }, "repository": { "type": "git", "url": "git://github.com/js-cookie/js-cookie.git" }, "files": [ "index.js", "dist/**/*" ], "author": "Klaus Hartl", "license": "MIT", "devDependencies": { "browserstack-runner": "^0.9.0", "eslint": "^7.31.0", "eslint-config-standard": "^16.0.3", "eslint-plugin-promise": "^5.1.0", "eslint-plugin-html": "^6.0.0", "eslint-plugin-markdown": "^2.2.0", "grunt": "^1.0.4", "grunt-compare-size": "^0.4.2", "grunt-contrib-connect": "^3.0.0", "grunt-contrib-nodeunit": "^3.0.0", "grunt-contrib-qunit": "^3.1.0", "grunt-contrib-watch": "^1.1.0", "grunt-exec": "^3.0.0", "gzip-js": "^0.3.2", "prettier": "^2.3.2", "qunit": "^2.9.3", "release-it": "^14.10.0", "rollup": "^2.0.0", "rollup-plugin-filesize": "^9.1.1", "rollup-plugin-license": "^2.5.0", "rollup-plugin-terser": "^7.0.2", "standard": "^16.0.3" }, "engines": { "node": ">=12" } } js-cookie-3.0.1/rollup.config.js000066400000000000000000000023171411365443200165230ustar00rootroot00000000000000import { terser } from 'rollup-plugin-terser' import filesize from 'rollup-plugin-filesize' import license from 'rollup-plugin-license' import pkg from './package.json' const licenseBanner = license({ banner: { content: '/*! <%= pkg.name %> v<%= pkg.version %> | <%= pkg.license %> */', commentStyle: 'none' } }) export default [ { input: 'src/api.mjs', output: [ // config for
js-cookie-3.0.1/test/encoding.js000066400000000000000000000711321411365443200165100ustar00rootroot00000000000000/* global QUnit, lifecycle, using */ /* eslint-disable no-var */ QUnit.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('\t', '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' ) }) }) /* eslint-enable no-var */ js-cookie-3.0.1/test/index.html000066400000000000000000000010301411365443200163470ustar00rootroot00000000000000 JavaScript Cookie Test Suite
js-cookie-3.0.1/test/missing_semicolon.html000066400000000000000000000014061411365443200207700ustar00rootroot00000000000000 js-cookie-3.0.1/test/module.html000066400000000000000000000006431411365443200165360ustar00rootroot00000000000000 JavaScript Cookie Test Suite - ES module
js-cookie-3.0.1/test/module.mjs000066400000000000000000000002671411365443200163650ustar00rootroot00000000000000/* global QUnit */ import Cookies from '../dist/js.cookie.min.mjs' QUnit.test('default export', function (test) { test.expect(1) test.ok(!!Cookies.get, 'should provide API') }) js-cookie-3.0.1/test/node.js000066400000000000000000000015131411365443200156430ustar00rootroot00000000000000exports.node = { shouldLoadApi: function (test) { test.expect(1) const Cookies = require('../dist/js.cookie.min.js') test.ok(!!Cookies.get, 'should load the Cookies API') test.done() }, shouldNotThrowErrorForSetCallInNode: function (test) { test.expect(0) const Cookies = require('../dist/js.cookie.min.js') Cookies.set('anything') Cookies.set('anything', { path: '' }) test.done() }, shouldNotThrowErrorForGetCallInNode: function (test) { test.expect(0) const Cookies = require('../dist/js.cookie.min.js') Cookies.get('anything') test.done() }, shouldNotThrowErrorForRemoveCallInNode: function (test) { test.expect(0) const Cookies = require('../dist/js.cookie.min.js') Cookies.remove('anything') Cookies.remove('anything', { path: '' }) test.done() } } js-cookie-3.0.1/test/tests.js000066400000000000000000000430751411365443200160710ustar00rootroot00000000000000/* global Cookies, QUnit, lifecycle, quoted */ /* eslint-disable no-var */ QUnit.module('setup', lifecycle) QUnit.test('api instance creation', function (assert) { assert.expect(4) var api api = Cookies.withAttributes({ path: '/bar' }) assert.ok( api.set('c', 'v').match(/c=v; path=\/bar/), 'should set up default cookie attributes' ) api = Cookies.withAttributes({ sameSite: 'Lax' }) assert.notOk( api.set('c', 'v').match(/c=v; path=\/bar/), 'should set up cookie attributes each time from original' ) api = Cookies.withConverter({ write: function (value, name) { return value.toUpperCase() } }).withAttributes({ path: '/foo' }) assert.ok( api.set('c', 'v').match(/c=V; path=\/foo/), 'should allow setting up converters followed by default cookie attributes' ) api = Cookies.withAttributes({ path: '/foo' }).withConverter({ write: function (value, name) { return value.toUpperCase() } }) assert.ok( api.set('c', 'v').match(/c=V; path=\/foo/), 'should allow setting up default cookie attributes followed by converter' ) }) QUnit.test('api instance with attributes', function (assert) { assert.expect(3) // Create a new instance so we don't affect remaining tests... var api = Cookies.withAttributes({ path: '/' }) delete api.attributes assert.ok(api.attributes, "won't allow to delete property") api.attributes = {} assert.ok(api.attributes.path, "won't allow to reassign property") api.attributes.path = '/foo' assert.equal( api.attributes.path, '/', "won't allow to reassign contained properties" ) }) QUnit.test('api instance with converter', function (assert) { assert.expect(3) var readConverter = function (value) { return value.toUpperCase() } // Create a new instance so we don't affect remaining tests... var api = Cookies.withConverter({ read: readConverter }) delete api.converter assert.ok(api.converter, "won't allow to delete property") api.converter = {} assert.ok(api.converter.read, "won't allow to reassign property") api.converter.read = function () {} assert.equal( api.converter.read.toString(), readConverter.toString(), "won't allow to reassign contained properties" ) }) // github.com/js-cookie/js-cookie/pull/171 QUnit.test('missing leading semicolon', function (assert) { assert.expect(1) var done = assert.async() var iframe = document.createElement('iframe') iframe.src = 'missing_semicolon.html' iframe.addEventListener('load', function () { assert.ok( iframe.contentWindow.__ok, 'concatenate with 3rd party script without error' ) done() }) document.body.appendChild(iframe) }) 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( 'unencoded percent character in cookie value mixed with encoded values not permitted', function (assert) { assert.expect(1) document.cookie = 'bad=foo%bar%22baz%qux' assert.strictEqual(Cookies.get('bad'), undefined, 'should skip reading') document.cookie = 'bad=foo; expires=Thu, 01 Jan 1970 00:00:00 GMT' } ) QUnit.test('lowercase percent character in cookie value', function (assert) { assert.expect(1) document.cookie = 'c=%d0%96' assert.strictEqual( Cookies.get('c'), 'Ж', 'should decode percent characters case insensitive' ) }) 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 = '%A1=foo' 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 = '%A1=foo; 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' ) document.cookie = 'invalid=foo; expires=Thu, 01 Jan 1970 00:00:00 GMT' } ) // 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') } ) QUnit.test('Passing `undefined` first argument', function (assert) { assert.expect(1) Cookies.set('foo', 'bar') assert.strictEqual( Cookies.get(undefined), undefined, 'should not attempt to retrieve all cookies' ) }) QUnit.test('Passing `null` first argument', function (assert) { assert.expect(1) Cookies.set('foo', 'bar') assert.strictEqual( Cookies.get(null), undefined, 'should not attempt to retrieve all cookies' ) }) 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('predefined path attribute', function (assert) { assert.expect(1) assert.ok( Cookies.set('c', 'v').match(/path=\/$/), 'should use root path when not configured otherwise' ) }) QUnit.test('API for changing defaults', function (assert) { assert.expect(3) var api api = Cookies.withAttributes({ path: '/foo' }) assert.ok( api.set('c', 'v').match(/path=\/foo/), 'should use attributes from defaults' ) assert.ok( api.set('c', 'v', { path: '/baz' }).match(/path=\/baz/), 'attributes argument has precedence' ) api = Cookies.withAttributes({ path: undefined }) assert.notOk(api.set('c', 'v').match(/path=/), 'should not set any path') Cookies.remove('c') }) 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('Custom 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({ read: 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({ read: 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(2) var cookies = Cookies.withConverter({ read: function (value, name) { if (name === 'escaped') { return unescape(value) } } }) document.cookie = 'escaped=%u5317' assert.strictEqual( cookies.get('escaped'), '北', 'should use custom read converter when retrieving single cookies' ) assert.deepEqual( cookies.get(), { escaped: '北' }, 'should use custom read converter when retrieving all cookies' ) } ) // github.com/js-cookie/js-cookie/issues/70 QUnit.test('should be able to set up 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 set up a read 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.test('should be able to extend read decoder', function (assert) { assert.expect(1) document.cookie = 'c=A%23' var cookies = Cookies.withConverter({ read: function (value) { var decoded = value.replace('A', 'a') return Cookies.converter.read(decoded) } }) assert.strictEqual(cookies.get('c'), 'a#', 'should call both read converters') }) QUnit.test('should be able to extend write decoder', function (assert) { assert.expect(1) Cookies.withConverter({ write: function (value) { var encoded = value.replace('a', 'A') return Cookies.converter.write(encoded) } }).set('c', 'a%') assert.strictEqual( document.cookie, 'c=A%25', 'should call both write converters' ) }) QUnit.test( 'should be able to convert incoming, non-String values', function (assert) { assert.expect(1) Cookies.withConverter({ write: function (value) { return JSON.stringify(value) } }).set('c', { foo: 'bar' }) assert.strictEqual( document.cookie, 'c={"foo":"bar"}', 'should convert object as JSON string' ) } ) 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 }) /* eslint-enable no-var */ js-cookie-3.0.1/test/utils.js000066400000000000000000000045671411365443200160720ustar00rootroot00000000000000/* global Cookies, QUnit */ /* eslint-disable no-var */ ;(function () { window.lifecycle = { afterEach: function () { // Remove the cookies created using js-cookie default attributes 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.using = function (assert) { function getQuery (key) { var queries = window.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() iframe.addEventListener('load', function () { var iframeDocument = iframe.contentWindow.document var root = iframeDocument.documentElement var content = root.textContent if (!content) { QUnit.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.quoted = function (input) { return '"' + input + '"' } })() /* eslint-enable no-var */