diff --git a/.browserslistrc b/.browserslistrc
index 7c8f0e2..de55567 100644
--- a/.browserslistrc
+++ b/.browserslistrc
@@ -1,2 +1 @@
-> 5%
-IE 11
\ No newline at end of file
+> 1%
diff --git a/.eslintrc b/.eslintrc.json
similarity index 64%
rename from .eslintrc
rename to .eslintrc.json
index 861656d..5055cc4 100644
--- a/.eslintrc
+++ b/.eslintrc.json
@@ -2,13 +2,18 @@
"parserOptions": {
"ecmaVersion": 2020
},
- "extends": ["airbnb-base", "plugin:prettier/recommended"],
+ "extends": [
+ "airbnb-base",
+ "plugin:prettier/recommended",
+ "plugin:compat/recommended"
+ ],
"plugins": ["prettier"],
"env": {
"es6": true,
"browser": true
},
"rules": {
+ "import/prefer-default-export": "off",
"import/no-extraneous-dependencies": [
"error",
{
@@ -41,7 +46,8 @@
"mocha": true
},
"rules": {
- "no-restricted-syntax": "off"
+ "no-restricted-syntax": "off",
+ "compat/compat": "off"
}
},
{
@@ -51,5 +57,18 @@
"cypress/globals": true
}
}
- ]
+ ],
+ "settings": {
+ "polyfills": [
+ "Array.from",
+ "Array.prototype.find",
+ "Array.prototype.includes",
+ "Symbol",
+ "Symbol.iterator",
+ "Object.assign",
+ "CustomEvent",
+ "Element.prototype.classList",
+ "Element.prototype.closest"
+ ]
+ }
}
diff --git a/.github/actions-scripts/polyfills-sync.js b/.github/actions-scripts/polyfills-sync.js
new file mode 100644
index 0000000..824a930
--- /dev/null
+++ b/.github/actions-scripts/polyfills-sync.js
@@ -0,0 +1,14 @@
+const { readFileSync } = require('fs');
+const path = require('path');
+const assert = require('assert');
+
+const readme = readFileSync(path.resolve(__dirname, '../../README.md'), 'utf8');
+
+const polyfillsFromDocs = /^```polyfills\s*\n([^`]+)\n^```/m
+ .exec(readme)[1]
+ .split('\n')
+ .map(v => v.trim())
+ .sort();
+// @ts-ignore
+const polyfillsFromSettings = require('../../.eslintrc.json').settings.polyfills.sort();
+assert.deepStrictEqual(polyfillsFromDocs, polyfillsFromSettings);
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 3fe5e90..0588e96 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -31,3 +31,8 @@ jobs:
if [[ -z $(sed -e 's/[[:space:]]*$//' <<<${CHANGED_JS}) ]]; then CHANGED_JS="src/scripts"; fi
echo $CHANGED_JS
node node_modules/eslint/bin/eslint.js $CHANGED_JS
+
+ - name: Lint JS bundle
+ run: |
+ npm run js:build
+ npx eslint --no-ignore ./public/assets/scripts/*.js
diff --git a/.github/workflows/polyfills-sync.yml b/.github/workflows/polyfills-sync.yml
new file mode 100644
index 0000000..819e4a6
--- /dev/null
+++ b/.github/workflows/polyfills-sync.yml
@@ -0,0 +1,23 @@
+name: Polyfills documentation
+
+on:
+ pull_request:
+ paths:
+ - 'README.md'
+ - '.browserslistrc'
+ - '.eslintrc.json'
+
+jobs:
+ sync:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 1
+
+ - uses: actions/setup-node@v1
+ with:
+ node-version: 12
+
+ - name: Check Polyfills documentation and settings sync
+ run: node .github/actions-scripts/polyfills-sync.js
diff --git a/README.md b/README.md
index cb87c7c..a414ed1 100644
--- a/README.md
+++ b/README.md
@@ -1029,29 +1029,30 @@ example.setChoiceByValue('Two'); // Choice with value of 'Two' has now been sele
## Browser compatibility
-Choices is compiled using [Babel](https://babeljs.io/) to enable support for [ES5 browsers](http://caniuse.com/#feat=es5). If you need to support a browser that does not support one of the features listed below, I suggest including a polyfill from the very good [polyfill.io](https://cdn.polyfill.io/v2/docs/):
+Choices is compiled using [Babel](https://babeljs.io/) targeting browsers [with more that 1% of global usage](https://github.com/jshjohnson/Choices/blob/master/.browserslistrc) and expecting that features [listed below](https://github.com/jshjohnson/Choices/blob/master/.eslintrc.json#L62) are available or polyfilled in browser.
+You may see exact list of target browsers by running `npx browserslist` withing this repository folder.
+If you need to support a browser that does not have one of the features listed below,
+I suggest including a polyfill from the very good [polyfill.io](https://polyfill.io/v3/):
**Polyfill example used for the demo:**
```html
-
+
```
**Features used in Choices:**
-- Array.prototype.forEach
-- Array.prototype.map
-- Array.prototype.find
-- Array.prototype.some
-- Array.prototype.includes
-- Array.from
-- Array.prototype.reduce
-- Array.prototype.indexOf
-- Object.assign
-- Element.prototype.classList
-- Element.prototype.closest
-- window.requestAnimationFrame
-- CustomEvent
+```polyfills
+Array.from
+Array.prototype.find
+Array.prototype.includes
+Symbol
+Symbol.iterator
+Object.assign
+CustomEvent
+Element.prototype.classList
+Element.prototype.closest
+```
## Development
diff --git a/package-lock.json b/package-lock.json
index 64f0e10..9fe0740 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -753,6 +753,15 @@
"source-map-support": "^0.5.9"
}
},
+ "@babel/runtime": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz",
+ "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==",
+ "dev": true,
+ "requires": {
+ "regenerator-runtime": "^0.13.2"
+ }
+ },
"@babel/template": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz",
@@ -1539,6 +1548,12 @@
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
"dev": true
},
+ "ast-metadata-inferer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.1.1.tgz",
+ "integrity": "sha512-hc9w8Qrgg9Lf9iFcZVhNjUnhrd2BBpTlyCnegPVvCe6O0yMrF57a6Cmh7k+xUsfUOMh9wajOL5AsGOBNEyTCcw==",
+ "dev": true
+ },
"astral-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
@@ -2214,6 +2229,12 @@
}
}
},
+ "caniuse-db": {
+ "version": "1.0.30001004",
+ "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30001004.tgz",
+ "integrity": "sha512-VBTptWLoxsIhIGFZOEvtHhdRyhh+6JARUnVy2debGRNmrKfunVAa9cRuAvOnrQk4z/SDiNm5S2d6h32eIHZMoA==",
+ "dev": true
+ },
"caniuse-lite": {
"version": "1.0.30001002",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001002.tgz",
@@ -3882,6 +3903,29 @@
}
}
},
+ "eslint-plugin-compat": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.3.0.tgz",
+ "integrity": "sha512-QCgYy3pZ+zH10dkBJus1xER0359h1UhJjufhQRqp9Owm6BEoLZeSqxf2zINwL1OGao9Yc96xPYIW3nQj5HUryg==",
+ "dev": true,
+ "requires": {
+ "@babel/runtime": "^7.4.5",
+ "ast-metadata-inferer": "^0.1.1",
+ "browserslist": "^4.6.3",
+ "caniuse-db": "^1.0.30000977",
+ "lodash.memoize": "4.1.2",
+ "mdn-browser-compat-data": "^0.0.84",
+ "semver": "^6.1.2"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
"eslint-plugin-cypress": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-2.7.0.tgz",
@@ -7971,6 +8015,12 @@
"integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
"dev": true
},
+ "lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+ "dev": true
+ },
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
@@ -8099,6 +8149,15 @@
"safe-buffer": "^5.1.2"
}
},
+ "mdn-browser-compat-data": {
+ "version": "0.0.84",
+ "resolved": "https://registry.npmjs.org/mdn-browser-compat-data/-/mdn-browser-compat-data-0.0.84.tgz",
+ "integrity": "sha512-fAznuGNaQMQiWLVf+gyp33FaABTglYWqMT7JqvH+4RZn2UQPD12gbMqxwP9m0lj8AAbNpu5/kD6n4Ox1SOffpw==",
+ "dev": true,
+ "requires": {
+ "extend": "3.0.2"
+ }
+ },
"mdn-data": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
@@ -11391,6 +11450,12 @@
"regenerate": "^1.4.0"
}
},
+ "regenerator-runtime": {
+ "version": "0.13.3",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
+ "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==",
+ "dev": true
+ },
"regenerator-transform": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz",
diff --git a/package.json b/package.json
index 4cbf8e0..34a475d 100644
--- a/package.json
+++ b/package.json
@@ -67,6 +67,7 @@
"eslint-config-airbnb-base": "^14.0.0",
"eslint-config-prettier": "^6.4.0",
"eslint-loader": "^3.0.2",
+ "eslint-plugin-compat": "3.3.0",
"eslint-plugin-cypress": "^2.7.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-prettier": "^3.1.1",
diff --git a/public/assets/scripts/.eslintrc.js b/public/assets/scripts/.eslintrc.js
new file mode 100644
index 0000000..00f2747
--- /dev/null
+++ b/public/assets/scripts/.eslintrc.js
@@ -0,0 +1,24 @@
+
+// get polyfill settings from top level config
+// @ts-ignore
+const { settings } = require('../../../.eslintrc.json');
+
+// Adding non-polyfilable Symbol-related functions as they are most probably
+// behind the flag
+
+settings.polyfills.push('Symbol.toStringTag', 'Symbol.for', 'Object.getOwnPropertySymbols', 'Object.getOwnPropertyDescriptors')
+
+module.exports = /** @type {import('eslint').Linter.Config} */({
+ root: true,
+ extends: [
+ "plugin:compat/recommended"
+ ],
+ parserOptions: {
+ // ensure that it's compatible with ES5 browsers, so, no `const`, etc
+ ecmaVersion: 5
+ },
+ env: {
+ browser: true
+ },
+ settings
+})
diff --git a/public/index.html b/public/index.html
index 4a30614..e7a3581 100644
--- a/public/index.html
+++ b/public/index.html
@@ -47,7 +47,7 @@
-
+
diff --git a/src/scripts/actions/general.js b/src/scripts/actions/general.js
index e41217c..06e59a3 100644
--- a/src/scripts/actions/general.js
+++ b/src/scripts/actions/general.js
@@ -1,5 +1,3 @@
-/* eslint-disable import/prefer-default-export */
-
export const setIsLoading = isLoading => ({
type: 'SET_IS_LOADING',
isLoading,
diff --git a/src/scripts/actions/groups.js b/src/scripts/actions/groups.js
index 8862b7f..2b29679 100644
--- a/src/scripts/actions/groups.js
+++ b/src/scripts/actions/groups.js
@@ -1,6 +1,5 @@
import { ACTION_TYPES } from '../constants';
-/* eslint-disable import/prefer-default-export */
export const addGroup = (value, id, active, disabled) => ({
type: ACTION_TYPES.ADD_GROUP,
value,