From 26a33eb44978ef28fa6bdb2d349f5738b4da841a Mon Sep 17 00:00:00 2001 From: Klaus Hartl Date: Fri, 6 Sep 2019 15:58:32 +0200 Subject: [PATCH 01/17] Turn source into ES module --- src/js.cookie.js | 163 ---------------------------------------------- src/js.cookie.mjs | 143 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 163 deletions(-) delete mode 100644 src/js.cookie.js create mode 100644 src/js.cookie.mjs diff --git a/src/js.cookie.js b/src/js.cookie.js deleted file mode 100644 index 80a75512..00000000 --- a/src/js.cookie.js +++ /dev/null @@ -1,163 +0,0 @@ -/*! - * 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 () {}); -})); diff --git a/src/js.cookie.mjs b/src/js.cookie.mjs new file mode 100644 index 00000000..119084e8 --- /dev/null +++ b/src/js.cookie.mjs @@ -0,0 +1,143 @@ +/*! + * 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 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; +} + +export default init(function () {}); From f75545c0fff53e68fe163b2478a7a58563c17048 Mon Sep 17 00:00:00 2001 From: Klaus Hartl Date: Fri, 6 Sep 2019 18:49:17 +0200 Subject: [PATCH 02/17] Introduce rollup --- package.json | 3 ++- rollup.config.js | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 rollup.config.js diff --git a/package.json b/package.json index ec330980..0c7b9837 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "grunt-exec": "3.0.0", "gzip-js": "0.3.2", "qunitjs": "1.23.1", - "requirejs": "2.3.5" + "requirejs": "2.3.5", + "rollup": "^1.20.3" } } diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 00000000..07c56a3e --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,18 @@ +export default { + input: "src/js.cookie.mjs", + output: [ + // config for - - - - -
-
- - diff --git a/test/amd.js b/test/amd.js deleted file mode 100644 index 5f655f14..00000000 --- a/test/amd.js +++ /dev/null @@ -1,14 +0,0 @@ -require(['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(); - }); - }); - -}); diff --git a/test/environment-with-amd-and-umd.html b/test/environment-with-amd-and-umd.html deleted file mode 100644 index 9e444f54..00000000 --- a/test/environment-with-amd-and-umd.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - JavaScript Cookie Test Suite - Environment with AMD and UMD - - - - - - -
-
- - diff --git a/test/environment-with-amd-and-umd.js b/test/environment-with-amd-and-umd.js deleted file mode 100644 index b4f32502..00000000 --- a/test/environment-with-amd-and-umd.js +++ /dev/null @@ -1,28 +0,0 @@ -require(['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(); - }); - }); - -}); From 2be6618aaa94f68bb56384d0b205251f5fb134df Mon Sep 17 00:00:00 2001 From: Klaus Hartl Date: Fri, 6 Sep 2019 19:19:30 +0200 Subject: [PATCH 09/17] Fix file references in tests We need to reference the rollup umd output file here. --- test/encoding.html | 2 +- test/node.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/encoding.html b/test/encoding.html index a2f898bf..440847fb 100644 --- a/test/encoding.html +++ b/test/encoding.html @@ -5,7 +5,7 @@ JavaScript Cookie Test Suite - Encoding - + diff --git a/test/node.js b/test/node.js index 861ed1b5..7a4e47a0 100644 --- a/test/node.js +++ b/test/node.js @@ -2,26 +2,26 @@ exports.node = { should_load_js_cookie: function (test) { test.expect(1); - var Cookies = require('../src/js.cookie'); + var Cookies = require('../build/js.cookie.min.js'); 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'); + var Cookies = require('../build/js.cookie.min.js'); 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'); + var Cookies = require('../build/js.cookie.min.js'); 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'); + var Cookies = require('../build/js.cookie.min.js'); Cookies.remove('anything'); Cookies.remove('anything', { path: '' }); test.done(); From e1e1d90ad0e8897e58b24568071412bbd44c4249 Mon Sep 17 00:00:00 2001 From: Klaus Hartl Date: Fri, 6 Sep 2019 19:25:06 +0200 Subject: [PATCH 10/17] Remove noConflict() testing remnants --- test/index.html | 1 - test/tests.js | 11 ----------- 2 files changed, 12 deletions(-) diff --git a/test/index.html b/test/index.html index 6d416912..66a2345b 100644 --- a/test/index.html +++ b/test/index.html @@ -5,7 +5,6 @@ JavaScript Cookie Test Suite - diff --git a/test/tests.js b/test/tests.js index 4c1b0c2c..f0877d48 100644 --- a/test/tests.js +++ b/test/tests.js @@ -453,14 +453,3 @@ QUnit.test('Prevent accidentally writing cookie when passing unexpected argument 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; -}); From a2c113677e9d4a519f164e4bab7f63a5dc12b618 Mon Sep 17 00:00:00 2001 From: Klaus Hartl Date: Fri, 6 Sep 2019 19:31:26 +0200 Subject: [PATCH 11/17] Remove support for Bower --- README.md | 2 +- bower.json | 17 ----------------- 2 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 bower.json diff --git a/README.md b/README.md index 1b9b1a08..1e9cc724 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ in Internet Explorer on Windows 7 for instance (because of the wrong MIME type). ### 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`. +JavaScript Cookie supports [npm](https://www.npmjs.com/package/js-cookie) under the name `js-cookie`. #### NPM ``` diff --git a/bower.json b/bower.json deleted file mode 100644 index 9678d99f..00000000 --- a/bower.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "js-cookie", - "license": "MIT", - "main": [ - "src/js.cookie.js" - ], - "ignore": [ - "test", - "Gruntfile.js", - "package.json", - ".gitignore", - ".eslintintignore", - ".eslintrc", - ".tm_properties", - ".travis.yml" - ] -} From 0a7d1db1b91b03dc2f71183fbe65981f463d7878 Mon Sep 17 00:00:00 2001 From: Klaus Hartl Date: Sat, 7 Sep 2019 10:44:25 +0200 Subject: [PATCH 12/17] Set up package for module/nomodule distributions We produce variants of the source code by rollup. Note using a "module" property is not (yet?) standard but the approach both webpack and rollup.js suggest going forward. --- .gitignore | 2 +- Gruntfile.js | 5 +-- package.json | 5 ++- rollup.config.js | 89 ++++++++++++++++++++----------------- test/encoding.html | 2 +- test/index.html | 2 +- test/missing_semicolon.html | 2 +- test/node.js | 8 ++-- 8 files changed, 61 insertions(+), 54 deletions(-) diff --git a/.gitignore b/.gitignore index 15812b0e..d4ca9e24 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ node_modules -build +dist .sizecache.json *.log* diff --git a/Gruntfile.js b/Gruntfile.js index 96c34b04..480981b5 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -24,7 +24,6 @@ module.exports = function (grunt) { } grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), qunit: { all: { options: { @@ -52,8 +51,8 @@ module.exports = function (grunt) { }, compare_size: { files: [ - 'build/js.cookie-<%= pkg.version %>.min.mjs', - 'build/js.cookie-<%= pkg.version %>.min.js', + 'dist/js.cookie.min.mjs', + 'dist/js.cookie.min.js', 'src/js.cookie.mjs' ], options: { diff --git a/package.json b/package.json index 14470f8c..66161504 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "name": "js-cookie", "version": "2.2.1", "description": "A simple, lightweight JavaScript API for handling cookies", - "main": "src/js.cookie.js", + "main": "dist/js.cookie.js", + "module": "dist/js.cookie.mjs", "directories": { "test": "test" }, @@ -24,7 +25,7 @@ "url": "git://github.com/js-cookie/js-cookie.git" }, "files": [ - "src/**/*.js", + "dist/**/*", "SERVER_SIDE.md", "CONTRIBUTING.md" ], diff --git a/rollup.config.js b/rollup.config.js index 793c2f3e..a0e61b63 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,46 +1,53 @@ import { terser } from "rollup-plugin-terser"; import filesize from "rollup-plugin-filesize"; import license from "rollup-plugin-license"; -import pkg from "./package.json"; -export default { - input: "src/js.cookie.mjs", - output: [ - // config for - + diff --git a/test/index.html b/test/index.html index 66a2345b..fb4c608d 100644 --- a/test/index.html +++ b/test/index.html @@ -5,7 +5,7 @@ JavaScript Cookie Test Suite - + diff --git a/test/missing_semicolon.html b/test/missing_semicolon.html index 385efd57..7a89499c 100644 --- a/test/missing_semicolon.html +++ b/test/missing_semicolon.html @@ -8,7 +8,7 @@ + + diff --git a/test/index.html b/test/index.html index fb4c608d..7f014d95 100644 --- a/test/index.html +++ b/test/index.html @@ -3,8 +3,8 @@ JavaScript Cookie Test Suite - - + + diff --git a/test/missing_semicolon.html b/test/missing_semicolon.html index 7a89499c..b1ac380d 100644 --- a/test/missing_semicolon.html +++ b/test/missing_semicolon.html @@ -3,9 +3,6 @@ - - - + + + +
+
+ + diff --git a/test/module.mjs b/test/module.mjs new file mode 100644 index 00000000..46147087 --- /dev/null +++ b/test/module.mjs @@ -0,0 +1,6 @@ +import Cookies from "../dist/js.cookie.min.mjs"; + +QUnit.test("default export", function(test) { + test.expect(1); + test.ok(!!Cookies.get, "should provide API"); +}); From ac129d269eea79c21f763c2060a663513d5d9043 Mon Sep 17 00:00:00 2001 From: Klaus Hartl Date: Sat, 7 Sep 2019 16:07:13 +0200 Subject: [PATCH 16/17] Bring back noConflict functionality for umd module Rollup provides an out-of-the-box option for this, thus not going to test (generated). --- rollup.config.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index a0e61b63..70206b97 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -17,7 +17,8 @@ export default [ dir: "dist", name: "Cookies", entryFileNames: "[name].js", - format: "umd" + format: "umd", + noConflict: true } ] }, @@ -35,7 +36,8 @@ export default [ dir: "dist", name: "Cookies", entryFileNames: "[name].min.js", - format: "umd" + format: "umd", + noConflict: true } ], plugins: [ From c96aea2def1572a6a37c37b79bd41de0993f213f Mon Sep 17 00:00:00 2001 From: Klaus Hartl Date: Sun, 8 Sep 2019 11:35:00 +0200 Subject: [PATCH 17/17] Adapt documentation for ES module usage --- README.md | 55 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 1e9cc724..252fc772 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ A simple, lightweight JavaScript API for handling cookies * [Heavily](test) tested * No dependency * [Unobtrusive](#json) JSON support +* 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) @@ -22,35 +23,61 @@ A simple, lightweight JavaScript API for handling cookies ## Installation +### NPM + +JavaScript Cookie supports [npm](https://www.npmjs.com/package/js-cookie) under the name `js-cookie`. + +``` +$ npm install js-cookie --save +``` + ### 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): +The source comes as an ES module. If you download it [here](https://github.com/js-cookie/js-cookie/blob/latest/src/js.cookie.mjs) directly, you must include it as such. + +Example: ```html - + + ``` -Or include it via [jsDelivr CDN](https://www.jsdelivr.com/package/npm/js-cookie): +*Not all browsers support ES modules natively yet*. For this reason the npm package/release +comes with both an ES module as well as an UMD module variant. Include the module along +with the fallback to account for this: ```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. +Note the different extensions: `.mjs` denotes an ES module. -### Package Managers +### CDN -JavaScript Cookie supports [npm](https://www.npmjs.com/package/js-cookie) under the name `js-cookie`. +Alternatively, include it via [jsDelivr CDN](https://www.jsdelivr.com/package/npm/js-cookie): -#### NPM -``` - $ npm install js-cookie --save +```html + ``` -### Module Loaders +**Never include the source directly from GitHub (http://raw.github.com/...).** The file +is being served as text/plain and as such may be blocked because of the wrong MIME type. +Bottom line: GitHub is not a CDN. + +## ES Module -JavaScript Cookie can also be loaded as an AMD or CommonJS module. +Example for how to import the ES module from another module: + +```javascript +import Cookies from "./node_modules/js-cookie/dist/js.cookie.mjs"; + +Cookies.set('foo', 'bar'); +``` ## Basic Usage @@ -303,7 +330,7 @@ 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 +* Increment the version number in the `src/js.cookie.mjs` 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