From 9b52b7b8d5dde8f5acb30478abb8d47fc3f78c8f Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Fri, 12 Jun 2020 21:43:39 +0300 Subject: [PATCH 1/2] Switch to xo and remove babel-eslint --- .eslintignore | 1 + .eslintrc.json | 268 ++++------------------ build/.eslintrc.json | 7 +- js/tests/unit/.eslintrc.json | 71 +++--- package-lock.json | 431 +++++++++++++++++++++++++++++++++++ package.json | 4 +- site/.eslintrc.json | 47 ++-- 7 files changed, 549 insertions(+), 280 deletions(-) diff --git a/.eslintignore b/.eslintignore index 9eb685cbe476..10b147b830e3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ **/vendor/ /_gh_pages/ /js/coverage/ +/site/sw.js /package.js diff --git a/.eslintrc.json b/.eslintrc.json index d61d2f9d14d2..f8e70335f000 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,231 +1,57 @@ { "root": true, - "parser": "babel-eslint", - "env": { - "browser": true, - "es6": true - }, - "extends": ["eslint:recommended"], + "extends": [ + "plugin:import/errors", + "plugin:import/warnings", + "plugin:unicorn/recommended", + "xo/esnext", + "xo/browser" + ], "rules": { - // Possible Errors - "no-await-in-loop": "error", - "no-extra-parens": "error", - "no-prototype-builtins": "error", - "no-template-curly-in-string": "error", - "valid-jsdoc": "error", - - // Best Practices - "accessor-pairs": "error", - "array-callback-return": "error", - "block-scoped-var": "error", - "class-methods-use-this": "off", - "complexity": "error", - "consistent-return": "error", - "curly": "error", - "default-case": "error", - "dot-location": ["error", "property"], - "dot-notation": "error", - "eqeqeq": "error", - "guard-for-in": "error", - "no-alert": "error", - "no-caller": "error", - "no-console": "error", - "no-div-regex": "error", - "no-else-return": "error", - "no-empty-function": "error", - "no-eq-null": "error", - "no-eval": "error", - "no-extend-native": "error", - "no-extra-bind": "error", - "no-extra-label": "error", - "no-floating-decimal": "error", - "no-implicit-coercion": "error", - "no-implicit-globals": "error", - "no-implied-eval": "error", - "no-invalid-this": "off", - "no-iterator": "error", - "no-labels": "error", - "no-lone-blocks": "error", - "no-loop-func": "error", - "no-magic-numbers": ["error", { - "ignore": [-1, 0, 1], - "ignoreArrayIndexes": true + "capitalized-comments": "off", + "indent": [ + "error", + 2, + { + "MemberExpression": "off", + "SwitchCase": 1 } ], - "no-multi-spaces": ["error", { - "ignoreEOLComments": true, - "exceptions": { - "AssignmentExpression": true, - "ArrowFunctionExpression": true, - "CallExpression": true, - "VariableDeclarator": true - } - } + "max-params": [ + "warn", + 5 ], - "no-multi-str": "error", - "no-new": "error", - "no-new-func": "error", - "no-new-wrappers": "error", - "no-octal-escape": "error", - "no-param-reassign": "off", - "no-proto": "error", - "no-restricted-properties": "error", - "no-return-assign": "error", - "no-return-await": "error", - "no-script-url": "error", - "no-self-compare": "error", - "no-sequences": "error", - "no-throw-literal": "error", - "no-unmodified-loop-condition": "error", - "no-unused-expressions": "error", - "no-useless-call": "error", - "no-useless-concat": "error", - "no-useless-return": "error", - "no-void": "error", - "no-warning-comments": "off", - "no-with": "error", - "prefer-promise-reject-errors": "error", - "radix": "error", - "require-await": "error", - "vars-on-top": "error", - "wrap-iife": "error", - "yoda": "error", - - // Strict Mode - "strict": "error", - - // Variables - "init-declarations": "off", - "no-catch-shadow": "error", - "no-label-var": "error", - "no-restricted-globals": "error", - "no-shadow": "off", - "no-shadow-restricted-names": "error", - "no-undef-init": "error", - "no-use-before-define": "off", - - // Node.js and CommonJS - "callback-return": "off", - "global-require": "error", - "handle-callback-err": "error", - "no-mixed-requires": "error", - "no-new-require": "error", - "no-path-concat": "error", - "no-process-exit": "error", - "no-restricted-modules": "error", - "no-sync": "error", - - // Stylistic Issues - "array-bracket-spacing": "error", - "block-spacing": "error", - "brace-style": "error", - "camelcase": "error", - "capitalized-comments": "off", - "comma-dangle": "error", - "comma-spacing": "error", - "comma-style": "error", - "computed-property-spacing": "error", - "consistent-this": "error", - "eol-last": "error", - "func-call-spacing": "error", - "func-name-matching": "error", - "func-names": "off", - "func-style": ["error", "declaration"], - "id-blacklist": "error", - "id-length": "off", - "id-match": "error", - "indent": ["error", 2, { "SwitchCase": 1 }], - "jsx-quotes": "error", - "key-spacing": "off", - "keyword-spacing": "error", - "linebreak-style": ["error", "unix"], - "line-comment-position": "off", - "lines-around-comment": "off", - "lines-around-directive": "error", - "max-depth": ["error", 10], - "max-len": "off", - "max-lines": "off", - "max-nested-callbacks": "error", - "max-params": "off", - "max-statements": "off", - "max-statements-per-line": "error", - "multiline-ternary": "off", - "new-cap": ["error", { "capIsNewExceptionPattern": "$.*" }], - "newline-after-var": "off", - "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 5 }], - "new-parens": "error", - "no-array-constructor": "error", - "no-bitwise": "error", - "no-continue": "off", - "no-inline-comments": "off", - "no-lonely-if": "error", + "new-cap": "off", + "no-console": "error", "no-mixed-operators": "off", - "no-multi-assign": "error", - "no-multiple-empty-lines": "error", - "nonblock-statement-body-position": "error", "no-negated-condition": "off", - "no-nested-ternary": "error", - "no-new-object": "error", - "no-plusplus": "off", - "no-restricted-syntax": "error", - "no-tabs": "error", - "no-ternary": "off", - "no-trailing-spaces": "error", - "no-underscore-dangle": "off", - "no-unneeded-ternary": "error", - "no-whitespace-before-property": "error", - "object-curly-spacing": ["error", "always"], - "object-property-newline": "error", - "one-var": ["error", "never"], - "one-var-declaration-per-line": "error", - "operator-assignment": "error", - "operator-linebreak": "error", - "padded-blocks": ["error", "never"], - "padding-line-between-statements": "off", - "quote-props": ["error", "as-needed"], - "quotes": ["error", "single"], - "require-jsdoc": "off", - "semi": ["error", "never"], - "semi-spacing": "error", - "sort-keys": "off", - "sort-vars": "error", - "space-before-blocks": "error", - "space-before-function-paren": ["error", { - "anonymous": "always", - "named": "never" - }], - "space-in-parens": "error", - "space-infix-ops": "error", - "space-unary-ops": "error", - "spaced-comment": "error", - "template-tag-spacing": "error", - "unicode-bom": "error", - "wrap-regex": "off", - - // ECMAScript 6 - "arrow-body-style": ["error", "as-needed"], - "arrow-parens": "error", - "arrow-spacing": "error", - "generator-star-spacing": "error", - "no-confusing-arrow": "error", - "no-duplicate-imports": "error", - "no-restricted-imports": "error", - "no-useless-computed-key": "error", - "no-useless-constructor": "error", - "no-useless-rename": "error", - "no-var": "error", - "object-shorthand": "error", - "prefer-arrow-callback": "error", - "prefer-const": "error", - "prefer-destructuring": "off", - "prefer-numeric-literals": "error", - "prefer-rest-params": "error", - "prefer-spread": "error", - "prefer-template": "error", - "rest-spread-spacing": "error", - "sort-imports": "error", - "symbol-description": "error", - "template-curly-spacing": "error", - "yield-star-spacing": "error" + "object-curly-spacing": [ + "error", + "always" + ], + "prefer-named-capture-group": "off", + "semi": [ + "error", + "never" + ], + "unicorn/consistent-function-scoping": "off", + "unicorn/explicit-length-check": "off", + "unicorn/import-index": "off", + "unicorn/no-fn-reference-in-iterator": "off", + "unicorn/no-for-loop": "off", + "unicorn/no-null": "off", + "unicorn/no-unused-properties": "error", + "unicorn/no-useless-undefined": "off", + "unicorn/prefer-array-find": "off", + "unicorn/prefer-dataset": "off", + "unicorn/prefer-includes": "off", + "unicorn/prefer-node-append": "off", + "unicorn/prefer-node-remove": "off", + "unicorn/prefer-number-properties": "off", + "unicorn/prefer-optional-catch-binding": "off", + "unicorn/prefer-query-selector": "off", + "unicorn/prefer-reflect-apply": "off", + "unicorn/prefer-set-has": "off", + "unicorn/prevent-abbreviations": "off" } } diff --git a/build/.eslintrc.json b/build/.eslintrc.json index e406f9f69d3d..679bd26f7ba2 100644 --- a/build/.eslintrc.json +++ b/build/.eslintrc.json @@ -8,12 +8,7 @@ }, "extends": "../.eslintrc.json", "rules": { - "consistent-return": "off", - "func-style": "off", "no-console": "off", - "no-magic-numbers": "off", - "no-process-exit": "off", - "no-sync": "off", - "spaced-comment": "off" + "strict": "error" } } diff --git a/js/tests/unit/.eslintrc.json b/js/tests/unit/.eslintrc.json index 86d851ad06d0..85369c3a01fe 100644 --- a/js/tests/unit/.eslintrc.json +++ b/js/tests/unit/.eslintrc.json @@ -1,40 +1,35 @@ { - "env": { - "es6": false, - "jquery": true, - "qunit": true - }, - "globals": { - "bootstrap": false, - "sinon": false, - "Util": false, - "Alert": false, - "Button": false, - "Carousel": false, - "Simulator": false, - "Toast": false - }, - "parserOptions": { - "ecmaVersion": 5, - "sourceType": "script" - }, - "extends": "../../../.eslintrc.json", - "rules": { - "no-console": "error", - // Best Practices - "consistent-return": "off", - "no-magic-numbers": "off", - "vars-on-top": "off", - - // Stylistic Issues - "func-style": "off", - "spaced-comment": "off", - - // ECMAScript 6 - "no-var": "off", - "object-shorthand": "off", - "prefer-arrow-callback": "off", - "prefer-template": "off", - "prefer-rest-params": "off" - } + "extends": [ + "../../../.eslintrc.json" + ], + "overrides": [ + { + "files": [ + "*.js" + ], + "env": { + "es6": false, + "jquery": true, + "qunit": true + }, + "globals": { + "bootstrap": false, + "sinon": false, + "Util": false, + "Alert": false, + "Button": false, + "Carousel": false, + "Simulator": false, + "Toast": false + }, + "rules": { + // ES6 + "no-var": "off", + "object-shorthand": "off", + "prefer-arrow-callback": "off", + "prefer-template": "off", + "prefer-rest-params": "off" + } + } + ] } diff --git a/package-lock.json b/package-lock.json index 26d32b45df33..a4bd407a6e43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1244,6 +1244,12 @@ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, "@types/minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", @@ -1470,6 +1476,17 @@ "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", "dev": true }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -1483,6 +1500,16 @@ "dev": true, "optional": true }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", @@ -2363,6 +2390,15 @@ } } }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, "cli-boxes": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", @@ -2570,6 +2606,12 @@ } } }, + "confusing-browser-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", + "dev": true + }, "connect": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", @@ -2588,6 +2630,12 @@ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -3384,6 +3432,228 @@ } } }, + "eslint-ast-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz", + "integrity": "sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==", + "dev": true, + "requires": { + "lodash.get": "^4.4.2", + "lodash.zip": "^4.2.0" + } + }, + "eslint-config-xo": { + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.32.1.tgz", + "integrity": "sha512-achnYLilUTtljR1CGRikVj9HRAf5GplJeGgeyQMvph7mKo+AqTkNuig4EO/IrNOChcjoazgw9YT4cW/3+69i3Q==", + "dev": true, + "requires": { + "confusing-browser-globals": "1.0.9" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz", + "integrity": "sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.3", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "eslint-plugin-unicorn": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-21.0.0.tgz", + "integrity": "sha512-S8v7+v4gZTQPj4pKKvexhgSUaLQSyItvxW2SVZDaX9Iu5IjlAmF2eni+L6w8a2aqshxgU8Lle4FIAVDtuejSKQ==", + "dev": true, + "requires": { + "ci-info": "^2.0.0", + "clean-regexp": "^1.0.0", + "eslint-ast-utils": "^1.1.0", + "eslint-template-visitor": "^2.0.0", + "eslint-utils": "^2.1.0", + "import-modules": "^2.0.0", + "lodash": "^4.17.15", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.21", + "reserved-words": "^0.1.2", + "safe-regex": "^2.1.1", + "semver": "^7.3.2" + }, + "dependencies": { + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, "eslint-scope": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", @@ -3394,6 +3664,18 @@ "estraverse": "^4.1.1" } }, + "eslint-template-visitor": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.2.1.tgz", + "integrity": "sha512-q3SxoBXz0XjPGkUpwGVAwIwIPIxzCAJX1uwfVc8tW3v7u/zS7WXNH3I2Mu2MDz2NgSITAyKLRaQFPHu/iyKxDQ==", + "dev": true, + "requires": { + "babel-eslint": "^10.1.0", + "eslint-visitor-keys": "^1.3.0", + "esquery": "^1.3.1", + "multimap": "^1.1.0" + } + }, "eslint-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", @@ -4676,6 +4958,12 @@ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, + "import-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.0.0.tgz", + "integrity": "sha512-iczM/v9drffdNnABOKwj0f9G3cFDon99VcG1mxeBsdqnbd+vnQ5c2uAiCHNQITqFTOPaEvwg3VjoWCur0uHLEw==", + "dev": true + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -5046,6 +5334,12 @@ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", "dev": true }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -5855,12 +6149,24 @@ "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", + "dev": true + }, "log-symbols": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", @@ -6205,6 +6511,12 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "multimap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz", + "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==", + "dev": true + }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", @@ -6981,6 +7293,18 @@ "isobject": "^3.0.1" } }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -7355,6 +7679,72 @@ "pinkie": "^2.0.0" } }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, "popper.js": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", @@ -8065,6 +8455,12 @@ "safe-regex": "^1.1.0" } }, + "regexp-tree": { + "version": "0.1.21", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.21.tgz", + "integrity": "sha512-kUUXjX4AnqnR8KRTCrayAo9PzYMRKmVoGgaz2tBuz0MF3g1ZbGebmtW0yFHfFK9CmBjQKeYIgoL22pFLBJY7sw==", + "dev": true + }, "regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", @@ -8272,6 +8668,12 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, + "reserved-words": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", + "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=", + "dev": true + }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -9849,6 +10251,35 @@ "glob": "^7.1.2" } }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", diff --git a/package.json b/package.json index 0b45421bbd9d..2a31c985705c 100644 --- a/package.json +++ b/package.json @@ -116,12 +116,14 @@ "@rollup/plugin-commonjs": "^14.0.0", "@rollup/plugin-node-resolve": "^8.4.0", "autoprefixer": "^9.8.6", - "babel-eslint": "^10.1.0", "babel-plugin-istanbul": "^6.0.0", "bundlewatch": "^0.2.7", "clean-css-cli": "^4.3.0", "cross-env": "^7.0.2", "eslint": "^7.6.0", + "eslint-config-xo": "^0.32.1", + "eslint-plugin-import": "^2.22.0", + "eslint-plugin-unicorn": "^21.0.0", "find-unused-sass-variables": "^2.0.0", "glob": "^7.1.6", "hammer-simulator": "0.0.1", diff --git a/site/.eslintrc.json b/site/.eslintrc.json index 04ac49314708..e911d46b27dc 100644 --- a/site/.eslintrc.json +++ b/site/.eslintrc.json @@ -1,4 +1,5 @@ { + "root": true, "env": { "es6": false, "jquery": true @@ -7,20 +8,38 @@ "ecmaVersion": 5, "sourceType": "script" }, - "extends": "../.eslintrc.json", + "extends": [ + "plugin:unicorn/recommended", + "xo", + "xo/browser" + ], "rules": { - // Best Practices - "no-magic-numbers": "off", - "vars-on-top": "off", - - // Stylistic Issues - "spaced-comment": "off", - - // ECMAScript 6 - "no-var": "off", - "object-shorthand": "off", - "prefer-arrow-callback": "off", - "prefer-template": "off", - "prefer-rest-params": "off" + "capitalized-comments": "off", + "indent": [ + "error", + 2, + { + "MemberExpression": "off", + "SwitchCase": 1 + } + ], + "object-curly-spacing": [ + "error", + "always" + ], + "semi": [ + "error", + "never" + ], + "strict": "error", + "unicorn/no-for-loop": "off", + "unicorn/no-null": "off", + "unicorn/prefer-array-find": "off", + "unicorn/prefer-dataset": "off", + "unicorn/prefer-includes": "off", + "unicorn/prefer-number-properties": "off", + "unicorn/prefer-node-append": "off", + "unicorn/prefer-query-selector": "off", + "unicorn/prevent-abbreviations": "off" } } From 272d3f6436f7a89a371ec663e99191d78b609846 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Fri, 12 Jun 2020 21:50:30 +0300 Subject: [PATCH 2/2] Comply to the new rules --- build/build-plugins.js | 4 +- build/change-version.js | 13 +- build/generate-sri.js | 2 +- build/postcss.config.js | 2 +- build/zip-examples.js | 2 +- js/src/alert.js | 30 +-- js/src/button.js | 35 +-- js/src/carousel.js | 200 +++++++++--------- js/src/collapse.js | 65 +++--- js/src/dropdown.js | 128 +++++------ js/src/modal.js | 139 ++++++------ js/src/popover.js | 48 +++-- js/src/scrollspy.js | 116 +++++----- js/src/tab.js | 47 ++-- js/src/toast.js | 48 ++--- js/src/tools/sanitizer.js | 4 +- js/src/tooltip.js | 188 ++++++++-------- js/src/util.js | 11 +- js/tests/browsers.js | 4 +- js/tests/karma.conf.js | 2 +- js/tests/unit/carousel.js | 14 +- js/tests/unit/collapse.js | 16 +- js/tests/unit/dropdown.js | 4 +- js/tests/unit/modal.js | 8 +- js/tests/unit/popover.js | 8 +- js/tests/unit/scrollspy.js | 4 +- js/tests/unit/tab.js | 8 +- js/tests/unit/toast.js | 4 +- js/tests/unit/tooltip.js | 12 +- js/tests/unit/util.js | 4 +- site/docs/4.5/assets/js/src/application.js | 6 +- .../js/src/ie-emulation-modes-warning.js | 7 +- site/docs/4.5/assets/js/src/search.js | 8 +- .../4.5/examples/checkout/form-validation.js | 3 +- site/docs/4.5/examples/dashboard/dashboard.js | 2 +- 35 files changed, 614 insertions(+), 582 deletions(-) diff --git a/build/build-plugins.js b/build/build-plugins.js index 3829bb294cb8..521450f8568c 100644 --- a/build/build-plugins.js +++ b/build/build-plugins.js @@ -39,7 +39,7 @@ const bsPlugins = { } const rootPath = TEST ? '../js/coverage/dist/' : '../js/dist/' -const build = async (plugin) => { +const build = async plugin => { console.log(`Building ${plugin} plugin...`) const external = ['jquery', 'popper.js'] @@ -81,7 +81,7 @@ const build = async (plugin) => { const main = async () => { try { - await Promise.all(Object.keys(bsPlugins).map((plugin) => build(plugin))) + await Promise.all(Object.keys(bsPlugins).map(plugin => build(plugin))) } catch (error) { console.error(error) diff --git a/build/change-version.js b/build/change-version.js index d1131237c135..e2de874d7f87 100755 --- a/build/change-version.js +++ b/build/change-version.js @@ -30,18 +30,21 @@ function walkAsync(directory, excludedDirectories, fileCallback, errback) { if (excludedDirectories.has(path.parse(directory).base)) { return } + fs.readdir(directory, (err, names) => { if (err) { errback(err) return } - names.forEach((name) => { + + names.forEach(name => { const filepath = path.join(directory, name) fs.lstat(filepath, (err, stats) => { if (err) { process.nextTick(errback, err) return } + if (stats.isDirectory()) { process.nextTick(walkAsync, filepath, excludedDirectories, fileCallback, errback) } else if (stats.isFile()) { @@ -55,18 +58,19 @@ function walkAsync(directory, excludedDirectories, fileCallback, errback) { function replaceRecursively(directory, excludedDirectories, allowedExtensions, original, replacement) { original = new RegExp(regExpQuote(original), 'g') replacement = regExpQuoteReplacement(replacement) - const updateFile = DRY_RUN ? (filepath) => { + const updateFile = DRY_RUN ? filepath => { if (allowedExtensions.has(path.parse(filepath).ext)) { console.log(`FILE: ${filepath}`) } else { console.log(`EXCLUDED:${filepath}`) } - } : (filepath) => { + } : filepath => { if (allowedExtensions.has(path.parse(filepath).ext)) { sh.sed('-i', original, replacement, filepath) } } - walkAsync(directory, excludedDirectories, updateFile, (err) => { + + walkAsync(directory, excludedDirectories, updateFile, err => { console.error('ERROR while traversing directory!:') console.error(err) process.exit(1) @@ -79,6 +83,7 @@ function main(args) { console.error('Got arguments:', args) process.exit(1) } + const oldVersion = args[0] const newVersion = args[1] const EXCLUDED_DIRS = new Set([ diff --git a/build/generate-sri.js b/build/generate-sri.js index d340b5378fad..972f8622ef27 100644 --- a/build/generate-sri.js +++ b/build/generate-sri.js @@ -49,7 +49,7 @@ const files = [ } ] -files.forEach((file) => { +files.forEach(file => { fs.readFile(file.file, 'utf8', (err, data) => { if (err) { throw err diff --git a/build/postcss.config.js b/build/postcss.config.js index 157291ffd2e2..bd307fa35da5 100644 --- a/build/postcss.config.js +++ b/build/postcss.config.js @@ -1,6 +1,6 @@ 'use strict' -module.exports = (ctx) => ({ +module.exports = ctx => ({ map: ctx.file.dirname.includes('examples') ? false : { inline: false, annotation: true, diff --git a/build/zip-examples.js b/build/zip-examples.js index 5d6d31454c7c..778d75f05bdb 100644 --- a/build/zip-examples.js +++ b/build/zip-examples.js @@ -43,7 +43,7 @@ sh.cp('-f', [ sh.rm(`${folderName}/index.html`) // get all examples' HTML files -sh.find(`${folderName}/**/*.html`).forEach((file) => { +sh.find(`${folderName}/**/*.html`).forEach(file => { const fileContents = sh.cat(file) .toString() .replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../') diff --git a/js/src/alert.js b/js/src/alert.js index 2cdb0f0238f8..29743aa9bc59 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -14,22 +14,22 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'alert' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.alert' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' -const JQUERY_NO_CONFLICT = $.fn[NAME] +const NAME = 'alert' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.alert' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' +const JQUERY_NO_CONFLICT = $.fn[NAME] const SELECTOR_DISMISS = '[data-dismiss="alert"]' -const EVENT_CLOSE = `close${EVENT_KEY}` -const EVENT_CLOSED = `closed${EVENT_KEY}` +const EVENT_CLOSE = `close${EVENT_KEY}` +const EVENT_CLOSED = `closed${EVENT_KEY}` const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` const CLASS_NAME_ALERT = 'alert' -const CLASS_NAME_FADE = 'fade' -const CLASS_NAME_SHOW = 'show' +const CLASS_NAME_FADE = 'fade' +const CLASS_NAME_SHOW = 'show' /** * ------------------------------------------------------------------------ @@ -74,7 +74,7 @@ class Alert { _getRootElement(element) { const selector = Util.getSelectorFromElement(element) - let parent = false + let parent = false if (selector) { parent = document.querySelector(selector) @@ -105,7 +105,7 @@ class Alert { const transitionDuration = Util.getTransitionDurationFromElement(element) $(element) - .one(Util.TRANSITION_END, (event) => this._destroyElement(element, event)) + .one(Util.TRANSITION_END, event => this._destroyElement(element, event)) .emulateTransitionEnd(transitionDuration) } @@ -121,7 +121,7 @@ class Alert { static _jQueryInterface(config) { return this.each(function () { const $element = $(this) - let data = $element.data(DATA_KEY) + let data = $element.data(DATA_KEY) if (!data) { data = new Alert(this) @@ -163,9 +163,9 @@ $(document).on( * ------------------------------------------------------------------------ */ -$.fn[NAME] = Alert._jQueryInterface +$.fn[NAME] = Alert._jQueryInterface $.fn[NAME].Constructor = Alert -$.fn[NAME].noConflict = () => { +$.fn[NAME].noConflict = () => { $.fn[NAME] = JQUERY_NO_CONFLICT return Alert._jQueryInterface } diff --git a/js/src/button.js b/js/src/button.js index 98fd8afce604..2aed6b09c718 100644 --- a/js/src/button.js +++ b/js/src/button.js @@ -13,29 +13,29 @@ import $ from 'jquery' * ------------------------------------------------------------------------ */ -const NAME = 'button' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.button' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' -const JQUERY_NO_CONFLICT = $.fn[NAME] +const NAME = 'button' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.button' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' +const JQUERY_NO_CONFLICT = $.fn[NAME] const CLASS_NAME_ACTIVE = 'active' const CLASS_NAME_BUTTON = 'btn' -const CLASS_NAME_FOCUS = 'focus' +const CLASS_NAME_FOCUS = 'focus' -const SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]' -const SELECTOR_DATA_TOGGLES = '[data-toggle="buttons"]' -const SELECTOR_DATA_TOGGLE = '[data-toggle="button"]' +const SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]' +const SELECTOR_DATA_TOGGLES = '[data-toggle="buttons"]' +const SELECTOR_DATA_TOGGLE = '[data-toggle="button"]' const SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle="buttons"] .btn' -const SELECTOR_INPUT = 'input:not([type="hidden"])' -const SELECTOR_ACTIVE = '.active' -const SELECTOR_BUTTON = '.btn' +const SELECTOR_INPUT = 'input:not([type="hidden"])' +const SELECTOR_ACTIVE = '.active' +const SELECTOR_BUTTON = '.btn' -const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` +const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` const EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` + `blur${EVENT_KEY}${DATA_API_KEY}` -const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` +const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` /** * ------------------------------------------------------------------------ @@ -85,6 +85,7 @@ class Button { if (input.type === 'checkbox' || input.type === 'radio') { input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE) } + $(input).trigger('change') } @@ -135,7 +136,7 @@ class Button { */ $(document) - .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, (event) => { + .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => { let button = event.target const initialButton = button @@ -158,7 +159,7 @@ $(document) } } }) - .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, (event) => { + .on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => { const button = $(event.target).closest(SELECTOR_BUTTON)[0] $(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type)) }) diff --git a/js/src/carousel.js b/js/src/carousel.js index d18cc8a1a028..8c03818ab0ea 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -14,75 +14,75 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'carousel' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.carousel' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' -const JQUERY_NO_CONFLICT = $.fn[NAME] -const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key -const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key +const NAME = 'carousel' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.carousel' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' +const JQUERY_NO_CONFLICT = $.fn[NAME] +const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key +const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch -const SWIPE_THRESHOLD = 40 +const SWIPE_THRESHOLD = 40 const Default = { - interval : 5000, - keyboard : true, - slide : false, - pause : 'hover', - wrap : true, - touch : true + interval: 5000, + keyboard: true, + slide: false, + pause: 'hover', + wrap: true, + touch: true } const DefaultType = { - interval : '(number|boolean)', - keyboard : 'boolean', - slide : '(boolean|string)', - pause : '(string|boolean)', - wrap : 'boolean', - touch : 'boolean' + interval: '(number|boolean)', + keyboard: 'boolean', + slide: '(boolean|string)', + pause: '(string|boolean)', + wrap: 'boolean', + touch: 'boolean' } -const DIRECTION_NEXT = 'next' -const DIRECTION_PREV = 'prev' -const DIRECTION_LEFT = 'left' -const DIRECTION_RIGHT = 'right' - -const EVENT_SLIDE = `slide${EVENT_KEY}` -const EVENT_SLID = `slid${EVENT_KEY}` -const EVENT_KEYDOWN = `keydown${EVENT_KEY}` -const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}` -const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}` -const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}` -const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}` -const EVENT_TOUCHEND = `touchend${EVENT_KEY}` -const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}` -const EVENT_POINTERUP = `pointerup${EVENT_KEY}` -const EVENT_DRAG_START = `dragstart${EVENT_KEY}` -const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` +const DIRECTION_NEXT = 'next' +const DIRECTION_PREV = 'prev' +const DIRECTION_LEFT = 'left' +const DIRECTION_RIGHT = 'right' + +const EVENT_SLIDE = `slide${EVENT_KEY}` +const EVENT_SLID = `slid${EVENT_KEY}` +const EVENT_KEYDOWN = `keydown${EVENT_KEY}` +const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}` +const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}` +const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}` +const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}` +const EVENT_TOUCHEND = `touchend${EVENT_KEY}` +const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}` +const EVENT_POINTERUP = `pointerup${EVENT_KEY}` +const EVENT_DRAG_START = `dragstart${EVENT_KEY}` +const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` -const CLASS_NAME_CAROUSEL = 'carousel' -const CLASS_NAME_ACTIVE = 'active' -const CLASS_NAME_SLIDE = 'slide' -const CLASS_NAME_RIGHT = 'carousel-item-right' -const CLASS_NAME_LEFT = 'carousel-item-left' -const CLASS_NAME_NEXT = 'carousel-item-next' -const CLASS_NAME_PREV = 'carousel-item-prev' +const CLASS_NAME_CAROUSEL = 'carousel' +const CLASS_NAME_ACTIVE = 'active' +const CLASS_NAME_SLIDE = 'slide' +const CLASS_NAME_RIGHT = 'carousel-item-right' +const CLASS_NAME_LEFT = 'carousel-item-left' +const CLASS_NAME_NEXT = 'carousel-item-next' +const CLASS_NAME_PREV = 'carousel-item-prev' const CLASS_NAME_POINTER_EVENT = 'pointer-event' -const SELECTOR_ACTIVE = '.active' +const SELECTOR_ACTIVE = '.active' const SELECTOR_ACTIVE_ITEM = '.active.carousel-item' -const SELECTOR_ITEM = '.carousel-item' -const SELECTOR_ITEM_IMG = '.carousel-item img' -const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev' -const SELECTOR_INDICATORS = '.carousel-indicators' -const SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]' -const SELECTOR_DATA_RIDE = '[data-ride="carousel"]' +const SELECTOR_ITEM = '.carousel-item' +const SELECTOR_ITEM_IMG = '.carousel-item img' +const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev' +const SELECTOR_INDICATORS = '.carousel-indicators' +const SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]' +const SELECTOR_DATA_RIDE = '[data-ride="carousel"]' const PointerType = { - TOUCH : 'touch', - PEN : 'pen' + TOUCH: 'touch', + PEN: 'pen' } /** @@ -92,20 +92,20 @@ const PointerType = { */ class Carousel { constructor(element, config) { - this._items = null - this._interval = null + this._items = null + this._interval = null this._activeElement = null - this._isPaused = false - this._isSliding = false - this.touchTimeout = null - this.touchStartX = 0 - this.touchDeltaX = 0 - - this._config = this._getConfig(config) - this._element = element + this._isPaused = false + this._isSliding = false + this.touchTimeout = null + this.touchStartX = 0 + this.touchDeltaX = 0 + + this._config = this._getConfig(config) + this._element = element this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS) - this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0 - this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent) + this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0 + this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent) this._addEventListeners() } @@ -195,9 +195,9 @@ class Carousel { return } - const direction = index > activeIndex - ? DIRECTION_NEXT - : DIRECTION_PREV + const direction = index > activeIndex ? + DIRECTION_NEXT : + DIRECTION_PREV this._slide(direction, this._items[index]) } @@ -206,13 +206,13 @@ class Carousel { $(this._element).off(EVENT_KEY) $.removeData(this._element, DATA_KEY) - this._items = null - this._config = null - this._element = null - this._interval = null - this._isPaused = null - this._isSliding = null - this._activeElement = null + this._items = null + this._config = null + this._element = null + this._interval = null + this._isPaused = null + this._isSliding = null + this._activeElement = null this._indicatorsElement = null } @@ -251,13 +251,13 @@ class Carousel { _addEventListeners() { if (this._config.keyboard) { - $(this._element).on(EVENT_KEYDOWN, (event) => this._keydown(event)) + $(this._element).on(EVENT_KEYDOWN, event => this._keydown(event)) } if (this._config.pause === 'hover') { $(this._element) - .on(EVENT_MOUSEENTER, (event) => this.pause(event)) - .on(EVENT_MOUSELEAVE, (event) => this.cycle(event)) + .on(EVENT_MOUSEENTER, event => this.pause(event)) + .on(EVENT_MOUSELEAVE, event => this.cycle(event)) } if (this._config.touch) { @@ -270,7 +270,7 @@ class Carousel { return } - const start = (event) => { + const start = event => { if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { this.touchStartX = event.originalEvent.clientX } else if (!this._pointerEvent) { @@ -278,7 +278,7 @@ class Carousel { } } - const move = (event) => { + const move = event => { // ensure swiping with one touch and not pinching if (event.originalEvent.touches && event.originalEvent.touches.length > 1) { this.touchDeltaX = 0 @@ -287,7 +287,7 @@ class Carousel { } } - const end = (event) => { + const end = event => { if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { this.touchDeltaX = event.originalEvent.clientX - this.touchStartX } @@ -306,22 +306,23 @@ class Carousel { if (this.touchTimeout) { clearTimeout(this.touchTimeout) } - this.touchTimeout = setTimeout((event) => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval) + + this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval) } } $(this._element.querySelectorAll(SELECTOR_ITEM_IMG)) - .on(EVENT_DRAG_START, (e) => e.preventDefault()) + .on(EVENT_DRAG_START, e => e.preventDefault()) if (this._pointerEvent) { - $(this._element).on(EVENT_POINTERDOWN, (event) => start(event)) - $(this._element).on(EVENT_POINTERUP, (event) => end(event)) + $(this._element).on(EVENT_POINTERDOWN, event => start(event)) + $(this._element).on(EVENT_POINTERUP, event => end(event)) this._element.classList.add(CLASS_NAME_POINTER_EVENT) } else { - $(this._element).on(EVENT_TOUCHSTART, (event) => start(event)) - $(this._element).on(EVENT_TOUCHMOVE, (event) => move(event)) - $(this._element).on(EVENT_TOUCHEND, (event) => end(event)) + $(this._element).on(EVENT_TOUCHSTART, event => start(event)) + $(this._element).on(EVENT_TOUCHMOVE, event => move(event)) + $(this._element).on(EVENT_TOUCHEND, event => end(event)) } } @@ -344,29 +345,29 @@ class Carousel { } _getItemIndex(element) { - this._items = element && element.parentNode - ? [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) - : [] + this._items = element && element.parentNode ? + [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) : + [] return this._items.indexOf(element) } _getItemByDirection(direction, activeElement) { const isNextDirection = direction === DIRECTION_NEXT const isPrevDirection = direction === DIRECTION_PREV - const activeIndex = this._getItemIndex(activeElement) - const lastItemIndex = this._items.length - 1 - const isGoingToWrap = isPrevDirection && activeIndex === 0 || + const activeIndex = this._getItemIndex(activeElement) + const lastItemIndex = this._items.length - 1 + const isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex if (isGoingToWrap && !this._config.wrap) { return activeElement } - const delta = direction === DIRECTION_PREV ? -1 : 1 + const delta = direction === DIRECTION_PREV ? -1 : 1 const itemIndex = (activeIndex + delta) % this._items.length - return itemIndex === -1 - ? this._items[this._items.length - 1] : this._items[itemIndex] + return itemIndex === -1 ? + this._items[this._items.length - 1] : this._items[itemIndex] } _triggerSlideEvent(relatedTarget, eventDirectionName) { @@ -402,7 +403,7 @@ class Carousel { _slide(direction, element) { const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM) const activeElementIndex = this._getItemIndex(activeElement) - const nextElement = element || activeElement && + const nextElement = element || activeElement && this._getItemByDirection(direction, activeElement) const nextElementIndex = this._getItemIndex(nextElement) const isCycling = Boolean(this._interval) @@ -525,6 +526,7 @@ class Carousel { if (typeof data[action] === 'undefined') { throw new TypeError(`No method named "${action}"`) } + data[action]() } else if (_config.interval && _config.ride) { data.pause() diff --git a/js/src/collapse.js b/js/src/collapse.js index 9e501e085a4b..04653b835eb9 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -14,38 +14,38 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'collapse' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.collapse' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' -const JQUERY_NO_CONFLICT = $.fn[NAME] +const NAME = 'collapse' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.collapse' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' +const JQUERY_NO_CONFLICT = $.fn[NAME] const Default = { - toggle : true, - parent : '' + toggle: true, + parent: '' } const DefaultType = { - toggle : 'boolean', - parent : '(string|element)' + toggle: 'boolean', + parent: '(string|element)' } -const EVENT_SHOW = `show${EVENT_KEY}` -const EVENT_SHOWN = `shown${EVENT_KEY}` -const EVENT_HIDE = `hide${EVENT_KEY}` -const EVENT_HIDDEN = `hidden${EVENT_KEY}` +const EVENT_SHOW = `show${EVENT_KEY}` +const EVENT_SHOWN = `shown${EVENT_KEY}` +const EVENT_HIDE = `hide${EVENT_KEY}` +const EVENT_HIDDEN = `hidden${EVENT_KEY}` const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` -const CLASS_NAME_SHOW = 'show' -const CLASS_NAME_COLLAPSE = 'collapse' +const CLASS_NAME_SHOW = 'show' +const CLASS_NAME_COLLAPSE = 'collapse' const CLASS_NAME_COLLAPSING = 'collapsing' -const CLASS_NAME_COLLAPSED = 'collapsed' +const CLASS_NAME_COLLAPSED = 'collapsed' -const DIMENSION_WIDTH = 'width' +const DIMENSION_WIDTH = 'width' const DIMENSION_HEIGHT = 'height' -const SELECTOR_ACTIVES = '.show, .collapsing' +const SELECTOR_ACTIVES = '.show, .collapsing' const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]' /** @@ -57,9 +57,9 @@ const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]' class Collapse { constructor(element, config) { this._isTransitioning = false - this._element = element - this._config = this._getConfig(config) - this._triggerArray = [].slice.call(document.querySelectorAll( + this._element = element + this._config = this._getConfig(config) + this._triggerArray = [].slice.call(document.querySelectorAll( `[data-toggle="collapse"][href="#${element.id}"],` + `[data-toggle="collapse"][data-target="#${element.id}"]` )) @@ -69,7 +69,7 @@ class Collapse { const elem = toggleList[i] const selector = Util.getSelectorFromElement(elem) const filterElement = [].slice.call(document.querySelectorAll(selector)) - .filter((foundElem) => foundElem === element) + .filter(foundElem => foundElem === element) if (selector !== null && filterElement.length > 0) { this._selector = selector @@ -119,7 +119,7 @@ class Collapse { if (this._parent) { actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES)) - .filter((elem) => { + .filter(elem => { if (typeof this._config.parent === 'string') { return elem.getAttribute('data-parent') === this._config.parent } @@ -254,10 +254,10 @@ class Collapse { dispose() { $.removeData(this._element, DATA_KEY) - this._config = null - this._parent = null - this._element = null - this._triggerArray = null + this._config = null + this._parent = null + this._element = null + this._triggerArray = null this._isTransitioning = null } @@ -324,8 +324,8 @@ class Collapse { static _jQueryInterface(config) { return this.each(function () { - const $this = $(this) - let data = $this.data(DATA_KEY) + const $this = $(this) + let data = $this.data(DATA_KEY) const _config = { ...Default, ...$this.data(), @@ -345,6 +345,7 @@ class Collapse { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`) } + data[config]() } }) @@ -369,8 +370,8 @@ $(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { $(selectors).each(function () { const $target = $(this) - const data = $target.data(DATA_KEY) - const config = data ? 'toggle' : $trigger.data() + const data = $target.data(DATA_KEY) + const config = data ? 'toggle' : $trigger.data() Collapse._jQueryInterface.call($target, config) }) }) diff --git a/js/src/dropdown.js b/js/src/dropdown.js index bfb1f668cc6a..8cfa5564ab44 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -15,66 +15,66 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'dropdown' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.dropdown' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' -const JQUERY_NO_CONFLICT = $.fn[NAME] -const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key -const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key -const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key -const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key -const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key +const NAME = 'dropdown' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.dropdown' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' +const JQUERY_NO_CONFLICT = $.fn[NAME] +const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key +const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key +const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key +const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key +const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse) -const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`) - -const EVENT_HIDE = `hide${EVENT_KEY}` -const EVENT_HIDDEN = `hidden${EVENT_KEY}` -const EVENT_SHOW = `show${EVENT_KEY}` -const EVENT_SHOWN = `shown${EVENT_KEY}` -const EVENT_CLICK = `click${EVENT_KEY}` -const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` +const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`) + +const EVENT_HIDE = `hide${EVENT_KEY}` +const EVENT_HIDDEN = `hidden${EVENT_KEY}` +const EVENT_SHOW = `show${EVENT_KEY}` +const EVENT_SHOWN = `shown${EVENT_KEY}` +const EVENT_CLICK = `click${EVENT_KEY}` +const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}` -const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}` - -const CLASS_NAME_DISABLED = 'disabled' -const CLASS_NAME_SHOW = 'show' -const CLASS_NAME_DROPUP = 'dropup' -const CLASS_NAME_DROPRIGHT = 'dropright' -const CLASS_NAME_DROPLEFT = 'dropleft' -const CLASS_NAME_MENURIGHT = 'dropdown-menu-right' +const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}` + +const CLASS_NAME_DISABLED = 'disabled' +const CLASS_NAME_SHOW = 'show' +const CLASS_NAME_DROPUP = 'dropup' +const CLASS_NAME_DROPRIGHT = 'dropright' +const CLASS_NAME_DROPLEFT = 'dropleft' +const CLASS_NAME_MENURIGHT = 'dropdown-menu-right' const CLASS_NAME_POSITION_STATIC = 'position-static' -const SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]' -const SELECTOR_FORM_CHILD = '.dropdown form' -const SELECTOR_MENU = '.dropdown-menu' -const SELECTOR_NAVBAR_NAV = '.navbar-nav' +const SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]' +const SELECTOR_FORM_CHILD = '.dropdown form' +const SELECTOR_MENU = '.dropdown-menu' +const SELECTOR_NAVBAR_NAV = '.navbar-nav' const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' -const PLACEMENT_TOP = 'top-start' -const PLACEMENT_TOPEND = 'top-end' -const PLACEMENT_BOTTOM = 'bottom-start' +const PLACEMENT_TOP = 'top-start' +const PLACEMENT_TOPEND = 'top-end' +const PLACEMENT_BOTTOM = 'bottom-start' const PLACEMENT_BOTTOMEND = 'bottom-end' -const PLACEMENT_RIGHT = 'right-start' -const PLACEMENT_LEFT = 'left-start' +const PLACEMENT_RIGHT = 'right-start' +const PLACEMENT_LEFT = 'left-start' const Default = { - offset : 0, - flip : true, - boundary : 'scrollParent', - reference : 'toggle', - display : 'dynamic', - popperConfig : null + offset: 0, + flip: true, + boundary: 'scrollParent', + reference: 'toggle', + display: 'dynamic', + popperConfig: null } const DefaultType = { - offset : '(number|string|function)', - flip : 'boolean', - boundary : '(string|element)', - reference : '(string|element)', - display : 'string', - popperConfig : '(null|object)' + offset: '(number|string|function)', + flip: 'boolean', + boundary: '(string|element)', + reference: '(string|element)', + display: 'string', + popperConfig: '(null|object)' } /** @@ -85,10 +85,10 @@ const DefaultType = { class Dropdown { constructor(element, config) { - this._element = element - this._popper = null - this._config = this._getConfig(config) - this._menu = this._getMenuElement() + this._element = element + this._popper = null + this._config = this._getConfig(config) + this._menu = this._getMenuElement() this._inNavbar = this._detectNavbar() this._addEventListeners() @@ -172,6 +172,7 @@ class Dropdown { if (this._config.boundary !== 'scrollParent') { $(parent).addClass(CLASS_NAME_POSITION_STATIC) } + this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()) } @@ -241,7 +242,7 @@ class Dropdown { // Private _addEventListeners() { - $(this._element).on(EVENT_CLICK, (event) => { + $(this._element).on(EVENT_CLICK, event => { event.preventDefault() event.stopPropagation() this.toggle() @@ -272,6 +273,7 @@ class Dropdown { this._menu = parent.querySelector(SELECTOR_MENU) } } + return this._menu } @@ -281,9 +283,9 @@ class Dropdown { // Handle dropup if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) { - placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) - ? PLACEMENT_TOPEND - : PLACEMENT_TOP + placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ? + PLACEMENT_TOPEND : + PLACEMENT_TOP } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) { placement = PLACEMENT_RIGHT } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) { @@ -291,6 +293,7 @@ class Dropdown { } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) { placement = PLACEMENT_BOTTOMEND } + return placement } @@ -302,7 +305,7 @@ class Dropdown { const offset = {} if (typeof this._config.offset === 'function') { - offset.fn = (data) => { + offset.fn = data => { data.offsets = { ...data.offsets, ...this._config.offset(data.offsets, this._element) || {} @@ -360,6 +363,7 @@ class Dropdown { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`) } + data[config]() } }) @@ -444,8 +448,8 @@ class Dropdown { // - If key is other than escape // - If key is not up or down => not a dropdown command // - If trigger inside the menu => not a dropdown command - if (/input|textarea/i.test(event.target.tagName) - ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && + if (/input|textarea/i.test(event.target.tagName) ? + event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { return @@ -455,7 +459,7 @@ class Dropdown { return } - const parent = Dropdown._getParentFromElement(this) + const parent = Dropdown._getParentFromElement(this) const isActive = $(parent).hasClass(CLASS_NAME_SHOW) if (!isActive && event.which === ESCAPE_KEYCODE) { @@ -475,7 +479,7 @@ class Dropdown { } const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)) - .filter((item) => $(item).is(':visible')) + .filter(item => $(item).is(':visible')) if (items.length === 0) { return @@ -514,7 +518,7 @@ $(document) event.stopPropagation() Dropdown._jQueryInterface.call($(this), 'toggle') }) - .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, (e) => { + .on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, e => { e.stopPropagation() }) diff --git a/js/src/modal.js b/js/src/modal.js index b67507b1ee1f..311c369ebb1d 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -14,54 +14,54 @@ import Util from './util' * ------------------------------------------------------------------------ */ -const NAME = 'modal' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.modal' -const EVENT_KEY = `.${DATA_KEY}` -const DATA_API_KEY = '.data-api' +const NAME = 'modal' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.modal' +const EVENT_KEY = `.${DATA_KEY}` +const DATA_API_KEY = '.data-api' const JQUERY_NO_CONFLICT = $.fn[NAME] -const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key +const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key const Default = { - backdrop : true, - keyboard : true, - focus : true, - show : true + backdrop: true, + keyboard: true, + focus: true, + show: true } const DefaultType = { - backdrop : '(boolean|string)', - keyboard : 'boolean', - focus : 'boolean', - show : 'boolean' + backdrop: '(boolean|string)', + keyboard: 'boolean', + focus: 'boolean', + show: 'boolean' } -const EVENT_HIDE = `hide${EVENT_KEY}` -const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}` -const EVENT_HIDDEN = `hidden${EVENT_KEY}` -const EVENT_SHOW = `show${EVENT_KEY}` -const EVENT_SHOWN = `shown${EVENT_KEY}` -const EVENT_FOCUSIN = `focusin${EVENT_KEY}` -const EVENT_RESIZE = `resize${EVENT_KEY}` -const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}` -const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}` -const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}` +const EVENT_HIDE = `hide${EVENT_KEY}` +const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}` +const EVENT_HIDDEN = `hidden${EVENT_KEY}` +const EVENT_SHOW = `show${EVENT_KEY}` +const EVENT_SHOWN = `shown${EVENT_KEY}` +const EVENT_FOCUSIN = `focusin${EVENT_KEY}` +const EVENT_RESIZE = `resize${EVENT_KEY}` +const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}` +const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}` +const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}` const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}` -const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` +const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` -const CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable' +const CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable' const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure' -const CLASS_NAME_BACKDROP = 'modal-backdrop' -const CLASS_NAME_OPEN = 'modal-open' -const CLASS_NAME_FADE = 'fade' -const CLASS_NAME_SHOW = 'show' -const CLASS_NAME_STATIC = 'modal-static' - -const SELECTOR_DIALOG = '.modal-dialog' -const SELECTOR_MODAL_BODY = '.modal-body' -const SELECTOR_DATA_TOGGLE = '[data-toggle="modal"]' -const SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]' -const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top' +const CLASS_NAME_BACKDROP = 'modal-backdrop' +const CLASS_NAME_OPEN = 'modal-open' +const CLASS_NAME_FADE = 'fade' +const CLASS_NAME_SHOW = 'show' +const CLASS_NAME_STATIC = 'modal-static' + +const SELECTOR_DIALOG = '.modal-dialog' +const SELECTOR_MODAL_BODY = '.modal-body' +const SELECTOR_DATA_TOGGLE = '[data-toggle="modal"]' +const SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]' +const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top' const SELECTOR_STICKY_CONTENT = '.sticky-top' /** @@ -72,15 +72,15 @@ const SELECTOR_STICKY_CONTENT = '.sticky-top' class Modal { constructor(element, config) { - this._config = this._getConfig(config) - this._element = element - this._dialog = element.querySelector(SELECTOR_DIALOG) - this._backdrop = null - this._isShown = false - this._isBodyOverflowing = false + this._config = this._getConfig(config) + this._element = element + this._dialog = element.querySelector(SELECTOR_DIALOG) + this._backdrop = null + this._isShown = false + this._isBodyOverflowing = false this._ignoreBackdropClick = false - this._isTransitioning = false - this._scrollbarWidth = 0 + this._isTransitioning = false + this._scrollbarWidth = 0 } // Getters @@ -131,11 +131,11 @@ class Modal { $(this._element).on( EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, - (event) => this.hide(event) + event => this.hide(event) ) $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => { - $(this._element).one(EVENT_MOUSEUP_DISMISS, (event) => { + $(this._element).one(EVENT_MOUSEUP_DISMISS, event => { if ($(event.target).is(this._element)) { this._ignoreBackdropClick = true } @@ -180,10 +180,10 @@ class Modal { $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS) if (transition) { - const transitionDuration = Util.getTransitionDurationFromElement(this._element) + const transitionDuration = Util.getTransitionDurationFromElement(this._element) $(this._element) - .one(Util.TRANSITION_END, (event) => this._hideModal(event)) + .one(Util.TRANSITION_END, event => this._hideModal(event)) .emulateTransitionEnd(transitionDuration) } else { this._hideModal() @@ -192,7 +192,7 @@ class Modal { dispose() { [window, this._element, this._dialog] - .forEach((htmlElement) => $(htmlElement).off(EVENT_KEY)) + .forEach(htmlElement => $(htmlElement).off(EVENT_KEY)) /** * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API` @@ -203,15 +203,15 @@ class Modal { $.removeData(this._element, DATA_KEY) - this._config = null - this._element = null - this._dialog = null - this._backdrop = null - this._isShown = null - this._isBodyOverflowing = null + this._config = null + this._element = null + this._dialog = null + this._backdrop = null + this._isShown = null + this._isBodyOverflowing = null this._ignoreBackdropClick = null - this._isTransitioning = null - this._scrollbarWidth = null + this._isTransitioning = null + this._scrollbarWidth = null } handleUpdate() { @@ -304,12 +304,13 @@ class Modal { if (this._config.focus) { this._element.focus() } + this._isTransitioning = false $(this._element).trigger(shownEvent) } if (transition) { - const transitionDuration = Util.getTransitionDurationFromElement(this._dialog) + const transitionDuration = Util.getTransitionDurationFromElement(this._dialog) $(this._dialog) .one(Util.TRANSITION_END, transitionComplete) @@ -322,7 +323,7 @@ class Modal { _enforceFocus() { $(document) .off(EVENT_FOCUSIN) // Guard against infinite focus loop - .on(EVENT_FOCUSIN, (event) => { + .on(EVENT_FOCUSIN, event => { if (document !== event.target && this._element !== event.target && $(this._element).has(event.target).length === 0) { @@ -333,7 +334,7 @@ class Modal { _setEscapeEvent() { if (this._isShown) { - $(this._element).on(EVENT_KEYDOWN_DISMISS, (event) => { + $(this._element).on(EVENT_KEYDOWN_DISMISS, event => { if (this._config.keyboard && event.which === ESCAPE_KEYCODE) { event.preventDefault() this.hide() @@ -348,7 +349,7 @@ class Modal { _setResizeEvent() { if (this._isShown) { - $(window).on(EVENT_RESIZE, (event) => this.handleUpdate(event)) + $(window).on(EVENT_RESIZE, event => this.handleUpdate(event)) } else { $(window).off(EVENT_RESIZE) } @@ -376,8 +377,8 @@ class Modal { } _showBackdrop(callback) { - const animate = $(this._element).hasClass(CLASS_NAME_FADE) - ? CLASS_NAME_FADE : '' + const animate = $(this._element).hasClass(CLASS_NAME_FADE) ? + CLASS_NAME_FADE : '' if (this._isShown && this._config.backdrop) { this._backdrop = document.createElement('div') @@ -389,11 +390,12 @@ class Modal { $(this._backdrop).appendTo(document.body) - $(this._element).on(EVENT_CLICK_DISMISS, (event) => { + $(this._element).on(EVENT_CLICK_DISMISS, event => { if (this._ignoreBackdropClick) { this._ignoreBackdropClick = false return } + if (event.target !== event.currentTarget) { return } @@ -563,6 +565,7 @@ class Modal { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`) } + data[config](relatedTarget) } else if (_config.show) { data.show(relatedTarget) @@ -585,8 +588,8 @@ $(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { target = document.querySelector(selector) } - const config = $(target).data(DATA_KEY) - ? 'toggle' : { + const config = $(target).data(DATA_KEY) ? + 'toggle' : { ...$(target).data(), ...$(this).data() } @@ -595,7 +598,7 @@ $(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { event.preventDefault() } - const $target = $(target).one(EVENT_SHOW, (showEvent) => { + const $target = $(target).one(EVENT_SHOW, showEvent => { if (showEvent.isDefaultPrevented()) { // Only register focus restorer if modal will actually get shown return diff --git a/js/src/popover.js b/js/src/popover.js index 885d16234905..c81a18bad813 100644 --- a/js/src/popover.js +++ b/js/src/popover.js @@ -14,20 +14,20 @@ import Tooltip from './tooltip' * ------------------------------------------------------------------------ */ -const NAME = 'popover' -const VERSION = '4.5.2' -const DATA_KEY = 'bs.popover' -const EVENT_KEY = `.${DATA_KEY}` -const JQUERY_NO_CONFLICT = $.fn[NAME] -const CLASS_PREFIX = 'bs-popover' -const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') +const NAME = 'popover' +const VERSION = '4.5.2' +const DATA_KEY = 'bs.popover' +const EVENT_KEY = `.${DATA_KEY}` +const JQUERY_NO_CONFLICT = $.fn[NAME] +const CLASS_PREFIX = 'bs-popover' +const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') const Default = { ...Tooltip.Default, - placement : 'right', - trigger : 'click', - content : '', - template : '