diff --git a/.babelrc.js b/.babelrc.js index 44a509954..51399697f 100644 --- a/.babelrc.js +++ b/.babelrc.js @@ -1,20 +1,12 @@ module.exports = { presets: [ [ - '@babel/env', + '@babel/preset-env', { loose: true, - modules: false, - exclude: ['transform-typeof-symbol'] + bugfixes: true, + modules: false } ] - ], - plugins: [ - '@babel/plugin-proposal-object-rest-spread' - ], - env: { - test: { - plugins: [ 'istanbul' ] - } - } + ] }; diff --git a/.browserslistrc b/.browserslistrc index 1bfd19753..b8e384bc9 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -1,13 +1,15 @@ # https://github.com/browserslist/browserslist#readme ->= 1% -last 1 major version +>= 0.5% +last 2 major versions not dead -Chrome >= 45 -Firefox >= 38 -Edge >= 12 -Explorer >= 10 -iOS >= 9 -Safari >= 9 -Android >= 4.4 -Opera >= 30 +Chrome >= 60 +Firefox >= 60 +# needed since Legacy Edge still has usage; 79 was the first Chromium Edge version +# should be removed in the future when its usage drops or when it's moved to dead browsers +not Edge < 79 +Firefox ESR +iOS >= 10 +Safari >= 10 +Android >= 6 +not Explorer <= 11 diff --git a/bundlesize.config.json b/.bundlewatch.config.json similarity index 53% rename from bundlesize.config.json rename to .bundlewatch.config.json index 91dd0823b..da47da480 100644 --- a/bundlesize.config.json +++ b/.bundlewatch.config.json @@ -6,39 +6,61 @@ }, { "path": "./dist/css/bootstrap-grid.min.css", - "maxSize": "6.25 kB" + "maxSize": "6 kB" }, { "path": "./dist/css/bootstrap-reboot.css", - "maxSize": "2 kB" + "maxSize": "2.25 kB" }, { "path": "./dist/css/bootstrap-reboot.min.css", "maxSize": "2 kB" }, + { + "path": "./dist/css/bootstrap-utilities.css", + "maxSize": "7.5 kB" + }, + { + "path": "./dist/css/bootstrap-utilities.min.css", + "maxSize": "6.75 kB" + }, { "path": "./dist/css/bootstrap.css", - "maxSize": "25.25 kB" + "maxSize": "24 kB" }, { "path": "./dist/css/bootstrap.min.css", - "maxSize": "23.25 kB" + "maxSize": "22 kB" }, { "path": "./dist/js/bootstrap.bundle.js", - "maxSize": "47.50 kB" + "maxSize": "41 kB" }, { "path": "./dist/js/bootstrap.bundle.min.js", - "maxSize": "22.25 kB" + "maxSize": "21.5 kB" + }, + { + "path": "./dist/js/bootstrap.esm.js", + "maxSize": "27 kB" + }, + { + "path": "./dist/js/bootstrap.esm.min.js", + "maxSize": "18 kB" }, { "path": "./dist/js/bootstrap.js", - "maxSize": "25 kB" + "maxSize": "28 kB" }, { "path": "./dist/js/bootstrap.min.js", "maxSize": "15.5 kB" } - ] + ], + "ci": { + "trackBranches": [ + "main", + "v4-dev" + ] + } } diff --git a/.editorconfig b/.editorconfig index 9d5248e86..f29d257cc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,6 +9,3 @@ indent_size = 2 indent_style = space insert_final_newline = true trim_trailing_whitespace = true - -[*.md] -trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore index 9eb685cbe..ae6baae7e 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,4 @@ **/vendor/ /_gh_pages/ /js/coverage/ -/package.js +/site/static/sw.js diff --git a/.eslintrc.json b/.eslintrc.json index e97ed0b0c..d5a54d46b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,234 +1,58 @@ { "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 - } - ], - "no-multi-spaces": ["error", { - "ignoreEOLComments": true, - "exceptions": { - "AssignmentExpression": true, - "ArrowFunctionExpression": true, - "CallExpression": true, - "VariableDeclarator": true - } - } - ], - "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-undefined": "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-env": "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", - "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-newline": ["error", { "minProperties": 1 }], - "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" + "indent": [ + "error", + 2, + { + "MemberExpression": "off", + "SwitchCase": 1 + } + ], + "max-params": [ + "warn", + 5 + ], + "multiline-ternary": [ + "error", + "always-multiline" + ], + "new-cap": [ + "error", + { + "properties": false + } + ], + "no-console": "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/no-array-callback-reference": "off", + "unicorn/no-for-loop": "off", + "unicorn/no-null": "off", + "unicorn/no-unused-properties": "error", + "unicorn/no-useless-undefined": "off", + "unicorn/prefer-dom-node-append": "off", + "unicorn/prefer-dom-node-dataset": "off", + "unicorn/prefer-dom-node-remove": "off", + "unicorn/prefer-optional-catch-binding": "off", + "unicorn/prefer-query-selector": "off", + "unicorn/prevent-abbreviations": "off" } } diff --git a/.gitattributes b/.gitattributes index 39813c758..40b1c3742 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,18 +1,8 @@ # Enforce Unix newlines -*.css text eol=lf -*.html text eol=lf -*.js text eol=lf -*.json text eol=lf -*.md text eol=lf -*.rb text eol=lf -*.scss text eol=lf -*.svg text eol=lf -*.txt text eol=lf -*.xml text eol=lf -*.yml text eol=lf +* text=auto eol=lf # Don't diff or textually merge source maps -*.map binary +*.map binary bootstrap.css linguist-vendored=false bootstrap.js linguist-vendored=false diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 6cd59b59b..32b30cdb3 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -19,7 +19,7 @@ and [submitting pull requests](#pull-requests), but please respect the following restrictions: * Please **do not** use the issue tracker for personal support requests. Stack - Overflow ([`bootstrap-4`](https://stackoverflow.com/questions/tagged/bootstrap-4) tag), + Overflow ([`bootstrap-5`](https://stackoverflow.com/questions/tagged/bootstrap-5) tag), [Slack](https://bootstrap-slack.herokuapp.com/) or [IRC](README.md#community) are better places to get help. * Please **do not** derail or troll issues. Keep the discussion on topic and @@ -58,14 +58,14 @@ Good bug reports are extremely helpful, so thanks! Guidelines for bug reports: -0. **[validate your HTML](https://html5.validator.nu/)** to ensure your +0. **[Validate your HTML](https://html5.validator.nu/)** to ensure your problem isn't caused by a simple error in your own code. 1. **Use the GitHub issue search** — check if the issue has already been reported. 2. **Check if the issue has been fixed** — try to reproduce it using the - latest `master` or development branch in the repository. + latest `main` (or `v4-dev` branch if the issue is about v4) in the repository. 3. **Isolate the problem** — ideally create a [reduced test case](https://css-tricks.com/reduced-test-cases/) and a live example. @@ -100,14 +100,13 @@ Example: ### Reporting upstream browser bugs Sometimes bugs reported to us are actually caused by bugs in the browser(s) themselves, not bugs in Bootstrap per se. -When feasible, we aim to report such upstream bugs to the relevant browser vendor(s), and then list them on our [Wall of Browser Bugs](https://getbootstrap.com/browser-bugs/) and [document them in MDN](https://developer.mozilla.org/en-US/docs/Web). -| Vendor(s) | Browser(s) | Rendering engine | Bug reporting website(s) | Notes | -| ------------- | ---------------------------- | ---------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------- | -| Mozilla | Firefox | Gecko | https://bugzilla.mozilla.org/enter_bug.cgi | "Core" is normally the right product option to choose. | -| Apple | Safari | WebKit | https://bugs.webkit.org/enter_bug.cgi?product=WebKit
https://bugreport.apple.com/ | In Apple's bug reporter, choose "Safari" as the product. | -| Google, Opera | Chrome, Chromium, Opera v15+ | Blink | https://bugs.chromium.org/p/chromium/issues/list | Click the "New issue" button. | -| Microsoft | Edge | EdgeHTML | https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/ | | +| Vendor(s) | Browser(s) | Rendering engine | Bug reporting website(s) | Notes | +| ------------- | ---------------------------- | ---------------- | ------------------------------------------------------ | -------------------------------------------------------- | +| Mozilla | Firefox | Gecko | https://bugzilla.mozilla.org/enter_bug.cgi | "Core" is normally the right product option to choose. | +| Apple | Safari | WebKit | https://bugs.webkit.org/enter_bug.cgi?product=WebKit | In Apple's bug reporter, choose "Safari" as the product. | +| Google, Opera | Chrome, Chromium, Opera v15+ | Blink | https://bugs.chromium.org/p/chromium/issues/list | Click the "New issue" button. | +| Microsoft | Edge | Blink | https://developer.microsoft.com/en-us/microsoft-edge/ | Go to "Help > Send Feedback" from the browser | ## Feature requests @@ -124,23 +123,25 @@ Good pull requests—patches, improvements, new features—are a fantastic help. They should remain focused in scope and avoid containing unrelated commits. -**Please ask first** before embarking on any significant pull request (e.g. +**Please ask first** before embarking on any **significant** pull request (e.g. implementing features, refactoring code, porting to a different language), otherwise you risk spending a lot of time working on something that the -project's developers might not want to merge into the project. +project's developers might not want to merge into the project. For trivial +things, or things that don't require a lot of your time, you can go ahead and +make a PR. Please adhere to the [coding guidelines](#code-guidelines) used throughout the project (indentation, accurate comments, etc.) and any other requirements (such as test coverage). -**Do not edit `bootstrap.css`, or `bootstrap.js` -directly!** Those files are automatically generated. You should edit the -source files in [`/bootstrap/scss/`](https://github.com/twbs/bootstrap/tree/master/scss) -and/or [`/bootstrap/js/src/`](https://github.com/twbs/bootstrap/tree/master/js/src) instead. +**Do not edit `bootstrap.css` or `bootstrap.js`, and do not commit +any dist files (`dist/` or `js/dist`).** Those files are automatically generated by our build tools. You should +edit the source files in [`/bootstrap/scss/`](https://github.com/twbs/bootstrap/tree/main/scss) +and/or [`/bootstrap/js/src/`](https://github.com/twbs/bootstrap/tree/main/js/src) instead. Similarly, when contributing to Bootstrap's documentation, you should edit the documentation source files in -[the `/bootstrap/site/docs/` directory of the `master` branch](https://github.com/twbs/bootstrap/tree/master/site/docs). +[the `/bootstrap/site/content/docs/` directory of the `main` branch](https://github.com/twbs/bootstrap/tree/main/site/content/docs). **Do not edit the `gh-pages` branch.** That branch is generated from the documentation source files and is managed separately by the Bootstrap Core Team. @@ -162,8 +163,8 @@ included in the project: 2. If you cloned a while ago, get the latest changes from upstream: ```bash - git checkout master - git pull upstream master + git checkout main + git pull upstream main ``` 3. Create a new topic branch (off the main project development branch) to @@ -182,7 +183,7 @@ included in the project: 5. Locally merge (or rebase) the upstream development branch into your topic branch: ```bash - git pull [--rebase] upstream master + git pull [--rebase] upstream main ``` 6. Push your topic branch up to your fork: @@ -192,7 +193,7 @@ included in the project: ``` 7. [Open a Pull Request](https://help.github.com/articles/about-pull-requests/) - with a clear title and description against the `master` branch. + with a clear title and description against the `main` branch. **IMPORTANT**: By submitting a patch, you agree to allow the project owners to license your work under the terms of the [MIT License](../LICENSE) (if it @@ -216,7 +217,7 @@ includes code changes) and under the terms of the [Adhere to the Code Guide.](https://codeguide.co/#css) - When feasible, default color palettes should comply with [WCAG color contrast guidelines](https://www.w3.org/TR/WCAG20/#visual-audio-contrast). -- Except in rare cases, don't remove default `:focus` styles (via e.g. `outline: none;`) without providing alternative styles. See [this A11Y Project post](https://a11yproject.com/posts/never-remove-css-outlines/) for more details. +- Except in rare cases, don't remove default `:focus` styles (via e.g. `outline: none;`) without providing alternative styles. See [this A11Y Project post](https://www.a11yproject.com/posts/2013-01-25-never-remove-css-outlines/) for more details. ### JS @@ -224,7 +225,6 @@ includes code changes) and under the terms of the - 2 spaces (no tabs) - strict mode - "Attractive" -- Don't use [jQuery event alias convenience methods](https://github.com/jquery/jquery/blob/master/src/event/alias.js) (such as `$().focus()`). Instead, use [`$().trigger(eventType, ...)`](https://api.jquery.com/trigger/) or [`$().on(eventType, ...)`](https://api.jquery.com/on/), depending on whether you're firing an event or listening for an event. (For example, `$().trigger('focus')` or `$().on('focus', function (event) { /* handle focus event */ })`) We do this to be compatible with custom builds of jQuery where the event aliases module has been excluded. ### Checking coding style diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..43ea984ba --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +open_collective: bootstrap diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md deleted file mode 100644 index 8971d44ad..000000000 --- a/.github/ISSUE_TEMPLATE/bug.md +++ /dev/null @@ -1,11 +0,0 @@ -Before opening: - -- [Search for duplicate or closed issues](https://github.com/twbs/bootstrap/issues?utf8=%E2%9C%93&q=is%3Aissue) -- [Validate](https://html5.validator.nu/) and [lint](https://github.com/twbs/bootlint#in-the-browser) any HTML to avoid common problems -- Read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/.github/CONTRIBUTING.md) - -Bug reports must include: - -- Operating system and version (Windows, macOS, Android, iOS, Win10 Mobile) -- Browser and version (Chrome, Firefox, Safari, IE, MS Edge, Opera 15+, Android Browser) -- [Reduced test case](https://css-tricks.com/reduced-test-cases/) and suggested fix using [CodePen](https://codepen.io/) or [JS Bin](https://jsbin.com/) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 2d77bb50e..70dcfd532 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,17 +1,20 @@ --- name: Bug report about: Tell us about a bug you may have identified in Bootstrap. +title: '' +labels: '' +assignees: '' --- Before opening: - [Search for duplicate or closed issues](https://github.com/twbs/bootstrap/issues?utf8=%E2%9C%93&q=is%3Aissue) -- [Validate](https://html5.validator.nu/) and [lint](https://github.com/twbs/bootlint#in-the-browser) any HTML to avoid common problems -- Read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/.github/CONTRIBUTING.md) +- [Validate](https://html5.validator.nu/) any HTML to avoid common problems +- Read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/main/.github/CONTRIBUTING.md) Bug reports must include: -- Operating system and version (Windows, macOS, Android, iOS, Win10 Mobile) -- Browser and version (Chrome, Firefox, Safari, IE, MS Edge, Opera 15+, Android Browser) -- [Reduced test case](https://css-tricks.com/reduced-test-cases/) and suggested fix using [CodePen](https://codepen.io/) or [JS Bin](https://jsbin.com/) +- Operating system and version (Windows, macOS, Android, iOS) +- Browser and version (Chrome, Firefox, Safari, Microsoft Edge, Opera, Android Browser) +- A [reduced test case](https://css-tricks.com/reduced-test-cases/) or suggested fix using [CodePen](https://codepen.io/) or [JS Bin](https://jsbin.com/) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..2913b45f0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,4 @@ +contact_links: + - name: Ask a question + url: https://github.com/twbs/bootstrap/discussions/new + about: Ask and discuss questions with other Bootstrap community members diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md deleted file mode 100644 index 4c13c86a5..000000000 --- a/.github/ISSUE_TEMPLATE/feature.md +++ /dev/null @@ -1,9 +0,0 @@ -Before opening: - -- [Search for duplicate or closed issues](https://github.com/twbs/bootstrap/issues?utf8=%E2%9C%93&q=is%3Aissue) -- Read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/.github/CONTRIBUTING.md) - -Feature requests must include: - -- As much detail as possible for what we should add and why it's important to Bootstrap -- Relevant links to prior art, screenshots, or live demos whenever possible diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index ed71d397d..422fa2bb4 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,13 +1,16 @@ --- name: Feature request about: Suggest an idea for a new feature in Bootstrap. +title: '' +labels: feature +assignees: '' --- Before opening: - [Search for duplicate or closed issues](https://github.com/twbs/bootstrap/issues?utf8=%E2%9C%93&q=is%3Aissue) -- Read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/.github/CONTRIBUTING.md) +- Read the [contributing guidelines](https://github.com/twbs/bootstrap/blob/main/.github/CONTRIBUTING.md) Feature requests must include: diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md index de3c4b552..c30bed3b4 100644 --- a/.github/SUPPORT.md +++ b/.github/SUPPORT.md @@ -8,4 +8,4 @@ For general troubleshooting or help getting started: - Join [the official Slack room](https://bootstrap-slack.herokuapp.com/). - Chat with fellow Bootstrappers in IRC. On the `irc.freenode.net` server, in the `##bootstrap` channel. -- Ask and explore Stack Overflow with the [`bootstrap-4`](https://stackoverflow.com/questions/tagged/bootstrap-4) tag. +- Ask and explore Stack Overflow with the [`bootstrap-5`](https://stackoverflow.com/questions/tagged/bootstrap-5) tag. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..29135b400 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,24 @@ +version: 2 +updates: + - package-ecosystem: npm + directory: "/" + schedule: + interval: weekly + day: tuesday + time: "12:00" + timezone: Europe/Athens + open-pull-requests-limit: 10 + reviewers: + - XhmikosR + labels: + - dependencies + - v5 + versioning-strategy: increase + rebase-strategy: disabled + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: weekly + day: tuesday + time: "12:00" + timezone: Europe/Athens diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 000000000..e2b70e03e --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,54 @@ +name-template: 'v$NEXT_MAJOR_VERSION' +tag-template: 'v$NEXT_MAJOR_VERSION' +prerelease: true +exclude-labels: + - 'skip-changelog' +categories: + - title: '❗ Breaking Changes' + labels: + - 'breaking-change' + - title: '🚀 Features' + labels: + - 'new-feature' + - 'feature' + - 'enhancement' + - title: '🐛 Bug fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - title: '⚡ Performance Improvements' + labels: + - 'performance' + - title: '🎨 CSS' + labels: + - 'css' + - title: '☕️ JavaScript' + labels: + - 'js' + - title: '📖 Docs' + labels: + - 'docs' + - title: '🌎 Accessibility' + labels: + - 'accessibility' + - title: '🔧 Utility API' + labels: + - 'utility API' + - 'utilities' + - title: '🏭 Tests' + labels: + - 'tests' + - title: '🧰 Misc' + labels: + - 'build' + - 'meta' + - 'chore' + - 'CI' + - title: '📦 Dependencies' + labels: + - 'dependencies' +change-template: '- #$NUMBER: $TITLE' +template: | + ## Changes + $CHANGES diff --git a/.github/workflows/browserstack.yml b/.github/workflows/browserstack.yml new file mode 100644 index 000000000..a12bffcf7 --- /dev/null +++ b/.github/workflows/browserstack.yml @@ -0,0 +1,44 @@ +name: BrowserStack + +on: + push: + +env: + FORCE_COLOR: 2 + NODE: 14 + +jobs: + browserstack: + runs-on: ubuntu-latest + if: github.repository == 'twbs/bootstrap' && (!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')) + timeout-minutes: 30 + + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: "${{ env.NODE }}" + + - name: Set up npm cache + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ env.NODE }}- + + - name: Install npm dependencies + run: npm ci + + - name: Run dist + run: npm run dist + + - name: Run BrowserStack tests + run: npm run js-test-cloud + env: + BROWSER_STACK_ACCESS_KEY: "${{ secrets.BROWSER_STACK_ACCESS_KEY }}" + BROWSER_STACK_USERNAME: "${{ secrets.BROWSER_STACK_USERNAME }}" diff --git a/.github/workflows/bundlewatch.yml b/.github/workflows/bundlewatch.yml new file mode 100644 index 000000000..b2bd5eed5 --- /dev/null +++ b/.github/workflows/bundlewatch.yml @@ -0,0 +1,45 @@ +name: Bundlewatch + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + +env: + FORCE_COLOR: 2 + NODE: 14 + +jobs: + bundlewatch: + runs-on: ubuntu-latest + + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: "${{ env.NODE }}" + + - name: Set up npm cache + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ env.NODE }}- + + - name: Install npm dependencies + run: npm ci + + - name: Run dist + run: npm run dist + + - name: Run bundlewatch + run: npm run bundlewatch + env: + BUNDLEWATCH_GITHUB_TOKEN: "${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}" + CI_BRANCH_BASE: main diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..469a5a4fc --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,36 @@ +name: "CodeQL" + +on: + push: + branches: + - main + - v4-dev + - "!dependabot/**" + pull_request: + # The branches below must be a subset of the branches above + branches: + - main + - v4-dev + schedule: + - cron: "0 2 * * 5" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: "javascript" + + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/css.yml b/.github/workflows/css.yml new file mode 100644 index 000000000..a28059d79 --- /dev/null +++ b/.github/workflows/css.yml @@ -0,0 +1,39 @@ +name: CSS + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + +env: + FORCE_COLOR: 2 + NODE: 14 + +jobs: + css: + runs-on: ubuntu-latest + + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: "${{ env.NODE }}" + + - name: Set up npm cache + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ env.NODE }}- + + - name: Install npm dependencies + run: npm ci + + - name: Build CSS + run: npm run css diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..150e4d16c --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,41 @@ +name: Docs + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + +env: + FORCE_COLOR: 2 + NODE: 14 + +jobs: + docs: + runs-on: ubuntu-latest + + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: "${{ env.NODE }}" + + - run: java -version + + - name: Set up npm cache + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ env.NODE }}- + + - name: Install npm dependencies + run: npm ci + + - name: Test docs + run: npm run docs diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml new file mode 100644 index 000000000..c56a2dfdd --- /dev/null +++ b/.github/workflows/js.yml @@ -0,0 +1,54 @@ +name: JS Tests + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + +env: + FORCE_COLOR: 2 + +jobs: + run: + name: Node ${{ matrix.node }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + node: [10, 12, 14] + + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + + - name: Set up npm cache + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }}} + restore-keys: | + ${{ runner.os }}-node-v${{ matrix.node }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ matrix.node }}- + + - name: Install npm dependencies + run: npm ci + + - name: Run dist + run: npm run js + + - name: Run JS tests + run: npm run js-test + + - name: Run Coveralls + uses: coverallsapp/github-action@master + if: matrix.node == 14 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + path-to-lcov: "./js/coverage/lcov.info" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 000000000..369aaced3 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,39 @@ +name: Lint + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + +env: + FORCE_COLOR: 2 + NODE: 14 + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: "${{ env.NODE }}" + + - name: Set up npm cache + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node-v${{ env.NODE }}-${{ hashFiles('package.json') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-node-v${{ env.NODE }}- + + - name: Install npm dependencies + run: npm ci + + - name: Lint + run: npm run lint diff --git a/.github/workflows/node-sass.yml b/.github/workflows/node-sass.yml new file mode 100644 index 000000000..ee64b2152 --- /dev/null +++ b/.github/workflows/node-sass.yml @@ -0,0 +1,30 @@ +name: CSS (node-sass) + +on: + push: + branches-ignore: + - "dependabot/**" + pull_request: + +env: + FORCE_COLOR: 2 + NODE: 14 + +jobs: + css: + runs-on: ubuntu-latest + + steps: + - name: Clone repository + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: "${{ env.NODE }}" + + - name: Build CSS with node-sass + run: | + npx --package node-sass@latest node-sass --version + npx --package node-sass@latest node-sass --output-style expanded --source-map true --source-map-contents true --precision 6 scss/ -o dist-sass/css/ + ls -Al dist-sass/css diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml new file mode 100644 index 000000000..1c4f4be9b --- /dev/null +++ b/.github/workflows/release-notes.yml @@ -0,0 +1,14 @@ +name: Release notes + +on: + push: + branches: + - main + +jobs: + update_release_draft: + runs-on: ubuntu-latest + steps: + - uses: release-drafter/release-drafter@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 9f1b9fb57..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: Tests -on: [push, pull_request] -env: - CI: true - -jobs: - run: - name: Node ${{ matrix.node }} - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - node: [6, 8, 12] - - steps: - - name: Clone repository - uses: actions/checkout@v1 - with: - fetch-depth: 3 - - - name: Set Node.js version - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node }} - - - name: Set up Ruby 2.4 - uses: actions/setup-ruby@v1 - with: - ruby-version: 2.4.x - - - name: Disable gem docs - run: 'echo "gem: --no-document" > ~/.gemrc' - - - name: Set up Bundler - run: gem install bundler -v "~> 1.17" - - - run: ruby --version - - run: gem --version - - run: bundle --version - - run: node --version - - run: npm --version - - run: java -version - - - name: Install npm dependencies - run: npm install - - - name: Install bundler dependencies - run: bundle install --deployment --jobs=3 --retry=3 --clean - - - name: Run tests - run: npm test - - - name: Run bundlesize - run: npm run bundlesize - if: matrix.node == 8 - env: - BUNDLESIZE_GITHUB_TOKEN: "${{ secrets.BUNDLESIZE_GITHUB_TOKEN }}" - - - name: Run BrowserStack tests - run: npm run js-test-cloud - if: matrix.node == 8 && github.repository == 'twbs/bootstrap' && github.event_name == 'push' - env: - BROWSER_STACK_ACCESS_KEY: "${{ secrets.BROWSER_STACK_ACCESS_KEY }}" - BROWSER_STACK_USERNAME: "${{ secrets.BROWSER_STACK_USERNAME }}" - - - name: Run Link Checker - run: npm run check-broken-links - if: matrix.node == 8 - - - name: Run Coveralls - uses: coverallsapp/github-action@master - if: matrix.node == 8 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - path-to-lcov: "./js/coverage/lcov.info" diff --git a/.gitignore b/.gitignore index fd07f09e0..0a0f88d15 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,8 @@ # Ignore docs files /_gh_pages/ -/site/.jekyll-metadata -/site/docs/**/dist/ -# Hugo folders +# Hugo resources folder /resources/ -# Ignore ruby/bundler files -/.bundle/ -/vendor/ -/.ruby-version - # Numerous always-ignore extensions *.diff *.err @@ -35,6 +28,9 @@ *.sublime-workspace nbproject Thumbs.db +/.vscode/ +# Local Netlify folder +.netlify # Komodo .komodotools diff --git a/.stylelintignore b/.stylelintignore index 7bc488e5f..e42e88938 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -2,3 +2,4 @@ **/dist/ **/vendor/ /_gh_pages/ +/js/coverage/ diff --git a/.stylelintrc b/.stylelintrc index 93af80b7d..c068d30b5 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -3,7 +3,16 @@ "stylelint-config-twbs-bootstrap/scss" ], "rules": { - "property-blacklist": [ + "declaration-property-value-disallowed-list": { + "border": "none", + "outline": "none" + }, + "function-disallowed-list": [ + "calc", + "lighten", + "darken" + ], + "property-disallowed-list": [ "border-radius", "border-top-left-radius", "border-top-right-radius", @@ -11,6 +20,12 @@ "border-bottom-left-radius", "transition" ], - "function-blacklist": ["calc"] + "scss/dollar-variable-default": [ + true, + { + "ignore": "local" + } + ], + "scss/selector-no-union-class-name": true } } diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 9d9922f25..5c6a4e727 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -8,19 +8,19 @@ In the interest of fostering an open and welcoming environment, we as contributo Examples of behavior that contributes to creating a positive environment include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities @@ -40,7 +40,4 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai ## Attribution -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html][version] - -[homepage]: https://www.contributor-covenant.org/ -[version]: https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 1.4, available at diff --git a/Gemfile b/Gemfile deleted file mode 100644 index f8e68fe11..000000000 --- a/Gemfile +++ /dev/null @@ -1,9 +0,0 @@ -source 'https://rubygems.org' - -group :development, :test do - gem 'jekyll', '~> 3.8.6' - gem 'jekyll-redirect-from', '~> 0.15.0' - gem 'jekyll-sitemap', '~> 1.4.0' - gem 'jekyll-toc', '~> 0.11.0' - gem 'wdm', '~> 0.1.1', :install_if => Gem.win_platform? -end diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 52e024d01..000000000 --- a/Gemfile.lock +++ /dev/null @@ -1,80 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - addressable (2.7.0) - public_suffix (>= 2.0.2, < 5.0) - colorator (1.1.0) - concurrent-ruby (1.1.5) - em-websocket (0.5.1) - eventmachine (>= 0.12.9) - http_parser.rb (~> 0.6.0) - eventmachine (1.2.7) - eventmachine (1.2.7-x64-mingw32) - ffi (1.11.3) - ffi (1.11.3-x64-mingw32) - forwardable-extended (2.6.0) - http_parser.rb (0.6.0) - i18n (0.9.5) - concurrent-ruby (~> 1.0) - jekyll (3.8.6) - addressable (~> 2.4) - colorator (~> 1.0) - em-websocket (~> 0.5) - i18n (~> 0.7) - jekyll-sass-converter (~> 1.0) - jekyll-watch (~> 2.0) - kramdown (~> 1.14) - liquid (~> 4.0) - mercenary (~> 0.3.3) - pathutil (~> 0.9) - rouge (>= 1.7, < 4) - safe_yaml (~> 1.0) - jekyll-redirect-from (0.15.0) - jekyll (>= 3.3, < 5.0) - jekyll-sass-converter (1.5.2) - sass (~> 3.4) - jekyll-sitemap (1.4.0) - jekyll (>= 3.7, < 5.0) - jekyll-toc (0.11.0) - nokogiri (~> 1.9) - jekyll-watch (2.2.1) - listen (~> 3.0) - kramdown (1.17.0) - liquid (4.0.3) - listen (3.2.0) - rb-fsevent (~> 0.10, >= 0.10.3) - rb-inotify (~> 0.9, >= 0.9.10) - mercenary (0.3.6) - mini_portile2 (2.4.0) - nokogiri (1.10.5) - mini_portile2 (~> 2.4.0) - nokogiri (1.10.5-x64-mingw32) - mini_portile2 (~> 2.4.0) - pathutil (0.16.2) - forwardable-extended (~> 2.6) - public_suffix (4.0.1) - rb-fsevent (0.10.3) - rb-inotify (0.10.0) - ffi (~> 1.0) - rouge (3.13.0) - safe_yaml (1.0.5) - sass (3.7.4) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - wdm (0.1.1) - -PLATFORMS - ruby - x64-mingw32 - -DEPENDENCIES - jekyll (~> 3.8.6) - jekyll-redirect-from (~> 0.15.0) - jekyll-sitemap (~> 1.4.0) - jekyll-toc (~> 0.11.0) - wdm (~> 0.1.1) - -BUNDLED WITH - 1.17.3 diff --git a/LICENSE b/LICENSE index 7d1e2311f..72dda234e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ The MIT License (MIT) -Copyright (c) 2011-2019 Twitter, Inc. -Copyright (c) 2011-2019 The Bootstrap Authors +Copyright (c) 2011-2021 Twitter, Inc. +Copyright (c) 2011-2021 The Bootstrap Authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index d70069ee2..f41498691 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

- Bootstrap logo + Bootstrap logo

@@ -9,12 +9,12 @@

Sleek, intuitive, and powerful front-end framework for faster and easier web development.
- Explore Bootstrap docs » + Explore Bootstrap docs »

- Report bug + Report bug · - Request feature + Request feature · Themes · @@ -22,6 +22,11 @@

+## Bootstrap 4 + +Our default branch is for development of our upcoming Bootstrap 5 release. Head to the [`v4-dev` branch](https://github.com/twbs/bootstrap/tree/v4-dev) to view the readme, documentation, and source code for Bootstrap 4. + + ## Table of contents - [Quick start](#quick-start) @@ -41,33 +46,35 @@ Several quick start options are available: -- [Download the latest release.](https://github.com/twbs/bootstrap/archive/v4.4.1.zip) +- [Download the latest release](https://github.com/twbs/bootstrap/archive/v5.0.0-beta1.zip) - Clone the repo: `git clone https://github.com/twbs/bootstrap.git` -- Install with [npm](https://www.npmjs.com/): `npm install bootstrap` -- Install with [yarn](https://yarnpkg.com/): `yarn add bootstrap@4.4.1` -- Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:4.4.1` +- Install with [npm](https://www.npmjs.com/): `npm install bootstrap@next` +- Install with [yarn](https://yarnpkg.com/): `yarn add bootstrap@next` +- Install with [Composer](https://getcomposer.org/): `composer require twbs/bootstrap:5.0.0-beta1` - Install with [NuGet](https://www.nuget.org/): CSS: `Install-Package bootstrap` Sass: `Install-Package bootstrap.sass` -Read the [Getting started page](https://getbootstrap.com/docs/4.4/getting-started/introduction/) for information on the framework contents, templates and examples, and more. +Read the [Getting started page](https://getbootstrap.com/docs/5.0/getting-started/introduction/) for information on the framework contents, templates and examples, and more. ## Status [![Slack](https://bootstrap-slack.herokuapp.com/badge.svg)](https://bootstrap-slack.herokuapp.com/) -[![Build Status](https://github.com/twbs/bootstrap/workflows/Tests/badge.svg)](https://github.com/twbs/bootstrap/actions?workflow=Tests) -[![npm version](https://img.shields.io/npm/v/bootstrap.svg)](https://www.npmjs.com/package/bootstrap) -[![Gem version](https://img.shields.io/gem/v/bootstrap.svg)](https://rubygems.org/gems/bootstrap) -[![Meteor Atmosphere](https://img.shields.io/badge/meteor-twbs%3Abootstrap-blue.svg)](https://atmospherejs.com/twbs/bootstrap) -[![Packagist Prerelease](https://img.shields.io/packagist/vpre/twbs/bootstrap.svg)](https://packagist.org/packages/twbs/bootstrap) -[![NuGet](https://img.shields.io/nuget/vpre/bootstrap.svg)](https://www.nuget.org/packages/bootstrap/absoluteLatest) -[![peerDependencies Status](https://img.shields.io/david/peer/twbs/bootstrap.svg)](https://david-dm.org/twbs/bootstrap?type=peer) -[![devDependency Status](https://img.shields.io/david/dev/twbs/bootstrap.svg)](https://david-dm.org/twbs/bootstrap?type=dev) -[![Coverage Status](https://img.shields.io/coveralls/github/twbs/bootstrap/v4-dev.svg)](https://coveralls.io/github/twbs/bootstrap?branch=v4-dev) -[![CSS gzip size](https://img.badgesize.io/twbs/bootstrap/v4-dev/dist/css/bootstrap.min.css?compression=gzip&label=CSS+gzip+size)](https://github.com/twbs/bootstrap/tree/v4-dev/dist/css/bootstrap.min.css) -[![JS gzip size](https://img.badgesize.io/twbs/bootstrap/v4-dev/dist/js/bootstrap.min.js?compression=gzip&label=JS+gzip+size)](https://github.com/twbs/bootstrap/tree/v4-dev/dist/js/bootstrap.min.js) +[![Build Status](https://github.com/twbs/bootstrap/workflows/JS%20Tests/badge.svg?branch=main)](https://github.com/twbs/bootstrap/actions?query=workflow%3AJS+Tests+branch%3Amain) +[![npm version](https://img.shields.io/npm/v/bootstrap)](https://www.npmjs.com/package/bootstrap) +[![Gem version](https://img.shields.io/gem/v/bootstrap)](https://rubygems.org/gems/bootstrap) +[![Meteor Atmosphere](https://img.shields.io/badge/meteor-twbs%3Abootstrap-blue)](https://atmospherejs.com/twbs/bootstrap) +[![Packagist Prerelease](https://img.shields.io/packagist/vpre/twbs/bootstrap)](https://packagist.org/packages/twbs/bootstrap) +[![NuGet](https://img.shields.io/nuget/vpre/bootstrap)](https://www.nuget.org/packages/bootstrap/absoluteLatest) +[![peerDependencies Status](https://img.shields.io/david/peer/twbs/bootstrap)](https://david-dm.org/twbs/bootstrap?type=peer) +[![devDependency Status](https://img.shields.io/david/dev/twbs/bootstrap)](https://david-dm.org/twbs/bootstrap?type=dev) +[![Coverage Status](https://img.shields.io/coveralls/github/twbs/bootstrap/main)](https://coveralls.io/github/twbs/bootstrap?branch=main) +[![CSS gzip size](https://img.badgesize.io/twbs/bootstrap/main/dist/css/bootstrap.min.css?compression=gzip&label=CSS%20gzip%20size)](https://github.com/twbs/bootstrap/blob/main/dist/css/bootstrap.min.css) +[![CSS Brotli size](https://img.badgesize.io/twbs/bootstrap/main/dist/css/bootstrap.min.css?compression=brotli&label=CSS%20Brotli%20size)](https://github.com/twbs/bootstrap/blob/main/dist/css/bootstrap.min.css) +[![JS gzip size](https://img.badgesize.io/twbs/bootstrap/main/dist/js/bootstrap.min.js?compression=gzip&label=JS%20gzip%20size)](https://github.com/twbs/bootstrap/blob/main/dist/js/bootstrap.min.js) +[![JS Brotli size](https://img.badgesize.io/twbs/bootstrap/main/dist/js/bootstrap.min.js?compression=brotli&label=JS%20Brotli%20size)](https://github.com/twbs/bootstrap/blob/main/dist/js/bootstrap.min.js) [![BrowserStack Status](https://www.browserstack.com/automate/badge.svg?badge_key=SkxZcStBeExEdVJqQ2hWYnlWckpkNmNEY213SFp6WHFETWk2bGFuY3pCbz0tLXhqbHJsVlZhQnRBdEpod3NLSDMzaHc9PQ==--3d0b75245708616eb93113221beece33e680b229)](https://www.browserstack.com/automate/public-build/SkxZcStBeExEdVJqQ2hWYnlWckpkNmNEY213SFp6WHFETWk2bGFuY3pCbz0tLXhqbHJsVlZhQnRBdEpod3NLSDMzaHc9PQ==--3d0b75245708616eb93113221beece33e680b229) -[![Backers on Open Collective](https://opencollective.com/bootstrap/backers/badge.svg)](#backers) -[![Sponsors on Open Collective](https://opencollective.com/bootstrap/sponsors/badge.svg)](#sponsors) +[![Backers on Open Collective](https://img.shields.io/opencollective/backers/bootstrap)](#backers) +[![Sponsors on Open Collective](https://img.shields.io/opencollective/sponsors/bootstrap)](#sponsors) ## What's included @@ -76,53 +83,76 @@ Within the download you'll find the following directories and files, logically g ```text bootstrap/ -└── dist/ - ├── css/ - │ ├── bootstrap-grid.css - │ ├── bootstrap-grid.css.map - │ ├── bootstrap-grid.min.css - │ ├── bootstrap-grid.min.css.map - │ ├── bootstrap-reboot.css - │ ├── bootstrap-reboot.css.map - │ ├── bootstrap-reboot.min.css - │ ├── bootstrap-reboot.min.css.map - │ ├── bootstrap.css - │ ├── bootstrap.css.map - │ ├── bootstrap.min.css - │ └── bootstrap.min.css.map - └── js/ - ├── bootstrap.bundle.js - ├── bootstrap.bundle.js.map - ├── bootstrap.bundle.min.js - ├── bootstrap.bundle.min.js.map - ├── bootstrap.js - ├── bootstrap.js.map - ├── bootstrap.min.js - └── bootstrap.min.js.map +├── css/ +│ ├── bootstrap-grid.css +│ ├── bootstrap-grid.css.map +│ ├── bootstrap-grid.min.css +│ ├── bootstrap-grid.min.css.map +│ ├── bootstrap-grid.rtl.css +│ ├── bootstrap-grid.rtl.css.map +│ ├── bootstrap-grid.rtl.min.css +│ ├── bootstrap-grid.rtl.min.css.map +│ ├── bootstrap-reboot.css +│ ├── bootstrap-reboot.css.map +│ ├── bootstrap-reboot.min.css +│ ├── bootstrap-reboot.min.css.map +│ ├── bootstrap-reboot.rtl.css +│ ├── bootstrap-reboot.rtl.css.map +│ ├── bootstrap-reboot.rtl.min.css +│ ├── bootstrap-reboot.rtl.min.css.map +│ ├── bootstrap-utilities.css +│ ├── bootstrap-utilities.css.map +│ ├── bootstrap-utilities.min.css +│ ├── bootstrap-utilities.min.css.map +│ ├── bootstrap-utilities.rtl.css +│ ├── bootstrap-utilities.rtl.css.map +│ ├── bootstrap-utilities.rtl.min.css +│ ├── bootstrap-utilities.rtl.min.css.map +│ ├── bootstrap.css +│ ├── bootstrap.css.map +│ ├── bootstrap.min.css +│ ├── bootstrap.min.css.map +│ ├── bootstrap.rtl.css +│ ├── bootstrap.rtl.css.map +│ ├── bootstrap.rtl.min.css +│ └── bootstrap.rtl.min.css.map +└── js/ + ├── bootstrap.bundle.js + ├── bootstrap.bundle.js.map + ├── bootstrap.bundle.min.js + ├── bootstrap.bundle.min.js.map + ├── bootstrap.esm.js + ├── bootstrap.esm.js.map + ├── bootstrap.esm.min.js + ├── bootstrap.esm.min.js.map + ├── bootstrap.js + ├── bootstrap.js.map + ├── bootstrap.min.js + └── bootstrap.min.js.map ``` -We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). [source maps](https://developers.google.com/web/tools/chrome-devtools/javascript/source-maps) (`bootstrap.*.map`) are available for use with certain browsers' developer tools. Bundled JS files (`bootstrap.bundle.js` and minified `bootstrap.bundle.min.js`) include [Popper](https://popper.js.org/), but not [jQuery](https://jquery.com/). +We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). [source maps](https://developers.google.com/web/tools/chrome-devtools/javascript/source-maps) (`bootstrap.*.map`) are available for use with certain browsers' developer tools. Bundled JS files (`bootstrap.bundle.js` and minified `bootstrap.bundle.min.js`) include [Popper](https://popper.js.org/). ## Bugs and feature requests -Have a bug or a feature request? Please first read the [issue guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md#using-the-issue-tracker) and search for existing and closed issues. If your problem or idea is not addressed yet, [please open a new issue](https://github.com/twbs/bootstrap/issues/new). +Have a bug or a feature request? Please first read the [issue guidelines](https://github.com/twbs/bootstrap/blob/main/.github/CONTRIBUTING.md#using-the-issue-tracker) and search for existing and closed issues. If your problem or idea is not addressed yet, [please open a new issue](https://github.com/twbs/bootstrap/issues/new). ## Documentation -Bootstrap's documentation, included in this repo in the root directory, is built with [Jekyll](https://jekyllrb.com/) and publicly hosted on GitHub Pages at . The docs may also be run locally. +Bootstrap's documentation, included in this repo in the root directory, is built with [Hugo](https://gohugo.io/) and publicly hosted on GitHub Pages at . The docs may also be run locally. -Documentation search is powered by [Algolia's DocSearch](https://community.algolia.com/docsearch/). Working on our search? Be sure to set `debug: true` in `site/docs/4.4/assets/js/src/search.js` file. +Documentation search is powered by [Algolia's DocSearch](https://community.algolia.com/docsearch/). Working on our search? Be sure to set `debug: true` in `site/assets/js/search.js`. ### Running documentation locally -1. Run through the [tooling setup](https://getbootstrap.com/docs/4.4/getting-started/build-tools/#tooling-setup) to install Jekyll (the site builder) and other Ruby dependencies with `bundle install`. -2. Run `npm install` to install Node.js dependencies. -3. Run `npm start` to compile CSS and JavaScript files, generate our docs, and watch for changes. -4. Open `http://localhost:9001` in your browser, and voilà. +1. Run `npm install` to install the Node.js dependencies, including Hugo (the site builder). +2. Run `npm run test` (or a specific npm script) to rebuild distributed CSS and JavaScript files, as well as our docs assets. +3. From the root `/bootstrap` directory, run `npm run docs-serve` in the command line. +4. Open `http://localhost:9001/` in your browser, and voilà. -Learn more about using Jekyll by reading its [documentation](https://jekyllrb.com/docs/). +Learn more about using Hugo by reading its [documentation](https://gohugo.io/documentation/). ### Documentation for previous releases @@ -133,11 +163,11 @@ You can find all our previous releases docs on . +Editor preferences are available in the [editor config](https://github.com/twbs/bootstrap/blob/main/.editorconfig) for easy use in common text editors. Read more and download plugins at . ## Community @@ -148,7 +178,7 @@ Get updates on Bootstrap's development and chat with the project maintainers and - Read and subscribe to [The Official Bootstrap Blog](https://blog.getbootstrap.com/). - Join [the official Slack room](https://bootstrap-slack.herokuapp.com/). - Chat with fellow Bootstrappers in IRC. On the `irc.freenode.net` server, in the `##bootstrap` channel. -- Implementation help may be found at Stack Overflow (tagged [`bootstrap-4`](https://stackoverflow.com/questions/tagged/bootstrap-4)). +- Implementation help may be found at Stack Overflow (tagged [`bootstrap-5`](https://stackoverflow.com/questions/tagged/bootstrap-5)). - Developers should use the keyword `bootstrap` on packages which modify or add to the functionality of Bootstrap when distributing through [npm](https://www.npmjs.com/browse/keyword/bootstrap) or similar delivery mechanisms for maximum discoverability. @@ -181,29 +211,29 @@ See [the Releases section of our GitHub project](https://github.com/twbs/bootstr Thanks to [BrowserStack](https://www.browserstack.com/) for providing the infrastructure that allows us to test in real browsers! -## Backers - -Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/bootstrap#backer)] - -[![Bakers](https://opencollective.com/bootstrap/backers.svg?width=890)](https://opencollective.com/bootstrap#backers) - - ## Sponsors Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/bootstrap#sponsor)] -[![](https://opencollective.com/bootstrap/sponsor/0/avatar.svg)](https://opencollective.com/bootstrap/sponsor/0/website) -[![](https://opencollective.com/bootstrap/sponsor/1/avatar.svg)](https://opencollective.com/bootstrap/sponsor/1/website) -[![](https://opencollective.com/bootstrap/sponsor/2/avatar.svg)](https://opencollective.com/bootstrap/sponsor/2/website) -[![](https://opencollective.com/bootstrap/sponsor/3/avatar.svg)](https://opencollective.com/bootstrap/sponsor/3/website) -[![](https://opencollective.com/bootstrap/sponsor/4/avatar.svg)](https://opencollective.com/bootstrap/sponsor/4/website) -[![](https://opencollective.com/bootstrap/sponsor/5/avatar.svg)](https://opencollective.com/bootstrap/sponsor/5/website) -[![](https://opencollective.com/bootstrap/sponsor/6/avatar.svg)](https://opencollective.com/bootstrap/sponsor/6/website) -[![](https://opencollective.com/bootstrap/sponsor/7/avatar.svg)](https://opencollective.com/bootstrap/sponsor/7/website) -[![](https://opencollective.com/bootstrap/sponsor/8/avatar.svg)](https://opencollective.com/bootstrap/sponsor/8/website) -[![](https://opencollective.com/bootstrap/sponsor/9/avatar.svg)](https://opencollective.com/bootstrap/sponsor/9/website) +[![OC sponsor 0](https://opencollective.com/bootstrap/sponsor/0/avatar.svg)](https://opencollective.com/bootstrap/sponsor/0/website) +[![OC sponsor 1](https://opencollective.com/bootstrap/sponsor/1/avatar.svg)](https://opencollective.com/bootstrap/sponsor/1/website) +[![OC sponsor 2](https://opencollective.com/bootstrap/sponsor/2/avatar.svg)](https://opencollective.com/bootstrap/sponsor/2/website) +[![OC sponsor 3](https://opencollective.com/bootstrap/sponsor/3/avatar.svg)](https://opencollective.com/bootstrap/sponsor/3/website) +[![OC sponsor 4](https://opencollective.com/bootstrap/sponsor/4/avatar.svg)](https://opencollective.com/bootstrap/sponsor/4/website) +[![OC sponsor 5](https://opencollective.com/bootstrap/sponsor/5/avatar.svg)](https://opencollective.com/bootstrap/sponsor/5/website) +[![OC sponsor 6](https://opencollective.com/bootstrap/sponsor/6/avatar.svg)](https://opencollective.com/bootstrap/sponsor/6/website) +[![OC sponsor 7](https://opencollective.com/bootstrap/sponsor/7/avatar.svg)](https://opencollective.com/bootstrap/sponsor/7/website) +[![OC sponsor 8](https://opencollective.com/bootstrap/sponsor/8/avatar.svg)](https://opencollective.com/bootstrap/sponsor/8/website) +[![OC sponsor 9](https://opencollective.com/bootstrap/sponsor/9/avatar.svg)](https://opencollective.com/bootstrap/sponsor/9/website) + + +## Backers + +Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/bootstrap#backer)] + +[![Backers](https://opencollective.com/bootstrap/backers.svg?width=890)](https://opencollective.com/bootstrap#backers) ## Copyright and license -Code and documentation copyright 2011-2019 the [Bootstrap Authors](https://github.com/twbs/bootstrap/graphs/contributors) and [Twitter, Inc.](https://twitter.com) Code released under the [MIT License](https://github.com/twbs/bootstrap/blob/master/LICENSE). Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/). +Code and documentation copyright 2011–2021 the [Bootstrap Authors](https://github.com/twbs/bootstrap/graphs/contributors) and [Twitter, Inc.](https://twitter.com) Code released under the [MIT License](https://github.com/twbs/bootstrap/blob/main/LICENSE). Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/). diff --git a/_config.yml b/_config.yml deleted file mode 100644 index d43107fc5..000000000 --- a/_config.yml +++ /dev/null @@ -1,69 +0,0 @@ -# Dependencies -markdown: kramdown -highlighter: rouge - -kramdown: - auto_ids: true - -# Permalinks -permalink: pretty - -# Server -source: "site" -destination: ./_gh_pages -host: "localhost" -port: 9001 -baseurl: "" -url: "https://getbootstrap.com" -encoding: UTF-8 -exclude: - - docs/4.4/assets/scss/ - -plugins: - - jekyll-redirect-from - - jekyll-sitemap - - jekyll-toc - -# Social -title: Bootstrap -description: "The most popular HTML, CSS, and JS library in the world." -twitter: getbootstrap -authors: "Mark Otto, Jacob Thornton, and Bootstrap contributors" -social_image_path: /docs/4.4/assets/brand/bootstrap-social.png -social_logo_path: /docs/4.4/assets/brand/bootstrap-social-logo.png - -# Custom variables -current_version: 4.4.1 -current_ruby_version: 4.4.1 -docs_version: 4.4 -repo: "https://github.com/twbs/bootstrap" -slack: "https://bootstrap-slack.herokuapp.com" -opencollective: "https://opencollective.com/bootstrap" -blog: "https://blog.getbootstrap.com" -expo: "https://expo.getbootstrap.com" -themes: "https://themes.getbootstrap.com" -icons: "https://icons.getbootstrap.com" - -download: - source: "https://github.com/twbs/bootstrap/archive/v4.4.1.zip" - dist: "https://github.com/twbs/bootstrap/releases/download/v4.4.1/bootstrap-4.4.1-dist.zip" - -cdn: - # See https://www.srihash.org for info on how to generate the hashes - css: "https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" - css_hash: "sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" - js: "https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" - js_hash: "sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" - js_bundle: "https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.bundle.min.js" - js_bundle_hash: "sha384-6khuMg9gaYr5AxOqhkVIODVIvm9ynTT5J4V1cfthmT+emCG6yVmEZsRHdxlotUnm" - jquery: "https://code.jquery.com/jquery-3.4.1.slim.min.js" - jquery_hash: "sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" - popper: "https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" - popper_hash: "sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" - -toc: - min_level: 2 - max_level: 4 - no_toc_section_class: - - "bd-callout" - - "bd-example" diff --git a/build/.eslintrc.json b/build/.eslintrc.json index 76e7f37b6..679bd26f7 100644 --- a/build/.eslintrc.json +++ b/build/.eslintrc.json @@ -8,13 +8,7 @@ }, "extends": "../.eslintrc.json", "rules": { - "consistent-return": "off", - "func-style": "off", "no-console": "off", - "no-magic-numbers": "off", - "no-process-env": "off", - "no-process-exit": "off", - "no-sync": "off", - "spaced-comment": "off" + "strict": "error" } } diff --git a/build/banner.js b/build/banner.js index 453fc3b6e..df82ff32e 100644 --- a/build/banner.js +++ b/build/banner.js @@ -7,7 +7,7 @@ function getBanner(pluginFilename) { return `/*! * Bootstrap${pluginFilename ? ` ${pluginFilename}` : ''} v${pkg.version} (${pkg.homepage}) * Copyright 2011-${year} ${pkg.author} - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */` } diff --git a/build/build-plugins.js b/build/build-plugins.js index 877621636..d1930b855 100644 --- a/build/build-plugins.js +++ b/build/build-plugins.js @@ -1,32 +1,35 @@ +#!/usr/bin/env node + /*! * Script to build our plugins to use them separately. - * Copyright 2019 The Bootstrap Authors - * Copyright 2019 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Copyright 2020-2021 The Bootstrap Authors + * Copyright 2020-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ 'use strict' -const path = require('path') -const rollup = require('rollup') -const babel = require('rollup-plugin-babel') -const banner = require('./banner.js') +const path = require('path') +const rollup = require('rollup') +const { babel } = require('@rollup/plugin-babel') +const banner = require('./banner.js') -const TEST = process.env.NODE_ENV === 'test' +const rootPath = path.resolve(__dirname, '../js/dist/') const plugins = [ babel({ - exclude: 'node_modules/**', // Only transpile our source code - externalHelpersWhitelist: [ // Include only required helpers - 'defineProperties', - 'createClass', - 'inheritsLoose', - 'defineProperty', - 'objectSpread2' - ] + // Only transpile our source code + exclude: 'node_modules/**', + // Include the helpers in each file, at most one copy of each + babelHelpers: 'bundled' }) ] const bsPlugins = { + Data: path.resolve(__dirname, '../js/src/dom/data.js'), + EventHandler: path.resolve(__dirname, '../js/src/dom/event-handler.js'), + Manipulator: path.resolve(__dirname, '../js/src/dom/manipulator.js'), + SelectorEngine: path.resolve(__dirname, '../js/src/dom/selector-engine.js'), Alert: path.resolve(__dirname, '../js/src/alert.js'), + Base: path.resolve(__dirname, '../js/src/base-component.js'), Button: path.resolve(__dirname, '../js/src/button.js'), Carousel: path.resolve(__dirname, '../js/src/carousel.js'), Collapse: path.resolve(__dirname, '../js/src/collapse.js'), @@ -36,50 +39,150 @@ const bsPlugins = { ScrollSpy: path.resolve(__dirname, '../js/src/scrollspy.js'), Tab: path.resolve(__dirname, '../js/src/tab.js'), Toast: path.resolve(__dirname, '../js/src/toast.js'), - Tooltip: path.resolve(__dirname, '../js/src/tooltip.js'), - Util: path.resolve(__dirname, '../js/src/util.js') + Tooltip: path.resolve(__dirname, '../js/src/tooltip.js') } -const rootPath = TEST ? '../js/coverage/dist/' : '../js/dist/' -function build(plugin) { +const defaultPluginConfig = { + external: [ + bsPlugins.Data, + bsPlugins.Base, + bsPlugins.EventHandler, + bsPlugins.SelectorEngine + ], + globals: { + [bsPlugins.Data]: 'Data', + [bsPlugins.Base]: 'Base', + [bsPlugins.EventHandler]: 'EventHandler', + [bsPlugins.SelectorEngine]: 'SelectorEngine' + } +} + +const getConfigByPluginKey = pluginKey => { + if ( + pluginKey === 'Data' || + pluginKey === 'Manipulator' || + pluginKey === 'EventHandler' || + pluginKey === 'SelectorEngine' || + pluginKey === 'Util' || + pluginKey === 'Sanitizer' + ) { + return { + external: [] + } + } + + if (pluginKey === 'Alert' || pluginKey === 'Tab') { + return defaultPluginConfig + } + + if ( + pluginKey === 'Base' || + pluginKey === 'Button' || + pluginKey === 'Carousel' || + pluginKey === 'Collapse' || + pluginKey === 'Modal' || + pluginKey === 'ScrollSpy' + ) { + const config = Object.assign(defaultPluginConfig) + config.external.push(bsPlugins.Manipulator) + config.globals[bsPlugins.Manipulator] = 'Manipulator' + return config + } + + if (pluginKey === 'Dropdown' || pluginKey === 'Tooltip') { + const config = Object.assign(defaultPluginConfig) + config.external.push(bsPlugins.Manipulator, '@popperjs/core') + config.globals[bsPlugins.Manipulator] = 'Manipulator' + config.globals['@popperjs/core'] = 'Popper' + return config + } + + if (pluginKey === 'Popover') { + return { + external: [ + bsPlugins.Data, + bsPlugins.SelectorEngine, + bsPlugins.Tooltip + ], + globals: { + [bsPlugins.Data]: 'Data', + [bsPlugins.SelectorEngine]: 'SelectorEngine', + [bsPlugins.Tooltip]: 'Tooltip' + } + } + } + + if (pluginKey === 'Toast') { + return { + external: [ + bsPlugins.Data, + bsPlugins.Base, + bsPlugins.EventHandler, + bsPlugins.Manipulator + ], + globals: { + [bsPlugins.Data]: 'Data', + [bsPlugins.Base]: 'Base', + [bsPlugins.EventHandler]: 'EventHandler', + [bsPlugins.Manipulator]: 'Manipulator' + } + } + } +} + +const utilObjects = new Set([ + 'Util', + 'Sanitizer' +]) + +const domObjects = new Set([ + 'Data', + 'EventHandler', + 'Manipulator', + 'SelectorEngine' +]) + +const build = async plugin => { console.log(`Building ${plugin} plugin...`) - const external = ['jquery', 'popper.js'] - const globals = { - jquery: 'jQuery', // Ensure we use jQuery which is always available even in noConflict mode - 'popper.js': 'Popper' + const { external, globals } = getConfigByPluginKey(plugin) + const pluginFilename = path.basename(bsPlugins[plugin]) + let pluginPath = rootPath + + if (utilObjects.has(plugin)) { + pluginPath = `${rootPath}/util/` } - // Do not bundle Util in plugins - if (plugin !== 'Util') { - external.push(bsPlugins.Util) - globals[bsPlugins.Util] = 'Util' + if (domObjects.has(plugin)) { + pluginPath = `${rootPath}/dom/` } - // Do not bundle Tooltip in Popover - if (plugin === 'Popover') { - external.push(bsPlugins.Tooltip) - globals[bsPlugins.Tooltip] = 'Tooltip' - } - - const pluginFilename = `${plugin.toLowerCase()}.js` - - rollup.rollup({ + const bundle = await rollup.rollup({ input: bsPlugins[plugin], plugins, external - }).then((bundle) => { - bundle.write({ - banner: banner(pluginFilename), - format: 'umd', - name: plugin, - sourcemap: true, - globals, - file: path.resolve(__dirname, `${rootPath}${pluginFilename}`) - }) - .then(() => console.log(`Building ${plugin} plugin... Done!`)) - .catch((err) => console.error(`${plugin}: ${err}`)) }) + + await bundle.write({ + banner: banner(pluginFilename), + format: 'umd', + name: plugin, + sourcemap: true, + globals, + file: path.resolve(__dirname, `${pluginPath}/${pluginFilename}`) + }) + + console.log(`Building ${plugin} plugin... Done!`) } -Object.keys(bsPlugins).forEach((plugin) => build(plugin)) +const main = async () => { + try { + await Promise.all(Object.keys(bsPlugins).map(plugin => build(plugin))) + } catch (error) { + console.error(error) + + process.exit(1) + } +} + +main() diff --git a/build/change-version.js b/build/change-version.js old mode 100755 new mode 100644 index f068e2a70..8086ed774 --- a/build/change-version.js +++ b/build/change-version.js @@ -2,9 +2,9 @@ /*! * Script to update version number references in the project. - * Copyright 2017-2019 The Bootstrap Authors - * Copyright 2017-2019 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Copyright 2017-2021 The Bootstrap Authors + * Copyright 2017-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ 'use strict' @@ -17,11 +17,11 @@ sh.config.fatal = true // Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37 function regExpQuote(string) { - return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&') + return string.replace(/[$()*+-.?[\\\]^{|}]/g, '\\$&') } function regExpQuoteReplacement(string) { - return string.replace(/[$]/g, '$$') + return string.replace(/\$/g, '$$') } const DRY_RUN = false @@ -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,21 @@ 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) => { - if (allowedExtensions.has(path.parse(filepath).ext)) { - console.log(`FILE: ${filepath}`) - } else { - console.log(`EXCLUDED:${filepath}`) + const updateFile = DRY_RUN ? + filepath => { + if (allowedExtensions.has(path.parse(filepath).ext)) { + console.log(`FILE: ${filepath}`) + } else { + console.log(`EXCLUDED:${filepath}`) + } + } : + filepath => { + if (allowedExtensions.has(path.parse(filepath).ext)) { + sh.sed('-i', original, replacement, 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 +85,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([ @@ -88,14 +95,13 @@ function main(args) { 'vendor' ]) const INCLUDED_EXTENSIONS = new Set([ - // This extension whitelist is how we avoid modifying binary files + // This extension allowlist is how we avoid modifying binary files '', '.css', '.html', '.js', '.json', '.md', - '.nuspec', '.scss', '.txt', '.yml' diff --git a/build/generate-sri.js b/build/generate-sri.js index 66544d4ad..221873b8f 100644 --- a/build/generate-sri.js +++ b/build/generate-sri.js @@ -5,9 +5,9 @@ * Remember to use the same vendor files as the CDN ones, * otherwise the hashes won't match! * - * Copyright 2017-2019 The Bootstrap Authors - * Copyright 2017-2019 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Copyright 2017-2021 The Bootstrap Authors + * Copyright 2017-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ 'use strict' @@ -17,20 +17,22 @@ const fs = require('fs') const path = require('path') const sh = require('shelljs') -const pkg = require('../package.json') - sh.config.fatal = true -const configFile = path.join(__dirname, '../_config.yml') +const configFile = path.join(__dirname, '../config.yml') // Array of objects which holds the files to generate SRI hashes for. // `file` is the path from the root folder -// `configPropertyName` is the _config.yml variable's name of the file +// `configPropertyName` is the config.yml variable's name of the file const files = [ { file: 'dist/css/bootstrap.min.css', configPropertyName: 'css_hash' }, + { + file: 'dist/css/bootstrap.rtl.min.css', + configPropertyName: 'css_rtl_hash' + }, { file: 'dist/js/bootstrap.min.js', configPropertyName: 'js_hash' @@ -40,16 +42,12 @@ const files = [ configPropertyName: 'js_bundle_hash' }, { - file: `site/docs/${pkg.version_short}/assets/js/vendor/jquery.slim.min.js`, - configPropertyName: 'jquery_hash' - }, - { - file: 'node_modules/popper.js/dist/umd/popper.min.js', + file: 'node_modules/@popperjs/core/dist/umd/popper.min.js', configPropertyName: 'popper_hash' } ] -files.forEach((file) => { +files.forEach(file => { fs.readFile(file.file, 'utf8', (err, data) => { if (err) { throw err @@ -61,6 +59,6 @@ files.forEach((file) => { console.log(`${file.configPropertyName}: ${integrity}`) - sh.sed('-i', new RegExp(`(\\s${file.configPropertyName}:\\s+"|')(\\S+)("|')`), `$1${integrity}$3`, configFile) + sh.sed('-i', new RegExp(`^(\\s+${file.configPropertyName}:\\s+["'])\\S*(["'])`), `$1${integrity}$2`, configFile) }) }) diff --git a/build/postcss.config.js b/build/postcss.config.js index 157291ffd..b179a0e77 100644 --- a/build/postcss.config.js +++ b/build/postcss.config.js @@ -1,14 +1,19 @@ 'use strict' -module.exports = (ctx) => ({ - map: ctx.file.dirname.includes('examples') ? false : { - inline: false, - annotation: true, - sourcesContent: true - }, - plugins: { - autoprefixer: { - cascade: false +module.exports = ctx => { + return { + map: ctx.file.dirname.includes('examples') ? + false : + { + inline: false, + annotation: true, + sourcesContent: true + }, + plugins: { + autoprefixer: { + cascade: false + }, + rtlcss: ctx.env === 'RTL' ? {} : false } } -}) +} diff --git a/build/rollup.config.js b/build/rollup.config.js index 0dfa5d48a..7f9c1c7e1 100644 --- a/build/rollup.config.js +++ b/build/rollup.config.js @@ -1,48 +1,50 @@ 'use strict' -const path = require('path') -const babel = require('rollup-plugin-babel') -const resolve = require('rollup-plugin-node-resolve') -const banner = require('./banner.js') +const path = require('path') +const { babel } = require('@rollup/plugin-babel') +const { nodeResolve } = require('@rollup/plugin-node-resolve') +const replace = require('@rollup/plugin-replace') +const banner = require('./banner.js') -const BUNDLE = process.env.BUNDLE === 'true' +const BUNDLE = process.env.BUNDLE === 'true' +const ESM = process.env.ESM === 'true' -let fileDest = 'bootstrap.js' -const external = ['jquery', 'popper.js'] +let fileDest = `bootstrap${ESM ? '.esm' : ''}` +const external = ['@popperjs/core'] const plugins = [ babel({ - exclude: 'node_modules/**', // Only transpile our source code - externalHelpersWhitelist: [ // Include only required helpers - 'defineProperties', - 'createClass', - 'inheritsLoose', - 'defineProperty', - 'objectSpread2' - ] + // Only transpile our source code + exclude: 'node_modules/**', + // Include the helpers in the bundle, at most one copy of each + babelHelpers: 'bundled' }) ] const globals = { - jquery: 'jQuery', // Ensure we use jQuery which is always available even in noConflict mode - 'popper.js': 'Popper' + '@popperjs/core': 'Popper' } if (BUNDLE) { - fileDest = 'bootstrap.bundle.js' + fileDest += '.bundle' // Remove last entry in external array to bundle Popper external.pop() - delete globals['popper.js'] - plugins.push(resolve()) + delete globals['@popperjs/core'] + plugins.push(replace({ 'process.env.NODE_ENV': '"production"' }), nodeResolve()) } -module.exports = { - input: path.resolve(__dirname, '../js/src/index.js'), +const rollupConfig = { + input: path.resolve(__dirname, `../js/index.${ESM ? 'esm' : 'umd'}.js`), output: { banner, - file: path.resolve(__dirname, `../dist/js/${fileDest}`), - format: 'umd', - globals, - name: 'bootstrap' + file: path.resolve(__dirname, `../dist/js/${fileDest}.js`), + format: ESM ? 'esm' : 'umd', + globals }, external, plugins } + +if (!ESM) { + rollupConfig.output.name = 'bootstrap' +} + +module.exports = rollupConfig diff --git a/build/ship.sh b/build/ship.sh old mode 100755 new mode 100644 index 289284383..da5a03bcd --- a/build/ship.sh +++ b/build/ship.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash + +set -e + # # Usage # --------------- @@ -18,35 +21,35 @@ end=$'\e[0m' current_version=$(node -p "require('./package.json').version") if [[ $# -lt 1 ]]; then - printf "\n%s⚠️ Shipping aborted. You must specify a version.\n%s" $red $end + printf "\n%s⚠️ Shipping aborted. You must specify a version.\n%s" "$red" "$end" exit 1 fi # Pulling latest changes, just to be sure -printf "\n%s=======================================================%s" $magenta $end -printf "\n%sPulling latest changes...%s" $magenta $end -printf "\n%s=======================================================\n\n%s" $magenta $end -git pull origin v4-dev +printf "\n%s=======================================================%s" "$magenta" "$end" +printf "\n%sPulling latest changes...%s" "$magenta" "$end" +printf "\n%s=======================================================\n\n%s" "$magenta" "$end" +git pull origin main # Update version number -printf "\n%s=======================================================%s" $magenta $end -printf "\n%sUpdating version number...%s" $magenta $end -printf "\n%s=======================================================\n%s" $magenta $end +printf "\n%s=======================================================%s" "$magenta" "$end" +printf "\n%sUpdating version number...%s" "$magenta" "$end" +printf "\n%s=======================================================\n%s" "$magenta" "$end" npm run release-version "$current_version" "$1" # Build release -printf "\n%s=======================================================%s" $magenta $end -printf "\n%sBuilding release...%s" $magenta $end -printf "\n%s=======================================================\n%s" $magenta $end +printf "\n%s=======================================================%s" "$magenta" "$end" +printf "\n%sBuilding release...%s" "$magenta" "$end" +printf "\n%s=======================================================\n%s" "$magenta" "$end" npm run release # Copy the contents of the built docs site over to `bs-docs` repo -printf "\n%s=======================================================%s" $magenta $end -printf "\n%sCopy it over...%s" $magenta $end -printf "\n%s=======================================================\n%s" $magenta $end +printf "\n%s=======================================================%s" "$magenta" "$end" +printf "\n%sCopy it over...%s" "$magenta" "$end" +printf "\n%s=======================================================\n%s" "$magenta" "$end" cp -rf _gh_pages/. ../bs-docs/ printf "\nDone!\n" -printf "\n%s=======================================================%s" $green $end -printf "\n%sSuccess, $1 is ready to review and publish.%s" $green $end -printf "\n%s=======================================================\n\n%s" $green $end +printf "\n%s=======================================================%s" "$green" "$end" +printf "\n%sSuccess, $1 is ready to review and publish.%s" "$green" "$end" +printf "\n%s=======================================================\n\n%s" "$green" "$end" diff --git a/build/svgo.yml b/build/svgo.yml index 1b592f00f..67940d393 100644 --- a/build/svgo.yml +++ b/build/svgo.yml @@ -15,10 +15,9 @@ js2svg: indent: 2 plugins: - # remove this with IE 11 is no longer supported - - addAttributesToSVGElement: - attributes: - - focusable: false +# - addAttributesToSVGElement: +# attributes: +# - focusable: false - cleanupAttrs: true - cleanupEnableBackground: true - cleanupIDs: true diff --git a/build/vnu-jar.js b/build/vnu-jar.js index 8567ba89d..c23b94d60 100644 --- a/build/vnu-jar.js +++ b/build/vnu-jar.js @@ -2,9 +2,9 @@ /*! * Script to run vnu-jar if Java is available. - * Copyright 2017-2019 The Bootstrap Authors - * Copyright 2017-2019 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Copyright 2017-2021 The Bootstrap Authors + * Copyright 2017-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ 'use strict' @@ -18,7 +18,7 @@ childProcess.exec('java -version', (error, stdout, stderr) => { return } - const is32bitJava = !stderr.match(/64-Bit/) + const is32bitJava = !/64-Bit/.test(stderr) // vnu-jar accepts multiple ignores joined with a `|`. // Also note that the ignores are regular expressions. @@ -33,10 +33,11 @@ childProcess.exec('java -version', (error, stdout, stderr) => { // Content → Reboot uses various date/time inputs as a visual example. // Documentation does not rely on them being usable. 'The “date” input type is not supported in all browsers.*', - 'The “time” input type is not supported in all browsers.*', - // IE11 doesn't recognise
/ give the element an implicit "main" landmark. - // Explicit role="main" is redundant for other modern browsers, but still valid. - 'The “main” role is unnecessary for element “main”.' + 'The “week” input type is not supported in all browsers.*', + 'The “month” input type is not supported in all browsers.*', + 'The “color” input type is not supported in all browsers.*', + 'The “datetime-local” input type is not supported in all browsers.*', + 'The “time” input type is not supported in all browsers.*' ].join('|') const args = [ diff --git a/build/zip-examples.js b/build/zip-examples.js new file mode 100644 index 000000000..b2f156502 --- /dev/null +++ b/build/zip-examples.js @@ -0,0 +1,90 @@ +#!/usr/bin/env node + +/*! + * Script to create the built examples zip archive; + * requires the `zip` command to be present! + * Copyright 2020-2021 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ + +'use strict' + +const path = require('path') +const sh = require('shelljs') + +const pkg = require('../package.json') + +const versionShort = pkg.config.version_short +const distFolder = `bootstrap-${pkg.version}-examples` +const rootDocsDir = '_gh_pages' +const docsDir = `${rootDocsDir}/docs/${versionShort}/` + +// these are the files we need in the examples +const cssFiles = [ + 'bootstrap.min.css', + 'bootstrap.min.css.map', + 'bootstrap.rtl.min.css', + 'bootstrap.rtl.min.css.map' +] +const jsFiles = [ + 'bootstrap.bundle.min.js', + 'bootstrap.bundle.min.js.map' +] +const imgFiles = [ + 'bootstrap-logo.svg', + 'bootstrap-logo-white.svg' +] + +sh.config.fatal = true + +if (!sh.test('-d', rootDocsDir)) { + throw new Error(`The "${rootDocsDir}" folder does not exist, did you forget building the docs?`) +} + +// switch to the root dir +sh.cd(path.join(__dirname, '..')) + +// remove any previously created folder/zip with the same name +sh.rm('-rf', [distFolder, `${distFolder}.zip`]) + +// create any folders so that `cp` works +sh.mkdir('-p', [ + distFolder, + `${distFolder}/assets/brand/`, + `${distFolder}/assets/dist/css/`, + `${distFolder}/assets/dist/js/` +]) + +sh.cp('-Rf', `${docsDir}/examples/*`, distFolder) + +cssFiles.forEach(file => { + sh.cp('-f', `${docsDir}/dist/css/${file}`, `${distFolder}/assets/dist/css/`) +}) + +jsFiles.forEach(file => { + sh.cp('-f', `${docsDir}/dist/js/${file}`, `${distFolder}/assets/dist/js/`) +}) + +imgFiles.forEach(file => { + sh.cp('-f', `${docsDir}/assets/brand/${file}`, `${distFolder}/assets/brand/`) +}) + +sh.rm(`${distFolder}/index.html`) + +// get all examples' HTML files +sh.find(`${distFolder}/**/*.html`).forEach(file => { + const fileContents = sh.cat(file) + .toString() + .replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../') + .replace(/"..\/dist\//g, '"../assets/dist/') + .replace(/(/g, '$1>') + .replace(/(') + .replace(/( +) 'click') + + var typeEvent = originalTypeEvent.replace(stripNameRegex, ''); + var custom = customEvents[typeEvent]; + + if (custom) { + typeEvent = custom; + } + + var isNative = nativeEvents.has(typeEvent); + + if (!isNative) { + typeEvent = originalTypeEvent; + } + + return [delegation, originalHandler, typeEvent]; + } + + function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) { + if (typeof originalTypeEvent !== 'string' || !element) { + return; + } + + if (!handler) { + handler = delegationFn; + delegationFn = null; + } + + var _normalizeParams = normalizeParams(originalTypeEvent, handler, delegationFn), + delegation = _normalizeParams[0], + originalHandler = _normalizeParams[1], + typeEvent = _normalizeParams[2]; + + var events = getEvent(element); + var handlers = events[typeEvent] || (events[typeEvent] = {}); + var previousFn = findHandler(handlers, originalHandler, delegation ? handler : null); + + if (previousFn) { + previousFn.oneOff = previousFn.oneOff && oneOff; + return; + } + + var uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, '')); + var fn = delegation ? bootstrapDelegationHandler(element, handler, delegationFn) : bootstrapHandler(element, handler); + fn.delegationSelector = delegation ? handler : null; + fn.originalHandler = originalHandler; + fn.oneOff = oneOff; + fn.uidEvent = uid; + handlers[uid] = fn; + element.addEventListener(typeEvent, fn, delegation); + } + + function removeHandler(element, events, typeEvent, handler, delegationSelector) { + var fn = findHandler(events[typeEvent], handler, delegationSelector); + + if (!fn) { + return; + } + + element.removeEventListener(typeEvent, fn, Boolean(delegationSelector)); + delete events[typeEvent][fn.uidEvent]; + } + + function removeNamespacedHandlers(element, events, typeEvent, namespace) { + var storeElementEvent = events[typeEvent] || {}; + Object.keys(storeElementEvent).forEach(function (handlerKey) { + if (handlerKey.includes(namespace)) { + var event = storeElementEvent[handlerKey]; + removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector); + } + }); + } + + var EventHandler = { + on: function on(element, event, handler, delegationFn) { + addHandler(element, event, handler, delegationFn, false); + }, + one: function one(element, event, handler, delegationFn) { + addHandler(element, event, handler, delegationFn, true); + }, + off: function off(element, originalTypeEvent, handler, delegationFn) { + if (typeof originalTypeEvent !== 'string' || !element) { + return; + } + + var _normalizeParams2 = normalizeParams(originalTypeEvent, handler, delegationFn), + delegation = _normalizeParams2[0], + originalHandler = _normalizeParams2[1], + typeEvent = _normalizeParams2[2]; + + var inNamespace = typeEvent !== originalTypeEvent; + var events = getEvent(element); + var isNamespace = originalTypeEvent.startsWith('.'); + + if (typeof originalHandler !== 'undefined') { + // Simplest case: handler is passed, remove that listener ONLY. + if (!events || !events[typeEvent]) { + return; + } + + removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null); + return; + } + + if (isNamespace) { + Object.keys(events).forEach(function (elementEvent) { + removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1)); + }); + } + + var storeElementEvent = events[typeEvent] || {}; + Object.keys(storeElementEvent).forEach(function (keyHandlers) { + var handlerKey = keyHandlers.replace(stripUidRegex, ''); + + if (!inNamespace || originalTypeEvent.includes(handlerKey)) { + var event = storeElementEvent[keyHandlers]; + removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector); + } + }); + }, + trigger: function trigger(element, event, args) { + if (typeof event !== 'string' || !element) { + return null; + } + + var $ = getjQuery(); + var typeEvent = event.replace(stripNameRegex, ''); + var inNamespace = event !== typeEvent; + var isNative = nativeEvents.has(typeEvent); + var jQueryEvent; + var bubbles = true; + var nativeDispatch = true; + var defaultPrevented = false; + var evt = null; + + if (inNamespace && $) { + jQueryEvent = $.Event(event, args); + $(element).trigger(jQueryEvent); + bubbles = !jQueryEvent.isPropagationStopped(); + nativeDispatch = !jQueryEvent.isImmediatePropagationStopped(); + defaultPrevented = jQueryEvent.isDefaultPrevented(); + } + + if (isNative) { + evt = document.createEvent('HTMLEvents'); + evt.initEvent(typeEvent, bubbles, true); + } else { + evt = new CustomEvent(event, { + bubbles: bubbles, + cancelable: true + }); + } // merge custom information in our event + + + if (typeof args !== 'undefined') { + Object.keys(args).forEach(function (key) { + Object.defineProperty(evt, key, { + get: function get() { + return args[key]; + } + }); + }); + } + + if (defaultPrevented) { + evt.preventDefault(); + } + + if (nativeDispatch) { + element.dispatchEvent(evt); + } + + if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') { + jQueryEvent.preventDefault(); + } + + return evt; + } + }; + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var VERSION = '5.0.0-beta1'; + + var BaseComponent = /*#__PURE__*/function () { + function BaseComponent(element) { + if (!element) { + return; + } + + this._element = element; + Data.setData(element, this.constructor.DATA_KEY, this); + } + + var _proto = BaseComponent.prototype; + + _proto.dispose = function dispose() { + Data.removeData(this._element, this.constructor.DATA_KEY); + this._element = null; + } + /** Static */ + ; + + BaseComponent.getInstance = function getInstance(element) { + return Data.getData(element, this.DATA_KEY); + }; + + _createClass(BaseComponent, null, [{ + key: "VERSION", + get: function get() { + return VERSION; + } + }]); + + return BaseComponent; + }(); /** * ------------------------------------------------------------------------ @@ -261,114 +624,86 @@ */ var NAME = 'alert'; - var VERSION = '4.4.1'; var DATA_KEY = 'bs.alert'; var EVENT_KEY = "." + DATA_KEY; var DATA_API_KEY = '.data-api'; - var JQUERY_NO_CONFLICT = $.fn[NAME]; - var Selector = { - DISMISS: '[data-dismiss="alert"]' - }; - var Event = { - CLOSE: "close" + EVENT_KEY, - CLOSED: "closed" + EVENT_KEY, - CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY - }; - var ClassName = { - ALERT: 'alert', - FADE: 'fade', - SHOW: 'show' - }; + var SELECTOR_DISMISS = '[data-bs-dismiss="alert"]'; + var EVENT_CLOSE = "close" + EVENT_KEY; + var EVENT_CLOSED = "closed" + EVENT_KEY; + var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY; + var CLASSNAME_ALERT = 'alert'; + var CLASSNAME_FADE = 'fade'; + var CLASSNAME_SHOW = 'show'; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ - var Alert = - /*#__PURE__*/ - function () { - function Alert(element) { - this._element = element; - } // Getters + var Alert = /*#__PURE__*/function (_BaseComponent) { + _inheritsLoose(Alert, _BaseComponent); + function Alert() { + return _BaseComponent.apply(this, arguments) || this; + } var _proto = Alert.prototype; // Public _proto.close = function close(element) { - var rootElement = this._element; - - if (element) { - rootElement = this._getRootElement(element); - } + var rootElement = element ? this._getRootElement(element) : this._element; var customEvent = this._triggerCloseEvent(rootElement); - if (customEvent.isDefaultPrevented()) { + if (customEvent === null || customEvent.defaultPrevented) { return; } this._removeElement(rootElement); - }; - - _proto.dispose = function dispose() { - $.removeData(this._element, DATA_KEY); - this._element = null; } // Private ; _proto._getRootElement = function _getRootElement(element) { - var selector = Util.getSelectorFromElement(element); - var parent = false; - - if (selector) { - parent = document.querySelector(selector); - } - - if (!parent) { - parent = $(element).closest("." + ClassName.ALERT)[0]; - } - - return parent; + return getElementFromSelector(element) || element.closest("." + CLASSNAME_ALERT); }; _proto._triggerCloseEvent = function _triggerCloseEvent(element) { - var closeEvent = $.Event(Event.CLOSE); - $(element).trigger(closeEvent); - return closeEvent; + return EventHandler.trigger(element, EVENT_CLOSE); }; _proto._removeElement = function _removeElement(element) { var _this = this; - $(element).removeClass(ClassName.SHOW); + element.classList.remove(CLASSNAME_SHOW); - if (!$(element).hasClass(ClassName.FADE)) { + if (!element.classList.contains(CLASSNAME_FADE)) { this._destroyElement(element); return; } - var transitionDuration = Util.getTransitionDurationFromElement(element); - $(element).one(Util.TRANSITION_END, function (event) { - return _this._destroyElement(element, event); - }).emulateTransitionEnd(transitionDuration); + var transitionDuration = getTransitionDurationFromElement(element); + EventHandler.one(element, TRANSITION_END, function () { + return _this._destroyElement(element); + }); + emulateTransitionEnd(element, transitionDuration); }; _proto._destroyElement = function _destroyElement(element) { - $(element).detach().trigger(Event.CLOSED).remove(); + if (element.parentNode) { + element.parentNode.removeChild(element); + } + + EventHandler.trigger(element, EVENT_CLOSED); } // Static ; - Alert._jQueryInterface = function _jQueryInterface(config) { + Alert.jQueryInterface = function jQueryInterface(config) { return this.each(function () { - var $element = $(this); - var data = $element.data(DATA_KEY); + var data = Data.getData(this, DATA_KEY); if (!data) { data = new Alert(this); - $element.data(DATA_KEY, data); } if (config === 'close') { @@ -377,7 +712,7 @@ }); }; - Alert._handleDismiss = function _handleDismiss(alertInstance) { + Alert.handleDismiss = function handleDismiss(alertInstance) { return function (event) { if (event) { event.preventDefault(); @@ -388,14 +723,15 @@ }; _createClass(Alert, null, [{ - key: "VERSION", + key: "DATA_KEY", + // Getters get: function get() { - return VERSION; + return DATA_KEY; } }]); return Alert; - }(); + }(BaseComponent); /** * ------------------------------------------------------------------------ * Data Api implementation @@ -403,20 +739,29 @@ */ - $(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert())); + EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DISMISS, Alert.handleDismiss(new Alert())); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ + * add .Alert to jQuery only if jQuery is present */ - $.fn[NAME] = Alert._jQueryInterface; - $.fn[NAME].Constructor = Alert; + onDOMContentLoaded(function () { + var $ = getjQuery(); + /* istanbul ignore if */ - $.fn[NAME].noConflict = function () { - $.fn[NAME] = JQUERY_NO_CONFLICT; - return Alert._jQueryInterface; - }; + if ($) { + var JQUERY_NO_CONFLICT = $.fn[NAME]; + $.fn[NAME] = Alert.jQueryInterface; + $.fn[NAME].Constructor = Alert; + + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return Alert.jQueryInterface; + }; + } + }); /** * ------------------------------------------------------------------------ @@ -425,109 +770,40 @@ */ var NAME$1 = 'button'; - var VERSION$1 = '4.4.1'; var DATA_KEY$1 = 'bs.button'; var EVENT_KEY$1 = "." + DATA_KEY$1; var DATA_API_KEY$1 = '.data-api'; - var JQUERY_NO_CONFLICT$1 = $.fn[NAME$1]; - var ClassName$1 = { - ACTIVE: 'active', - BUTTON: 'btn', - FOCUS: 'focus' - }; - var Selector$1 = { - DATA_TOGGLE_CARROT: '[data-toggle^="button"]', - DATA_TOGGLES: '[data-toggle="buttons"]', - DATA_TOGGLE: '[data-toggle="button"]', - DATA_TOGGLES_BUTTONS: '[data-toggle="buttons"] .btn', - INPUT: 'input:not([type="hidden"])', - ACTIVE: '.active', - BUTTON: '.btn' - }; - var Event$1 = { - CLICK_DATA_API: "click" + EVENT_KEY$1 + DATA_API_KEY$1, - FOCUS_BLUR_DATA_API: "focus" + EVENT_KEY$1 + DATA_API_KEY$1 + " " + ("blur" + EVENT_KEY$1 + DATA_API_KEY$1), - LOAD_DATA_API: "load" + EVENT_KEY$1 + DATA_API_KEY$1 - }; + var CLASS_NAME_ACTIVE = 'active'; + var SELECTOR_DATA_TOGGLE = '[data-bs-toggle="button"]'; + var EVENT_CLICK_DATA_API$1 = "click" + EVENT_KEY$1 + DATA_API_KEY$1; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ - var Button = - /*#__PURE__*/ - function () { - function Button(element) { - this._element = element; - } // Getters + var Button = /*#__PURE__*/function (_BaseComponent) { + _inheritsLoose(Button, _BaseComponent); + function Button() { + return _BaseComponent.apply(this, arguments) || this; + } var _proto = Button.prototype; // Public _proto.toggle = function toggle() { - var triggerChangeEvent = true; - var addAriaPressed = true; - var rootElement = $(this._element).closest(Selector$1.DATA_TOGGLES)[0]; - - if (rootElement) { - var input = this._element.querySelector(Selector$1.INPUT); - - if (input) { - if (input.type === 'radio') { - if (input.checked && this._element.classList.contains(ClassName$1.ACTIVE)) { - triggerChangeEvent = false; - } else { - var activeElement = rootElement.querySelector(Selector$1.ACTIVE); - - if (activeElement) { - $(activeElement).removeClass(ClassName$1.ACTIVE); - } - } - } else if (input.type === 'checkbox') { - if (this._element.tagName === 'LABEL' && input.checked === this._element.classList.contains(ClassName$1.ACTIVE)) { - triggerChangeEvent = false; - } - } else { - // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input - triggerChangeEvent = false; - } - - if (triggerChangeEvent) { - input.checked = !this._element.classList.contains(ClassName$1.ACTIVE); - $(input).trigger('change'); - } - - input.focus(); - addAriaPressed = false; - } - } - - if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) { - if (addAriaPressed) { - this._element.setAttribute('aria-pressed', !this._element.classList.contains(ClassName$1.ACTIVE)); - } - - if (triggerChangeEvent) { - $(this._element).toggleClass(ClassName$1.ACTIVE); - } - } - }; - - _proto.dispose = function dispose() { - $.removeData(this._element, DATA_KEY$1); - this._element = null; + // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method + this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE)); } // Static ; - Button._jQueryInterface = function _jQueryInterface(config) { + Button.jQueryInterface = function jQueryInterface(config) { return this.each(function () { - var data = $(this).data(DATA_KEY$1); + var data = Data.getData(this, DATA_KEY$1); if (!data) { data = new Button(this); - $(this).data(DATA_KEY$1, data); } if (config === 'toggle') { @@ -537,14 +813,15 @@ }; _createClass(Button, null, [{ - key: "VERSION", + key: "DATA_KEY", + // Getters get: function get() { - return VERSION$1; + return DATA_KEY$1; } }]); return Button; - }(); + }(BaseComponent); /** * ------------------------------------------------------------------------ * Data Api implementation @@ -552,71 +829,194 @@ */ - $(document).on(Event$1.CLICK_DATA_API, Selector$1.DATA_TOGGLE_CARROT, function (event) { - var button = event.target; + EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE, function (event) { + event.preventDefault(); + var button = event.target.closest(SELECTOR_DATA_TOGGLE); + var data = Data.getData(button, DATA_KEY$1); - if (!$(button).hasClass(ClassName$1.BUTTON)) { - button = $(button).closest(Selector$1.BUTTON)[0]; + if (!data) { + data = new Button(button); } - if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) { - event.preventDefault(); // work around Firefox bug #1540995 - } else { - var inputBtn = button.querySelector(Selector$1.INPUT); - - if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) { - event.preventDefault(); // work around Firefox bug #1540995 - - return; - } - - Button._jQueryInterface.call($(button), 'toggle'); - } - }).on(Event$1.FOCUS_BLUR_DATA_API, Selector$1.DATA_TOGGLE_CARROT, function (event) { - var button = $(event.target).closest(Selector$1.BUTTON)[0]; - $(button).toggleClass(ClassName$1.FOCUS, /^focus(in)?$/.test(event.type)); - }); - $(window).on(Event$1.LOAD_DATA_API, function () { - // ensure correct active class is set to match the controls' actual values/states - // find all checkboxes/readio buttons inside data-toggle groups - var buttons = [].slice.call(document.querySelectorAll(Selector$1.DATA_TOGGLES_BUTTONS)); - - for (var i = 0, len = buttons.length; i < len; i++) { - var button = buttons[i]; - var input = button.querySelector(Selector$1.INPUT); - - if (input.checked || input.hasAttribute('checked')) { - button.classList.add(ClassName$1.ACTIVE); - } else { - button.classList.remove(ClassName$1.ACTIVE); - } - } // find all button toggles - - - buttons = [].slice.call(document.querySelectorAll(Selector$1.DATA_TOGGLE)); - - for (var _i = 0, _len = buttons.length; _i < _len; _i++) { - var _button = buttons[_i]; - - if (_button.getAttribute('aria-pressed') === 'true') { - _button.classList.add(ClassName$1.ACTIVE); - } else { - _button.classList.remove(ClassName$1.ACTIVE); - } - } + data.toggle(); }); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ + * add .Button to jQuery only if jQuery is present */ - $.fn[NAME$1] = Button._jQueryInterface; - $.fn[NAME$1].Constructor = Button; + onDOMContentLoaded(function () { + var $ = getjQuery(); + /* istanbul ignore if */ - $.fn[NAME$1].noConflict = function () { - $.fn[NAME$1] = JQUERY_NO_CONFLICT$1; - return Button._jQueryInterface; + if ($) { + var JQUERY_NO_CONFLICT = $.fn[NAME$1]; + $.fn[NAME$1] = Button.jQueryInterface; + $.fn[NAME$1].Constructor = Button; + + $.fn[NAME$1].noConflict = function () { + $.fn[NAME$1] = JQUERY_NO_CONFLICT; + return Button.jQueryInterface; + }; + } + }); + + /** + * -------------------------------------------------------------------------- + * Bootstrap (v5.0.0-beta1): dom/manipulator.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * -------------------------------------------------------------------------- + */ + function normalizeData(val) { + if (val === 'true') { + return true; + } + + if (val === 'false') { + return false; + } + + if (val === Number(val).toString()) { + return Number(val); + } + + if (val === '' || val === 'null') { + return null; + } + + return val; + } + + function normalizeDataKey(key) { + return key.replace(/[A-Z]/g, function (chr) { + return "-" + chr.toLowerCase(); + }); + } + + var Manipulator = { + setDataAttribute: function setDataAttribute(element, key, value) { + element.setAttribute("data-bs-" + normalizeDataKey(key), value); + }, + removeDataAttribute: function removeDataAttribute(element, key) { + element.removeAttribute("data-bs-" + normalizeDataKey(key)); + }, + getDataAttributes: function getDataAttributes(element) { + if (!element) { + return {}; + } + + var attributes = {}; + Object.keys(element.dataset).filter(function (key) { + return key.startsWith('bs'); + }).forEach(function (key) { + var pureKey = key.replace(/^bs/, ''); + pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length); + attributes[pureKey] = normalizeData(element.dataset[key]); + }); + return attributes; + }, + getDataAttribute: function getDataAttribute(element, key) { + return normalizeData(element.getAttribute("data-bs-" + normalizeDataKey(key))); + }, + offset: function offset(element) { + var rect = element.getBoundingClientRect(); + return { + top: rect.top + document.body.scrollTop, + left: rect.left + document.body.scrollLeft + }; + }, + position: function position(element) { + return { + top: element.offsetTop, + left: element.offsetLeft + }; + } + }; + + /** + * -------------------------------------------------------------------------- + * Bootstrap (v5.0.0-beta1): dom/selector-engine.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * -------------------------------------------------------------------------- + */ + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + var NODE_TEXT = 3; + var SelectorEngine = { + matches: function matches(element, selector) { + return element.matches(selector); + }, + find: function find(selector, element) { + var _ref; + + if (element === void 0) { + element = document.documentElement; + } + + return (_ref = []).concat.apply(_ref, Element.prototype.querySelectorAll.call(element, selector)); + }, + findOne: function findOne(selector, element) { + if (element === void 0) { + element = document.documentElement; + } + + return Element.prototype.querySelector.call(element, selector); + }, + children: function children(element, selector) { + var _ref2; + + var children = (_ref2 = []).concat.apply(_ref2, element.children); + + return children.filter(function (child) { + return child.matches(selector); + }); + }, + parents: function parents(element, selector) { + var parents = []; + var ancestor = element.parentNode; + + while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) { + if (this.matches(ancestor, selector)) { + parents.push(ancestor); + } + + ancestor = ancestor.parentNode; + } + + return parents; + }, + prev: function prev(element, selector) { + var previous = element.previousElementSibling; + + while (previous) { + if (previous.matches(selector)) { + return [previous]; + } + + previous = previous.previousElementSibling; + } + + return []; + }, + next: function next(element, selector) { + var next = element.nextElementSibling; + + while (next) { + if (this.matches(next, selector)) { + return [next]; + } + + next = next.nextElementSibling; + } + + return []; + } }; /** @@ -626,15 +1026,11 @@ */ var NAME$2 = 'carousel'; - var VERSION$2 = '4.4.1'; var DATA_KEY$2 = 'bs.carousel'; var EVENT_KEY$2 = "." + DATA_KEY$2; var DATA_API_KEY$2 = '.data-api'; - var JQUERY_NO_CONFLICT$2 = $.fn[NAME$2]; - var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key - - var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key - + var ARROW_LEFT_KEY = 'ArrowLeft'; + var ARROW_RIGHT_KEY = 'ArrowRight'; var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch var SWIPE_THRESHOLD = 40; @@ -654,48 +1050,39 @@ wrap: 'boolean', touch: 'boolean' }; - var Direction = { - NEXT: 'next', - PREV: 'prev', - LEFT: 'left', - RIGHT: 'right' - }; - var Event$2 = { - SLIDE: "slide" + EVENT_KEY$2, - SLID: "slid" + EVENT_KEY$2, - KEYDOWN: "keydown" + EVENT_KEY$2, - MOUSEENTER: "mouseenter" + EVENT_KEY$2, - MOUSELEAVE: "mouseleave" + EVENT_KEY$2, - TOUCHSTART: "touchstart" + EVENT_KEY$2, - TOUCHMOVE: "touchmove" + EVENT_KEY$2, - TOUCHEND: "touchend" + EVENT_KEY$2, - POINTERDOWN: "pointerdown" + EVENT_KEY$2, - POINTERUP: "pointerup" + EVENT_KEY$2, - DRAG_START: "dragstart" + EVENT_KEY$2, - LOAD_DATA_API: "load" + EVENT_KEY$2 + DATA_API_KEY$2, - CLICK_DATA_API: "click" + EVENT_KEY$2 + DATA_API_KEY$2 - }; - var ClassName$2 = { - CAROUSEL: 'carousel', - ACTIVE: 'active', - SLIDE: 'slide', - RIGHT: 'carousel-item-right', - LEFT: 'carousel-item-left', - NEXT: 'carousel-item-next', - PREV: 'carousel-item-prev', - ITEM: 'carousel-item', - POINTER_EVENT: 'pointer-event' - }; - var Selector$2 = { - ACTIVE: '.active', - ACTIVE_ITEM: '.active.carousel-item', - ITEM: '.carousel-item', - ITEM_IMG: '.carousel-item img', - NEXT_PREV: '.carousel-item-next, .carousel-item-prev', - INDICATORS: '.carousel-indicators', - DATA_SLIDE: '[data-slide], [data-slide-to]', - DATA_RIDE: '[data-ride="carousel"]' - }; + var DIRECTION_NEXT = 'next'; + var DIRECTION_PREV = 'prev'; + var DIRECTION_LEFT = 'left'; + var DIRECTION_RIGHT = 'right'; + var EVENT_SLIDE = "slide" + EVENT_KEY$2; + var EVENT_SLID = "slid" + EVENT_KEY$2; + var EVENT_KEYDOWN = "keydown" + EVENT_KEY$2; + var EVENT_MOUSEENTER = "mouseenter" + EVENT_KEY$2; + var EVENT_MOUSELEAVE = "mouseleave" + EVENT_KEY$2; + var EVENT_TOUCHSTART = "touchstart" + EVENT_KEY$2; + var EVENT_TOUCHMOVE = "touchmove" + EVENT_KEY$2; + var EVENT_TOUCHEND = "touchend" + EVENT_KEY$2; + var EVENT_POINTERDOWN = "pointerdown" + EVENT_KEY$2; + var EVENT_POINTERUP = "pointerup" + EVENT_KEY$2; + var EVENT_DRAG_START = "dragstart" + EVENT_KEY$2; + var EVENT_LOAD_DATA_API = "load" + EVENT_KEY$2 + DATA_API_KEY$2; + var EVENT_CLICK_DATA_API$2 = "click" + EVENT_KEY$2 + DATA_API_KEY$2; + var CLASS_NAME_CAROUSEL = 'carousel'; + var CLASS_NAME_ACTIVE$1 = 'active'; + var CLASS_NAME_SLIDE = 'slide'; + var CLASS_NAME_END = 'carousel-item-end'; + var CLASS_NAME_START = 'carousel-item-start'; + var CLASS_NAME_NEXT = 'carousel-item-next'; + var CLASS_NAME_PREV = 'carousel-item-prev'; + var CLASS_NAME_POINTER_EVENT = 'pointer-event'; + var SELECTOR_ACTIVE = '.active'; + var SELECTOR_ACTIVE_ITEM = '.active.carousel-item'; + var SELECTOR_ITEM = '.carousel-item'; + var SELECTOR_ITEM_IMG = '.carousel-item img'; + var SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'; + var SELECTOR_INDICATORS = '.carousel-indicators'; + var SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'; + var SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]'; var PointerType = { TOUCH: 'touch', PEN: 'pen' @@ -706,25 +1093,29 @@ * ------------------------------------------------------------------------ */ - var Carousel = - /*#__PURE__*/ - function () { - function Carousel(element, config) { - 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._indicatorsElement = this._element.querySelector(Selector$2.INDICATORS); - this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0; - this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent); + var Carousel = /*#__PURE__*/function (_BaseComponent) { + _inheritsLoose(Carousel, _BaseComponent); - this._addEventListeners(); + function Carousel(element, config) { + var _this; + + _this = _BaseComponent.call(this, element) || this; + _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._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, _this._element); + _this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0; + _this._pointerEvent = Boolean(window.PointerEvent); + + _this._addEventListeners(); + + return _this; } // Getters @@ -733,21 +1124,21 @@ // Public _proto.next = function next() { if (!this._isSliding) { - this._slide(Direction.NEXT); + this._slide(DIRECTION_NEXT); } }; _proto.nextWhenVisible = function nextWhenVisible() { // Don't call next when the page isn't visible // or the carousel or its parent isn't visible - if (!document.hidden && $(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden') { + if (!document.hidden && isVisible(this._element)) { this.next(); } }; _proto.prev = function prev() { if (!this._isSliding) { - this._slide(Direction.PREV); + this._slide(DIRECTION_PREV); } }; @@ -756,8 +1147,8 @@ this._isPaused = true; } - if (this._element.querySelector(Selector$2.NEXT_PREV)) { - Util.triggerTransitionEnd(this._element); + if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) { + triggerTransitionEnd(this._element); this.cycle(true); } @@ -775,15 +1166,17 @@ this._interval = null; } - if (this._config.interval && !this._isPaused) { + if (this._config && this._config.interval && !this._isPaused) { + this._updateInterval(); + this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval); } }; _proto.to = function to(index) { - var _this = this; + var _this2 = this; - this._activeElement = this._element.querySelector(Selector$2.ACTIVE_ITEM); + this._activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element); var activeIndex = this._getItemIndex(this._activeElement); @@ -792,8 +1185,8 @@ } if (this._isSliding) { - $(this._element).one(Event$2.SLID, function () { - return _this.to(index); + EventHandler.one(this._element, EVENT_SLID, function () { + return _this2.to(index); }); return; } @@ -804,17 +1197,17 @@ return; } - var direction = index > activeIndex ? Direction.NEXT : Direction.PREV; + var direction = index > activeIndex ? DIRECTION_NEXT : DIRECTION_PREV; this._slide(direction, this._items[index]); }; _proto.dispose = function dispose() { - $(this._element).off(EVENT_KEY$2); - $.removeData(this._element, DATA_KEY$2); + _BaseComponent.prototype.dispose.call(this); + + EventHandler.off(this._element, EVENT_KEY$2); this._items = null; this._config = null; - this._element = null; this._interval = null; this._isPaused = null; this._isSliding = null; @@ -824,8 +1217,8 @@ ; _proto._getConfig = function _getConfig(config) { - config = _objectSpread2({}, Default, {}, config); - Util.typeCheckConfig(NAME$2, config, DefaultType); + config = _extends({}, Default, config); + typeCheckConfig(NAME$2, config, DefaultType); return config; }; @@ -850,59 +1243,56 @@ }; _proto._addEventListeners = function _addEventListeners() { - var _this2 = this; + var _this3 = this; if (this._config.keyboard) { - $(this._element).on(Event$2.KEYDOWN, function (event) { - return _this2._keydown(event); + EventHandler.on(this._element, EVENT_KEYDOWN, function (event) { + return _this3._keydown(event); }); } if (this._config.pause === 'hover') { - $(this._element).on(Event$2.MOUSEENTER, function (event) { - return _this2.pause(event); - }).on(Event$2.MOUSELEAVE, function (event) { - return _this2.cycle(event); + EventHandler.on(this._element, EVENT_MOUSEENTER, function (event) { + return _this3.pause(event); + }); + EventHandler.on(this._element, EVENT_MOUSELEAVE, function (event) { + return _this3.cycle(event); }); } - if (this._config.touch) { + if (this._config.touch && this._touchSupported) { this._addTouchEventListeners(); } }; _proto._addTouchEventListeners = function _addTouchEventListeners() { - var _this3 = this; - - if (!this._touchSupported) { - return; - } + var _this4 = this; var start = function start(event) { - if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { - _this3.touchStartX = event.originalEvent.clientX; - } else if (!_this3._pointerEvent) { - _this3.touchStartX = event.originalEvent.touches[0].clientX; + if (_this4._pointerEvent && PointerType[event.pointerType.toUpperCase()]) { + _this4.touchStartX = event.clientX; + } else if (!_this4._pointerEvent) { + _this4.touchStartX = event.touches[0].clientX; } }; var move = function move(event) { // ensure swiping with one touch and not pinching - if (event.originalEvent.touches && event.originalEvent.touches.length > 1) { - _this3.touchDeltaX = 0; + if (event.touches && event.touches.length > 1) { + _this4.touchDeltaX = 0; } else { - _this3.touchDeltaX = event.originalEvent.touches[0].clientX - _this3.touchStartX; + _this4.touchDeltaX = event.touches[0].clientX - _this4.touchStartX; } }; var end = function end(event) { - if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { - _this3.touchDeltaX = event.originalEvent.clientX - _this3.touchStartX; + if (_this4._pointerEvent && PointerType[event.pointerType.toUpperCase()]) { + _this4.touchDeltaX = event.clientX - _this4.touchStartX; } - _this3._handleSwipe(); + _this4._handleSwipe(); - if (_this3._config.pause === 'hover') { + if (_this4._config.pause === 'hover') { // If it's a touch-enabled device, mouseenter/leave are fired as // part of the mouse compatibility events on first tap - the carousel // would stop cycling until user tapped out of it; @@ -910,39 +1300,41 @@ // (as if it's the second time we tap on it, mouseenter compat event // is NOT fired) and after a timeout (to allow for mouse compatibility // events to fire) we explicitly restart cycling - _this3.pause(); + _this4.pause(); - if (_this3.touchTimeout) { - clearTimeout(_this3.touchTimeout); + if (_this4.touchTimeout) { + clearTimeout(_this4.touchTimeout); } - _this3.touchTimeout = setTimeout(function (event) { - return _this3.cycle(event); - }, TOUCHEVENT_COMPAT_WAIT + _this3._config.interval); + _this4.touchTimeout = setTimeout(function (event) { + return _this4.cycle(event); + }, TOUCHEVENT_COMPAT_WAIT + _this4._config.interval); } }; - $(this._element.querySelectorAll(Selector$2.ITEM_IMG)).on(Event$2.DRAG_START, function (e) { - return e.preventDefault(); + SelectorEngine.find(SELECTOR_ITEM_IMG, this._element).forEach(function (itemImg) { + EventHandler.on(itemImg, EVENT_DRAG_START, function (e) { + return e.preventDefault(); + }); }); if (this._pointerEvent) { - $(this._element).on(Event$2.POINTERDOWN, function (event) { + EventHandler.on(this._element, EVENT_POINTERDOWN, function (event) { return start(event); }); - $(this._element).on(Event$2.POINTERUP, function (event) { + EventHandler.on(this._element, EVENT_POINTERUP, function (event) { return end(event); }); - this._element.classList.add(ClassName$2.POINTER_EVENT); + this._element.classList.add(CLASS_NAME_POINTER_EVENT); } else { - $(this._element).on(Event$2.TOUCHSTART, function (event) { + EventHandler.on(this._element, EVENT_TOUCHSTART, function (event) { return start(event); }); - $(this._element).on(Event$2.TOUCHMOVE, function (event) { + EventHandler.on(this._element, EVENT_TOUCHMOVE, function (event) { return move(event); }); - $(this._element).on(Event$2.TOUCHEND, function (event) { + EventHandler.on(this._element, EVENT_TOUCHEND, function (event) { return end(event); }); } @@ -953,13 +1345,13 @@ return; } - switch (event.which) { - case ARROW_LEFT_KEYCODE: + switch (event.key) { + case ARROW_LEFT_KEY: event.preventDefault(); this.prev(); break; - case ARROW_RIGHT_KEYCODE: + case ARROW_RIGHT_KEY: event.preventDefault(); this.next(); break; @@ -967,13 +1359,13 @@ }; _proto._getItemIndex = function _getItemIndex(element) { - this._items = element && element.parentNode ? [].slice.call(element.parentNode.querySelectorAll(Selector$2.ITEM)) : []; + this._items = element && element.parentNode ? SelectorEngine.find(SELECTOR_ITEM, element.parentNode) : []; return this._items.indexOf(element); }; _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) { - var isNextDirection = direction === Direction.NEXT; - var isPrevDirection = direction === Direction.PREV; + var isNextDirection = direction === DIRECTION_NEXT; + var isPrevDirection = direction === DIRECTION_PREV; var activeIndex = this._getItemIndex(activeElement); @@ -984,7 +1376,7 @@ return activeElement; } - var delta = direction === Direction.PREV ? -1 : 1; + var delta = direction === DIRECTION_PREV ? -1 : 1; var itemIndex = (activeIndex + delta) % this._items.length; return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex]; }; @@ -992,35 +1384,53 @@ _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) { var targetIndex = this._getItemIndex(relatedTarget); - var fromIndex = this._getItemIndex(this._element.querySelector(Selector$2.ACTIVE_ITEM)); + var fromIndex = this._getItemIndex(SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)); - var slideEvent = $.Event(Event$2.SLIDE, { + return EventHandler.trigger(this._element, EVENT_SLIDE, { relatedTarget: relatedTarget, direction: eventDirectionName, from: fromIndex, to: targetIndex }); - $(this._element).trigger(slideEvent); - return slideEvent; }; _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) { if (this._indicatorsElement) { - var indicators = [].slice.call(this._indicatorsElement.querySelectorAll(Selector$2.ACTIVE)); - $(indicators).removeClass(ClassName$2.ACTIVE); + var indicators = SelectorEngine.find(SELECTOR_ACTIVE, this._indicatorsElement); + + for (var i = 0; i < indicators.length; i++) { + indicators[i].classList.remove(CLASS_NAME_ACTIVE$1); + } var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)]; if (nextIndicator) { - $(nextIndicator).addClass(ClassName$2.ACTIVE); + nextIndicator.classList.add(CLASS_NAME_ACTIVE$1); } } }; - _proto._slide = function _slide(direction, element) { - var _this4 = this; + _proto._updateInterval = function _updateInterval() { + var element = this._activeElement || SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element); - var activeElement = this._element.querySelector(Selector$2.ACTIVE_ITEM); + if (!element) { + return; + } + + var elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10); + + if (elementInterval) { + this._config.defaultInterval = this._config.defaultInterval || this._config.interval; + this._config.interval = elementInterval; + } else { + this._config.interval = this._config.defaultInterval || this._config.interval; + } + }; + + _proto._slide = function _slide(direction, element) { + var _this5 = this; + + var activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element); var activeElementIndex = this._getItemIndex(activeElement); @@ -1033,24 +1443,24 @@ var orderClassName; var eventDirectionName; - if (direction === Direction.NEXT) { - directionalClassName = ClassName$2.LEFT; - orderClassName = ClassName$2.NEXT; - eventDirectionName = Direction.LEFT; + if (direction === DIRECTION_NEXT) { + directionalClassName = CLASS_NAME_START; + orderClassName = CLASS_NAME_NEXT; + eventDirectionName = DIRECTION_LEFT; } else { - directionalClassName = ClassName$2.RIGHT; - orderClassName = ClassName$2.PREV; - eventDirectionName = Direction.RIGHT; + directionalClassName = CLASS_NAME_END; + orderClassName = CLASS_NAME_PREV; + eventDirectionName = DIRECTION_RIGHT; } - if (nextElement && $(nextElement).hasClass(ClassName$2.ACTIVE)) { + if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE$1)) { this._isSliding = false; return; } var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName); - if (slideEvent.isDefaultPrevented()) { + if (slideEvent.defaultPrevented) { return; } @@ -1067,41 +1477,39 @@ this._setActiveIndicatorElement(nextElement); - var slidEvent = $.Event(Event$2.SLID, { - relatedTarget: nextElement, - direction: eventDirectionName, - from: activeElementIndex, - to: nextElementIndex - }); + this._activeElement = nextElement; - if ($(this._element).hasClass(ClassName$2.SLIDE)) { - $(nextElement).addClass(orderClassName); - Util.reflow(nextElement); - $(activeElement).addClass(directionalClassName); - $(nextElement).addClass(directionalClassName); - var nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10); - - if (nextElementInterval) { - this._config.defaultInterval = this._config.defaultInterval || this._config.interval; - this._config.interval = nextElementInterval; - } else { - this._config.interval = this._config.defaultInterval || this._config.interval; - } - - var transitionDuration = Util.getTransitionDurationFromElement(activeElement); - $(activeElement).one(Util.TRANSITION_END, function () { - $(nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(ClassName$2.ACTIVE); - $(activeElement).removeClass(ClassName$2.ACTIVE + " " + orderClassName + " " + directionalClassName); - _this4._isSliding = false; + if (this._element.classList.contains(CLASS_NAME_SLIDE)) { + nextElement.classList.add(orderClassName); + reflow(nextElement); + activeElement.classList.add(directionalClassName); + nextElement.classList.add(directionalClassName); + var transitionDuration = getTransitionDurationFromElement(activeElement); + EventHandler.one(activeElement, TRANSITION_END, function () { + nextElement.classList.remove(directionalClassName, orderClassName); + nextElement.classList.add(CLASS_NAME_ACTIVE$1); + activeElement.classList.remove(CLASS_NAME_ACTIVE$1, orderClassName, directionalClassName); + _this5._isSliding = false; setTimeout(function () { - return $(_this4._element).trigger(slidEvent); + EventHandler.trigger(_this5._element, EVENT_SLID, { + relatedTarget: nextElement, + direction: eventDirectionName, + from: activeElementIndex, + to: nextElementIndex + }); }, 0); - }).emulateTransitionEnd(transitionDuration); + }); + emulateTransitionEnd(activeElement, transitionDuration); } else { - $(activeElement).removeClass(ClassName$2.ACTIVE); - $(nextElement).addClass(ClassName$2.ACTIVE); + activeElement.classList.remove(CLASS_NAME_ACTIVE$1); + nextElement.classList.add(CLASS_NAME_ACTIVE$1); this._isSliding = false; - $(this._element).trigger(slidEvent); + EventHandler.trigger(this._element, EVENT_SLID, { + relatedTarget: nextElement, + direction: eventDirectionName, + from: activeElementIndex, + to: nextElementIndex + }); } if (isCycling) { @@ -1110,82 +1518,79 @@ } // Static ; - Carousel._jQueryInterface = function _jQueryInterface(config) { + Carousel.carouselInterface = function carouselInterface(element, config) { + var data = Data.getData(element, DATA_KEY$2); + + var _config = _extends({}, Default, Manipulator.getDataAttributes(element)); + + if (typeof config === 'object') { + _config = _extends({}, _config, config); + } + + var action = typeof config === 'string' ? config : _config.slide; + + if (!data) { + data = new Carousel(element, _config); + } + + if (typeof config === 'number') { + data.to(config); + } else if (typeof action === 'string') { + if (typeof data[action] === 'undefined') { + throw new TypeError("No method named \"" + action + "\""); + } + + data[action](); + } else if (_config.interval && _config.ride) { + data.pause(); + data.cycle(); + } + }; + + Carousel.jQueryInterface = function jQueryInterface(config) { return this.each(function () { - var data = $(this).data(DATA_KEY$2); - - var _config = _objectSpread2({}, Default, {}, $(this).data()); - - if (typeof config === 'object') { - _config = _objectSpread2({}, _config, {}, config); - } - - var action = typeof config === 'string' ? config : _config.slide; - - if (!data) { - data = new Carousel(this, _config); - $(this).data(DATA_KEY$2, data); - } - - if (typeof config === 'number') { - data.to(config); - } else if (typeof action === 'string') { - if (typeof data[action] === 'undefined') { - throw new TypeError("No method named \"" + action + "\""); - } - - data[action](); - } else if (_config.interval && _config.ride) { - data.pause(); - data.cycle(); - } + Carousel.carouselInterface(this, config); }); }; - Carousel._dataApiClickHandler = function _dataApiClickHandler(event) { - var selector = Util.getSelectorFromElement(this); + Carousel.dataApiClickHandler = function dataApiClickHandler(event) { + var target = getElementFromSelector(this); - if (!selector) { + if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) { return; } - var target = $(selector)[0]; + var config = _extends({}, Manipulator.getDataAttributes(target), Manipulator.getDataAttributes(this)); - if (!target || !$(target).hasClass(ClassName$2.CAROUSEL)) { - return; - } - - var config = _objectSpread2({}, $(target).data(), {}, $(this).data()); - - var slideIndex = this.getAttribute('data-slide-to'); + var slideIndex = this.getAttribute('data-bs-slide-to'); if (slideIndex) { config.interval = false; } - Carousel._jQueryInterface.call($(target), config); + Carousel.carouselInterface(target, config); if (slideIndex) { - $(target).data(DATA_KEY$2).to(slideIndex); + Data.getData(target, DATA_KEY$2).to(slideIndex); } event.preventDefault(); }; _createClass(Carousel, null, [{ - key: "VERSION", - get: function get() { - return VERSION$2; - } - }, { key: "Default", get: function get() { return Default; } + }, { + key: "DATA_KEY", + get: function get() { + return DATA_KEY$2; + } }]); return Carousel; - }(); + }(BaseComponent); /** * ------------------------------------------------------------------------ * Data Api implementation @@ -1193,29 +1598,36 @@ */ - $(document).on(Event$2.CLICK_DATA_API, Selector$2.DATA_SLIDE, Carousel._dataApiClickHandler); - $(window).on(Event$2.LOAD_DATA_API, function () { - var carousels = [].slice.call(document.querySelectorAll(Selector$2.DATA_RIDE)); + EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler); + EventHandler.on(window, EVENT_LOAD_DATA_API, function () { + var carousels = SelectorEngine.find(SELECTOR_DATA_RIDE); for (var i = 0, len = carousels.length; i < len; i++) { - var $carousel = $(carousels[i]); - - Carousel._jQueryInterface.call($carousel, $carousel.data()); + Carousel.carouselInterface(carousels[i], Data.getData(carousels[i], DATA_KEY$2)); } }); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ + * add .Carousel to jQuery only if jQuery is present */ - $.fn[NAME$2] = Carousel._jQueryInterface; - $.fn[NAME$2].Constructor = Carousel; + onDOMContentLoaded(function () { + var $ = getjQuery(); + /* istanbul ignore if */ - $.fn[NAME$2].noConflict = function () { - $.fn[NAME$2] = JQUERY_NO_CONFLICT$2; - return Carousel._jQueryInterface; - }; + if ($) { + var JQUERY_NO_CONFLICT = $.fn[NAME$2]; + $.fn[NAME$2] = Carousel.jQueryInterface; + $.fn[NAME$2].Constructor = Carousel; + + $.fn[NAME$2].noConflict = function () { + $.fn[NAME$2] = JQUERY_NO_CONFLICT; + return Carousel.jQueryInterface; + }; + } + }); /** * ------------------------------------------------------------------------ @@ -1224,11 +1636,9 @@ */ var NAME$3 = 'collapse'; - var VERSION$3 = '4.4.1'; var DATA_KEY$3 = 'bs.collapse'; var EVENT_KEY$3 = "." + DATA_KEY$3; var DATA_API_KEY$3 = '.data-api'; - var JQUERY_NO_CONFLICT$3 = $.fn[NAME$3]; var Default$1 = { toggle: true, parent: '' @@ -1237,66 +1647,62 @@ toggle: 'boolean', parent: '(string|element)' }; - var Event$3 = { - SHOW: "show" + EVENT_KEY$3, - SHOWN: "shown" + EVENT_KEY$3, - HIDE: "hide" + EVENT_KEY$3, - HIDDEN: "hidden" + EVENT_KEY$3, - CLICK_DATA_API: "click" + EVENT_KEY$3 + DATA_API_KEY$3 - }; - var ClassName$3 = { - SHOW: 'show', - COLLAPSE: 'collapse', - COLLAPSING: 'collapsing', - COLLAPSED: 'collapsed' - }; - var Dimension = { - WIDTH: 'width', - HEIGHT: 'height' - }; - var Selector$3 = { - ACTIVES: '.show, .collapsing', - DATA_TOGGLE: '[data-toggle="collapse"]' - }; + var EVENT_SHOW = "show" + EVENT_KEY$3; + var EVENT_SHOWN = "shown" + EVENT_KEY$3; + var EVENT_HIDE = "hide" + EVENT_KEY$3; + var EVENT_HIDDEN = "hidden" + EVENT_KEY$3; + var EVENT_CLICK_DATA_API$3 = "click" + EVENT_KEY$3 + DATA_API_KEY$3; + var CLASS_NAME_SHOW = 'show'; + var CLASS_NAME_COLLAPSE = 'collapse'; + var CLASS_NAME_COLLAPSING = 'collapsing'; + var CLASS_NAME_COLLAPSED = 'collapsed'; + var WIDTH = 'width'; + var HEIGHT = 'height'; + var SELECTOR_ACTIVES = '.show, .collapsing'; + var SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="collapse"]'; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ - var Collapse = - /*#__PURE__*/ - function () { + var Collapse = /*#__PURE__*/function (_BaseComponent) { + _inheritsLoose(Collapse, _BaseComponent); + function Collapse(element, config) { - this._isTransitioning = false; - 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 + "\"]"))); - var toggleList = [].slice.call(document.querySelectorAll(Selector$3.DATA_TOGGLE)); + var _this; + + _this = _BaseComponent.call(this, element) || this; + _this._isTransitioning = false; + _this._config = _this._getConfig(config); + _this._triggerArray = SelectorEngine.find(SELECTOR_DATA_TOGGLE$1 + "[href=\"#" + element.id + "\"]," + (SELECTOR_DATA_TOGGLE$1 + "[data-bs-target=\"#" + element.id + "\"]")); + var toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$1); for (var i = 0, len = toggleList.length; i < len; i++) { var elem = toggleList[i]; - var selector = Util.getSelectorFromElement(elem); - var filterElement = [].slice.call(document.querySelectorAll(selector)).filter(function (foundElem) { + var selector = getSelectorFromElement(elem); + var filterElement = SelectorEngine.find(selector).filter(function (foundElem) { return foundElem === element; }); - if (selector !== null && filterElement.length > 0) { - this._selector = selector; + if (selector !== null && filterElement.length) { + _this._selector = selector; - this._triggerArray.push(elem); + _this._triggerArray.push(elem); } } - this._parent = this._config.parent ? this._getParent() : null; + _this._parent = _this._config.parent ? _this._getParent() : null; - if (!this._config.parent) { - this._addAriaAndCollapsedClass(this._element, this._triggerArray); + if (!_this._config.parent) { + _this._addAriaAndCollapsedClass(_this._element, _this._triggerArray); } - if (this._config.toggle) { - this.toggle(); + if (_this._config.toggle) { + _this.toggle(); } + + return _this; } // Getters @@ -1304,7 +1710,7 @@ // Public _proto.toggle = function toggle() { - if ($(this._element).hasClass(ClassName$3.SHOW)) { + if (this._element.classList.contains(CLASS_NAME_SHOW)) { this.hide(); } else { this.show(); @@ -1312,9 +1718,9 @@ }; _proto.show = function show() { - var _this = this; + var _this2 = this; - if (this._isTransitioning || $(this._element).hasClass(ClassName$3.SHOW)) { + if (this._isTransitioning || this._element.classList.contains(CLASS_NAME_SHOW)) { return; } @@ -1322,12 +1728,12 @@ var activesData; if (this._parent) { - actives = [].slice.call(this._parent.querySelectorAll(Selector$3.ACTIVES)).filter(function (elem) { - if (typeof _this._config.parent === 'string') { - return elem.getAttribute('data-parent') === _this._config.parent; + actives = SelectorEngine.find(SELECTOR_ACTIVES, this._parent).filter(function (elem) { + if (typeof _this2._config.parent === 'string') { + return elem.getAttribute('data-bs-parent') === _this2._config.parent; } - return elem.classList.contains(ClassName$3.COLLAPSE); + return elem.classList.contains(CLASS_NAME_COLLAPSE); }); if (actives.length === 0) { @@ -1335,88 +1741,106 @@ } } + var container = SelectorEngine.findOne(this._selector); + if (actives) { - activesData = $(actives).not(this._selector).data(DATA_KEY$3); + var tempActiveData = actives.find(function (elem) { + return container !== elem; + }); + activesData = tempActiveData ? Data.getData(tempActiveData, DATA_KEY$3) : null; if (activesData && activesData._isTransitioning) { return; } } - var startEvent = $.Event(Event$3.SHOW); - $(this._element).trigger(startEvent); + var startEvent = EventHandler.trigger(this._element, EVENT_SHOW); - if (startEvent.isDefaultPrevented()) { + if (startEvent.defaultPrevented) { return; } if (actives) { - Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide'); + actives.forEach(function (elemActive) { + if (container !== elemActive) { + Collapse.collapseInterface(elemActive, 'hide'); + } - if (!activesData) { - $(actives).data(DATA_KEY$3, null); - } + if (!activesData) { + Data.setData(elemActive, DATA_KEY$3, null); + } + }); } var dimension = this._getDimension(); - $(this._element).removeClass(ClassName$3.COLLAPSE).addClass(ClassName$3.COLLAPSING); + this._element.classList.remove(CLASS_NAME_COLLAPSE); + + this._element.classList.add(CLASS_NAME_COLLAPSING); + this._element.style[dimension] = 0; if (this._triggerArray.length) { - $(this._triggerArray).removeClass(ClassName$3.COLLAPSED).attr('aria-expanded', true); + this._triggerArray.forEach(function (element) { + element.classList.remove(CLASS_NAME_COLLAPSED); + element.setAttribute('aria-expanded', true); + }); } this.setTransitioning(true); var complete = function complete() { - $(_this._element).removeClass(ClassName$3.COLLAPSING).addClass(ClassName$3.COLLAPSE).addClass(ClassName$3.SHOW); - _this._element.style[dimension] = ''; + _this2._element.classList.remove(CLASS_NAME_COLLAPSING); - _this.setTransitioning(false); + _this2._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW); - $(_this._element).trigger(Event$3.SHOWN); + _this2._element.style[dimension] = ''; + + _this2.setTransitioning(false); + + EventHandler.trigger(_this2._element, EVENT_SHOWN); }; var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); var scrollSize = "scroll" + capitalizedDimension; - var transitionDuration = Util.getTransitionDurationFromElement(this._element); - $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); + var transitionDuration = getTransitionDurationFromElement(this._element); + EventHandler.one(this._element, TRANSITION_END, complete); + emulateTransitionEnd(this._element, transitionDuration); this._element.style[dimension] = this._element[scrollSize] + "px"; }; _proto.hide = function hide() { - var _this2 = this; + var _this3 = this; - if (this._isTransitioning || !$(this._element).hasClass(ClassName$3.SHOW)) { + if (this._isTransitioning || !this._element.classList.contains(CLASS_NAME_SHOW)) { return; } - var startEvent = $.Event(Event$3.HIDE); - $(this._element).trigger(startEvent); + var startEvent = EventHandler.trigger(this._element, EVENT_HIDE); - if (startEvent.isDefaultPrevented()) { + if (startEvent.defaultPrevented) { return; } var dimension = this._getDimension(); this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px"; - Util.reflow(this._element); - $(this._element).addClass(ClassName$3.COLLAPSING).removeClass(ClassName$3.COLLAPSE).removeClass(ClassName$3.SHOW); + reflow(this._element); + + this._element.classList.add(CLASS_NAME_COLLAPSING); + + this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW); + var triggerArrayLength = this._triggerArray.length; if (triggerArrayLength > 0) { for (var i = 0; i < triggerArrayLength; i++) { var trigger = this._triggerArray[i]; - var selector = Util.getSelectorFromElement(trigger); + var elem = getElementFromSelector(trigger); - if (selector !== null) { - var $elem = $([].slice.call(document.querySelectorAll(selector))); - - if (!$elem.hasClass(ClassName$3.SHOW)) { - $(trigger).addClass(ClassName$3.COLLAPSED).attr('aria-expanded', false); - } + if (elem && !elem.classList.contains(CLASS_NAME_SHOW)) { + trigger.classList.add(CLASS_NAME_COLLAPSED); + trigger.setAttribute('aria-expanded', false); } } } @@ -1424,14 +1848,19 @@ this.setTransitioning(true); var complete = function complete() { - _this2.setTransitioning(false); + _this3.setTransitioning(false); - $(_this2._element).removeClass(ClassName$3.COLLAPSING).addClass(ClassName$3.COLLAPSE).trigger(Event$3.HIDDEN); + _this3._element.classList.remove(CLASS_NAME_COLLAPSING); + + _this3._element.classList.add(CLASS_NAME_COLLAPSE); + + EventHandler.trigger(_this3._element, EVENT_HIDDEN); }; this._element.style[dimension] = ''; - var transitionDuration = Util.getTransitionDurationFromElement(this._element); - $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); + var transitionDuration = getTransitionDurationFromElement(this._element); + EventHandler.one(this._element, TRANSITION_END, complete); + emulateTransitionEnd(this._element, transitionDuration); }; _proto.setTransitioning = function setTransitioning(isTransitioning) { @@ -1439,105 +1868,110 @@ }; _proto.dispose = function dispose() { - $.removeData(this._element, DATA_KEY$3); + _BaseComponent.prototype.dispose.call(this); + this._config = null; this._parent = null; - this._element = null; this._triggerArray = null; this._isTransitioning = null; } // Private ; _proto._getConfig = function _getConfig(config) { - config = _objectSpread2({}, Default$1, {}, config); + config = _extends({}, Default$1, config); config.toggle = Boolean(config.toggle); // Coerce string values - Util.typeCheckConfig(NAME$3, config, DefaultType$1); + typeCheckConfig(NAME$3, config, DefaultType$1); return config; }; _proto._getDimension = function _getDimension() { - var hasWidth = $(this._element).hasClass(Dimension.WIDTH); - return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT; + return this._element.classList.contains(WIDTH) ? WIDTH : HEIGHT; }; _proto._getParent = function _getParent() { - var _this3 = this; + var _this4 = this; - var parent; + var parent = this._config.parent; - if (Util.isElement(this._config.parent)) { - parent = this._config.parent; // It's a jQuery object - - if (typeof this._config.parent.jquery !== 'undefined') { - parent = this._config.parent[0]; + if (isElement(parent)) { + // it's a jQuery object + if (typeof parent.jquery !== 'undefined' || typeof parent[0] !== 'undefined') { + parent = parent[0]; } } else { - parent = document.querySelector(this._config.parent); + parent = SelectorEngine.findOne(parent); } - var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]"; - var children = [].slice.call(parent.querySelectorAll(selector)); - $(children).each(function (i, element) { - _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]); + var selector = SELECTOR_DATA_TOGGLE$1 + "[data-bs-parent=\"" + parent + "\"]"; + SelectorEngine.find(selector, parent).forEach(function (element) { + var selected = getElementFromSelector(element); + + _this4._addAriaAndCollapsedClass(selected, [element]); }); return parent; }; _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) { - var isOpen = $(element).hasClass(ClassName$3.SHOW); - - if (triggerArray.length) { - $(triggerArray).toggleClass(ClassName$3.COLLAPSED, !isOpen).attr('aria-expanded', isOpen); + if (!element || !triggerArray.length) { + return; } + + var isOpen = element.classList.contains(CLASS_NAME_SHOW); + triggerArray.forEach(function (elem) { + if (isOpen) { + elem.classList.remove(CLASS_NAME_COLLAPSED); + } else { + elem.classList.add(CLASS_NAME_COLLAPSED); + } + + elem.setAttribute('aria-expanded', isOpen); + }); } // Static ; - Collapse._getTargetFromElement = function _getTargetFromElement(element) { - var selector = Util.getSelectorFromElement(element); - return selector ? document.querySelector(selector) : null; + Collapse.collapseInterface = function collapseInterface(element, config) { + var data = Data.getData(element, DATA_KEY$3); + + var _config = _extends({}, Default$1, Manipulator.getDataAttributes(element), typeof config === 'object' && config ? config : {}); + + if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) { + _config.toggle = false; + } + + if (!data) { + data = new Collapse(element, _config); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](); + } }; - Collapse._jQueryInterface = function _jQueryInterface(config) { + Collapse.jQueryInterface = function jQueryInterface(config) { return this.each(function () { - var $this = $(this); - var data = $this.data(DATA_KEY$3); - - var _config = _objectSpread2({}, Default$1, {}, $this.data(), {}, typeof config === 'object' && config ? config : {}); - - if (!data && _config.toggle && /show|hide/.test(config)) { - _config.toggle = false; - } - - if (!data) { - data = new Collapse(this, _config); - $this.data(DATA_KEY$3, data); - } - - if (typeof config === 'string') { - if (typeof data[config] === 'undefined') { - throw new TypeError("No method named \"" + config + "\""); - } - - data[config](); - } + Collapse.collapseInterface(this, config); }); }; _createClass(Collapse, null, [{ - key: "VERSION", - get: function get() { - return VERSION$3; - } - }, { key: "Default", get: function get() { return Default$1; } + }, { + key: "DATA_KEY", + get: function get() { + return DATA_KEY$3; + } }]); return Collapse; - }(); + }(BaseComponent); /** * ------------------------------------------------------------------------ * Data Api implementation @@ -1545,2650 +1979,1771 @@ */ - $(document).on(Event$3.CLICK_DATA_API, Selector$3.DATA_TOGGLE, function (event) { + EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$1, function (event) { // preventDefault only for elements (which change the URL) not inside the collapsible element - if (event.currentTarget.tagName === 'A') { + if (event.target.tagName === 'A') { event.preventDefault(); } - var $trigger = $(this); - var selector = Util.getSelectorFromElement(this); - var selectors = [].slice.call(document.querySelectorAll(selector)); - $(selectors).each(function () { - var $target = $(this); - var data = $target.data(DATA_KEY$3); - var config = data ? 'toggle' : $trigger.data(); + var triggerData = Manipulator.getDataAttributes(this); + var selector = getSelectorFromElement(this); + var selectorElements = SelectorEngine.find(selector); + selectorElements.forEach(function (element) { + var data = Data.getData(element, DATA_KEY$3); + var config; - Collapse._jQueryInterface.call($target, config); + if (data) { + // update parent attribute + if (data._parent === null && typeof triggerData.parent === 'string') { + data._config.parent = triggerData.parent; + data._parent = data._getParent(); + } + + config = 'toggle'; + } else { + config = triggerData; + } + + Collapse.collapseInterface(element, config); }); }); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ + * add .Collapse to jQuery only if jQuery is present */ - $.fn[NAME$3] = Collapse._jQueryInterface; - $.fn[NAME$3].Constructor = Collapse; + onDOMContentLoaded(function () { + var $ = getjQuery(); + /* istanbul ignore if */ - $.fn[NAME$3].noConflict = function () { - $.fn[NAME$3] = JQUERY_NO_CONFLICT$3; - return Collapse._jQueryInterface; - }; + if ($) { + var JQUERY_NO_CONFLICT = $.fn[NAME$3]; + $.fn[NAME$3] = Collapse.jQueryInterface; + $.fn[NAME$3].Constructor = Collapse; - /**! - * @fileOverview Kickass library to create and place poppers near their reference elements. - * @version 1.16.0 - * @license - * Copyright (c) 2016 Federico Zivolo and contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined'; - - var timeoutDuration = function () { - var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; - for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { - if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { - return 1; - } + $.fn[NAME$3].noConflict = function () { + $.fn[NAME$3] = JQUERY_NO_CONFLICT; + return Collapse.jQueryInterface; + }; } - return 0; - }(); + }); - function microtaskDebounce(fn) { - var called = false; - return function () { - if (called) { - return; - } - called = true; - window.Promise.resolve().then(function () { - called = false; - fn(); - }); - }; + var top = 'top'; + var bottom = 'bottom'; + var right = 'right'; + var left = 'left'; + var auto = 'auto'; + var basePlacements = [top, bottom, right, left]; + var start = 'start'; + var end = 'end'; + var clippingParents = 'clippingParents'; + var viewport = 'viewport'; + var popper = 'popper'; + var reference = 'reference'; + var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) { + return acc.concat([placement + "-" + start, placement + "-" + end]); + }, []); + var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) { + return acc.concat([placement, placement + "-" + start, placement + "-" + end]); + }, []); // modifiers that need to read the DOM + + var beforeRead = 'beforeRead'; + var read = 'read'; + var afterRead = 'afterRead'; // pure-logic modifiers + + var beforeMain = 'beforeMain'; + var main = 'main'; + var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state) + + var beforeWrite = 'beforeWrite'; + var write = 'write'; + var afterWrite = 'afterWrite'; + var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; + + function getNodeName(element) { + return element ? (element.nodeName || '').toLowerCase() : null; } - function taskDebounce(fn) { - var scheduled = false; - return function () { - if (!scheduled) { - scheduled = true; - setTimeout(function () { - scheduled = false; - fn(); - }, timeoutDuration); - } - }; - } + /*:: import type { Window } from '../types'; */ - var supportsMicroTasks = isBrowser && window.Promise; - - /** - * Create a debounced version of a method, that's asynchronously deferred - * but called in the minimum time possible. - * - * @method - * @memberof Popper.Utils - * @argument {Function} fn - * @returns {Function} - */ - var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; - - /** - * Check if the given variable is a function - * @method - * @memberof Popper.Utils - * @argument {Any} functionToCheck - variable to check - * @returns {Boolean} answer to: is a function? - */ - function isFunction(functionToCheck) { - var getType = {}; - return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; - } - - /** - * Get CSS computed property of the given element - * @method - * @memberof Popper.Utils - * @argument {Eement} element - * @argument {String} property - */ - function getStyleComputedProperty(element, property) { - if (element.nodeType !== 1) { - return []; - } - // NOTE: 1 DOM access here - var window = element.ownerDocument.defaultView; - var css = window.getComputedStyle(element, null); - return property ? css[property] : css; - } - - /** - * Returns the parentNode or the host of the element - * @method - * @memberof Popper.Utils - * @argument {Element} element - * @returns {Element} parent - */ - function getParentNode(element) { - if (element.nodeName === 'HTML') { - return element; - } - return element.parentNode || element.host; - } - - /** - * Returns the scrolling parent of the given element - * @method - * @memberof Popper.Utils - * @argument {Element} element - * @returns {Element} scroll parent - */ - function getScrollParent(element) { - // Return body, `getScroll` will take care to get the correct `scrollTop` from it - if (!element) { - return document.body; - } - - switch (element.nodeName) { - case 'HTML': - case 'BODY': - return element.ownerDocument.body; - case '#document': - return element.body; - } - - // Firefox want us to check `-x` and `-y` variations as well - - var _getStyleComputedProp = getStyleComputedProperty(element), - overflow = _getStyleComputedProp.overflow, - overflowX = _getStyleComputedProp.overflowX, - overflowY = _getStyleComputedProp.overflowY; - - if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { - return element; - } - - return getScrollParent(getParentNode(element)); - } - - /** - * Returns the reference node of the reference object, or the reference object itself. - * @method - * @memberof Popper.Utils - * @param {Element|Object} reference - the reference element (the popper will be relative to this) - * @returns {Element} parent - */ - function getReferenceNode(reference) { - return reference && reference.referenceNode ? reference.referenceNode : reference; - } - - var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); - var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent); - - /** - * Determines if the browser is Internet Explorer - * @method - * @memberof Popper.Utils - * @param {Number} version to check - * @returns {Boolean} isIE - */ - function isIE(version) { - if (version === 11) { - return isIE11; - } - if (version === 10) { - return isIE10; - } - return isIE11 || isIE10; - } - - /** - * Returns the offset parent of the given element - * @method - * @memberof Popper.Utils - * @argument {Element} element - * @returns {Element} offset parent - */ - function getOffsetParent(element) { - if (!element) { - return document.documentElement; - } - - var noOffsetParent = isIE(10) ? document.body : null; - - // NOTE: 1 DOM access here - var offsetParent = element.offsetParent || null; - // Skip hidden elements which don't have an offsetParent - while (offsetParent === noOffsetParent && element.nextElementSibling) { - offsetParent = (element = element.nextElementSibling).offsetParent; - } - - var nodeName = offsetParent && offsetParent.nodeName; - - if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { - return element ? element.ownerDocument.documentElement : document.documentElement; - } - - // .offsetParent will return the closest TH, TD or TABLE in case - // no offsetParent is present, I hate this job... - if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { - return getOffsetParent(offsetParent); - } - - return offsetParent; - } - - function isOffsetContainer(element) { - var nodeName = element.nodeName; - - if (nodeName === 'BODY') { - return false; - } - return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; - } - - /** - * Finds the root node (document, shadowDOM root) of the given element - * @method - * @memberof Popper.Utils - * @argument {Element} node - * @returns {Element} root node - */ - function getRoot(node) { - if (node.parentNode !== null) { - return getRoot(node.parentNode); + /*:: declare function getWindow(node: Node | Window): Window; */ + function getWindow(node) { + if (node.toString() !== '[object Window]') { + var ownerDocument = node.ownerDocument; + return ownerDocument ? ownerDocument.defaultView || window : window; } return node; } - /** - * Finds the offset parent common to the two provided nodes - * @method - * @memberof Popper.Utils - * @argument {Element} element1 - * @argument {Element} element2 - * @returns {Element} common offset parent - */ - function findCommonOffsetParent(element1, element2) { - // This check is needed to avoid errors in case one of the elements isn't defined for any reason - if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { - return document.documentElement; + /*:: declare function isElement(node: mixed): boolean %checks(node instanceof + Element); */ + + function isElement$1(node) { + var OwnElement = getWindow(node).Element; + return node instanceof OwnElement || node instanceof Element; + } + /*:: declare function isHTMLElement(node: mixed): boolean %checks(node instanceof + HTMLElement); */ + + + function isHTMLElement(node) { + var OwnElement = getWindow(node).HTMLElement; + return node instanceof OwnElement || node instanceof HTMLElement; + } + /*:: declare function isShadowRoot(node: mixed): boolean %checks(node instanceof + ShadowRoot); */ + + + function isShadowRoot(node) { + var OwnElement = getWindow(node).ShadowRoot; + return node instanceof OwnElement || node instanceof ShadowRoot; + } + + // and applies them to the HTMLElements such as popper and arrow + + function applyStyles(_ref) { + var state = _ref.state; + Object.keys(state.elements).forEach(function (name) { + var style = state.styles[name] || {}; + var attributes = state.attributes[name] || {}; + var element = state.elements[name]; // arrow is optional + virtual elements + + if (!isHTMLElement(element) || !getNodeName(element)) { + return; + } // Flow doesn't support to extend this property, but it's the most + // effective way to apply styles to an HTMLElement + // $FlowFixMe + + + Object.assign(element.style, style); + Object.keys(attributes).forEach(function (name) { + var value = attributes[name]; + + if (value === false) { + element.removeAttribute(name); + } else { + element.setAttribute(name, value === true ? '' : value); + } + }); + }); + } + + function effect(_ref2) { + var state = _ref2.state; + var initialStyles = { + popper: { + position: state.options.strategy, + left: '0', + top: '0', + margin: '0' + }, + arrow: { + position: 'absolute' + }, + reference: {} + }; + Object.assign(state.elements.popper.style, initialStyles.popper); + + if (state.elements.arrow) { + Object.assign(state.elements.arrow.style, initialStyles.arrow); } - // Here we make sure to give as "start" the element that comes first in the DOM - var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; - var start = order ? element1 : element2; - var end = order ? element2 : element1; + return function () { + Object.keys(state.elements).forEach(function (name) { + var element = state.elements[name]; + var attributes = state.attributes[name] || {}; + var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them - // Get common ancestor container - var range = document.createRange(); - range.setStart(start, 0); - range.setEnd(end, 0); - var commonAncestorContainer = range.commonAncestorContainer; + var style = styleProperties.reduce(function (style, property) { + style[property] = ''; + return style; + }, {}); // arrow is optional + virtual elements - // Both nodes are inside #document + if (!isHTMLElement(element) || !getNodeName(element)) { + return; + } // Flow doesn't support to extend this property, but it's the most + // effective way to apply styles to an HTMLElement + // $FlowFixMe - if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { - if (isOffsetContainer(commonAncestorContainer)) { - return commonAncestorContainer; - } - return getOffsetParent(commonAncestorContainer); - } + Object.assign(element.style, style); + Object.keys(attributes).forEach(function (attribute) { + element.removeAttribute(attribute); + }); + }); + }; + } // eslint-disable-next-line import/no-unused-modules - // one of the nodes is inside shadowDOM, find which one - var element1root = getRoot(element1); - if (element1root.host) { - return findCommonOffsetParent(element1root.host, element2); - } else { - return findCommonOffsetParent(element1, getRoot(element2).host); - } + + var applyStyles$1 = { + name: 'applyStyles', + enabled: true, + phase: 'write', + fn: applyStyles, + effect: effect, + requires: ['computeStyles'] + }; + + function getBasePlacement(placement) { + return placement.split('-')[0]; } - /** - * Gets the scroll value of the given element in the given side (top and left) - * @method - * @memberof Popper.Utils - * @argument {Element} element - * @argument {String} side `top` or `left` - * @returns {number} amount of scrolled pixels - */ - function getScroll(element) { - var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; - - var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; - var nodeName = element.nodeName; - - if (nodeName === 'BODY' || nodeName === 'HTML') { - var html = element.ownerDocument.documentElement; - var scrollingElement = element.ownerDocument.scrollingElement || html; - return scrollingElement[upperSide]; - } - - return element[upperSide]; - } - - /* - * Sum or subtract the element scroll values (left and top) from a given rect object - * @method - * @memberof Popper.Utils - * @param {Object} rect - Rect object you want to change - * @param {HTMLElement} element - The element from the function reads the scroll values - * @param {Boolean} subtract - set to true if you want to subtract the scroll values - * @return {Object} rect - The modifier rect object - */ - function includeScroll(rect, element) { - var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - - var scrollTop = getScroll(element, 'top'); - var scrollLeft = getScroll(element, 'left'); - var modifier = subtract ? -1 : 1; - rect.top += scrollTop * modifier; - rect.bottom += scrollTop * modifier; - rect.left += scrollLeft * modifier; - rect.right += scrollLeft * modifier; - return rect; - } - - /* - * Helper to detect borders of a given element - * @method - * @memberof Popper.Utils - * @param {CSSStyleDeclaration} styles - * Result of `getStyleComputedProperty` on the given element - * @param {String} axis - `x` or `y` - * @return {number} borders - The borders size of the given axis - */ - - function getBordersSize(styles, axis) { - var sideA = axis === 'x' ? 'Left' : 'Top'; - var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; - - return parseFloat(styles['border' + sideA + 'Width'], 10) + parseFloat(styles['border' + sideB + 'Width'], 10); - } - - function getSize(axis, body, html, computedStyle) { - return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0); - } - - function getWindowSizes(document) { - var body = document.body; - var html = document.documentElement; - var computedStyle = isIE(10) && getComputedStyle(html); - + // Returns the layout rect of an element relative to its offsetParent. Layout + // means it doesn't take into account transforms. + function getLayoutRect(element) { return { - height: getSize('Height', body, html, computedStyle), - width: getSize('Width', body, html, computedStyle) + x: element.offsetLeft, + y: element.offsetTop, + width: element.offsetWidth, + height: element.offsetHeight }; } - var classCallCheck = function (instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - }; + function contains(parent, child) { + var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method - var createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; - }(); - - - - - - var defineProperty = function (obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - - return obj; - }; - - var _extends = Object.assign || function (target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - - return target; - }; - - /** - * Given element offsets, generate an output similar to getBoundingClientRect - * @method - * @memberof Popper.Utils - * @argument {Object} offsets - * @returns {Object} ClientRect like output - */ - function getClientRect(offsets) { - return _extends({}, offsets, { - right: offsets.left + offsets.width, - bottom: offsets.top + offsets.height - }); - } - - /** - * Get bounding client rect of given element - * @method - * @memberof Popper.Utils - * @param {HTMLElement} element - * @return {Object} client rect - */ - function getBoundingClientRect(element) { - var rect = {}; - - // IE10 10 FIX: Please, don't ask, the element isn't - // considered in DOM in some circumstances... - // This isn't reproducible in IE10 compatibility mode of IE11 - try { - if (isIE(10)) { - rect = element.getBoundingClientRect(); - var scrollTop = getScroll(element, 'top'); - var scrollLeft = getScroll(element, 'left'); - rect.top += scrollTop; - rect.left += scrollLeft; - rect.bottom += scrollTop; - rect.right += scrollLeft; - } else { - rect = element.getBoundingClientRect(); - } - } catch (e) {} - - var result = { - left: rect.left, - top: rect.top, - width: rect.right - rect.left, - height: rect.bottom - rect.top - }; - - // subtract scrollbar size from sizes - var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {}; - var width = sizes.width || element.clientWidth || result.width; - var height = sizes.height || element.clientHeight || result.height; - - var horizScrollbar = element.offsetWidth - width; - var vertScrollbar = element.offsetHeight - height; - - // if an hypothetical scrollbar is detected, we must be sure it's not a `border` - // we make this check conditional for performance reasons - if (horizScrollbar || vertScrollbar) { - var styles = getStyleComputedProperty(element); - horizScrollbar -= getBordersSize(styles, 'x'); - vertScrollbar -= getBordersSize(styles, 'y'); - - result.width -= horizScrollbar; - result.height -= vertScrollbar; - } - - return getClientRect(result); - } - - function getOffsetRectRelativeToArbitraryNode(children, parent) { - var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - - var isIE10 = isIE(10); - var isHTML = parent.nodeName === 'HTML'; - var childrenRect = getBoundingClientRect(children); - var parentRect = getBoundingClientRect(parent); - var scrollParent = getScrollParent(children); - - var styles = getStyleComputedProperty(parent); - var borderTopWidth = parseFloat(styles.borderTopWidth, 10); - var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10); - - // In cases where the parent is fixed, we must ignore negative scroll in offset calc - if (fixedPosition && isHTML) { - parentRect.top = Math.max(parentRect.top, 0); - parentRect.left = Math.max(parentRect.left, 0); - } - var offsets = getClientRect({ - top: childrenRect.top - parentRect.top - borderTopWidth, - left: childrenRect.left - parentRect.left - borderLeftWidth, - width: childrenRect.width, - height: childrenRect.height - }); - offsets.marginTop = 0; - offsets.marginLeft = 0; - - // Subtract margins of documentElement in case it's being used as parent - // we do this only on HTML because it's the only element that behaves - // differently when margins are applied to it. The margins are included in - // the box of the documentElement, in the other cases not. - if (!isIE10 && isHTML) { - var marginTop = parseFloat(styles.marginTop, 10); - var marginLeft = parseFloat(styles.marginLeft, 10); - - offsets.top -= borderTopWidth - marginTop; - offsets.bottom -= borderTopWidth - marginTop; - offsets.left -= borderLeftWidth - marginLeft; - offsets.right -= borderLeftWidth - marginLeft; - - // Attach marginTop and marginLeft because in some circumstances we may need them - offsets.marginTop = marginTop; - offsets.marginLeft = marginLeft; - } - - if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { - offsets = includeScroll(offsets, parent); - } - - return offsets; - } - - function getViewportOffsetRectRelativeToArtbitraryNode(element) { - var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - var html = element.ownerDocument.documentElement; - var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); - var width = Math.max(html.clientWidth, window.innerWidth || 0); - var height = Math.max(html.clientHeight, window.innerHeight || 0); - - var scrollTop = !excludeScroll ? getScroll(html) : 0; - var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; - - var offset = { - top: scrollTop - relativeOffset.top + relativeOffset.marginTop, - left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, - width: width, - height: height - }; - - return getClientRect(offset); - } - - /** - * Check if the given element is fixed or is inside a fixed parent - * @method - * @memberof Popper.Utils - * @argument {Element} element - * @argument {Element} customContainer - * @returns {Boolean} answer to "isFixed?" - */ - function isFixed(element) { - var nodeName = element.nodeName; - if (nodeName === 'BODY' || nodeName === 'HTML') { - return false; - } - if (getStyleComputedProperty(element, 'position') === 'fixed') { + if (parent.contains(child)) { return true; - } - var parentNode = getParentNode(element); - if (!parentNode) { - return false; - } - return isFixed(parentNode); + } // then fallback to custom implementation with Shadow DOM support + else if (rootNode && isShadowRoot(rootNode)) { + var next = child; + + do { + if (next && parent.isSameNode(next)) { + return true; + } // $FlowFixMe: need a better way to handle this... + + + next = next.parentNode || next.host; + } while (next); + } // Give up, the result is false + + + return false; } - /** - * Finds the first parent of an element that has a transformed property defined - * @method - * @memberof Popper.Utils - * @argument {Element} element - * @returns {Element} first transformed parent or documentElement - */ - - function getFixedPositionOffsetParent(element) { - // This check is needed to avoid errors in case one of the elements isn't defined for any reason - if (!element || !element.parentElement || isIE()) { - return document.documentElement; - } - var el = element.parentElement; - while (el && getStyleComputedProperty(el, 'transform') === 'none') { - el = el.parentElement; - } - return el || document.documentElement; + function getComputedStyle$1(element) { + return getWindow(element).getComputedStyle(element); } - /** - * Computed the boundaries limits and return them - * @method - * @memberof Popper.Utils - * @param {HTMLElement} popper - * @param {HTMLElement} reference - * @param {number} padding - * @param {HTMLElement} boundariesElement - Element used to define the boundaries - * @param {Boolean} fixedPosition - Is in fixed position mode - * @returns {Object} Coordinates of the boundaries - */ - function getBoundaries(popper, reference, padding, boundariesElement) { - var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + function isTableElement(element) { + return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0; + } - // NOTE: 1 DOM access here + function getDocumentElement(element) { + // $FlowFixMe: assume body is always available + return ((isElement$1(element) ? element.ownerDocument : element.document) || window.document).documentElement; + } - var boundaries = { top: 0, left: 0 }; - var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); + function getParentNode(element) { + if (getNodeName(element) === 'html') { + return element; + } - // Handle viewport case - if (boundariesElement === 'viewport') { - boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); - } else { - // Handle other cases based on DOM element used as boundaries - var boundariesNode = void 0; - if (boundariesElement === 'scrollParent') { - boundariesNode = getScrollParent(getParentNode(reference)); - if (boundariesNode.nodeName === 'BODY') { - boundariesNode = popper.ownerDocument.documentElement; - } - } else if (boundariesElement === 'window') { - boundariesNode = popper.ownerDocument.documentElement; + return (// $FlowFixMe: this is a quicker (but less type safe) way to save quite some bytes from the bundle + element.assignedSlot || // step into the shadow DOM of the parent of a slotted node + element.parentNode || // DOM Element detected + // $FlowFixMe: need a better way to handle this... + element.host || // ShadowRoot detected + // $FlowFixMe: HTMLElement is a Node + getDocumentElement(element) // fallback + + ); + } + + function getTrueOffsetParent(element) { + if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 + getComputedStyle$1(element).position === 'fixed') { + return null; + } + + var offsetParent = element.offsetParent; + + if (offsetParent) { + var html = getDocumentElement(offsetParent); + + if (getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static' && getComputedStyle$1(html).position !== 'static') { + return html; + } + } + + return offsetParent; + } // `.offsetParent` reports `null` for fixed elements, while absolute elements + // return the containing block + + + function getContainingBlock(element) { + var currentNode = getParentNode(element); + + while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) { + var css = getComputedStyle$1(currentNode); // This is non-exhaustive but covers the most common CSS properties that + // create a containing block. + + if (css.transform !== 'none' || css.perspective !== 'none' || css.willChange && css.willChange !== 'auto') { + return currentNode; } else { - boundariesNode = boundariesElement; - } - - var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); - - // In case of HTML, we need a different computation - if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { - var _getWindowSizes = getWindowSizes(popper.ownerDocument), - height = _getWindowSizes.height, - width = _getWindowSizes.width; - - boundaries.top += offsets.top - offsets.marginTop; - boundaries.bottom = height + offsets.top; - boundaries.left += offsets.left - offsets.marginLeft; - boundaries.right = width + offsets.left; - } else { - // for all the other DOM elements, this one is good - boundaries = offsets; + currentNode = currentNode.parentNode; } } - // Add paddings - padding = padding || 0; - var isPaddingNumber = typeof padding === 'number'; - boundaries.left += isPaddingNumber ? padding : padding.left || 0; - boundaries.top += isPaddingNumber ? padding : padding.top || 0; - boundaries.right -= isPaddingNumber ? padding : padding.right || 0; - boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; + return null; + } // Gets the closest ancestor positioned element. Handles some edge cases, + // such as table ancestors and cross browser bugs. - return boundaries; - } - function getArea(_ref) { - var width = _ref.width, - height = _ref.height; + function getOffsetParent(element) { + var window = getWindow(element); + var offsetParent = getTrueOffsetParent(element); - return width * height; - } - - /** - * Utility used to transform the `auto` placement to the placement with more - * available space. - * @method - * @memberof Popper.Utils - * @argument {Object} data - The data object generated by update method - * @argument {Object} options - Modifiers configuration and options - * @returns {Object} The data object, properly modified - */ - function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { - var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; - - if (placement.indexOf('auto') === -1) { - return placement; + while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') { + offsetParent = getTrueOffsetParent(offsetParent); } - var boundaries = getBoundaries(popper, reference, padding, boundariesElement); + if (offsetParent && getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static') { + return window; + } - var rects = { - top: { - width: boundaries.width, - height: refRect.top - boundaries.top - }, - right: { - width: boundaries.right - refRect.right, - height: boundaries.height - }, - bottom: { - width: boundaries.width, - height: boundaries.bottom - refRect.bottom - }, - left: { - width: refRect.left - boundaries.left, - height: boundaries.height + return offsetParent || getContainingBlock(element) || window; + } + + function getMainAxisFromPlacement(placement) { + return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y'; + } + + function within(min, value, max) { + return Math.max(min, Math.min(value, max)); + } + + function getFreshSideObject() { + return { + top: 0, + right: 0, + bottom: 0, + left: 0 + }; + } + + function mergePaddingObject(paddingObject) { + return Object.assign(Object.assign({}, getFreshSideObject()), paddingObject); + } + + function expandToHashMap(value, keys) { + return keys.reduce(function (hashMap, key) { + hashMap[key] = value; + return hashMap; + }, {}); + } + + function arrow(_ref) { + var _state$modifiersData$; + + var state = _ref.state, + name = _ref.name; + var arrowElement = state.elements.arrow; + var popperOffsets = state.modifiersData.popperOffsets; + var basePlacement = getBasePlacement(state.placement); + var axis = getMainAxisFromPlacement(basePlacement); + var isVertical = [left, right].indexOf(basePlacement) >= 0; + var len = isVertical ? 'height' : 'width'; + + if (!arrowElement || !popperOffsets) { + return; + } + + var paddingObject = state.modifiersData[name + "#persistent"].padding; + var arrowRect = getLayoutRect(arrowElement); + var minProp = axis === 'y' ? top : left; + var maxProp = axis === 'y' ? bottom : right; + var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len]; + var startDiff = popperOffsets[axis] - state.rects.reference[axis]; + var arrowOffsetParent = getOffsetParent(arrowElement); + var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; + var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is + // outside of the popper bounds + + var min = paddingObject[minProp]; + var max = clientSize - arrowRect[len] - paddingObject[maxProp]; + var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; + var offset = within(min, center, max); // Prevents breaking syntax highlighting... + + var axisProp = axis; + state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$); + } + + function effect$1(_ref2) { + var state = _ref2.state, + options = _ref2.options, + name = _ref2.name; + var _options$element = options.element, + arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element, + _options$padding = options.padding, + padding = _options$padding === void 0 ? 0 : _options$padding; + + if (arrowElement == null) { + return; + } // CSS selector + + + if (typeof arrowElement === 'string') { + arrowElement = state.elements.popper.querySelector(arrowElement); + + if (!arrowElement) { + return; } + } + + if (!contains(state.elements.popper, arrowElement)) { + + return; + } + + state.elements.arrow = arrowElement; + state.modifiersData[name + "#persistent"] = { + padding: mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)) + }; + } // eslint-disable-next-line import/no-unused-modules + + + var arrow$1 = { + name: 'arrow', + enabled: true, + phase: 'main', + fn: arrow, + effect: effect$1, + requires: ['popperOffsets'], + requiresIfExists: ['preventOverflow'] + }; + + var unsetSides = { + top: 'auto', + right: 'auto', + bottom: 'auto', + left: 'auto' + }; // Round the offsets to the nearest suitable subpixel based on the DPR. + // Zooming can change the DPR, but it seems to report a value that will + // cleanly divide the values into the appropriate subpixels. + + function roundOffsets(_ref) { + var x = _ref.x, + y = _ref.y; + var win = window; + var dpr = win.devicePixelRatio || 1; + return { + x: Math.round(x * dpr) / dpr || 0, + y: Math.round(y * dpr) / dpr || 0 + }; + } + + function mapToStyles(_ref2) { + var _Object$assign2; + + var popper = _ref2.popper, + popperRect = _ref2.popperRect, + placement = _ref2.placement, + offsets = _ref2.offsets, + position = _ref2.position, + gpuAcceleration = _ref2.gpuAcceleration, + adaptive = _ref2.adaptive; + + var _roundOffsets = roundOffsets(offsets), + x = _roundOffsets.x, + y = _roundOffsets.y; + + var hasX = offsets.hasOwnProperty('x'); + var hasY = offsets.hasOwnProperty('y'); + var sideX = left; + var sideY = top; + var win = window; + + if (adaptive) { + var offsetParent = getOffsetParent(popper); + + if (offsetParent === getWindow(popper)) { + offsetParent = getDocumentElement(popper); + } // $FlowFixMe: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it + + /*:: offsetParent = (offsetParent: Element); */ + + + if (placement === top) { + sideY = bottom; + y -= offsetParent.clientHeight - popperRect.height; + y *= gpuAcceleration ? 1 : -1; + } + + if (placement === left) { + sideX = right; + x -= offsetParent.clientWidth - popperRect.width; + x *= gpuAcceleration ? 1 : -1; + } + } + + var commonStyles = Object.assign({ + position: position + }, adaptive && unsetSides); + + if (gpuAcceleration) { + var _Object$assign; + + return Object.assign(Object.assign({}, commonStyles), {}, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) < 2 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); + } + + return Object.assign(Object.assign({}, commonStyles), {}, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2)); + } + + function computeStyles(_ref3) { + var state = _ref3.state, + options = _ref3.options; + var _options$gpuAccelerat = options.gpuAcceleration, + gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, + _options$adaptive = options.adaptive, + adaptive = _options$adaptive === void 0 ? true : _options$adaptive; + + var commonStyles = { + placement: getBasePlacement(state.placement), + popper: state.elements.popper, + popperRect: state.rects.popper, + gpuAcceleration: gpuAcceleration }; - var sortedAreas = Object.keys(rects).map(function (key) { - return _extends({ - key: key - }, rects[key], { - area: getArea(rects[key]) + if (state.modifiersData.popperOffsets != null) { + state.styles.popper = Object.assign(Object.assign({}, state.styles.popper), mapToStyles(Object.assign(Object.assign({}, commonStyles), {}, { + offsets: state.modifiersData.popperOffsets, + position: state.options.strategy, + adaptive: adaptive + }))); + } + + if (state.modifiersData.arrow != null) { + state.styles.arrow = Object.assign(Object.assign({}, state.styles.arrow), mapToStyles(Object.assign(Object.assign({}, commonStyles), {}, { + offsets: state.modifiersData.arrow, + position: 'absolute', + adaptive: false + }))); + } + + state.attributes.popper = Object.assign(Object.assign({}, state.attributes.popper), {}, { + 'data-popper-placement': state.placement + }); + } // eslint-disable-next-line import/no-unused-modules + + + var computeStyles$1 = { + name: 'computeStyles', + enabled: true, + phase: 'beforeWrite', + fn: computeStyles, + data: {} + }; + + var passive = { + passive: true + }; + + function effect$2(_ref) { + var state = _ref.state, + instance = _ref.instance, + options = _ref.options; + var _options$scroll = options.scroll, + scroll = _options$scroll === void 0 ? true : _options$scroll, + _options$resize = options.resize, + resize = _options$resize === void 0 ? true : _options$resize; + var window = getWindow(state.elements.popper); + var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); + + if (scroll) { + scrollParents.forEach(function (scrollParent) { + scrollParent.addEventListener('scroll', instance.update, passive); }); - }).sort(function (a, b) { - return b.area - a.area; - }); + } - var filteredAreas = sortedAreas.filter(function (_ref2) { - var width = _ref2.width, - height = _ref2.height; - return width >= popper.clientWidth && height >= popper.clientHeight; - }); + if (resize) { + window.addEventListener('resize', instance.update, passive); + } - var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; + return function () { + if (scroll) { + scrollParents.forEach(function (scrollParent) { + scrollParent.removeEventListener('scroll', instance.update, passive); + }); + } - var variation = placement.split('-')[1]; - - return computedPlacement + (variation ? '-' + variation : ''); - } - - /** - * Get offsets to the reference element - * @method - * @memberof Popper.Utils - * @param {Object} state - * @param {Element} popper - the popper element - * @param {Element} reference - the reference element (the popper will be relative to this) - * @param {Element} fixedPosition - is in fixed position mode - * @returns {Object} An object containing the offsets which will be applied to the popper - */ - function getReferenceOffsets(state, popper, reference) { - var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; - - var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); - return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); - } - - /** - * Get the outer sizes of the given element (offset size + margins) - * @method - * @memberof Popper.Utils - * @argument {Element} element - * @returns {Object} object containing width and height properties - */ - function getOuterSizes(element) { - var window = element.ownerDocument.defaultView; - var styles = window.getComputedStyle(element); - var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0); - var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0); - var result = { - width: element.offsetWidth + y, - height: element.offsetHeight + x + if (resize) { + window.removeEventListener('resize', instance.update, passive); + } }; - return result; - } + } // eslint-disable-next-line import/no-unused-modules - /** - * Get the opposite placement of the given one - * @method - * @memberof Popper.Utils - * @argument {String} placement - * @returns {String} flipped placement - */ + + var eventListeners = { + name: 'eventListeners', + enabled: true, + phase: 'write', + fn: function fn() {}, + effect: effect$2, + data: {} + }; + + var hash = { + left: 'right', + right: 'left', + bottom: 'top', + top: 'bottom' + }; function getOppositePlacement(placement) { - var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; return placement.replace(/left|right|bottom|top/g, function (matched) { return hash[matched]; }); } - /** - * Get offsets to the popper - * @method - * @memberof Popper.Utils - * @param {Object} position - CSS position the Popper will get applied - * @param {HTMLElement} popper - the popper element - * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) - * @param {String} placement - one of the valid placement options - * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper - */ - function getPopperOffsets(popper, referenceOffsets, placement) { - placement = placement.split('-')[0]; + var hash$1 = { + start: 'end', + end: 'start' + }; + function getOppositeVariationPlacement(placement) { + return placement.replace(/start|end/g, function (matched) { + return hash$1[matched]; + }); + } - // Get popper node sizes - var popperRect = getOuterSizes(popper); - - // Add position, width and height to our offsets object - var popperOffsets = { - width: popperRect.width, - height: popperRect.height + function getBoundingClientRect(element) { + var rect = element.getBoundingClientRect(); + return { + width: rect.width, + height: rect.height, + top: rect.top, + right: rect.right, + bottom: rect.bottom, + left: rect.left, + x: rect.left, + y: rect.top }; - - // depending by the popper placement we have to compute its offsets slightly differently - var isHoriz = ['right', 'left'].indexOf(placement) !== -1; - var mainSide = isHoriz ? 'top' : 'left'; - var secondarySide = isHoriz ? 'left' : 'top'; - var measurement = isHoriz ? 'height' : 'width'; - var secondaryMeasurement = !isHoriz ? 'height' : 'width'; - - popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; - if (placement === secondarySide) { - popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; - } else { - popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; - } - - return popperOffsets; } - /** - * Mimics the `find` method of Array - * @method - * @memberof Popper.Utils - * @argument {Array} arr - * @argument prop - * @argument value - * @returns index or -1 - */ - function find(arr, check) { - // use native find if supported - if (Array.prototype.find) { - return arr.find(check); - } - - // use `filter` to obtain the same behavior of `find` - return arr.filter(check)[0]; - } - - /** - * Return the index of the matching object - * @method - * @memberof Popper.Utils - * @argument {Array} arr - * @argument prop - * @argument value - * @returns index or -1 - */ - function findIndex(arr, prop, value) { - // use native findIndex if supported - if (Array.prototype.findIndex) { - return arr.findIndex(function (cur) { - return cur[prop] === value; - }); - } - - // use `find` + `indexOf` if `findIndex` isn't supported - var match = find(arr, function (obj) { - return obj[prop] === value; - }); - return arr.indexOf(match); - } - - /** - * Loop trough the list of modifiers and run them in order, - * each of them will then edit the data object. - * @method - * @memberof Popper.Utils - * @param {dataObject} data - * @param {Array} modifiers - * @param {String} ends - Optional modifier name used as stopper - * @returns {dataObject} - */ - function runModifiers(modifiers, data, ends) { - var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); - - modifiersToRun.forEach(function (modifier) { - if (modifier['function']) { - // eslint-disable-line dot-notation - console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); - } - var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation - if (modifier.enabled && isFunction(fn)) { - // Add properties to offsets to make them a complete clientRect object - // we do this before each modifier to make sure the previous one doesn't - // mess with these values - data.offsets.popper = getClientRect(data.offsets.popper); - data.offsets.reference = getClientRect(data.offsets.reference); - - data = fn(data, modifier); - } - }); - - return data; - } - - /** - * Updates the position of the popper, computing the new offsets and applying - * the new style.
- * Prefer `scheduleUpdate` over `update` because of performance reasons. - * @method - * @memberof Popper - */ - function update() { - // if popper is destroyed, don't perform any further update - if (this.state.isDestroyed) { - return; - } - - var data = { - instance: this, - styles: {}, - arrowStyles: {}, - attributes: {}, - flipped: false, - offsets: {} + function getWindowScroll(node) { + var win = getWindow(node); + var scrollLeft = win.pageXOffset; + var scrollTop = win.pageYOffset; + return { + scrollLeft: scrollLeft, + scrollTop: scrollTop }; - - // compute reference element offsets - data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); - - // compute auto placement, store placement inside the data object, - // modifiers will be able to edit `placement` if needed - // and refer to originalPlacement to know the original value - data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); - - // store the computed placement inside `originalPlacement` - data.originalPlacement = data.placement; - - data.positionFixed = this.options.positionFixed; - - // compute the popper offsets - data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); - - data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; - - // run the modifiers - data = runModifiers(this.modifiers, data); - - // the first `update` will call `onCreate` callback - // the other ones will call `onUpdate` callback - if (!this.state.isCreated) { - this.state.isCreated = true; - this.options.onCreate(data); - } else { - this.options.onUpdate(data); - } } - /** - * Helper used to know if the given modifier is enabled. - * @method - * @memberof Popper.Utils - * @returns {Boolean} - */ - function isModifierEnabled(modifiers, modifierName) { - return modifiers.some(function (_ref) { - var name = _ref.name, - enabled = _ref.enabled; - return enabled && name === modifierName; - }); + function getWindowScrollBarX(element) { + // If has a CSS width greater than the viewport, then this will be + // incorrect for RTL. + // Popper 1 is broken in this case and never had a bug report so let's assume + // it's not an issue. I don't think anyone ever specifies width on + // anyway. + // Browsers where the left scrollbar doesn't cause an issue report `0` for + // this (e.g. Edge 2019, IE11, Safari) + return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; } - /** - * Get the prefixed supported property name - * @method - * @memberof Popper.Utils - * @argument {String} property (camelCase) - * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) - */ - function getSupportedPropertyName(property) { - var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; - var upperProp = property.charAt(0).toUpperCase() + property.slice(1); + function getViewportRect(element) { + var win = getWindow(element); + var html = getDocumentElement(element); + var visualViewport = win.visualViewport; + var width = html.clientWidth; + var height = html.clientHeight; + var x = 0; + var y = 0; // NB: This isn't supported on iOS <= 12. If the keyboard is open, the popper + // can be obscured underneath it. + // Also, `html.clientHeight` adds the bottom bar height in Safari iOS, even + // if it isn't open, so if this isn't available, the popper will be detected + // to overflow the bottom of the screen too early. - for (var i = 0; i < prefixes.length; i++) { - var prefix = prefixes[i]; - var toCheck = prefix ? '' + prefix + upperProp : property; - if (typeof document.body.style[toCheck] !== 'undefined') { - return toCheck; + if (visualViewport) { + width = visualViewport.width; + height = visualViewport.height; // Uses Layout Viewport (like Chrome; Safari does not currently) + // In Chrome, it returns a value very close to 0 (+/-) but contains rounding + // errors due to floating point numbers, so we need to check precision. + // Safari returns a number <= 0, usually < -1 when pinch-zoomed + // Feature detection fails in mobile emulation mode in Chrome. + // Math.abs(win.innerWidth / visualViewport.scale - visualViewport.width) < + // 0.001 + // Fallback here: "Not Safari" userAgent + + if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { + x = visualViewport.offsetLeft; + y = visualViewport.offsetTop; } } - return null; - } - - /** - * Destroys the popper. - * @method - * @memberof Popper - */ - function destroy() { - this.state.isDestroyed = true; - - // touch DOM only if `applyStyle` modifier is enabled - if (isModifierEnabled(this.modifiers, 'applyStyle')) { - this.popper.removeAttribute('x-placement'); - this.popper.style.position = ''; - this.popper.style.top = ''; - this.popper.style.left = ''; - this.popper.style.right = ''; - this.popper.style.bottom = ''; - this.popper.style.willChange = ''; - this.popper.style[getSupportedPropertyName('transform')] = ''; - } - - this.disableEventListeners(); - - // remove the popper if user explicitly asked for the deletion on destroy - // do not use `remove` because IE11 doesn't support it - if (this.options.removeOnDestroy) { - this.popper.parentNode.removeChild(this.popper); - } - return this; - } - - /** - * Get the window associated with the element - * @argument {Element} element - * @returns {Window} - */ - function getWindow(element) { - var ownerDocument = element.ownerDocument; - return ownerDocument ? ownerDocument.defaultView : window; - } - - function attachToScrollParents(scrollParent, event, callback, scrollParents) { - var isBody = scrollParent.nodeName === 'BODY'; - var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; - target.addEventListener(event, callback, { passive: true }); - - if (!isBody) { - attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); - } - scrollParents.push(target); - } - - /** - * Setup needed event listeners used to update the popper position - * @method - * @memberof Popper.Utils - * @private - */ - function setupEventListeners(reference, options, state, updateBound) { - // Resize event listener on window - state.updateBound = updateBound; - getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); - - // Scroll event listener on scroll parents - var scrollElement = getScrollParent(reference); - attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); - state.scrollElement = scrollElement; - state.eventsEnabled = true; - - return state; - } - - /** - * It will add resize/scroll events and start recalculating - * position of the popper element when they are triggered. - * @method - * @memberof Popper - */ - function enableEventListeners() { - if (!this.state.eventsEnabled) { - this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); - } - } - - /** - * Remove event listeners used to update the popper position - * @method - * @memberof Popper.Utils - * @private - */ - function removeEventListeners(reference, state) { - // Remove resize event listener on window - getWindow(reference).removeEventListener('resize', state.updateBound); - - // Remove scroll event listener on scroll parents - state.scrollParents.forEach(function (target) { - target.removeEventListener('scroll', state.updateBound); - }); - - // Reset state - state.updateBound = null; - state.scrollParents = []; - state.scrollElement = null; - state.eventsEnabled = false; - return state; - } - - /** - * It will remove resize/scroll events and won't recalculate popper position - * when they are triggered. It also won't trigger `onUpdate` callback anymore, - * unless you call `update` method manually. - * @method - * @memberof Popper - */ - function disableEventListeners() { - if (this.state.eventsEnabled) { - cancelAnimationFrame(this.scheduleUpdate); - this.state = removeEventListeners(this.reference, this.state); - } - } - - /** - * Tells if a given input is a number - * @method - * @memberof Popper.Utils - * @param {*} input to check - * @return {Boolean} - */ - function isNumeric(n) { - return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); - } - - /** - * Set the style to the given popper - * @method - * @memberof Popper.Utils - * @argument {Element} element - Element to apply the style to - * @argument {Object} styles - * Object with a list of properties and values which will be applied to the element - */ - function setStyles(element, styles) { - Object.keys(styles).forEach(function (prop) { - var unit = ''; - // add unit if the value is numeric and is one of the following - if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { - unit = 'px'; - } - element.style[prop] = styles[prop] + unit; - }); - } - - /** - * Set the attributes to the given popper - * @method - * @memberof Popper.Utils - * @argument {Element} element - Element to apply the attributes to - * @argument {Object} styles - * Object with a list of properties and values which will be applied to the element - */ - function setAttributes(element, attributes) { - Object.keys(attributes).forEach(function (prop) { - var value = attributes[prop]; - if (value !== false) { - element.setAttribute(prop, attributes[prop]); - } else { - element.removeAttribute(prop); - } - }); - } - - /** - * @function - * @memberof Modifiers - * @argument {Object} data - The data object generated by `update` method - * @argument {Object} data.styles - List of style properties - values to apply to popper element - * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element - * @argument {Object} options - Modifiers configuration and options - * @returns {Object} The same data object - */ - function applyStyle(data) { - // any property present in `data.styles` will be applied to the popper, - // in this way we can make the 3rd party modifiers add custom styles to it - // Be aware, modifiers could override the properties defined in the previous - // lines of this modifier! - setStyles(data.instance.popper, data.styles); - - // any property present in `data.attributes` will be applied to the popper, - // they will be set as HTML attributes of the element - setAttributes(data.instance.popper, data.attributes); - - // if arrowElement is defined and arrowStyles has some properties - if (data.arrowElement && Object.keys(data.arrowStyles).length) { - setStyles(data.arrowElement, data.arrowStyles); - } - - return data; - } - - /** - * Set the x-placement attribute before everything else because it could be used - * to add margins to the popper margins needs to be calculated to get the - * correct popper offsets. - * @method - * @memberof Popper.modifiers - * @param {HTMLElement} reference - The reference element used to position the popper - * @param {HTMLElement} popper - The HTML element used as popper - * @param {Object} options - Popper.js options - */ - function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { - // compute reference element offsets - var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); - - // compute auto placement, store placement inside the data object, - // modifiers will be able to edit `placement` if needed - // and refer to originalPlacement to know the original value - var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); - - popper.setAttribute('x-placement', placement); - - // Apply `position` to popper before anything else because - // without the position applied we can't guarantee correct computations - setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); - - return options; - } - - /** - * @function - * @memberof Popper.Utils - * @argument {Object} data - The data object generated by `update` method - * @argument {Boolean} shouldRound - If the offsets should be rounded at all - * @returns {Object} The popper's position offsets rounded - * - * The tale of pixel-perfect positioning. It's still not 100% perfect, but as - * good as it can be within reason. - * Discussion here: https://github.com/FezVrasta/popper.js/pull/715 - * - * Low DPI screens cause a popper to be blurry if not using full pixels (Safari - * as well on High DPI screens). - * - * Firefox prefers no rounding for positioning and does not have blurriness on - * high DPI screens. - * - * Only horizontal placement and left/right values need to be considered. - */ - function getRoundedOffsets(data, shouldRound) { - var _data$offsets = data.offsets, - popper = _data$offsets.popper, - reference = _data$offsets.reference; - var round = Math.round, - floor = Math.floor; - - var noRound = function noRound(v) { - return v; - }; - - var referenceWidth = round(reference.width); - var popperWidth = round(popper.width); - - var isVertical = ['left', 'right'].indexOf(data.placement) !== -1; - var isVariation = data.placement.indexOf('-') !== -1; - var sameWidthParity = referenceWidth % 2 === popperWidth % 2; - var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1; - - var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor; - var verticalToInteger = !shouldRound ? noRound : round; return { - left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left), - top: verticalToInteger(popper.top), - bottom: verticalToInteger(popper.bottom), - right: horizontalToInteger(popper.right) + width: width, + height: height, + x: x + getWindowScrollBarX(element), + y: y }; } - var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent); + // of the `` and `` rect bounds if horizontally scrollable - /** - * @function - * @memberof Modifiers - * @argument {Object} data - The data object generated by `update` method - * @argument {Object} options - Modifiers configuration and options - * @returns {Object} The data object, properly modified - */ - function computeStyle(data, options) { - var x = options.x, - y = options.y; - var popper = data.offsets.popper; + function getDocumentRect(element) { + var html = getDocumentElement(element); + var winScroll = getWindowScroll(element); + var body = element.ownerDocument.body; + var width = Math.max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); + var height = Math.max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); + var x = -winScroll.scrollLeft + getWindowScrollBarX(element); + var y = -winScroll.scrollTop; - // Remove this legacy support in Popper.js v2 - - var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { - return modifier.name === 'applyStyle'; - }).gpuAcceleration; - if (legacyGpuAccelerationOption !== undefined) { - console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); + if (getComputedStyle$1(body || html).direction === 'rtl') { + x += Math.max(html.clientWidth, body ? body.clientWidth : 0) - width; } - var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; - var offsetParent = getOffsetParent(data.instance.popper); - var offsetParentRect = getBoundingClientRect(offsetParent); - - // Styles - var styles = { - position: popper.position + return { + width: width, + height: height, + x: x, + y: y }; - - var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox); - - var sideA = x === 'bottom' ? 'top' : 'bottom'; - var sideB = y === 'right' ? 'left' : 'right'; - - // if gpuAcceleration is set to `true` and transform is supported, - // we use `translate3d` to apply the position to the popper we - // automatically use the supported prefixed version if needed - var prefixedProperty = getSupportedPropertyName('transform'); - - // now, let's make a step back and look at this code closely (wtf?) - // If the content of the popper grows once it's been positioned, it - // may happen that the popper gets misplaced because of the new content - // overflowing its reference element - // To avoid this problem, we provide two options (x and y), which allow - // the consumer to define the offset origin. - // If we position a popper on top of a reference element, we can set - // `x` to `top` to make the popper grow towards its top instead of - // its bottom. - var left = void 0, - top = void 0; - if (sideA === 'bottom') { - // when offsetParent is the positioning is relative to the bottom of the screen (excluding the scrollbar) - // and not the bottom of the html element - if (offsetParent.nodeName === 'HTML') { - top = -offsetParent.clientHeight + offsets.bottom; - } else { - top = -offsetParentRect.height + offsets.bottom; - } - } else { - top = offsets.top; - } - if (sideB === 'right') { - if (offsetParent.nodeName === 'HTML') { - left = -offsetParent.clientWidth + offsets.right; - } else { - left = -offsetParentRect.width + offsets.right; - } - } else { - left = offsets.left; - } - if (gpuAcceleration && prefixedProperty) { - styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; - styles[sideA] = 0; - styles[sideB] = 0; - styles.willChange = 'transform'; - } else { - // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties - var invertTop = sideA === 'bottom' ? -1 : 1; - var invertLeft = sideB === 'right' ? -1 : 1; - styles[sideA] = top * invertTop; - styles[sideB] = left * invertLeft; - styles.willChange = sideA + ', ' + sideB; - } - - // Attributes - var attributes = { - 'x-placement': data.placement - }; - - // Update `data` attributes, styles and arrowStyles - data.attributes = _extends({}, attributes, data.attributes); - data.styles = _extends({}, styles, data.styles); - data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); - - return data; } - /** - * Helper used to know if the given modifier depends from another one.
- * It checks if the needed modifier is listed and enabled. - * @method - * @memberof Popper.Utils - * @param {Array} modifiers - list of modifiers - * @param {String} requestingName - name of requesting modifier - * @param {String} requestedName - name of requested modifier - * @returns {Boolean} - */ - function isModifierRequired(modifiers, requestingName, requestedName) { - var requesting = find(modifiers, function (_ref) { - var name = _ref.name; - return name === requestingName; + function isScrollParent(element) { + // Firefox wants us to check `-x` and `-y` variations as well + var _getComputedStyle = getComputedStyle$1(element), + overflow = _getComputedStyle.overflow, + overflowX = _getComputedStyle.overflowX, + overflowY = _getComputedStyle.overflowY; + + return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); + } + + function getScrollParent(node) { + if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) { + // $FlowFixMe: assume body is always available + return node.ownerDocument.body; + } + + if (isHTMLElement(node) && isScrollParent(node)) { + return node; + } + + return getScrollParent(getParentNode(node)); + } + + /* + given a DOM element, return the list of all scroll parents, up the list of ancesors + until we get to the top window object. This list is what we attach scroll listeners + to, because if any of these parent elements scroll, we'll need to re-calculate the + reference element's position. + */ + + function listScrollParents(element, list) { + if (list === void 0) { + list = []; + } + + var scrollParent = getScrollParent(element); + var isBody = getNodeName(scrollParent) === 'body'; + var win = getWindow(scrollParent); + var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; + var updatedList = list.concat(target); + return isBody ? updatedList : // $FlowFixMe: isBody tells us target will be an HTMLElement here + updatedList.concat(listScrollParents(getParentNode(target))); + } + + function rectToClientRect(rect) { + return Object.assign(Object.assign({}, rect), {}, { + left: rect.x, + top: rect.y, + right: rect.x + rect.width, + bottom: rect.y + rect.height }); + } - var isRequired = !!requesting && modifiers.some(function (modifier) { - return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; + function getInnerBoundingClientRect(element) { + var rect = getBoundingClientRect(element); + rect.top = rect.top + element.clientTop; + rect.left = rect.left + element.clientLeft; + rect.bottom = rect.top + element.clientHeight; + rect.right = rect.left + element.clientWidth; + rect.width = element.clientWidth; + rect.height = element.clientHeight; + rect.x = rect.left; + rect.y = rect.top; + return rect; + } + + function getClientRectFromMixedType(element, clippingParent) { + return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isHTMLElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element))); + } // A "clipping parent" is an overflowable container with the characteristic of + // clipping (or hiding) overflowing elements with a position different from + // `initial` + + + function getClippingParents(element) { + var clippingParents = listScrollParents(getParentNode(element)); + var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle$1(element).position) >= 0; + var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; + + if (!isElement$1(clipperElement)) { + return []; + } // $FlowFixMe: https://github.com/facebook/flow/issues/1414 + + + return clippingParents.filter(function (clippingParent) { + return isElement$1(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body'; }); + } // Gets the maximum area that the element is visible in due to any number of + // clipping parents - if (!isRequired) { - var _requesting = '`' + requestingName + '`'; - var requested = '`' + requestedName + '`'; - console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); - } - return isRequired; + + function getClippingRect(element, boundary, rootBoundary) { + var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary); + var clippingParents = [].concat(mainClippingParents, [rootBoundary]); + var firstClippingParent = clippingParents[0]; + var clippingRect = clippingParents.reduce(function (accRect, clippingParent) { + var rect = getClientRectFromMixedType(element, clippingParent); + accRect.top = Math.max(rect.top, accRect.top); + accRect.right = Math.min(rect.right, accRect.right); + accRect.bottom = Math.min(rect.bottom, accRect.bottom); + accRect.left = Math.max(rect.left, accRect.left); + return accRect; + }, getClientRectFromMixedType(element, firstClippingParent)); + clippingRect.width = clippingRect.right - clippingRect.left; + clippingRect.height = clippingRect.bottom - clippingRect.top; + clippingRect.x = clippingRect.left; + clippingRect.y = clippingRect.top; + return clippingRect; } - /** - * @function - * @memberof Modifiers - * @argument {Object} data - The data object generated by update method - * @argument {Object} options - Modifiers configuration and options - * @returns {Object} The data object, properly modified - */ - function arrow(data, options) { - var _data$offsets$arrow; - - // arrow depends on keepTogether in order to work - if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { - return data; - } - - var arrowElement = options.element; - - // if arrowElement is a string, suppose it's a CSS selector - if (typeof arrowElement === 'string') { - arrowElement = data.instance.popper.querySelector(arrowElement); - - // if arrowElement is not found, don't run the modifier - if (!arrowElement) { - return data; - } - } else { - // if the arrowElement isn't a query selector we must check that the - // provided DOM node is child of its popper node - if (!data.instance.popper.contains(arrowElement)) { - console.warn('WARNING: `arrow.element` must be child of its popper element!'); - return data; - } - } - - var placement = data.placement.split('-')[0]; - var _data$offsets = data.offsets, - popper = _data$offsets.popper, - reference = _data$offsets.reference; - - var isVertical = ['left', 'right'].indexOf(placement) !== -1; - - var len = isVertical ? 'height' : 'width'; - var sideCapitalized = isVertical ? 'Top' : 'Left'; - var side = sideCapitalized.toLowerCase(); - var altSide = isVertical ? 'left' : 'top'; - var opSide = isVertical ? 'bottom' : 'right'; - var arrowElementSize = getOuterSizes(arrowElement)[len]; - - // - // extends keepTogether behavior making sure the popper and its - // reference have enough pixels in conjunction - // - - // top/left side - if (reference[opSide] - arrowElementSize < popper[side]) { - data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); - } - // bottom/right side - if (reference[side] + arrowElementSize > popper[opSide]) { - data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; - } - data.offsets.popper = getClientRect(data.offsets.popper); - - // compute center of the popper - var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; - - // Compute the sideValue using the updated popper offsets - // take popper margin in account because we don't have this info available - var css = getStyleComputedProperty(data.instance.popper); - var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10); - var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10); - var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; - - // prevent arrowElement from being placed not contiguously to its popper - sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); - - data.arrowElement = arrowElement; - data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); - - return data; + function getVariation(placement) { + return placement.split('-')[1]; } - /** - * Get the opposite placement variation of the given one - * @method - * @memberof Popper.Utils - * @argument {String} placement variation - * @returns {String} flipped placement variation - */ - function getOppositeVariation(variation) { - if (variation === 'end') { - return 'start'; - } else if (variation === 'start') { - return 'end'; - } - return variation; - } + function computeOffsets(_ref) { + var reference = _ref.reference, + element = _ref.element, + placement = _ref.placement; + var basePlacement = placement ? getBasePlacement(placement) : null; + var variation = placement ? getVariation(placement) : null; + var commonX = reference.x + reference.width / 2 - element.width / 2; + var commonY = reference.y + reference.height / 2 - element.height / 2; + var offsets; - /** - * List of accepted placements to use as values of the `placement` option.
- * Valid placements are: - * - `auto` - * - `top` - * - `right` - * - `bottom` - * - `left` - * - * Each placement can have a variation from this list: - * - `-start` - * - `-end` - * - * Variations are interpreted easily if you think of them as the left to right - * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` - * is right.
- * Vertically (`left` and `right`), `start` is top and `end` is bottom. - * - * Some valid examples are: - * - `top-end` (on top of reference, right aligned) - * - `right-start` (on right of reference, top aligned) - * - `bottom` (on bottom, centered) - * - `auto-end` (on the side with more space available, alignment depends by placement) - * - * @static - * @type {Array} - * @enum {String} - * @readonly - * @method placements - * @memberof Popper - */ - var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; - - // Get rid of `auto` `auto-start` and `auto-end` - var validPlacements = placements.slice(3); - - /** - * Given an initial placement, returns all the subsequent placements - * clockwise (or counter-clockwise). - * - * @method - * @memberof Popper.Utils - * @argument {String} placement - A valid placement (it accepts variations) - * @argument {Boolean} counter - Set to true to walk the placements counterclockwise - * @returns {Array} placements including their variations - */ - function clockwise(placement) { - var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - var index = validPlacements.indexOf(placement); - var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); - return counter ? arr.reverse() : arr; - } - - var BEHAVIORS = { - FLIP: 'flip', - CLOCKWISE: 'clockwise', - COUNTERCLOCKWISE: 'counterclockwise' - }; - - /** - * @function - * @memberof Modifiers - * @argument {Object} data - The data object generated by update method - * @argument {Object} options - Modifiers configuration and options - * @returns {Object} The data object, properly modified - */ - function flip(data, options) { - // if `inner` modifier is enabled, we can't use the `flip` modifier - if (isModifierEnabled(data.instance.modifiers, 'inner')) { - return data; - } - - if (data.flipped && data.placement === data.originalPlacement) { - // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides - return data; - } - - var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); - - var placement = data.placement.split('-')[0]; - var placementOpposite = getOppositePlacement(placement); - var variation = data.placement.split('-')[1] || ''; - - var flipOrder = []; - - switch (options.behavior) { - case BEHAVIORS.FLIP: - flipOrder = [placement, placementOpposite]; + switch (basePlacement) { + case top: + offsets = { + x: commonX, + y: reference.y - element.height + }; break; - case BEHAVIORS.CLOCKWISE: - flipOrder = clockwise(placement); + + case bottom: + offsets = { + x: commonX, + y: reference.y + reference.height + }; break; - case BEHAVIORS.COUNTERCLOCKWISE: - flipOrder = clockwise(placement, true); + + case right: + offsets = { + x: reference.x + reference.width, + y: commonY + }; break; + + case left: + offsets = { + x: reference.x - element.width, + y: commonY + }; + break; + default: - flipOrder = options.behavior; + offsets = { + x: reference.x, + y: reference.y + }; } - flipOrder.forEach(function (step, index) { - if (placement !== step || flipOrder.length === index + 1) { - return data; - } + var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; - placement = data.placement.split('-')[0]; - placementOpposite = getOppositePlacement(placement); + if (mainAxis != null) { + var len = mainAxis === 'y' ? 'height' : 'width'; - var popperOffsets = data.offsets.popper; - var refOffsets = data.offsets.reference; - - // using floor because the reference offsets may contain decimals we are not going to consider here - var floor = Math.floor; - var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom); - - var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); - var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); - var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); - var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); - - var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; - - // flip the variation if required - var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; - - // flips variation if reference element overflows boundaries - var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); - - // flips variation if popper content overflows boundaries - var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop); - - var flippedVariation = flippedVariationByRef || flippedVariationByContent; - - if (overlapsRef || overflowsBoundaries || flippedVariation) { - // this boolean to detect any flip loop - data.flipped = true; - - if (overlapsRef || overflowsBoundaries) { - placement = flipOrder[index + 1]; - } - - if (flippedVariation) { - variation = getOppositeVariation(variation); - } - - data.placement = placement + (variation ? '-' + variation : ''); - - // this object contains `position`, we want to preserve it along with - // any additional property we may add in the future - data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); - - data = runModifiers(data.instance.modifiers, data, 'flip'); - } - }); - return data; - } - - /** - * @function - * @memberof Modifiers - * @argument {Object} data - The data object generated by update method - * @argument {Object} options - Modifiers configuration and options - * @returns {Object} The data object, properly modified - */ - function keepTogether(data) { - var _data$offsets = data.offsets, - popper = _data$offsets.popper, - reference = _data$offsets.reference; - - var placement = data.placement.split('-')[0]; - var floor = Math.floor; - var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; - var side = isVertical ? 'right' : 'bottom'; - var opSide = isVertical ? 'left' : 'top'; - var measurement = isVertical ? 'width' : 'height'; - - if (popper[side] < floor(reference[opSide])) { - data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; - } - if (popper[opSide] > floor(reference[side])) { - data.offsets.popper[opSide] = floor(reference[side]); - } - - return data; - } - - /** - * Converts a string containing value + unit into a px value number - * @function - * @memberof {modifiers~offset} - * @private - * @argument {String} str - Value + unit string - * @argument {String} measurement - `height` or `width` - * @argument {Object} popperOffsets - * @argument {Object} referenceOffsets - * @returns {Number|String} - * Value in pixels, or original string if no values were extracted - */ - function toValue(str, measurement, popperOffsets, referenceOffsets) { - // separate value from unit - var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); - var value = +split[1]; - var unit = split[2]; - - // If it's not a number it's an operator, I guess - if (!value) { - return str; - } - - if (unit.indexOf('%') === 0) { - var element = void 0; - switch (unit) { - case '%p': - element = popperOffsets; + switch (variation) { + case start: + offsets[mainAxis] = Math.floor(offsets[mainAxis]) - Math.floor(reference[len] / 2 - element[len] / 2); + break; + + case end: + offsets[mainAxis] = Math.floor(offsets[mainAxis]) + Math.ceil(reference[len] / 2 - element[len] / 2); break; - case '%': - case '%r': - default: - element = referenceOffsets; } - - var rect = getClientRect(element); - return rect[measurement] / 100 * value; - } else if (unit === 'vh' || unit === 'vw') { - // if is a vh or vw, we calculate the size based on the viewport - var size = void 0; - if (unit === 'vh') { - size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); - } else { - size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); - } - return size / 100 * value; - } else { - // if is an explicit pixel unit, we get rid of the unit and keep the value - // if is an implicit unit, it's px, and we return just the value - return value; - } - } - - /** - * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. - * @function - * @memberof {modifiers~offset} - * @private - * @argument {String} offset - * @argument {Object} popperOffsets - * @argument {Object} referenceOffsets - * @argument {String} basePlacement - * @returns {Array} a two cells array with x and y offsets in numbers - */ - function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { - var offsets = [0, 0]; - - // Use height if placement is left or right and index is 0 otherwise use width - // in this way the first offset will use an axis and the second one - // will use the other one - var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; - - // Split the offset string to obtain a list of values and operands - // The regex addresses values with the plus or minus sign in front (+10, -20, etc) - var fragments = offset.split(/(\+|\-)/).map(function (frag) { - return frag.trim(); - }); - - // Detect if the offset string contains a pair of values or a single one - // they could be separated by comma or space - var divider = fragments.indexOf(find(fragments, function (frag) { - return frag.search(/,|\s/) !== -1; - })); - - if (fragments[divider] && fragments[divider].indexOf(',') === -1) { - console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); } - // If divider is found, we divide the list of values and operands to divide - // them by ofset X and Y. - var splitRegex = /\s*,\s*|\s+/; - var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments]; - - // Convert the values with units to absolute pixels to allow our computations - ops = ops.map(function (op, index) { - // Most of the units rely on the orientation of the popper - var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; - var mergeWithPrevious = false; - return op - // This aggregates any `+` or `-` sign that aren't considered operators - // e.g.: 10 + +5 => [10, +, +5] - .reduce(function (a, b) { - if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { - a[a.length - 1] = b; - mergeWithPrevious = true; - return a; - } else if (mergeWithPrevious) { - a[a.length - 1] += b; - mergeWithPrevious = false; - return a; - } else { - return a.concat(b); - } - }, []) - // Here we convert the string values into number values (in px) - .map(function (str) { - return toValue(str, measurement, popperOffsets, referenceOffsets); - }); - }); - - // Loop trough the offsets arrays and execute the operations - ops.forEach(function (op, index) { - op.forEach(function (frag, index2) { - if (isNumeric(frag)) { - offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); - } - }); - }); return offsets; } - /** - * @function - * @memberof Modifiers - * @argument {Object} data - The data object generated by update method - * @argument {Object} options - Modifiers configuration and options - * @argument {Number|String} options.offset=0 - * The offset value as described in the modifier description - * @returns {Object} The data object, properly modified - */ - function offset(data, _ref) { - var offset = _ref.offset; - var placement = data.placement, - _data$offsets = data.offsets, - popper = _data$offsets.popper, - reference = _data$offsets.reference; - - var basePlacement = placement.split('-')[0]; - - var offsets = void 0; - if (isNumeric(+offset)) { - offsets = [+offset, 0]; - } else { - offsets = parseOffset(offset, popper, reference, basePlacement); + function detectOverflow(state, options) { + if (options === void 0) { + options = {}; } - if (basePlacement === 'left') { - popper.top += offsets[0]; - popper.left -= offsets[1]; - } else if (basePlacement === 'right') { - popper.top += offsets[0]; - popper.left += offsets[1]; - } else if (basePlacement === 'top') { - popper.left += offsets[0]; - popper.top -= offsets[1]; - } else if (basePlacement === 'bottom') { - popper.left += offsets[0]; - popper.top += offsets[1]; + var _options = options, + _options$placement = _options.placement, + placement = _options$placement === void 0 ? state.placement : _options$placement, + _options$boundary = _options.boundary, + boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, + _options$rootBoundary = _options.rootBoundary, + rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, + _options$elementConte = _options.elementContext, + elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, + _options$altBoundary = _options.altBoundary, + altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, + _options$padding = _options.padding, + padding = _options$padding === void 0 ? 0 : _options$padding; + var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); + var altContext = elementContext === popper ? reference : popper; + var referenceElement = state.elements.reference; + var popperRect = state.rects.popper; + var element = state.elements[altBoundary ? altContext : elementContext]; + var clippingClientRect = getClippingRect(isElement$1(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary); + var referenceClientRect = getBoundingClientRect(referenceElement); + var popperOffsets = computeOffsets({ + reference: referenceClientRect, + element: popperRect, + strategy: 'absolute', + placement: placement + }); + var popperClientRect = rectToClientRect(Object.assign(Object.assign({}, popperRect), popperOffsets)); + var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect + // 0 or negative = within the clipping rect + + var overflowOffsets = { + top: clippingClientRect.top - elementClientRect.top + paddingObject.top, + bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, + left: clippingClientRect.left - elementClientRect.left + paddingObject.left, + right: elementClientRect.right - clippingClientRect.right + paddingObject.right + }; + var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element + + if (elementContext === popper && offsetData) { + var offset = offsetData[placement]; + Object.keys(overflowOffsets).forEach(function (key) { + var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; + var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x'; + overflowOffsets[key] += offset[axis] * multiply; + }); } - data.popper = popper; - return data; + return overflowOffsets; } - /** - * @function - * @memberof Modifiers - * @argument {Object} data - The data object generated by `update` method - * @argument {Object} options - Modifiers configuration and options - * @returns {Object} The data object, properly modified - */ - function preventOverflow(data, options) { - var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); + /*:: type OverflowsMap = { [ComputedPlacement]: number }; */ - // If offsetParent is the reference element, we really want to - // go one step up and use the next offsetParent as reference to - // avoid to make this modifier completely useless and look like broken - if (data.instance.reference === boundariesElement) { - boundariesElement = getOffsetParent(boundariesElement); + /*;; type OverflowsMap = { [key in ComputedPlacement]: number }; */ + function computeAutoPlacement(state, options) { + if (options === void 0) { + options = {}; } - // NOTE: DOM access here - // resets the popper's position so that the document size can be calculated excluding - // the size of the popper element itself - var transformProp = getSupportedPropertyName('transform'); - var popperStyles = data.instance.popper.style; // assignment to help minification - var top = popperStyles.top, - left = popperStyles.left, - transform = popperStyles[transformProp]; + var _options = options, + placement = _options.placement, + boundary = _options.boundary, + rootBoundary = _options.rootBoundary, + padding = _options.padding, + flipVariations = _options.flipVariations, + _options$allowedAutoP = _options.allowedAutoPlacements, + allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; + var variation = getVariation(placement); + var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) { + return getVariation(placement) === variation; + }) : basePlacements; // $FlowFixMe - popperStyles.top = ''; - popperStyles.left = ''; - popperStyles[transformProp] = ''; - - var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); - - // NOTE: DOM access here - // restores the original style properties after the offsets have been computed - popperStyles.top = top; - popperStyles.left = left; - popperStyles[transformProp] = transform; - - options.boundaries = boundaries; - - var order = options.priority; - var popper = data.offsets.popper; - - var check = { - primary: function primary(placement) { - var value = popper[placement]; - if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { - value = Math.max(popper[placement], boundaries[placement]); - } - return defineProperty({}, placement, value); - }, - secondary: function secondary(placement) { - var mainSide = placement === 'right' ? 'left' : 'top'; - var value = popper[mainSide]; - if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { - value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); - } - return defineProperty({}, mainSide, value); - } - }; - - order.forEach(function (placement) { - var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; - popper = _extends({}, popper, check[side](placement)); + var allowedPlacements = placements$1.filter(function (placement) { + return allowedAutoPlacements.indexOf(placement) >= 0; }); - data.offsets.popper = popper; + if (allowedPlacements.length === 0) { + allowedPlacements = placements$1; + } // $FlowFixMe: Flow seems to have problems with two array unions... - return data; + + var overflows = allowedPlacements.reduce(function (acc, placement) { + acc[placement] = detectOverflow(state, { + placement: placement, + boundary: boundary, + rootBoundary: rootBoundary, + padding: padding + })[getBasePlacement(placement)]; + return acc; + }, {}); + return Object.keys(overflows).sort(function (a, b) { + return overflows[a] - overflows[b]; + }); } - /** - * @function - * @memberof Modifiers - * @argument {Object} data - The data object generated by `update` method - * @argument {Object} options - Modifiers configuration and options - * @returns {Object} The data object, properly modified - */ - function shift(data) { - var placement = data.placement; - var basePlacement = placement.split('-')[0]; - var shiftvariation = placement.split('-')[1]; - - // if shift shiftvariation is specified, run the modifier - if (shiftvariation) { - var _data$offsets = data.offsets, - reference = _data$offsets.reference, - popper = _data$offsets.popper; - - var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; - var side = isVertical ? 'left' : 'top'; - var measurement = isVertical ? 'width' : 'height'; - - var shiftOffsets = { - start: defineProperty({}, side, reference[side]), - end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) - }; - - data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); + function getExpandedFallbackPlacements(placement) { + if (getBasePlacement(placement) === auto) { + return []; } - return data; + var oppositePlacement = getOppositePlacement(placement); + return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; } - /** - * @function - * @memberof Modifiers - * @argument {Object} data - The data object generated by update method - * @argument {Object} options - Modifiers configuration and options - * @returns {Object} The data object, properly modified - */ - function hide(data) { - if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { - return data; + function flip(_ref) { + var state = _ref.state, + options = _ref.options, + name = _ref.name; + + if (state.modifiersData[name]._skip) { + return; } - var refRect = data.offsets.reference; - var bound = find(data.instance.modifiers, function (modifier) { - return modifier.name === 'preventOverflow'; - }).boundaries; + var _options$mainAxis = options.mainAxis, + checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, + _options$altAxis = options.altAxis, + checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, + specifiedFallbackPlacements = options.fallbackPlacements, + padding = options.padding, + boundary = options.boundary, + rootBoundary = options.rootBoundary, + altBoundary = options.altBoundary, + _options$flipVariatio = options.flipVariations, + flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, + allowedAutoPlacements = options.allowedAutoPlacements; + var preferredPlacement = state.options.placement; + var basePlacement = getBasePlacement(preferredPlacement); + var isBasePlacement = basePlacement === preferredPlacement; + var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); + var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) { + return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, { + placement: placement, + boundary: boundary, + rootBoundary: rootBoundary, + padding: padding, + flipVariations: flipVariations, + allowedAutoPlacements: allowedAutoPlacements + }) : placement); + }, []); + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var checksMap = new Map(); + var makeFallbackChecks = true; + var firstFittingPlacement = placements[0]; - if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { - // Avoid unnecessary DOM access if visibility hasn't changed - if (data.hide === true) { - return data; + for (var i = 0; i < placements.length; i++) { + var placement = placements[i]; + + var _basePlacement = getBasePlacement(placement); + + var isStartVariation = getVariation(placement) === start; + var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; + var len = isVertical ? 'width' : 'height'; + var overflow = detectOverflow(state, { + placement: placement, + boundary: boundary, + rootBoundary: rootBoundary, + altBoundary: altBoundary, + padding: padding + }); + var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; + + if (referenceRect[len] > popperRect[len]) { + mainVariationSide = getOppositePlacement(mainVariationSide); } - data.hide = true; - data.attributes['x-out-of-boundaries'] = ''; + var altVariationSide = getOppositePlacement(mainVariationSide); + var checks = []; + + if (checkMainAxis) { + checks.push(overflow[_basePlacement] <= 0); + } + + if (checkAltAxis) { + checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); + } + + if (checks.every(function (check) { + return check; + })) { + firstFittingPlacement = placement; + makeFallbackChecks = false; + break; + } + + checksMap.set(placement, checks); + } + + if (makeFallbackChecks) { + // `2` may be desired in some cases – research later + var numberOfChecks = flipVariations ? 3 : 1; + + var _loop = function _loop(_i) { + var fittingPlacement = placements.find(function (placement) { + var checks = checksMap.get(placement); + + if (checks) { + return checks.slice(0, _i).every(function (check) { + return check; + }); + } + }); + + if (fittingPlacement) { + firstFittingPlacement = fittingPlacement; + return "break"; + } + }; + + for (var _i = numberOfChecks; _i > 0; _i--) { + var _ret = _loop(_i); + + if (_ret === "break") break; + } + } + + if (state.placement !== firstFittingPlacement) { + state.modifiersData[name]._skip = true; + state.placement = firstFittingPlacement; + state.reset = true; + } + } // eslint-disable-next-line import/no-unused-modules + + + var flip$1 = { + name: 'flip', + enabled: true, + phase: 'main', + fn: flip, + requiresIfExists: ['offset'], + data: { + _skip: false + } + }; + + function getSideOffsets(overflow, rect, preventedOffsets) { + if (preventedOffsets === void 0) { + preventedOffsets = { + x: 0, + y: 0 + }; + } + + return { + top: overflow.top - rect.height - preventedOffsets.y, + right: overflow.right - rect.width + preventedOffsets.x, + bottom: overflow.bottom - rect.height + preventedOffsets.y, + left: overflow.left - rect.width - preventedOffsets.x + }; + } + + function isAnySideFullyClipped(overflow) { + return [top, right, bottom, left].some(function (side) { + return overflow[side] >= 0; + }); + } + + function hide(_ref) { + var state = _ref.state, + name = _ref.name; + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var preventedOffsets = state.modifiersData.preventOverflow; + var referenceOverflow = detectOverflow(state, { + elementContext: 'reference' + }); + var popperAltOverflow = detectOverflow(state, { + altBoundary: true + }); + var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); + var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); + var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); + var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); + state.modifiersData[name] = { + referenceClippingOffsets: referenceClippingOffsets, + popperEscapeOffsets: popperEscapeOffsets, + isReferenceHidden: isReferenceHidden, + hasPopperEscaped: hasPopperEscaped + }; + state.attributes.popper = Object.assign(Object.assign({}, state.attributes.popper), {}, { + 'data-popper-reference-hidden': isReferenceHidden, + 'data-popper-escaped': hasPopperEscaped + }); + } // eslint-disable-next-line import/no-unused-modules + + + var hide$1 = { + name: 'hide', + enabled: true, + phase: 'main', + requiresIfExists: ['preventOverflow'], + fn: hide + }; + + function distanceAndSkiddingToXY(placement, rects, offset) { + var basePlacement = getBasePlacement(placement); + var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; + + var _ref = typeof offset === 'function' ? offset(Object.assign(Object.assign({}, rects), {}, { + placement: placement + })) : offset, + skidding = _ref[0], + distance = _ref[1]; + + skidding = skidding || 0; + distance = (distance || 0) * invertDistance; + return [left, right].indexOf(basePlacement) >= 0 ? { + x: distance, + y: skidding + } : { + x: skidding, + y: distance + }; + } + + function offset(_ref2) { + var state = _ref2.state, + options = _ref2.options, + name = _ref2.name; + var _options$offset = options.offset, + offset = _options$offset === void 0 ? [0, 0] : _options$offset; + var data = placements.reduce(function (acc, placement) { + acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset); + return acc; + }, {}); + var _data$state$placement = data[state.placement], + x = _data$state$placement.x, + y = _data$state$placement.y; + + if (state.modifiersData.popperOffsets != null) { + state.modifiersData.popperOffsets.x += x; + state.modifiersData.popperOffsets.y += y; + } + + state.modifiersData[name] = data; + } // eslint-disable-next-line import/no-unused-modules + + + var offset$1 = { + name: 'offset', + enabled: true, + phase: 'main', + requires: ['popperOffsets'], + fn: offset + }; + + function popperOffsets(_ref) { + var state = _ref.state, + name = _ref.name; + // Offsets are the actual position the popper needs to have to be + // properly positioned near its reference element + // This is the most basic placement, and will be adjusted by + // the modifiers in the next step + state.modifiersData[name] = computeOffsets({ + reference: state.rects.reference, + element: state.rects.popper, + strategy: 'absolute', + placement: state.placement + }); + } // eslint-disable-next-line import/no-unused-modules + + + var popperOffsets$1 = { + name: 'popperOffsets', + enabled: true, + phase: 'read', + fn: popperOffsets, + data: {} + }; + + function getAltAxis(axis) { + return axis === 'x' ? 'y' : 'x'; + } + + function preventOverflow(_ref) { + var state = _ref.state, + options = _ref.options, + name = _ref.name; + var _options$mainAxis = options.mainAxis, + checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, + _options$altAxis = options.altAxis, + checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, + boundary = options.boundary, + rootBoundary = options.rootBoundary, + altBoundary = options.altBoundary, + padding = options.padding, + _options$tether = options.tether, + tether = _options$tether === void 0 ? true : _options$tether, + _options$tetherOffset = options.tetherOffset, + tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; + var overflow = detectOverflow(state, { + boundary: boundary, + rootBoundary: rootBoundary, + padding: padding, + altBoundary: altBoundary + }); + var basePlacement = getBasePlacement(state.placement); + var variation = getVariation(state.placement); + var isBasePlacement = !variation; + var mainAxis = getMainAxisFromPlacement(basePlacement); + var altAxis = getAltAxis(mainAxis); + var popperOffsets = state.modifiersData.popperOffsets; + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign(Object.assign({}, state.rects), {}, { + placement: state.placement + })) : tetherOffset; + var data = { + x: 0, + y: 0 + }; + + if (!popperOffsets) { + return; + } + + if (checkMainAxis) { + var mainSide = mainAxis === 'y' ? top : left; + var altSide = mainAxis === 'y' ? bottom : right; + var len = mainAxis === 'y' ? 'height' : 'width'; + var offset = popperOffsets[mainAxis]; + var min = popperOffsets[mainAxis] + overflow[mainSide]; + var max = popperOffsets[mainAxis] - overflow[altSide]; + var additive = tether ? -popperRect[len] / 2 : 0; + var minLen = variation === start ? referenceRect[len] : popperRect[len]; + var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go + // outside the reference bounds + + var arrowElement = state.elements.arrow; + var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { + width: 0, + height: 0 + }; + var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject(); + var arrowPaddingMin = arrowPaddingObject[mainSide]; + var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want + // to include its full size in the calculation. If the reference is small + // and near the edge of a boundary, the popper can overflow even if the + // reference is not overflowing as well (e.g. virtual elements with no + // width or height) + + var arrowLen = within(0, referenceRect[len], arrowRect[len]); + var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - tetherOffsetValue : minLen - arrowLen - arrowPaddingMin - tetherOffsetValue; + var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + tetherOffsetValue : maxLen + arrowLen + arrowPaddingMax + tetherOffsetValue; + var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); + var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; + var offsetModifierValue = state.modifiersData.offset ? state.modifiersData.offset[state.placement][mainAxis] : 0; + var tetherMin = popperOffsets[mainAxis] + minOffset - offsetModifierValue - clientOffset; + var tetherMax = popperOffsets[mainAxis] + maxOffset - offsetModifierValue; + var preventedOffset = within(tether ? Math.min(min, tetherMin) : min, offset, tether ? Math.max(max, tetherMax) : max); + popperOffsets[mainAxis] = preventedOffset; + data[mainAxis] = preventedOffset - offset; + } + + if (checkAltAxis) { + var _mainSide = mainAxis === 'x' ? top : left; + + var _altSide = mainAxis === 'x' ? bottom : right; + + var _offset = popperOffsets[altAxis]; + + var _min = _offset + overflow[_mainSide]; + + var _max = _offset - overflow[_altSide]; + + var _preventedOffset = within(_min, _offset, _max); + + popperOffsets[altAxis] = _preventedOffset; + data[altAxis] = _preventedOffset - _offset; + } + + state.modifiersData[name] = data; + } // eslint-disable-next-line import/no-unused-modules + + + var preventOverflow$1 = { + name: 'preventOverflow', + enabled: true, + phase: 'main', + fn: preventOverflow, + requiresIfExists: ['offset'] + }; + + function getHTMLElementScroll(element) { + return { + scrollLeft: element.scrollLeft, + scrollTop: element.scrollTop + }; + } + + function getNodeScroll(node) { + if (node === getWindow(node) || !isHTMLElement(node)) { + return getWindowScroll(node); } else { - // Avoid unnecessary DOM access if visibility hasn't changed - if (data.hide === false) { - return data; + return getHTMLElementScroll(node); + } + } + + // Composite means it takes into account transforms as well as layout. + + function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { + if (isFixed === void 0) { + isFixed = false; + } + + var documentElement = getDocumentElement(offsetParent); + var rect = getBoundingClientRect(elementOrVirtualElement); + var isOffsetParentAnElement = isHTMLElement(offsetParent); + var scroll = { + scrollLeft: 0, + scrollTop: 0 + }; + var offsets = { + x: 0, + y: 0 + }; + + if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { + if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078 + isScrollParent(documentElement)) { + scroll = getNodeScroll(offsetParent); } - data.hide = false; - data.attributes['x-out-of-boundaries'] = false; + if (isHTMLElement(offsetParent)) { + offsets = getBoundingClientRect(offsetParent); + offsets.x += offsetParent.clientLeft; + offsets.y += offsetParent.clientTop; + } else if (documentElement) { + offsets.x = getWindowScrollBarX(documentElement); + } } - return data; + return { + x: rect.left + scroll.scrollLeft - offsets.x, + y: rect.top + scroll.scrollTop - offsets.y, + width: rect.width, + height: rect.height + }; } - /** - * @function - * @memberof Modifiers - * @argument {Object} data - The data object generated by `update` method - * @argument {Object} options - Modifiers configuration and options - * @returns {Object} The data object, properly modified - */ - function inner(data) { - var placement = data.placement; - var basePlacement = placement.split('-')[0]; - var _data$offsets = data.offsets, - popper = _data$offsets.popper, - reference = _data$offsets.reference; + function order(modifiers) { + var map = new Map(); + var visited = new Set(); + var result = []; + modifiers.forEach(function (modifier) { + map.set(modifier.name, modifier); + }); // On visiting object, check for its dependencies and visit them recursively - var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; + function sort(modifier) { + visited.add(modifier.name); + var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); + requires.forEach(function (dep) { + if (!visited.has(dep)) { + var depModifier = map.get(dep); - var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; - - popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); - - data.placement = getOppositePlacement(placement); - data.offsets.popper = getClientRect(popper); - - return data; - } - - /** - * Modifier function, each modifier can have a function of this type assigned - * to its `fn` property.
- * These functions will be called on each update, this means that you must - * make sure they are performant enough to avoid performance bottlenecks. - * - * @function ModifierFn - * @argument {dataObject} data - The data object generated by `update` method - * @argument {Object} options - Modifiers configuration and options - * @returns {dataObject} The data object, properly modified - */ - - /** - * Modifiers are plugins used to alter the behavior of your poppers.
- * Popper.js uses a set of 9 modifiers to provide all the basic functionalities - * needed by the library. - * - * Usually you don't want to override the `order`, `fn` and `onLoad` props. - * All the other properties are configurations that could be tweaked. - * @namespace modifiers - */ - var modifiers = { - /** - * Modifier used to shift the popper on the start or end of its reference - * element.
- * It will read the variation of the `placement` property.
- * It can be one either `-end` or `-start`. - * @memberof modifiers - * @inner - */ - shift: { - /** @prop {number} order=100 - Index used to define the order of execution */ - order: 100, - /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ - enabled: true, - /** @prop {ModifierFn} */ - fn: shift - }, - - /** - * The `offset` modifier can shift your popper on both its axis. - * - * It accepts the following units: - * - `px` or unit-less, interpreted as pixels - * - `%` or `%r`, percentage relative to the length of the reference element - * - `%p`, percentage relative to the length of the popper element - * - `vw`, CSS viewport width unit - * - `vh`, CSS viewport height unit - * - * For length is intended the main axis relative to the placement of the popper.
- * This means that if the placement is `top` or `bottom`, the length will be the - * `width`. In case of `left` or `right`, it will be the `height`. - * - * You can provide a single value (as `Number` or `String`), or a pair of values - * as `String` divided by a comma or one (or more) white spaces.
- * The latter is a deprecated method because it leads to confusion and will be - * removed in v2.
- * Additionally, it accepts additions and subtractions between different units. - * Note that multiplications and divisions aren't supported. - * - * Valid examples are: - * ``` - * 10 - * '10%' - * '10, 10' - * '10%, 10' - * '10 + 10%' - * '10 - 5vh + 3%' - * '-10px + 5vh, 5px - 6%' - * ``` - * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap - * > with their reference element, unfortunately, you will have to disable the `flip` modifier. - * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373). - * - * @memberof modifiers - * @inner - */ - offset: { - /** @prop {number} order=200 - Index used to define the order of execution */ - order: 200, - /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ - enabled: true, - /** @prop {ModifierFn} */ - fn: offset, - /** @prop {Number|String} offset=0 - * The offset value as described in the modifier description - */ - offset: 0 - }, - - /** - * Modifier used to prevent the popper from being positioned outside the boundary. - * - * A scenario exists where the reference itself is not within the boundaries.
- * We can say it has "escaped the boundaries" — or just "escaped".
- * In this case we need to decide whether the popper should either: - * - * - detach from the reference and remain "trapped" in the boundaries, or - * - if it should ignore the boundary and "escape with its reference" - * - * When `escapeWithReference` is set to`true` and reference is completely - * outside its boundaries, the popper will overflow (or completely leave) - * the boundaries in order to remain attached to the edge of the reference. - * - * @memberof modifiers - * @inner - */ - preventOverflow: { - /** @prop {number} order=300 - Index used to define the order of execution */ - order: 300, - /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ - enabled: true, - /** @prop {ModifierFn} */ - fn: preventOverflow, - /** - * @prop {Array} [priority=['left','right','top','bottom']] - * Popper will try to prevent overflow following these priorities by default, - * then, it could overflow on the left and on top of the `boundariesElement` - */ - priority: ['left', 'right', 'top', 'bottom'], - /** - * @prop {number} padding=5 - * Amount of pixel used to define a minimum distance between the boundaries - * and the popper. This makes sure the popper always has a little padding - * between the edges of its container - */ - padding: 5, - /** - * @prop {String|HTMLElement} boundariesElement='scrollParent' - * Boundaries used by the modifier. Can be `scrollParent`, `window`, - * `viewport` or any DOM element. - */ - boundariesElement: 'scrollParent' - }, - - /** - * Modifier used to make sure the reference and its popper stay near each other - * without leaving any gap between the two. Especially useful when the arrow is - * enabled and you want to ensure that it points to its reference element. - * It cares only about the first axis. You can still have poppers with margin - * between the popper and its reference element. - * @memberof modifiers - * @inner - */ - keepTogether: { - /** @prop {number} order=400 - Index used to define the order of execution */ - order: 400, - /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ - enabled: true, - /** @prop {ModifierFn} */ - fn: keepTogether - }, - - /** - * This modifier is used to move the `arrowElement` of the popper to make - * sure it is positioned between the reference element and its popper element. - * It will read the outer size of the `arrowElement` node to detect how many - * pixels of conjunction are needed. - * - * It has no effect if no `arrowElement` is provided. - * @memberof modifiers - * @inner - */ - arrow: { - /** @prop {number} order=500 - Index used to define the order of execution */ - order: 500, - /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ - enabled: true, - /** @prop {ModifierFn} */ - fn: arrow, - /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ - element: '[x-arrow]' - }, - - /** - * Modifier used to flip the popper's placement when it starts to overlap its - * reference element. - * - * Requires the `preventOverflow` modifier before it in order to work. - * - * **NOTE:** this modifier will interrupt the current update cycle and will - * restart it if it detects the need to flip the placement. - * @memberof modifiers - * @inner - */ - flip: { - /** @prop {number} order=600 - Index used to define the order of execution */ - order: 600, - /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ - enabled: true, - /** @prop {ModifierFn} */ - fn: flip, - /** - * @prop {String|Array} behavior='flip' - * The behavior used to change the popper's placement. It can be one of - * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid - * placements (with optional variations) - */ - behavior: 'flip', - /** - * @prop {number} padding=5 - * The popper will flip if it hits the edges of the `boundariesElement` - */ - padding: 5, - /** - * @prop {String|HTMLElement} boundariesElement='viewport' - * The element which will define the boundaries of the popper position. - * The popper will never be placed outside of the defined boundaries - * (except if `keepTogether` is enabled) - */ - boundariesElement: 'viewport', - /** - * @prop {Boolean} flipVariations=false - * The popper will switch placement variation between `-start` and `-end` when - * the reference element overlaps its boundaries. - * - * The original placement should have a set variation. - */ - flipVariations: false, - /** - * @prop {Boolean} flipVariationsByContent=false - * The popper will switch placement variation between `-start` and `-end` when - * the popper element overlaps its reference boundaries. - * - * The original placement should have a set variation. - */ - flipVariationsByContent: false - }, - - /** - * Modifier used to make the popper flow toward the inner of the reference element. - * By default, when this modifier is disabled, the popper will be placed outside - * the reference element. - * @memberof modifiers - * @inner - */ - inner: { - /** @prop {number} order=700 - Index used to define the order of execution */ - order: 700, - /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ - enabled: false, - /** @prop {ModifierFn} */ - fn: inner - }, - - /** - * Modifier used to hide the popper when its reference element is outside of the - * popper boundaries. It will set a `x-out-of-boundaries` attribute which can - * be used to hide with a CSS selector the popper when its reference is - * out of boundaries. - * - * Requires the `preventOverflow` modifier before it in order to work. - * @memberof modifiers - * @inner - */ - hide: { - /** @prop {number} order=800 - Index used to define the order of execution */ - order: 800, - /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ - enabled: true, - /** @prop {ModifierFn} */ - fn: hide - }, - - /** - * Computes the style that will be applied to the popper element to gets - * properly positioned. - * - * Note that this modifier will not touch the DOM, it just prepares the styles - * so that `applyStyle` modifier can apply it. This separation is useful - * in case you need to replace `applyStyle` with a custom implementation. - * - * This modifier has `850` as `order` value to maintain backward compatibility - * with previous versions of Popper.js. Expect the modifiers ordering method - * to change in future major versions of the library. - * - * @memberof modifiers - * @inner - */ - computeStyle: { - /** @prop {number} order=850 - Index used to define the order of execution */ - order: 850, - /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ - enabled: true, - /** @prop {ModifierFn} */ - fn: computeStyle, - /** - * @prop {Boolean} gpuAcceleration=true - * If true, it uses the CSS 3D transformation to position the popper. - * Otherwise, it will use the `top` and `left` properties - */ - gpuAcceleration: true, - /** - * @prop {string} [x='bottom'] - * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. - * Change this if your popper should grow in a direction different from `bottom` - */ - x: 'bottom', - /** - * @prop {string} [x='left'] - * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. - * Change this if your popper should grow in a direction different from `right` - */ - y: 'right' - }, - - /** - * Applies the computed styles to the popper element. - * - * All the DOM manipulations are limited to this modifier. This is useful in case - * you want to integrate Popper.js inside a framework or view library and you - * want to delegate all the DOM manipulations to it. - * - * Note that if you disable this modifier, you must make sure the popper element - * has its position set to `absolute` before Popper.js can do its work! - * - * Just disable this modifier and define your own to achieve the desired effect. - * - * @memberof modifiers - * @inner - */ - applyStyle: { - /** @prop {number} order=900 - Index used to define the order of execution */ - order: 900, - /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ - enabled: true, - /** @prop {ModifierFn} */ - fn: applyStyle, - /** @prop {Function} */ - onLoad: applyStyleOnLoad, - /** - * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier - * @prop {Boolean} gpuAcceleration=true - * If true, it uses the CSS 3D transformation to position the popper. - * Otherwise, it will use the `top` and `left` properties - */ - gpuAcceleration: undefined - } - }; - - /** - * The `dataObject` is an object containing all the information used by Popper.js. - * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks. - * @name dataObject - * @property {Object} data.instance The Popper.js instance - * @property {String} data.placement Placement applied to popper - * @property {String} data.originalPlacement Placement originally defined on init - * @property {Boolean} data.flipped True if popper has been flipped by flip modifier - * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper - * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier - * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`) - * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`) - * @property {Object} data.boundaries Offsets of the popper boundaries - * @property {Object} data.offsets The measurements of popper, reference and arrow elements - * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values - * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values - * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 - */ - - /** - * Default options provided to Popper.js constructor.
- * These can be overridden using the `options` argument of Popper.js.
- * To override an option, simply pass an object with the same - * structure of the `options` object, as the 3rd argument. For example: - * ``` - * new Popper(ref, pop, { - * modifiers: { - * preventOverflow: { enabled: false } - * } - * }) - * ``` - * @type {Object} - * @static - * @memberof Popper - */ - var Defaults = { - /** - * Popper's placement. - * @prop {Popper.placements} placement='bottom' - */ - placement: 'bottom', - - /** - * Set this to true if you want popper to position it self in 'fixed' mode - * @prop {Boolean} positionFixed=false - */ - positionFixed: false, - - /** - * Whether events (resize, scroll) are initially enabled. - * @prop {Boolean} eventsEnabled=true - */ - eventsEnabled: true, - - /** - * Set to true if you want to automatically remove the popper when - * you call the `destroy` method. - * @prop {Boolean} removeOnDestroy=false - */ - removeOnDestroy: false, - - /** - * Callback called when the popper is created.
- * By default, it is set to no-op.
- * Access Popper.js instance with `data.instance`. - * @prop {onCreate} - */ - onCreate: function onCreate() {}, - - /** - * Callback called when the popper is updated. This callback is not called - * on the initialization/creation of the popper, but only on subsequent - * updates.
- * By default, it is set to no-op.
- * Access Popper.js instance with `data.instance`. - * @prop {onUpdate} - */ - onUpdate: function onUpdate() {}, - - /** - * List of modifiers used to modify the offsets before they are applied to the popper. - * They provide most of the functionalities of Popper.js. - * @prop {modifiers} - */ - modifiers: modifiers - }; - - /** - * @callback onCreate - * @param {dataObject} data - */ - - /** - * @callback onUpdate - * @param {dataObject} data - */ - - // Utils - // Methods - var Popper = function () { - /** - * Creates a new Popper.js instance. - * @class Popper - * @param {Element|referenceObject} reference - The reference element used to position the popper - * @param {Element} popper - The HTML / XML element used as the popper - * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) - * @return {Object} instance - The generated Popper.js instance - */ - function Popper(reference, popper) { - var _this = this; - - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - classCallCheck(this, Popper); - - this.scheduleUpdate = function () { - return requestAnimationFrame(_this.update); - }; - - // make update() debounced, so that it only runs at most once-per-tick - this.update = debounce(this.update.bind(this)); - - // with {} we create a new object with the options inside it - this.options = _extends({}, Popper.Defaults, options); - - // init state - this.state = { - isDestroyed: false, - isCreated: false, - scrollParents: [] - }; - - // get reference and popper elements (allow jQuery wrappers) - this.reference = reference && reference.jquery ? reference[0] : reference; - this.popper = popper && popper.jquery ? popper[0] : popper; - - // Deep merge modifiers options - this.options.modifiers = {}; - Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { - _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); - }); - - // Refactoring modifiers' list (Object => Array) - this.modifiers = Object.keys(this.options.modifiers).map(function (name) { - return _extends({ - name: name - }, _this.options.modifiers[name]); - }) - // sort the modifiers by order - .sort(function (a, b) { - return a.order - b.order; - }); - - // modifiers have the ability to execute arbitrary code when Popper.js get inited - // such code is executed in the same order of its modifier - // they could add new properties to their options configuration - // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! - this.modifiers.forEach(function (modifierOptions) { - if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { - modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); + if (depModifier) { + sort(depModifier); + } } }); - - // fire the first update to position the popper in the right place - this.update(); - - var eventsEnabled = this.options.eventsEnabled; - if (eventsEnabled) { - // setup event listeners, they will take care of update the position in specific situations - this.enableEventListeners(); - } - - this.state.eventsEnabled = eventsEnabled; + result.push(modifier); } - // We can't use class properties because they don't get listed in the - // class prototype and break stuff like Sinon stubs + modifiers.forEach(function (modifier) { + if (!visited.has(modifier.name)) { + // check for visited object + sort(modifier); + } + }); + return result; + } + function orderModifiers(modifiers) { + // order based on dependencies + var orderedModifiers = order(modifiers); // order based on phase - createClass(Popper, [{ - key: 'update', - value: function update$$1() { - return update.call(this); - } - }, { - key: 'destroy', - value: function destroy$$1() { - return destroy.call(this); - } - }, { - key: 'enableEventListeners', - value: function enableEventListeners$$1() { - return enableEventListeners.call(this); - } - }, { - key: 'disableEventListeners', - value: function disableEventListeners$$1() { - return disableEventListeners.call(this); + return modifierPhases.reduce(function (acc, phase) { + return acc.concat(orderedModifiers.filter(function (modifier) { + return modifier.phase === phase; + })); + }, []); + } + + function debounce(fn) { + var pending; + return function () { + if (!pending) { + pending = new Promise(function (resolve) { + Promise.resolve().then(function () { + pending = undefined; + resolve(fn()); + }); + }); } - /** - * Schedules an update. It will run on the next UI update available. - * @method scheduleUpdate - * @memberof Popper - */ + return pending; + }; + } + + function mergeByName(modifiers) { + var merged = modifiers.reduce(function (merged, current) { + var existing = merged[current.name]; + merged[current.name] = existing ? Object.assign(Object.assign(Object.assign({}, existing), current), {}, { + options: Object.assign(Object.assign({}, existing.options), current.options), + data: Object.assign(Object.assign({}, existing.data), current.data) + }) : current; + return merged; + }, {}); // IE11 does not support Object.values + + return Object.keys(merged).map(function (key) { + return merged[key]; + }); + } + + var DEFAULT_OPTIONS = { + placement: 'bottom', + modifiers: [], + strategy: 'absolute' + }; + + function areValidElements() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return !args.some(function (element) { + return !(element && typeof element.getBoundingClientRect === 'function'); + }); + } + + function popperGenerator(generatorOptions) { + if (generatorOptions === void 0) { + generatorOptions = {}; + } + + var _generatorOptions = generatorOptions, + _generatorOptions$def = _generatorOptions.defaultModifiers, + defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, + _generatorOptions$def2 = _generatorOptions.defaultOptions, + defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; + return function createPopper(reference, popper, options) { + if (options === void 0) { + options = defaultOptions; + } + + var state = { + placement: 'bottom', + orderedModifiers: [], + options: Object.assign(Object.assign({}, DEFAULT_OPTIONS), defaultOptions), + modifiersData: {}, + elements: { + reference: reference, + popper: popper + }, + attributes: {}, + styles: {} + }; + var effectCleanupFns = []; + var isDestroyed = false; + var instance = { + state: state, + setOptions: function setOptions(options) { + cleanupModifierEffects(); + state.options = Object.assign(Object.assign(Object.assign({}, defaultOptions), state.options), options); + state.scrollParents = { + reference: isElement$1(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [], + popper: listScrollParents(popper) + }; // Orders the modifiers based on their dependencies and `phase` + // properties + + var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers + + state.orderedModifiers = orderedModifiers.filter(function (m) { + return m.enabled; + }); // Validate the provided modifiers so that the consumer will get warned + + runModifierEffects(); + return instance.update(); + }, + // Sync update – it will always be executed, even if not necessary. This + // is useful for low frequency updates where sync behavior simplifies the + // logic. + // For high frequency updates (e.g. `resize` and `scroll` events), always + // prefer the async Popper#update method + forceUpdate: function forceUpdate() { + if (isDestroyed) { + return; + } + + var _state$elements = state.elements, + reference = _state$elements.reference, + popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements + // anymore + + if (!areValidElements(reference, popper)) { + + return; + } // Store the reference and popper rects to be read by modifiers - /** - * Collection of utilities useful when writing custom modifiers. - * Starting from version 1.7, this method is available only if you - * include `popper-utils.js` before `popper.js`. - * - * **DEPRECATION**: This way to access PopperUtils is deprecated - * and will be removed in v2! Use the PopperUtils module directly instead. - * Due to the high instability of the methods contained in Utils, we can't - * guarantee them to follow semver. Use them at your own risk! - * @static - * @private - * @type {Object} - * @deprecated since version 1.8 - * @member Utils - * @memberof Popper - */ + state.rects = { + reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'), + popper: getLayoutRect(popper) + }; // Modifiers have the ability to reset the current update cycle. The + // most common use case for this is the `flip` modifier changing the + // placement, which then needs to re-run all the modifiers, because the + // logic was previously ran for the previous placement and is therefore + // stale/incorrect - }]); - return Popper; - }(); + state.reset = false; + state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier + // is filled with the initial data specified by the modifier. This means + // it doesn't persist and is fresh on each update. + // To ensure persistent data, use `${name}#persistent` - /** - * The `referenceObject` is an object that provides an interface compatible with Popper.js - * and lets you use it as replacement of a real DOM node.
- * You can use this method to position a popper relatively to a set of coordinates - * in case you don't have a DOM node to use as reference. - * - * ``` - * new Popper(referenceObject, popperNode); - * ``` - * - * NB: This feature isn't supported in Internet Explorer 10. - * @name referenceObject - * @property {Function} data.getBoundingClientRect - * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. - * @property {number} data.clientWidth - * An ES6 getter that will return the width of the virtual reference element. - * @property {number} data.clientHeight - * An ES6 getter that will return the height of the virtual reference element. - */ + state.orderedModifiers.forEach(function (modifier) { + return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); + }); + for (var index = 0; index < state.orderedModifiers.length; index++) { - Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; - Popper.placements = placements; - Popper.Defaults = Defaults; + if (state.reset === true) { + state.reset = false; + index = -1; + continue; + } + + var _state$orderedModifie = state.orderedModifiers[index], + fn = _state$orderedModifie.fn, + _state$orderedModifie2 = _state$orderedModifie.options, + _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, + name = _state$orderedModifie.name; + + if (typeof fn === 'function') { + state = fn({ + state: state, + options: _options, + name: name, + instance: instance + }) || state; + } + } + }, + // Async and optimistically optimized update – it will not be executed if + // not necessary (debounced to run at most once-per-tick) + update: debounce(function () { + return new Promise(function (resolve) { + instance.forceUpdate(); + resolve(state); + }); + }), + destroy: function destroy() { + cleanupModifierEffects(); + isDestroyed = true; + } + }; + + if (!areValidElements(reference, popper)) { + + return instance; + } + + instance.setOptions(options).then(function (state) { + if (!isDestroyed && options.onFirstUpdate) { + options.onFirstUpdate(state); + } + }); // Modifiers have the ability to execute arbitrary code before the first + // update cycle runs. They will be executed in the same order as the update + // cycle. This is useful when a modifier adds some persistent data that + // other modifiers need to use, but the modifier is run after the dependent + // one. + + function runModifierEffects() { + state.orderedModifiers.forEach(function (_ref3) { + var name = _ref3.name, + _ref3$options = _ref3.options, + options = _ref3$options === void 0 ? {} : _ref3$options, + effect = _ref3.effect; + + if (typeof effect === 'function') { + var cleanupFn = effect({ + state: state, + name: name, + instance: instance, + options: options + }); + + var noopFn = function noopFn() {}; + + effectCleanupFns.push(cleanupFn || noopFn); + } + }); + } + + function cleanupModifierEffects() { + effectCleanupFns.forEach(function (fn) { + return fn(); + }); + effectCleanupFns = []; + } + + return instance; + }; + } + var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules + + var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1]; + var createPopper$1 = /*#__PURE__*/popperGenerator({ + defaultModifiers: defaultModifiers + }); // eslint-disable-next-line import/no-unused-modules + + var defaultModifiers$1 = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1]; + var createPopper$2 = /*#__PURE__*/popperGenerator({ + defaultModifiers: defaultModifiers$1 + }); // eslint-disable-next-line import/no-unused-modules + + var Popper = /*#__PURE__*/Object.freeze({ + __proto__: null, + popperGenerator: popperGenerator, + detectOverflow: detectOverflow, + createPopperBase: createPopper, + createPopper: createPopper$2, + createPopperLite: createPopper$1, + top: top, + bottom: bottom, + right: right, + left: left, + auto: auto, + basePlacements: basePlacements, + start: start, + end: end, + clippingParents: clippingParents, + viewport: viewport, + popper: popper, + reference: reference, + variationPlacements: variationPlacements, + placements: placements, + beforeRead: beforeRead, + read: read, + afterRead: afterRead, + beforeMain: beforeMain, + main: main, + afterMain: afterMain, + beforeWrite: beforeWrite, + write: write, + afterWrite: afterWrite, + modifierPhases: modifierPhases, + applyStyles: applyStyles$1, + arrow: arrow$1, + computeStyles: computeStyles$1, + eventListeners: eventListeners, + flip: flip$1, + hide: hide$1, + offset: offset$1, + popperOffsets: popperOffsets$1, + preventOverflow: preventOverflow$1 + }); /** * ------------------------------------------------------------------------ @@ -4197,65 +3752,46 @@ */ var NAME$4 = 'dropdown'; - var VERSION$4 = '4.4.1'; var DATA_KEY$4 = 'bs.dropdown'; var EVENT_KEY$4 = "." + DATA_KEY$4; var DATA_API_KEY$4 = '.data-api'; - var JQUERY_NO_CONFLICT$4 = $.fn[NAME$4]; - var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key + var ESCAPE_KEY = 'Escape'; + var SPACE_KEY = 'Space'; + var TAB_KEY = 'Tab'; + var ARROW_UP_KEY = 'ArrowUp'; + var ARROW_DOWN_KEY = 'ArrowDown'; + var RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button - var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key - - var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key - - var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key - - var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key - - var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse) - - var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE); - var Event$4 = { - HIDE: "hide" + EVENT_KEY$4, - HIDDEN: "hidden" + EVENT_KEY$4, - SHOW: "show" + EVENT_KEY$4, - SHOWN: "shown" + EVENT_KEY$4, - CLICK: "click" + EVENT_KEY$4, - CLICK_DATA_API: "click" + EVENT_KEY$4 + DATA_API_KEY$4, - KEYDOWN_DATA_API: "keydown" + EVENT_KEY$4 + DATA_API_KEY$4, - KEYUP_DATA_API: "keyup" + EVENT_KEY$4 + DATA_API_KEY$4 - }; - var ClassName$4 = { - DISABLED: 'disabled', - SHOW: 'show', - DROPUP: 'dropup', - DROPRIGHT: 'dropright', - DROPLEFT: 'dropleft', - MENURIGHT: 'dropdown-menu-right', - MENULEFT: 'dropdown-menu-left', - POSITION_STATIC: 'position-static' - }; - var Selector$4 = { - DATA_TOGGLE: '[data-toggle="dropdown"]', - FORM_CHILD: '.dropdown form', - MENU: '.dropdown-menu', - NAVBAR_NAV: '.navbar-nav', - VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' - }; - var AttachmentMap = { - TOP: 'top-start', - TOPEND: 'top-end', - BOTTOM: 'bottom-start', - BOTTOMEND: 'bottom-end', - RIGHT: 'right-start', - RIGHTEND: 'right-end', - LEFT: 'left-start', - LEFTEND: 'left-end' - }; + var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEY + "|" + ARROW_DOWN_KEY + "|" + ESCAPE_KEY); + var EVENT_HIDE$1 = "hide" + EVENT_KEY$4; + var EVENT_HIDDEN$1 = "hidden" + EVENT_KEY$4; + var EVENT_SHOW$1 = "show" + EVENT_KEY$4; + var EVENT_SHOWN$1 = "shown" + EVENT_KEY$4; + var EVENT_CLICK = "click" + EVENT_KEY$4; + var EVENT_CLICK_DATA_API$4 = "click" + EVENT_KEY$4 + DATA_API_KEY$4; + var EVENT_KEYDOWN_DATA_API = "keydown" + EVENT_KEY$4 + DATA_API_KEY$4; + var EVENT_KEYUP_DATA_API = "keyup" + EVENT_KEY$4 + DATA_API_KEY$4; + var CLASS_NAME_DISABLED = 'disabled'; + var CLASS_NAME_SHOW$1 = 'show'; + var CLASS_NAME_DROPUP = 'dropup'; + var CLASS_NAME_DROPEND = 'dropend'; + var CLASS_NAME_DROPSTART = 'dropstart'; + var CLASS_NAME_NAVBAR = 'navbar'; + var SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle="dropdown"]'; + var SELECTOR_FORM_CHILD = '.dropdown form'; + var SELECTOR_MENU = '.dropdown-menu'; + var SELECTOR_NAVBAR_NAV = '.navbar-nav'; + var SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'; + var PLACEMENT_TOP = isRTL ? 'top-end' : 'top-start'; + var PLACEMENT_TOPEND = isRTL ? 'top-start' : 'top-end'; + var PLACEMENT_BOTTOM = isRTL ? 'bottom-end' : 'bottom-start'; + var PLACEMENT_BOTTOMEND = isRTL ? 'bottom-start' : 'bottom-end'; + var PLACEMENT_RIGHT = isRTL ? 'left-start' : 'right-start'; + var PLACEMENT_LEFT = isRTL ? 'right-start' : 'left-start'; var Default$2 = { offset: 0, flip: true, - boundary: 'scrollParent', + boundary: 'clippingParents', reference: 'toggle', display: 'dynamic', popperConfig: null @@ -4274,17 +3810,21 @@ * ------------------------------------------------------------------------ */ - var Dropdown = - /*#__PURE__*/ - function () { - function Dropdown(element, config) { - this._element = element; - this._popper = null; - this._config = this._getConfig(config); - this._menu = this._getMenuElement(); - this._inNavbar = this._detectNavbar(); + var Dropdown = /*#__PURE__*/function (_BaseComponent) { + _inheritsLoose(Dropdown, _BaseComponent); - this._addEventListeners(); + function Dropdown(element, config) { + var _this; + + _this = _BaseComponent.call(this, element) || this; + _this._popper = null; + _this._config = _this._getConfig(config); + _this._menu = _this._getMenuElement(); + _this._inNavbar = _this._detectNavbar(); + + _this._addEventListeners(); + + return _this; } // Getters @@ -4292,106 +3832,92 @@ // Public _proto.toggle = function toggle() { - if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED)) { + if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED)) { return; } - var isActive = $(this._menu).hasClass(ClassName$4.SHOW); + var isActive = this._element.classList.contains(CLASS_NAME_SHOW$1); - Dropdown._clearMenus(); + Dropdown.clearMenus(); if (isActive) { return; } - this.show(true); + this.show(); }; - _proto.show = function show(usePopper) { - if (usePopper === void 0) { - usePopper = false; - } - - if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED) || $(this._menu).hasClass(ClassName$4.SHOW)) { + _proto.show = function show() { + if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED) || this._menu.classList.contains(CLASS_NAME_SHOW$1)) { return; } + var parent = Dropdown.getParentFromElement(this._element); var relatedTarget = { relatedTarget: this._element }; - var showEvent = $.Event(Event$4.SHOW, relatedTarget); + var showEvent = EventHandler.trigger(this._element, EVENT_SHOW$1, relatedTarget); - var parent = Dropdown._getParentFromElement(this._element); - - $(parent).trigger(showEvent); - - if (showEvent.isDefaultPrevented()) { + if (showEvent.defaultPrevented) { return; - } // Disable totally Popper.js for Dropdown in Navbar + } // Totally disable Popper for Dropdowns in Navbar - if (!this._inNavbar && usePopper) { - /** - * Check for Popper dependency - * Popper - https://popper.js.org - */ + if (!this._inNavbar) { if (typeof Popper === 'undefined') { - throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)'); + throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)'); } var referenceElement = this._element; if (this._config.reference === 'parent') { referenceElement = parent; - } else if (Util.isElement(this._config.reference)) { + } else if (isElement(this._config.reference)) { referenceElement = this._config.reference; // Check if it's jQuery element if (typeof this._config.reference.jquery !== 'undefined') { referenceElement = this._config.reference[0]; } - } // If boundary is not `scrollParent`, then set position to `static` - // to allow the menu to "escape" the scroll parent's boundaries - // https://github.com/twbs/bootstrap/issues/24251 - - - if (this._config.boundary !== 'scrollParent') { - $(parent).addClass(ClassName$4.POSITION_STATIC); } - this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()); + this._popper = createPopper$2(referenceElement, this._menu, this._getPopperConfig()); } // If this is a touch-enabled device we add extra // empty mouseover listeners to the body's immediate children; // only needed because of broken event delegation on iOS // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html - if ('ontouchstart' in document.documentElement && $(parent).closest(Selector$4.NAVBAR_NAV).length === 0) { - $(document.body).children().on('mouseover', null, $.noop); + if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) { + var _ref; + + (_ref = []).concat.apply(_ref, document.body.children).forEach(function (elem) { + return EventHandler.on(elem, 'mouseover', null, noop()); + }); } this._element.focus(); this._element.setAttribute('aria-expanded', true); - $(this._menu).toggleClass(ClassName$4.SHOW); - $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.SHOWN, relatedTarget)); + this._menu.classList.toggle(CLASS_NAME_SHOW$1); + + this._element.classList.toggle(CLASS_NAME_SHOW$1); + + EventHandler.trigger(parent, EVENT_SHOWN$1, relatedTarget); }; _proto.hide = function hide() { - if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED) || !$(this._menu).hasClass(ClassName$4.SHOW)) { + if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED) || !this._menu.classList.contains(CLASS_NAME_SHOW$1)) { return; } + var parent = Dropdown.getParentFromElement(this._element); var relatedTarget = { relatedTarget: this._element }; - var hideEvent = $.Event(Event$4.HIDE, relatedTarget); + var hideEvent = EventHandler.trigger(parent, EVENT_HIDE$1, relatedTarget); - var parent = Dropdown._getParentFromElement(this._element); - - $(parent).trigger(hideEvent); - - if (hideEvent.isDefaultPrevented()) { + if (hideEvent.defaultPrevented) { return; } @@ -4399,17 +3925,20 @@ this._popper.destroy(); } - $(this._menu).toggleClass(ClassName$4.SHOW); - $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.HIDDEN, relatedTarget)); + this._menu.classList.toggle(CLASS_NAME_SHOW$1); + + this._element.classList.toggle(CLASS_NAME_SHOW$1); + + EventHandler.trigger(parent, EVENT_HIDDEN$1, relatedTarget); }; _proto.dispose = function dispose() { - $.removeData(this._element, DATA_KEY$4); - $(this._element).off(EVENT_KEY$4); - this._element = null; + _BaseComponent.prototype.dispose.call(this); + + EventHandler.off(this._element, EVENT_KEY$4); this._menu = null; - if (this._popper !== null) { + if (this._popper) { this._popper.destroy(); this._popper = null; @@ -4419,139 +3948,115 @@ _proto.update = function update() { this._inNavbar = this._detectNavbar(); - if (this._popper !== null) { - this._popper.scheduleUpdate(); + if (this._popper) { + this._popper.update(); } } // Private ; _proto._addEventListeners = function _addEventListeners() { - var _this = this; + var _this2 = this; - $(this._element).on(Event$4.CLICK, function (event) { + EventHandler.on(this._element, EVENT_CLICK, function (event) { event.preventDefault(); event.stopPropagation(); - _this.toggle(); + _this2.toggle(); }); }; _proto._getConfig = function _getConfig(config) { - config = _objectSpread2({}, this.constructor.Default, {}, $(this._element).data(), {}, config); - Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType); + config = _extends({}, this.constructor.Default, Manipulator.getDataAttributes(this._element), config); + typeCheckConfig(NAME$4, config, this.constructor.DefaultType); return config; }; _proto._getMenuElement = function _getMenuElement() { - if (!this._menu) { - var parent = Dropdown._getParentFromElement(this._element); - - if (parent) { - this._menu = parent.querySelector(Selector$4.MENU); - } - } - - return this._menu; + return SelectorEngine.next(this._element, SELECTOR_MENU)[0]; }; _proto._getPlacement = function _getPlacement() { - var $parentDropdown = $(this._element.parentNode); - var placement = AttachmentMap.BOTTOM; // Handle dropup + var parentDropdown = this._element.parentNode; - if ($parentDropdown.hasClass(ClassName$4.DROPUP)) { - placement = AttachmentMap.TOP; - - if ($(this._menu).hasClass(ClassName$4.MENURIGHT)) { - placement = AttachmentMap.TOPEND; - } - } else if ($parentDropdown.hasClass(ClassName$4.DROPRIGHT)) { - placement = AttachmentMap.RIGHT; - } else if ($parentDropdown.hasClass(ClassName$4.DROPLEFT)) { - placement = AttachmentMap.LEFT; - } else if ($(this._menu).hasClass(ClassName$4.MENURIGHT)) { - placement = AttachmentMap.BOTTOMEND; + if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) { + return PLACEMENT_RIGHT; } - return placement; + if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) { + return PLACEMENT_LEFT; + } // We need to trim the value because custom properties can also include spaces + + + var isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'; + + if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) { + return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP; + } + + return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM; }; _proto._detectNavbar = function _detectNavbar() { - return $(this._element).closest('.navbar').length > 0; - }; - - _proto._getOffset = function _getOffset() { - var _this2 = this; - - var offset = {}; - - if (typeof this._config.offset === 'function') { - offset.fn = function (data) { - data.offsets = _objectSpread2({}, data.offsets, {}, _this2._config.offset(data.offsets, _this2._element) || {}); - return data; - }; - } else { - offset.offset = this._config.offset; - } - - return offset; + return this._element.closest("." + CLASS_NAME_NAVBAR) !== null; }; _proto._getPopperConfig = function _getPopperConfig() { var popperConfig = { placement: this._getPlacement(), - modifiers: { - offset: this._getOffset(), - flip: { - enabled: this._config.flip - }, - preventOverflow: { - boundariesElement: this._config.boundary + modifiers: [{ + name: 'preventOverflow', + options: { + altBoundary: this._config.flip, + rootBoundary: this._config.boundary } - } - }; // Disable Popper.js if we have a static display + }] + }; // Disable Popper if we have a static display if (this._config.display === 'static') { - popperConfig.modifiers.applyStyle = { + popperConfig.modifiers = [{ + name: 'applyStyles', enabled: false - }; + }]; } - return _objectSpread2({}, popperConfig, {}, this._config.popperConfig); + return _extends({}, popperConfig, this._config.popperConfig); } // Static ; - Dropdown._jQueryInterface = function _jQueryInterface(config) { + Dropdown.dropdownInterface = function dropdownInterface(element, config) { + var data = Data.getData(element, DATA_KEY$4); + + var _config = typeof config === 'object' ? config : null; + + if (!data) { + data = new Dropdown(element, _config); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](); + } + }; + + Dropdown.jQueryInterface = function jQueryInterface(config) { return this.each(function () { - var data = $(this).data(DATA_KEY$4); - - var _config = typeof config === 'object' ? config : null; - - if (!data) { - data = new Dropdown(this, _config); - $(this).data(DATA_KEY$4, data); - } - - if (typeof config === 'string') { - if (typeof data[config] === 'undefined') { - throw new TypeError("No method named \"" + config + "\""); - } - - data[config](); - } + Dropdown.dropdownInterface(this, config); }); }; - Dropdown._clearMenus = function _clearMenus(event) { - if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) { + Dropdown.clearMenus = function clearMenus(event) { + if (event && (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY)) { return; } - var toggles = [].slice.call(document.querySelectorAll(Selector$4.DATA_TOGGLE)); + var toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE$2); for (var i = 0, len = toggles.length; i < len; i++) { - var parent = Dropdown._getParentFromElement(toggles[i]); - - var context = $(toggles[i]).data(DATA_KEY$4); + var parent = Dropdown.getParentFromElement(toggles[i]); + var context = Data.getData(toggles[i], DATA_KEY$4); var relatedTarget = { relatedTarget: toggles[i] }; @@ -4566,25 +4071,28 @@ var dropdownMenu = context._menu; - if (!$(parent).hasClass(ClassName$4.SHOW)) { + if (!toggles[i].classList.contains(CLASS_NAME_SHOW$1)) { continue; } - if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) { + if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.key === TAB_KEY) && dropdownMenu.contains(event.target)) { continue; } - var hideEvent = $.Event(Event$4.HIDE, relatedTarget); - $(parent).trigger(hideEvent); + var hideEvent = EventHandler.trigger(parent, EVENT_HIDE$1, relatedTarget); - if (hideEvent.isDefaultPrevented()) { + if (hideEvent.defaultPrevented) { continue; } // If this is a touch-enabled device we remove the extra // empty mouseover listeners we added for iOS support if ('ontouchstart' in document.documentElement) { - $(document.body).children().off('mouseover', null, $.noop); + var _ref2; + + (_ref2 = []).concat.apply(_ref2, document.body.children).forEach(function (elem) { + return EventHandler.off(elem, 'mouseover', null, noop()); + }); } toggles[i].setAttribute('aria-expanded', 'false'); @@ -4593,24 +4101,17 @@ context._popper.destroy(); } - $(dropdownMenu).removeClass(ClassName$4.SHOW); - $(parent).removeClass(ClassName$4.SHOW).trigger($.Event(Event$4.HIDDEN, relatedTarget)); + dropdownMenu.classList.remove(CLASS_NAME_SHOW$1); + toggles[i].classList.remove(CLASS_NAME_SHOW$1); + EventHandler.trigger(parent, EVENT_HIDDEN$1, relatedTarget); } }; - Dropdown._getParentFromElement = function _getParentFromElement(element) { - var parent; - var selector = Util.getSelectorFromElement(element); + Dropdown.getParentFromElement = function getParentFromElement(element) { + return getElementFromSelector(element) || element.parentNode; + }; - if (selector) { - parent = document.querySelector(selector); - } - - return parent || element.parentNode; - } // eslint-disable-next-line complexity - ; - - Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) { + Dropdown.dataApiKeydownHandler = function dataApiKeydownHandler(event) { // If not input/textarea: // - And not a key in REGEXP_KEYDOWN => not a dropdown command // If input/textarea: @@ -4618,68 +4119,55 @@ // - 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 && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(Selector$4.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { + if (/input|textarea/i.test(event.target.tagName) ? event.key === SPACE_KEY || event.key !== ESCAPE_KEY && (event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY || event.target.closest(SELECTOR_MENU)) : !REGEXP_KEYDOWN.test(event.key)) { return; } event.preventDefault(); event.stopPropagation(); - if (this.disabled || $(this).hasClass(ClassName$4.DISABLED)) { + if (this.disabled || this.classList.contains(CLASS_NAME_DISABLED)) { return; } - var parent = Dropdown._getParentFromElement(this); + var parent = Dropdown.getParentFromElement(this); + var isActive = this.classList.contains(CLASS_NAME_SHOW$1); - var isActive = $(parent).hasClass(ClassName$4.SHOW); - - if (!isActive && event.which === ESCAPE_KEYCODE) { + if (event.key === ESCAPE_KEY) { + var button = this.matches(SELECTOR_DATA_TOGGLE$2) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$2)[0]; + button.focus(); + Dropdown.clearMenus(); return; } - if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) { - if (event.which === ESCAPE_KEYCODE) { - var toggle = parent.querySelector(Selector$4.DATA_TOGGLE); - $(toggle).trigger('focus'); - } - - $(this).trigger('click'); + if (!isActive || event.key === SPACE_KEY) { + Dropdown.clearMenus(); return; } - var items = [].slice.call(parent.querySelectorAll(Selector$4.VISIBLE_ITEMS)).filter(function (item) { - return $(item).is(':visible'); - }); + var items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, parent).filter(isVisible); - if (items.length === 0) { + if (!items.length) { return; } - var index = items.indexOf(event.target); + var index = items.indexOf(event.target); // Up - if (event.which === ARROW_UP_KEYCODE && index > 0) { - // Up + if (event.key === ARROW_UP_KEY && index > 0) { index--; - } + } // Down - if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { - // Down + + if (event.key === ARROW_DOWN_KEY && index < items.length - 1) { index++; - } + } // index is -1 if the first keydown is an ArrowUp - if (index < 0) { - index = 0; - } + index = index === -1 ? 0 : index; items[index].focus(); }; _createClass(Dropdown, null, [{ - key: "VERSION", - get: function get() { - return VERSION$4; - } - }, { key: "Default", get: function get() { return Default$2; @@ -4689,10 +4177,15 @@ get: function get() { return DefaultType$2; } + }, { + key: "DATA_KEY", + get: function get() { + return DATA_KEY$4; + } }]); return Dropdown; - }(); + }(BaseComponent); /** * ------------------------------------------------------------------------ * Data Api implementation @@ -4700,27 +4193,40 @@ */ - $(document).on(Event$4.KEYDOWN_DATA_API, Selector$4.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event$4.KEYDOWN_DATA_API, Selector$4.MENU, Dropdown._dataApiKeydownHandler).on(Event$4.CLICK_DATA_API + " " + Event$4.KEYUP_DATA_API, Dropdown._clearMenus).on(Event$4.CLICK_DATA_API, Selector$4.DATA_TOGGLE, function (event) { + EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$2, Dropdown.dataApiKeydownHandler); + EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler); + EventHandler.on(document, EVENT_CLICK_DATA_API$4, Dropdown.clearMenus); + EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus); + EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$2, function (event) { event.preventDefault(); event.stopPropagation(); - - Dropdown._jQueryInterface.call($(this), 'toggle'); - }).on(Event$4.CLICK_DATA_API, Selector$4.FORM_CHILD, function (e) { - e.stopPropagation(); + Dropdown.dropdownInterface(this, 'toggle'); + }); + EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_FORM_CHILD, function (e) { + return e.stopPropagation(); }); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ + * add .Dropdown to jQuery only if jQuery is present */ - $.fn[NAME$4] = Dropdown._jQueryInterface; - $.fn[NAME$4].Constructor = Dropdown; + onDOMContentLoaded(function () { + var $ = getjQuery(); + /* istanbul ignore if */ - $.fn[NAME$4].noConflict = function () { - $.fn[NAME$4] = JQUERY_NO_CONFLICT$4; - return Dropdown._jQueryInterface; - }; + if ($) { + var JQUERY_NO_CONFLICT = $.fn[NAME$4]; + $.fn[NAME$4] = Dropdown.jQueryInterface; + $.fn[NAME$4].Constructor = Dropdown; + + $.fn[NAME$4].noConflict = function () { + $.fn[NAME$4] = JQUERY_NO_CONFLICT; + return Dropdown.jQueryInterface; + }; + } + }); /** * ------------------------------------------------------------------------ @@ -4729,75 +4235,66 @@ */ var NAME$5 = 'modal'; - var VERSION$5 = '4.4.1'; var DATA_KEY$5 = 'bs.modal'; var EVENT_KEY$5 = "." + DATA_KEY$5; var DATA_API_KEY$5 = '.data-api'; - var JQUERY_NO_CONFLICT$5 = $.fn[NAME$5]; - var ESCAPE_KEYCODE$1 = 27; // KeyboardEvent.which value for Escape (Esc) key - + var ESCAPE_KEY$1 = 'Escape'; var Default$3 = { backdrop: true, keyboard: true, - focus: true, - show: true + focus: true }; var DefaultType$3 = { backdrop: '(boolean|string)', keyboard: 'boolean', - focus: 'boolean', - show: 'boolean' - }; - var Event$5 = { - HIDE: "hide" + EVENT_KEY$5, - HIDE_PREVENTED: "hidePrevented" + EVENT_KEY$5, - HIDDEN: "hidden" + EVENT_KEY$5, - SHOW: "show" + EVENT_KEY$5, - SHOWN: "shown" + EVENT_KEY$5, - FOCUSIN: "focusin" + EVENT_KEY$5, - RESIZE: "resize" + EVENT_KEY$5, - CLICK_DISMISS: "click.dismiss" + EVENT_KEY$5, - KEYDOWN_DISMISS: "keydown.dismiss" + EVENT_KEY$5, - MOUSEUP_DISMISS: "mouseup.dismiss" + EVENT_KEY$5, - MOUSEDOWN_DISMISS: "mousedown.dismiss" + EVENT_KEY$5, - CLICK_DATA_API: "click" + EVENT_KEY$5 + DATA_API_KEY$5 - }; - var ClassName$5 = { - SCROLLABLE: 'modal-dialog-scrollable', - SCROLLBAR_MEASURER: 'modal-scrollbar-measure', - BACKDROP: 'modal-backdrop', - OPEN: 'modal-open', - FADE: 'fade', - SHOW: 'show', - STATIC: 'modal-static' - }; - var Selector$5 = { - DIALOG: '.modal-dialog', - MODAL_BODY: '.modal-body', - DATA_TOGGLE: '[data-toggle="modal"]', - DATA_DISMISS: '[data-dismiss="modal"]', - FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top', - STICKY_CONTENT: '.sticky-top' + focus: 'boolean' }; + var EVENT_HIDE$2 = "hide" + EVENT_KEY$5; + var EVENT_HIDE_PREVENTED = "hidePrevented" + EVENT_KEY$5; + var EVENT_HIDDEN$2 = "hidden" + EVENT_KEY$5; + var EVENT_SHOW$2 = "show" + EVENT_KEY$5; + var EVENT_SHOWN$2 = "shown" + EVENT_KEY$5; + var EVENT_FOCUSIN = "focusin" + EVENT_KEY$5; + var EVENT_RESIZE = "resize" + EVENT_KEY$5; + var EVENT_CLICK_DISMISS = "click.dismiss" + EVENT_KEY$5; + var EVENT_KEYDOWN_DISMISS = "keydown.dismiss" + EVENT_KEY$5; + var EVENT_MOUSEUP_DISMISS = "mouseup.dismiss" + EVENT_KEY$5; + var EVENT_MOUSEDOWN_DISMISS = "mousedown.dismiss" + EVENT_KEY$5; + var EVENT_CLICK_DATA_API$5 = "click" + EVENT_KEY$5 + DATA_API_KEY$5; + var CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'; + var CLASS_NAME_BACKDROP = 'modal-backdrop'; + var CLASS_NAME_OPEN = 'modal-open'; + var CLASS_NAME_FADE = 'fade'; + var CLASS_NAME_SHOW$2 = 'show'; + var CLASS_NAME_STATIC = 'modal-static'; + var SELECTOR_DIALOG = '.modal-dialog'; + var SELECTOR_MODAL_BODY = '.modal-body'; + var SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="modal"]'; + var SELECTOR_DATA_DISMISS = '[data-bs-dismiss="modal"]'; + var SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'; + var SELECTOR_STICKY_CONTENT = '.sticky-top'; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ - var Modal = - /*#__PURE__*/ - function () { + var Modal = /*#__PURE__*/function (_BaseComponent) { + _inheritsLoose(Modal, _BaseComponent); + function Modal(element, config) { - this._config = this._getConfig(config); - this._element = element; - this._dialog = element.querySelector(Selector$5.DIALOG); - this._backdrop = null; - this._isShown = false; - this._isBodyOverflowing = false; - this._ignoreBackdropClick = false; - this._isTransitioning = false; - this._scrollbarWidth = 0; + var _this; + + _this = _BaseComponent.call(this, element) || this; + _this._config = _this._getConfig(config); + _this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, element); + _this._backdrop = null; + _this._isShown = false; + _this._isBodyOverflowing = false; + _this._ignoreBackdropClick = false; + _this._isTransitioning = false; + _this._scrollbarWidth = 0; + return _this; } // Getters @@ -4809,22 +4306,21 @@ }; _proto.show = function show(relatedTarget) { - var _this = this; + var _this2 = this; if (this._isShown || this._isTransitioning) { return; } - if ($(this._element).hasClass(ClassName$5.FADE)) { + if (this._element.classList.contains(CLASS_NAME_FADE)) { this._isTransitioning = true; } - var showEvent = $.Event(Event$5.SHOW, { + var showEvent = EventHandler.trigger(this._element, EVENT_SHOW$2, { relatedTarget: relatedTarget }); - $(this._element).trigger(showEvent); - if (this._isShown || showEvent.isDefaultPrevented()) { + if (this._isShown || showEvent.defaultPrevented) { return; } @@ -4840,24 +4336,24 @@ this._setResizeEvent(); - $(this._element).on(Event$5.CLICK_DISMISS, Selector$5.DATA_DISMISS, function (event) { - return _this.hide(event); + EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, function (event) { + return _this2.hide(event); }); - $(this._dialog).on(Event$5.MOUSEDOWN_DISMISS, function () { - $(_this._element).one(Event$5.MOUSEUP_DISMISS, function (event) { - if ($(event.target).is(_this._element)) { - _this._ignoreBackdropClick = true; + EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, function () { + EventHandler.one(_this2._element, EVENT_MOUSEUP_DISMISS, function (event) { + if (event.target === _this2._element) { + _this2._ignoreBackdropClick = true; } }); }); this._showBackdrop(function () { - return _this._showElement(relatedTarget); + return _this2._showElement(relatedTarget); }); }; _proto.hide = function hide(event) { - var _this2 = this; + var _this3 = this; if (event) { event.preventDefault(); @@ -4867,15 +4363,15 @@ return; } - var hideEvent = $.Event(Event$5.HIDE); - $(this._element).trigger(hideEvent); + var hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$2); - if (!this._isShown || hideEvent.isDefaultPrevented()) { + if (hideEvent.defaultPrevented) { return; } this._isShown = false; - var transition = $(this._element).hasClass(ClassName$5.FADE); + + var transition = this._element.classList.contains(CLASS_NAME_FADE); if (transition) { this._isTransitioning = true; @@ -4885,16 +4381,19 @@ this._setResizeEvent(); - $(document).off(Event$5.FOCUSIN); - $(this._element).removeClass(ClassName$5.SHOW); - $(this._element).off(Event$5.CLICK_DISMISS); - $(this._dialog).off(Event$5.MOUSEDOWN_DISMISS); + EventHandler.off(document, EVENT_FOCUSIN); + + this._element.classList.remove(CLASS_NAME_SHOW$2); + + EventHandler.off(this._element, EVENT_CLICK_DISMISS); + EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS); if (transition) { - var transitionDuration = Util.getTransitionDurationFromElement(this._element); - $(this._element).one(Util.TRANSITION_END, function (event) { - return _this2._hideModal(event); - }).emulateTransitionEnd(transitionDuration); + var transitionDuration = getTransitionDurationFromElement(this._element); + EventHandler.one(this._element, TRANSITION_END, function (event) { + return _this3._hideModal(event); + }); + emulateTransitionEnd(this._element, transitionDuration); } else { this._hideModal(); } @@ -4902,18 +4401,19 @@ _proto.dispose = function dispose() { [window, this._element, this._dialog].forEach(function (htmlElement) { - return $(htmlElement).off(EVENT_KEY$5); + return EventHandler.off(htmlElement, EVENT_KEY$5); }); + + _BaseComponent.prototype.dispose.call(this); /** - * `document` has 2 events `Event.FOCUSIN` and `Event.CLICK_DATA_API` + * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API` * Do not move `document` in `htmlElements` array - * It will remove `Event.CLICK_DATA_API` event that should remain + * It will remove `EVENT_CLICK_DATA_API` event that should remain */ - $(document).off(Event$5.FOCUSIN); - $.removeData(this._element, DATA_KEY$5); + + EventHandler.off(document, EVENT_FOCUSIN); this._config = null; - this._element = null; this._dialog = null; this._backdrop = null; this._isShown = null; @@ -4929,40 +4429,17 @@ ; _proto._getConfig = function _getConfig(config) { - config = _objectSpread2({}, Default$3, {}, config); - Util.typeCheckConfig(NAME$5, config, DefaultType$3); + config = _extends({}, Default$3, config); + typeCheckConfig(NAME$5, config, DefaultType$3); return config; }; - _proto._triggerBackdropTransition = function _triggerBackdropTransition() { - var _this3 = this; - - if (this._config.backdrop === 'static') { - var hideEventPrevented = $.Event(Event$5.HIDE_PREVENTED); - $(this._element).trigger(hideEventPrevented); - - if (hideEventPrevented.defaultPrevented) { - return; - } - - this._element.classList.add(ClassName$5.STATIC); - - var modalTransitionDuration = Util.getTransitionDurationFromElement(this._element); - $(this._element).one(Util.TRANSITION_END, function () { - _this3._element.classList.remove(ClassName$5.STATIC); - }).emulateTransitionEnd(modalTransitionDuration); - - this._element.focus(); - } else { - this.hide(); - } - }; - _proto._showElement = function _showElement(relatedTarget) { var _this4 = this; - var transition = $(this._element).hasClass(ClassName$5.FADE); - var modalBody = this._dialog ? this._dialog.querySelector(Selector$5.MODAL_BODY) : null; + var transition = this._element.classList.contains(CLASS_NAME_FADE); + + var modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog); if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { // Don't move modal's DOM position @@ -4975,38 +4452,39 @@ this._element.setAttribute('aria-modal', true); - if ($(this._dialog).hasClass(ClassName$5.SCROLLABLE) && modalBody) { + this._element.setAttribute('role', 'dialog'); + + this._element.scrollTop = 0; + + if (modalBody) { modalBody.scrollTop = 0; - } else { - this._element.scrollTop = 0; } if (transition) { - Util.reflow(this._element); + reflow(this._element); } - $(this._element).addClass(ClassName$5.SHOW); + this._element.classList.add(CLASS_NAME_SHOW$2); if (this._config.focus) { this._enforceFocus(); } - var shownEvent = $.Event(Event$5.SHOWN, { - relatedTarget: relatedTarget - }); - var transitionComplete = function transitionComplete() { if (_this4._config.focus) { _this4._element.focus(); } _this4._isTransitioning = false; - $(_this4._element).trigger(shownEvent); + EventHandler.trigger(_this4._element, EVENT_SHOWN$2, { + relatedTarget: relatedTarget + }); }; if (transition) { - var transitionDuration = Util.getTransitionDurationFromElement(this._dialog); - $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration); + var transitionDuration = getTransitionDurationFromElement(this._dialog); + EventHandler.one(this._dialog, TRANSITION_END, transitionComplete); + emulateTransitionEnd(this._dialog, transitionDuration); } else { transitionComplete(); } @@ -5015,9 +4493,10 @@ _proto._enforceFocus = function _enforceFocus() { var _this5 = this; - $(document).off(Event$5.FOCUSIN) // Guard against infinite focus loop - .on(Event$5.FOCUSIN, function (event) { - if (document !== event.target && _this5._element !== event.target && $(_this5._element).has(event.target).length === 0) { + EventHandler.off(document, EVENT_FOCUSIN); // guard against infinite focus loop + + EventHandler.on(document, EVENT_FOCUSIN, function (event) { + if (document !== event.target && _this5._element !== event.target && !_this5._element.contains(event.target)) { _this5._element.focus(); } }); @@ -5026,14 +4505,18 @@ _proto._setEscapeEvent = function _setEscapeEvent() { var _this6 = this; - if (this._isShown && this._config.keyboard) { - $(this._element).on(Event$5.KEYDOWN_DISMISS, function (event) { - if (event.which === ESCAPE_KEYCODE$1) { + if (this._isShown) { + EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, function (event) { + if (_this6._config.keyboard && event.key === ESCAPE_KEY$1) { + event.preventDefault(); + + _this6.hide(); + } else if (!_this6._config.keyboard && event.key === ESCAPE_KEY$1) { _this6._triggerBackdropTransition(); } }); - } else if (!this._isShown) { - $(this._element).off(Event$5.KEYDOWN_DISMISS); + } else { + EventHandler.off(this._element, EVENT_KEYDOWN_DISMISS); } }; @@ -5041,11 +4524,11 @@ var _this7 = this; if (this._isShown) { - $(window).on(Event$5.RESIZE, function (event) { - return _this7.handleUpdate(event); + EventHandler.on(window, EVENT_RESIZE, function () { + return _this7._adjustDialog(); }); } else { - $(window).off(Event$5.RESIZE); + EventHandler.off(window, EVENT_RESIZE); } }; @@ -5058,41 +4541,42 @@ this._element.removeAttribute('aria-modal'); + this._element.removeAttribute('role'); + this._isTransitioning = false; this._showBackdrop(function () { - $(document.body).removeClass(ClassName$5.OPEN); + document.body.classList.remove(CLASS_NAME_OPEN); _this8._resetAdjustments(); _this8._resetScrollbar(); - $(_this8._element).trigger(Event$5.HIDDEN); + EventHandler.trigger(_this8._element, EVENT_HIDDEN$2); }); }; _proto._removeBackdrop = function _removeBackdrop() { - if (this._backdrop) { - $(this._backdrop).remove(); - this._backdrop = null; - } + this._backdrop.parentNode.removeChild(this._backdrop); + + this._backdrop = null; }; _proto._showBackdrop = function _showBackdrop(callback) { var _this9 = this; - var animate = $(this._element).hasClass(ClassName$5.FADE) ? ClassName$5.FADE : ''; + var animate = this._element.classList.contains(CLASS_NAME_FADE) ? CLASS_NAME_FADE : ''; if (this._isShown && this._config.backdrop) { this._backdrop = document.createElement('div'); - this._backdrop.className = ClassName$5.BACKDROP; + this._backdrop.className = CLASS_NAME_BACKDROP; if (animate) { this._backdrop.classList.add(animate); } - $(this._backdrop).appendTo(document.body); - $(this._element).on(Event$5.CLICK_DISMISS, function (event) { + document.body.appendChild(this._backdrop); + EventHandler.on(this._element, EVENT_CLICK_DISMISS, function (event) { if (_this9._ignoreBackdropClick) { _this9._ignoreBackdropClick = false; return; @@ -5102,61 +4586,94 @@ return; } - _this9._triggerBackdropTransition(); + if (_this9._config.backdrop === 'static') { + _this9._triggerBackdropTransition(); + } else { + _this9.hide(); + } }); if (animate) { - Util.reflow(this._backdrop); + reflow(this._backdrop); } - $(this._backdrop).addClass(ClassName$5.SHOW); - - if (!callback) { - return; - } + this._backdrop.classList.add(CLASS_NAME_SHOW$2); if (!animate) { callback(); return; } - var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); - $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration); + var backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop); + EventHandler.one(this._backdrop, TRANSITION_END, callback); + emulateTransitionEnd(this._backdrop, backdropTransitionDuration); } else if (!this._isShown && this._backdrop) { - $(this._backdrop).removeClass(ClassName$5.SHOW); + this._backdrop.classList.remove(CLASS_NAME_SHOW$2); var callbackRemove = function callbackRemove() { _this9._removeBackdrop(); - if (callback) { - callback(); - } + callback(); }; - if ($(this._element).hasClass(ClassName$5.FADE)) { - var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); + if (this._element.classList.contains(CLASS_NAME_FADE)) { + var _backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop); - $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration); + EventHandler.one(this._backdrop, TRANSITION_END, callbackRemove); + emulateTransitionEnd(this._backdrop, _backdropTransitionDuration); } else { callbackRemove(); } - } else if (callback) { + } else { callback(); } + }; + + _proto._triggerBackdropTransition = function _triggerBackdropTransition() { + var _this10 = this; + + var hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); + + if (hideEvent.defaultPrevented) { + return; + } + + var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; + + if (!isModalOverflowing) { + this._element.style.overflowY = 'hidden'; + } + + this._element.classList.add(CLASS_NAME_STATIC); + + var modalTransitionDuration = getTransitionDurationFromElement(this._dialog); + EventHandler.off(this._element, TRANSITION_END); + EventHandler.one(this._element, TRANSITION_END, function () { + _this10._element.classList.remove(CLASS_NAME_STATIC); + + if (!isModalOverflowing) { + EventHandler.one(_this10._element, TRANSITION_END, function () { + _this10._element.style.overflowY = ''; + }); + emulateTransitionEnd(_this10._element, modalTransitionDuration); + } + }); + emulateTransitionEnd(this._element, modalTransitionDuration); + + this._element.focus(); } // ---------------------------------------------------------------------- // the following methods are used to handle overflowing modals - // todo (fat): these should probably be refactored out of modal.js // ---------------------------------------------------------------------- ; _proto._adjustDialog = function _adjustDialog() { var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; - if (!this._isBodyOverflowing && isModalOverflowing) { + if (!this._isBodyOverflowing && isModalOverflowing && !isRTL || this._isBodyOverflowing && !isModalOverflowing && isRTL) { this._element.style.paddingLeft = this._scrollbarWidth + "px"; } - if (this._isBodyOverflowing && !isModalOverflowing) { + if (this._isBodyOverflowing && !isModalOverflowing && !isRTL || !this._isBodyOverflowing && isModalOverflowing && isRTL) { this._element.style.paddingRight = this._scrollbarWidth + "px"; } }; @@ -5168,66 +4685,74 @@ _proto._checkScrollbar = function _checkScrollbar() { var rect = document.body.getBoundingClientRect(); - this._isBodyOverflowing = rect.left + rect.right < window.innerWidth; + this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth; this._scrollbarWidth = this._getScrollbarWidth(); }; _proto._setScrollbar = function _setScrollbar() { - var _this10 = this; + var _this11 = this; if (this._isBodyOverflowing) { // Note: DOMNode.style.paddingRight returns the actual value or '' if not set // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set - var fixedContent = [].slice.call(document.querySelectorAll(Selector$5.FIXED_CONTENT)); - var stickyContent = [].slice.call(document.querySelectorAll(Selector$5.STICKY_CONTENT)); // Adjust fixed content padding - - $(fixedContent).each(function (index, element) { + // Adjust fixed content padding + SelectorEngine.find(SELECTOR_FIXED_CONTENT).forEach(function (element) { var actualPadding = element.style.paddingRight; - var calculatedPadding = $(element).css('padding-right'); - $(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this10._scrollbarWidth + "px"); + var calculatedPadding = window.getComputedStyle(element)['padding-right']; + Manipulator.setDataAttribute(element, 'padding-right', actualPadding); + element.style.paddingRight = Number.parseFloat(calculatedPadding) + _this11._scrollbarWidth + "px"; }); // Adjust sticky content margin - $(stickyContent).each(function (index, element) { + SelectorEngine.find(SELECTOR_STICKY_CONTENT).forEach(function (element) { var actualMargin = element.style.marginRight; - var calculatedMargin = $(element).css('margin-right'); - $(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this10._scrollbarWidth + "px"); + var calculatedMargin = window.getComputedStyle(element)['margin-right']; + Manipulator.setDataAttribute(element, 'margin-right', actualMargin); + element.style.marginRight = Number.parseFloat(calculatedMargin) - _this11._scrollbarWidth + "px"; }); // Adjust body padding var actualPadding = document.body.style.paddingRight; - var calculatedPadding = $(document.body).css('padding-right'); - $(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px"); + var calculatedPadding = window.getComputedStyle(document.body)['padding-right']; + Manipulator.setDataAttribute(document.body, 'padding-right', actualPadding); + document.body.style.paddingRight = Number.parseFloat(calculatedPadding) + this._scrollbarWidth + "px"; } - $(document.body).addClass(ClassName$5.OPEN); + document.body.classList.add(CLASS_NAME_OPEN); }; _proto._resetScrollbar = function _resetScrollbar() { // Restore fixed content padding - var fixedContent = [].slice.call(document.querySelectorAll(Selector$5.FIXED_CONTENT)); - $(fixedContent).each(function (index, element) { - var padding = $(element).data('padding-right'); - $(element).removeData('padding-right'); - element.style.paddingRight = padding ? padding : ''; - }); // Restore sticky content + SelectorEngine.find(SELECTOR_FIXED_CONTENT).forEach(function (element) { + var padding = Manipulator.getDataAttribute(element, 'padding-right'); - var elements = [].slice.call(document.querySelectorAll("" + Selector$5.STICKY_CONTENT)); - $(elements).each(function (index, element) { - var margin = $(element).data('margin-right'); + if (typeof padding !== 'undefined') { + Manipulator.removeDataAttribute(element, 'padding-right'); + element.style.paddingRight = padding; + } + }); // Restore sticky content and navbar-toggler margin + + SelectorEngine.find("" + SELECTOR_STICKY_CONTENT).forEach(function (element) { + var margin = Manipulator.getDataAttribute(element, 'margin-right'); if (typeof margin !== 'undefined') { - $(element).css('margin-right', margin).removeData('margin-right'); + Manipulator.removeDataAttribute(element, 'margin-right'); + element.style.marginRight = margin; } }); // Restore body padding - var padding = $(document.body).data('padding-right'); - $(document.body).removeData('padding-right'); - document.body.style.paddingRight = padding ? padding : ''; + var padding = Manipulator.getDataAttribute(document.body, 'padding-right'); + + if (typeof padding === 'undefined') { + document.body.style.paddingRight = ''; + } else { + Manipulator.removeDataAttribute(document.body, 'padding-right'); + document.body.style.paddingRight = padding; + } }; _proto._getScrollbarWidth = function _getScrollbarWidth() { // thx d.walsh var scrollDiv = document.createElement('div'); - scrollDiv.className = ClassName$5.SCROLLBAR_MEASURER; + scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER; document.body.appendChild(scrollDiv); var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth; document.body.removeChild(scrollDiv); @@ -5235,15 +4760,14 @@ } // Static ; - Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) { + Modal.jQueryInterface = function jQueryInterface(config, relatedTarget) { return this.each(function () { - var data = $(this).data(DATA_KEY$5); + var data = Data.getData(this, DATA_KEY$5); - var _config = _objectSpread2({}, Default$3, {}, $(this).data(), {}, typeof config === 'object' && config ? config : {}); + var _config = _extends({}, Default$3, Manipulator.getDataAttributes(this), typeof config === 'object' && config ? config : {}); if (!data) { data = new Modal(this, _config); - $(this).data(DATA_KEY$5, data); } if (typeof config === 'string') { @@ -5252,26 +4776,24 @@ } data[config](relatedTarget); - } else if (_config.show) { - data.show(relatedTarget); } }); }; _createClass(Modal, null, [{ - key: "VERSION", - get: function get() { - return VERSION$5; - } - }, { key: "Default", get: function get() { return Default$3; } + }, { + key: "DATA_KEY", + get: function get() { + return DATA_KEY$5; + } }]); return Modal; - }(); + }(BaseComponent); /** * ------------------------------------------------------------------------ * Data Api implementation @@ -5279,60 +4801,108 @@ */ - $(document).on(Event$5.CLICK_DATA_API, Selector$5.DATA_TOGGLE, function (event) { - var _this11 = this; + EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_TOGGLE$3, function (event) { + var _this12 = this; - var target; - var selector = Util.getSelectorFromElement(this); - - if (selector) { - target = document.querySelector(selector); - } - - var config = $(target).data(DATA_KEY$5) ? 'toggle' : _objectSpread2({}, $(target).data(), {}, $(this).data()); + var target = getElementFromSelector(this); if (this.tagName === 'A' || this.tagName === 'AREA') { event.preventDefault(); } - var $target = $(target).one(Event$5.SHOW, function (showEvent) { - if (showEvent.isDefaultPrevented()) { - // Only register focus restorer if modal will actually get shown + EventHandler.one(target, EVENT_SHOW$2, function (showEvent) { + if (showEvent.defaultPrevented) { + // only register focus restorer if modal will actually get shown return; } - $target.one(Event$5.HIDDEN, function () { - if ($(_this11).is(':visible')) { - _this11.focus(); + EventHandler.one(target, EVENT_HIDDEN$2, function () { + if (isVisible(_this12)) { + _this12.focus(); } }); }); + var data = Data.getData(target, DATA_KEY$5); - Modal._jQueryInterface.call($(target), config, this); + if (!data) { + var config = _extends({}, Manipulator.getDataAttributes(target), Manipulator.getDataAttributes(this)); + + data = new Modal(target, config); + } + + data.show(this); }); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ + * add .Modal to jQuery only if jQuery is present */ - $.fn[NAME$5] = Modal._jQueryInterface; - $.fn[NAME$5].Constructor = Modal; + onDOMContentLoaded(function () { + var $ = getjQuery(); + /* istanbul ignore if */ - $.fn[NAME$5].noConflict = function () { - $.fn[NAME$5] = JQUERY_NO_CONFLICT$5; - return Modal._jQueryInterface; - }; + if ($) { + var JQUERY_NO_CONFLICT = $.fn[NAME$5]; + $.fn[NAME$5] = Modal.jQueryInterface; + $.fn[NAME$5].Constructor = Modal; + + $.fn[NAME$5].noConflict = function () { + $.fn[NAME$5] = JQUERY_NO_CONFLICT; + return Modal.jQueryInterface; + }; + } + }); /** * -------------------------------------------------------------------------- - * Bootstrap (v4.4.1): tools/sanitizer.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Bootstrap (v5.0.0-beta1): util/sanitizer.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ - var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']; + var uriAttrs = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']); var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; - var DefaultWhitelist = { + /** + * A pattern that recognizes a commonly useful subset of URLs that are safe. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + + var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi; + /** + * A pattern that matches safe data URLs. Only matches image, video and audio types. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + + var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i; + + var allowedAttribute = function allowedAttribute(attr, allowedAttributeList) { + var attrName = attr.nodeName.toLowerCase(); + + if (allowedAttributeList.includes(attrName)) { + if (uriAttrs.has(attrName)) { + return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); + } + + return true; + } + + var regExp = allowedAttributeList.filter(function (attrRegex) { + return attrRegex instanceof RegExp; + }); // Check if a regular expression validates the attribute. + + for (var i = 0, len = regExp.length; i < len; i++) { + if (attrName.match(regExp[i])) { + return true; + } + } + + return false; + }; + + var DefaultAllowlist = { // Global attributes allowed on any supplied element below. '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], a: ['target', 'href', 'title', 'rel'], @@ -5351,7 +4921,7 @@ h5: [], h6: [], i: [], - img: ['src', 'alt', 'title', 'width', 'height'], + img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], li: [], ol: [], p: [], @@ -5365,47 +4935,10 @@ u: [], ul: [] }; - /** - * A pattern that recognizes a commonly useful subset of URLs that are safe. - * - * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts - */ + function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) { + var _ref; - var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi; - /** - * A pattern that matches safe data URLs. Only matches image, video and audio types. - * - * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts - */ - - var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i; - - function allowedAttribute(attr, allowedAttributeList) { - var attrName = attr.nodeName.toLowerCase(); - - if (allowedAttributeList.indexOf(attrName) !== -1) { - if (uriAttrs.indexOf(attrName) !== -1) { - return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); - } - - return true; - } - - var regExp = allowedAttributeList.filter(function (attrRegex) { - return attrRegex instanceof RegExp; - }); // Check if a regular expression validates the attribute. - - for (var i = 0, l = regExp.length; i < l; i++) { - if (attrName.match(regExp[i])) { - return true; - } - } - - return false; - } - - function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { - if (unsafeHtml.length === 0) { + if (!unsafeHtml.length) { return unsafeHtml; } @@ -5415,22 +4948,26 @@ var domParser = new window.DOMParser(); var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); - var whitelistKeys = Object.keys(whiteList); - var elements = [].slice.call(createdDocument.body.querySelectorAll('*')); + var allowlistKeys = Object.keys(allowList); + + var elements = (_ref = []).concat.apply(_ref, createdDocument.body.querySelectorAll('*')); var _loop = function _loop(i, len) { + var _ref2; + var el = elements[i]; var elName = el.nodeName.toLowerCase(); - if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) { + if (!allowlistKeys.includes(elName)) { el.parentNode.removeChild(el); return "continue"; } - var attributeList = [].slice.call(el.attributes); - var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); + var attributeList = (_ref2 = []).concat.apply(_ref2, el.attributes); + + var allowedAttributes = [].concat(allowList['*'] || [], allowList[elName] || []); attributeList.forEach(function (attr) { - if (!allowedAttribute(attr, whitelistedAttributes)) { + if (!allowedAttribute(attr, allowedAttributes)) { el.removeAttribute(attr.nodeName); } }); @@ -5452,13 +4989,11 @@ */ var NAME$6 = 'tooltip'; - var VERSION$6 = '4.4.1'; var DATA_KEY$6 = 'bs.tooltip'; var EVENT_KEY$6 = "." + DATA_KEY$6; - var JQUERY_NO_CONFLICT$6 = $.fn[NAME$6]; var CLASS_PREFIX = 'bs-tooltip'; var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); - var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; + var DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']); var DefaultType$4 = { animation: 'boolean', template: 'string', @@ -5468,45 +5003,41 @@ html: 'boolean', selector: '(string|boolean)', placement: '(string|function)', - offset: '(number|string|function)', container: '(string|element|boolean)', - fallbackPlacement: '(string|array)', + fallbackPlacements: '(null|array)', boundary: '(string|element)', + customClass: '(string|function)', sanitize: 'boolean', sanitizeFn: '(null|function)', - whiteList: 'object', + allowList: 'object', popperConfig: '(null|object)' }; - var AttachmentMap$1 = { + var AttachmentMap = { AUTO: 'auto', TOP: 'top', - RIGHT: 'right', + RIGHT: isRTL ? 'left' : 'right', BOTTOM: 'bottom', - LEFT: 'left' + LEFT: isRTL ? 'right' : 'left' }; var Default$4 = { animation: true, - template: '', + template: '', trigger: 'hover focus', title: '', delay: 0, html: false, selector: false, placement: 'top', - offset: 0, container: false, - fallbackPlacement: 'flip', - boundary: 'scrollParent', + fallbackPlacements: null, + boundary: 'clippingParents', + customClass: '', sanitize: true, sanitizeFn: null, - whiteList: DefaultWhitelist, + allowList: DefaultAllowlist, popperConfig: null }; - var HoverState = { - SHOW: 'show', - OUT: 'out' - }; - var Event$6 = { + var Event$1 = { HIDE: "hide" + EVENT_KEY$6, HIDDEN: "hidden" + EVENT_KEY$6, SHOW: "show" + EVENT_KEY$6, @@ -5518,47 +5049,46 @@ MOUSEENTER: "mouseenter" + EVENT_KEY$6, MOUSELEAVE: "mouseleave" + EVENT_KEY$6 }; - var ClassName$6 = { - FADE: 'fade', - SHOW: 'show' - }; - var Selector$6 = { - TOOLTIP: '.tooltip', - TOOLTIP_INNER: '.tooltip-inner', - ARROW: '.arrow' - }; - var Trigger = { - HOVER: 'hover', - FOCUS: 'focus', - CLICK: 'click', - MANUAL: 'manual' - }; + var CLASS_NAME_FADE$1 = 'fade'; + var CLASS_NAME_MODAL = 'modal'; + var CLASS_NAME_SHOW$3 = 'show'; + var HOVER_STATE_SHOW = 'show'; + var HOVER_STATE_OUT = 'out'; + var SELECTOR_TOOLTIP_INNER = '.tooltip-inner'; + var TRIGGER_HOVER = 'hover'; + var TRIGGER_FOCUS = 'focus'; + var TRIGGER_CLICK = 'click'; + var TRIGGER_MANUAL = 'manual'; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ - var Tooltip = - /*#__PURE__*/ - function () { + var Tooltip = /*#__PURE__*/function (_BaseComponent) { + _inheritsLoose(Tooltip, _BaseComponent); + function Tooltip(element, config) { + var _this; + if (typeof Popper === 'undefined') { - throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)'); - } // private + throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)'); + } + _this = _BaseComponent.call(this, element) || this; // private - this._isEnabled = true; - this._timeout = 0; - this._hoverState = ''; - this._activeTrigger = {}; - this._popper = null; // Protected + _this._isEnabled = true; + _this._timeout = 0; + _this._hoverState = ''; + _this._activeTrigger = {}; + _this._popper = null; // Protected - this.element = element; - this.config = this._getConfig(config); - this.tip = null; + _this.config = _this._getConfig(config); + _this.tip = null; - this._setListeners(); + _this._setListeners(); + + return _this; } // Getters @@ -5584,11 +5114,11 @@ if (event) { var dataKey = this.constructor.DATA_KEY; - var context = $(event.currentTarget).data(dataKey); + var context = Data.getData(event.delegateTarget, dataKey); if (!context) { - context = new this.constructor(event.currentTarget, this._getDelegateConfig()); - $(event.currentTarget).data(dataKey, context); + context = new this.constructor(event.delegateTarget, this._getDelegateConfig()); + Data.setData(event.delegateTarget, dataKey, context); } context._activeTrigger.click = !context._activeTrigger.click; @@ -5599,7 +5129,7 @@ context._leave(null, context); } } else { - if ($(this.getTipElement()).hasClass(ClassName$6.SHOW)) { + if (this.getTipElement().classList.contains(CLASS_NAME_SHOW$3)) { this._leave(null, this); return; @@ -5611,12 +5141,11 @@ _proto.dispose = function dispose() { clearTimeout(this._timeout); - $.removeData(this.element, this.constructor.DATA_KEY); - $(this.element).off(this.constructor.EVENT_KEY); - $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler); + EventHandler.off(this._element, this.constructor.EVENT_KEY); + EventHandler.off(this._element.closest("." + CLASS_NAME_MODAL), 'hide.bs.modal', this._hideModalHandler); if (this.tip) { - $(this.tip).remove(); + this.tip.parentNode.removeChild(this.tip); } this._isEnabled = null; @@ -5629,133 +5158,149 @@ } this._popper = null; - this.element = null; this.config = null; this.tip = null; + + _BaseComponent.prototype.dispose.call(this); }; _proto.show = function show() { - var _this = this; + var _this2 = this; - if ($(this.element).css('display') === 'none') { + if (this._element.style.display === 'none') { throw new Error('Please use show on visible elements'); } - var showEvent = $.Event(this.constructor.Event.SHOW); - if (this.isWithContent() && this._isEnabled) { - $(this.element).trigger(showEvent); - var shadowRoot = Util.findShadowRoot(this.element); - var isInTheDom = $.contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element); + var showEvent = EventHandler.trigger(this._element, this.constructor.Event.SHOW); + var shadowRoot = findShadowRoot(this._element); + var isInTheDom = shadowRoot === null ? this._element.ownerDocument.documentElement.contains(this._element) : shadowRoot.contains(this._element); - if (showEvent.isDefaultPrevented() || !isInTheDom) { + if (showEvent.defaultPrevented || !isInTheDom) { return; } var tip = this.getTipElement(); - var tipId = Util.getUID(this.constructor.NAME); + var tipId = getUID(this.constructor.NAME); tip.setAttribute('id', tipId); - this.element.setAttribute('aria-describedby', tipId); + + this._element.setAttribute('aria-describedby', tipId); + this.setContent(); if (this.config.animation) { - $(tip).addClass(ClassName$6.FADE); + tip.classList.add(CLASS_NAME_FADE$1); } - var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; + var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this._element) : this.config.placement; var attachment = this._getAttachment(placement); - this.addAttachmentClass(attachment); + this._addAttachmentClass(attachment); var container = this._getContainer(); - $(tip).data(this.constructor.DATA_KEY, this); + Data.setData(tip, this.constructor.DATA_KEY, this); - if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) { - $(tip).appendTo(container); + if (!this._element.ownerDocument.documentElement.contains(this.tip)) { + container.appendChild(tip); } - $(this.element).trigger(this.constructor.Event.INSERTED); - this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment)); - $(tip).addClass(ClassName$6.SHOW); // If this is a touch-enabled device we add extra + EventHandler.trigger(this._element, this.constructor.Event.INSERTED); + this._popper = createPopper$2(this._element, tip, this._getPopperConfig(attachment)); + tip.classList.add(CLASS_NAME_SHOW$3); + var customClass = typeof this.config.customClass === 'function' ? this.config.customClass() : this.config.customClass; + + if (customClass) { + var _tip$classList; + + (_tip$classList = tip.classList).add.apply(_tip$classList, customClass.split(' ')); + } // If this is a touch-enabled device we add extra // empty mouseover listeners to the body's immediate children; // only needed because of broken event delegation on iOS // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html + if ('ontouchstart' in document.documentElement) { - $(document.body).children().on('mouseover', null, $.noop); + var _ref; + + (_ref = []).concat.apply(_ref, document.body.children).forEach(function (element) { + EventHandler.on(element, 'mouseover', noop()); + }); } var complete = function complete() { - if (_this.config.animation) { - _this._fixTransition(); - } + var prevHoverState = _this2._hoverState; + _this2._hoverState = null; + EventHandler.trigger(_this2._element, _this2.constructor.Event.SHOWN); - var prevHoverState = _this._hoverState; - _this._hoverState = null; - $(_this.element).trigger(_this.constructor.Event.SHOWN); - - if (prevHoverState === HoverState.OUT) { - _this._leave(null, _this); + if (prevHoverState === HOVER_STATE_OUT) { + _this2._leave(null, _this2); } }; - if ($(this.tip).hasClass(ClassName$6.FADE)) { - var transitionDuration = Util.getTransitionDurationFromElement(this.tip); - $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); + if (this.tip.classList.contains(CLASS_NAME_FADE$1)) { + var transitionDuration = getTransitionDurationFromElement(this.tip); + EventHandler.one(this.tip, TRANSITION_END, complete); + emulateTransitionEnd(this.tip, transitionDuration); } else { complete(); } } }; - _proto.hide = function hide(callback) { - var _this2 = this; + _proto.hide = function hide() { + var _this3 = this; - var tip = this.getTipElement(); - var hideEvent = $.Event(this.constructor.Event.HIDE); - - var complete = function complete() { - if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) { - tip.parentNode.removeChild(tip); - } - - _this2._cleanTipClass(); - - _this2.element.removeAttribute('aria-describedby'); - - $(_this2.element).trigger(_this2.constructor.Event.HIDDEN); - - if (_this2._popper !== null) { - _this2._popper.destroy(); - } - - if (callback) { - callback(); - } - }; - - $(this.element).trigger(hideEvent); - - if (hideEvent.isDefaultPrevented()) { + if (!this._popper) { return; } - $(tip).removeClass(ClassName$6.SHOW); // If this is a touch-enabled device we remove the extra + var tip = this.getTipElement(); + + var complete = function complete() { + if (_this3._hoverState !== HOVER_STATE_SHOW && tip.parentNode) { + tip.parentNode.removeChild(tip); + } + + _this3._cleanTipClass(); + + _this3._element.removeAttribute('aria-describedby'); + + EventHandler.trigger(_this3._element, _this3.constructor.Event.HIDDEN); + + if (_this3._popper) { + _this3._popper.destroy(); + + _this3._popper = null; + } + }; + + var hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE); + + if (hideEvent.defaultPrevented) { + return; + } + + tip.classList.remove(CLASS_NAME_SHOW$3); // If this is a touch-enabled device we remove the extra // empty mouseover listeners we added for iOS support if ('ontouchstart' in document.documentElement) { - $(document.body).children().off('mouseover', null, $.noop); + var _ref2; + + (_ref2 = []).concat.apply(_ref2, document.body.children).forEach(function (element) { + return EventHandler.off(element, 'mouseover', noop); + }); } - this._activeTrigger[Trigger.CLICK] = false; - this._activeTrigger[Trigger.FOCUS] = false; - this._activeTrigger[Trigger.HOVER] = false; + this._activeTrigger[TRIGGER_CLICK] = false; + this._activeTrigger[TRIGGER_FOCUS] = false; + this._activeTrigger[TRIGGER_HOVER] = false; - if ($(this.tip).hasClass(ClassName$6.FADE)) { - var transitionDuration = Util.getTransitionDurationFromElement(tip); - $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); + if (this.tip.classList.contains(CLASS_NAME_FADE$1)) { + var transitionDuration = getTransitionDurationFromElement(tip); + EventHandler.one(tip, TRANSITION_END, complete); + emulateTransitionEnd(tip, transitionDuration); } else { complete(); } @@ -5765,7 +5310,7 @@ _proto.update = function update() { if (this._popper !== null) { - this._popper.scheduleUpdate(); + this._popper.update(); } } // Protected ; @@ -5774,30 +5319,41 @@ return Boolean(this.getTitle()); }; - _proto.addAttachmentClass = function addAttachmentClass(attachment) { - $(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); - }; - _proto.getTipElement = function getTipElement() { - this.tip = this.tip || $(this.config.template)[0]; + if (this.tip) { + return this.tip; + } + + var element = document.createElement('div'); + element.innerHTML = this.config.template; + this.tip = element.children[0]; return this.tip; }; _proto.setContent = function setContent() { var tip = this.getTipElement(); - this.setElementContent($(tip.querySelectorAll(Selector$6.TOOLTIP_INNER)), this.getTitle()); - $(tip).removeClass(ClassName$6.FADE + " " + ClassName$6.SHOW); + this.setElementContent(SelectorEngine.findOne(SELECTOR_TOOLTIP_INNER, tip), this.getTitle()); + tip.classList.remove(CLASS_NAME_FADE$1, CLASS_NAME_SHOW$3); }; - _proto.setElementContent = function setElementContent($element, content) { - if (typeof content === 'object' && (content.nodeType || content.jquery)) { - // Content is a DOM node or a jQuery + _proto.setElementContent = function setElementContent(element, content) { + if (element === null) { + return; + } + + if (typeof content === 'object' && isElement(content)) { + if (content.jquery) { + content = content[0]; + } // content is a DOM node or a jQuery + + if (this.config.html) { - if (!$(content).parent().is($element)) { - $element.empty().append(content); + if (content.parentNode !== element) { + element.innerHTML = ''; + element.appendChild(content); } } else { - $element.text($(content).text()); + element.textContent = content.textContent; } return; @@ -5805,70 +5361,83 @@ if (this.config.html) { if (this.config.sanitize) { - content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn); + content = sanitizeHtml(content, this.config.allowList, this.config.sanitizeFn); } - $element.html(content); + element.innerHTML = content; } else { - $element.text(content); + element.textContent = content; } }; _proto.getTitle = function getTitle() { - var title = this.element.getAttribute('data-original-title'); + var title = this._element.getAttribute('data-bs-original-title'); if (!title) { - title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title; + title = typeof this.config.title === 'function' ? this.config.title.call(this._element) : this.config.title; } return title; + }; + + _proto.updateAttachment = function updateAttachment(attachment) { + if (attachment === 'right') { + return 'end'; + } + + if (attachment === 'left') { + return 'start'; + } + + return attachment; } // Private ; _proto._getPopperConfig = function _getPopperConfig(attachment) { - var _this3 = this; + var _this4 = this; + + var flipModifier = { + name: 'flip', + options: { + altBoundary: true + } + }; + + if (this.config.fallbackPlacements) { + flipModifier.options.fallbackPlacements = this.config.fallbackPlacements; + } var defaultBsConfig = { placement: attachment, - modifiers: { - offset: this._getOffset(), - flip: { - behavior: this.config.fallbackPlacement - }, - arrow: { - element: Selector$6.ARROW - }, - preventOverflow: { - boundariesElement: this.config.boundary + modifiers: [flipModifier, { + name: 'preventOverflow', + options: { + rootBoundary: this.config.boundary } - }, - onCreate: function onCreate(data) { - if (data.originalPlacement !== data.placement) { - _this3._handlePopperPlacementChange(data); + }, { + name: 'arrow', + options: { + element: "." + this.constructor.NAME + "-arrow" + } + }, { + name: 'onChange', + enabled: true, + phase: 'afterWrite', + fn: function fn(data) { + return _this4._handlePopperPlacementChange(data); + } + }], + onFirstUpdate: function onFirstUpdate(data) { + if (data.options.placement !== data.placement) { + _this4._handlePopperPlacementChange(data); } - }, - onUpdate: function onUpdate(data) { - return _this3._handlePopperPlacementChange(data); } }; - return _objectSpread2({}, defaultBsConfig, {}, this.config.popperConfig); + return _extends({}, defaultBsConfig, this.config.popperConfig); }; - _proto._getOffset = function _getOffset() { - var _this4 = this; - - var offset = {}; - - if (typeof this.config.offset === 'function') { - offset.fn = function (data) { - data.offsets = _objectSpread2({}, data.offsets, {}, _this4.config.offset(data.offsets, _this4.element) || {}); - return data; - }; - } else { - offset.offset = this.config.offset; - } - - return offset; + _proto._addAttachmentClass = function _addAttachmentClass(attachment) { + this.getTipElement().classList.add(CLASS_PREFIX + "-" + this.updateAttachment(attachment)); }; _proto._getContainer = function _getContainer() { @@ -5876,15 +5445,15 @@ return document.body; } - if (Util.isElement(this.config.container)) { - return $(this.config.container); + if (isElement(this.config.container)) { + return this.config.container; } - return $(document).find(this.config.container); + return SelectorEngine.findOne(this.config.container); }; _proto._getAttachment = function _getAttachment(placement) { - return AttachmentMap$1[placement.toUpperCase()]; + return AttachmentMap[placement.toUpperCase()]; }; _proto._setListeners = function _setListeners() { @@ -5893,30 +5462,31 @@ var triggers = this.config.trigger.split(' '); triggers.forEach(function (trigger) { if (trigger === 'click') { - $(_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) { + EventHandler.on(_this5._element, _this5.constructor.Event.CLICK, _this5.config.selector, function (event) { return _this5.toggle(event); }); - } else if (trigger !== Trigger.MANUAL) { - var eventIn = trigger === Trigger.HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN; - var eventOut = trigger === Trigger.HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT; - $(_this5.element).on(eventIn, _this5.config.selector, function (event) { + } else if (trigger !== TRIGGER_MANUAL) { + var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN; + var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT; + EventHandler.on(_this5._element, eventIn, _this5.config.selector, function (event) { return _this5._enter(event); - }).on(eventOut, _this5.config.selector, function (event) { + }); + EventHandler.on(_this5._element, eventOut, _this5.config.selector, function (event) { return _this5._leave(event); }); } }); this._hideModalHandler = function () { - if (_this5.element) { + if (_this5._element) { _this5.hide(); } }; - $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler); + EventHandler.on(this._element.closest("." + CLASS_NAME_MODAL), 'hide.bs.modal', this._hideModalHandler); if (this.config.selector) { - this.config = _objectSpread2({}, this.config, { + this.config = _extends({}, this.config, { trigger: 'manual', selector: '' }); @@ -5926,34 +5496,41 @@ }; _proto._fixTitle = function _fixTitle() { - var titleType = typeof this.element.getAttribute('data-original-title'); + var title = this._element.getAttribute('title'); - if (this.element.getAttribute('title') || titleType !== 'string') { - this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''); - this.element.setAttribute('title', ''); + var originalTitleType = typeof this._element.getAttribute('data-bs-original-title'); + + if (title || originalTitleType !== 'string') { + this._element.setAttribute('data-bs-original-title', title || ''); + + if (title && !this._element.getAttribute('aria-label') && !this._element.textContent) { + this._element.setAttribute('aria-label', title); + } + + this._element.setAttribute('title', ''); } }; _proto._enter = function _enter(event, context) { var dataKey = this.constructor.DATA_KEY; - context = context || $(event.currentTarget).data(dataKey); + context = context || Data.getData(event.delegateTarget, dataKey); if (!context) { - context = new this.constructor(event.currentTarget, this._getDelegateConfig()); - $(event.currentTarget).data(dataKey, context); + context = new this.constructor(event.delegateTarget, this._getDelegateConfig()); + Data.setData(event.delegateTarget, dataKey, context); } if (event) { - context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true; + context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; } - if ($(context.getTipElement()).hasClass(ClassName$6.SHOW) || context._hoverState === HoverState.SHOW) { - context._hoverState = HoverState.SHOW; + if (context.getTipElement().classList.contains(CLASS_NAME_SHOW$3) || context._hoverState === HOVER_STATE_SHOW) { + context._hoverState = HOVER_STATE_SHOW; return; } clearTimeout(context._timeout); - context._hoverState = HoverState.SHOW; + context._hoverState = HOVER_STATE_SHOW; if (!context.config.delay || !context.config.delay.show) { context.show(); @@ -5961,7 +5538,7 @@ } context._timeout = setTimeout(function () { - if (context._hoverState === HoverState.SHOW) { + if (context._hoverState === HOVER_STATE_SHOW) { context.show(); } }, context.config.delay.show); @@ -5969,15 +5546,15 @@ _proto._leave = function _leave(event, context) { var dataKey = this.constructor.DATA_KEY; - context = context || $(event.currentTarget).data(dataKey); + context = context || Data.getData(event.delegateTarget, dataKey); if (!context) { - context = new this.constructor(event.currentTarget, this._getDelegateConfig()); - $(event.currentTarget).data(dataKey, context); + context = new this.constructor(event.delegateTarget, this._getDelegateConfig()); + Data.setData(event.delegateTarget, dataKey, context); } if (event) { - context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false; + context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false; } if (context._isWithActiveTrigger()) { @@ -5985,7 +5562,7 @@ } clearTimeout(context._timeout); - context._hoverState = HoverState.OUT; + context._hoverState = HOVER_STATE_OUT; if (!context.config.delay || !context.config.delay.hide) { context.hide(); @@ -5993,7 +5570,7 @@ } context._timeout = setTimeout(function () { - if (context._hoverState === HoverState.OUT) { + if (context._hoverState === HOVER_STATE_OUT) { context.hide(); } }, context.config.delay.hide); @@ -6010,13 +5587,18 @@ }; _proto._getConfig = function _getConfig(config) { - var dataAttributes = $(this.element).data(); + var dataAttributes = Manipulator.getDataAttributes(this._element); Object.keys(dataAttributes).forEach(function (dataAttr) { - if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { + if (DISALLOWED_ATTRIBUTES.has(dataAttr)) { delete dataAttributes[dataAttr]; } }); - config = _objectSpread2({}, this.constructor.Default, {}, dataAttributes, {}, typeof config === 'object' && config ? config : {}); + + if (config && typeof config.container === 'object' && config.container.jquery) { + config.container = config.container[0]; + } + + config = _extends({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {}); if (typeof config.delay === 'number') { config.delay = { @@ -6033,10 +5615,10 @@ config.content = config.content.toString(); } - Util.typeCheckConfig(NAME$6, config, this.constructor.DefaultType); + typeCheckConfig(NAME$6, config, this.constructor.DefaultType); if (config.sanitize) { - config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn); + config.template = sanitizeHtml(config.template, config.allowList, config.sanitizeFn); } return config; @@ -6057,42 +5639,36 @@ }; _proto._cleanTipClass = function _cleanTipClass() { - var $tip = $(this.getTipElement()); - var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); + var tip = this.getTipElement(); + var tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX); - if (tabClass !== null && tabClass.length) { - $tip.removeClass(tabClass.join('')); + if (tabClass !== null && tabClass.length > 0) { + tabClass.map(function (token) { + return token.trim(); + }).forEach(function (tClass) { + return tip.classList.remove(tClass); + }); } }; _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) { - var popperInstance = popperData.instance; - this.tip = popperInstance.popper; + var state = popperData.state; - this._cleanTipClass(); - - this.addAttachmentClass(this._getAttachment(popperData.placement)); - }; - - _proto._fixTransition = function _fixTransition() { - var tip = this.getTipElement(); - var initConfigAnimation = this.config.animation; - - if (tip.getAttribute('x-placement') !== null) { + if (!state) { return; } - $(tip).removeClass(ClassName$6.FADE); - this.config.animation = false; - this.hide(); - this.show(); - this.config.animation = initConfigAnimation; + this.tip = state.elements.popper; + + this._cleanTipClass(); + + this._addAttachmentClass(this._getAttachment(state.placement)); } // Static ; - Tooltip._jQueryInterface = function _jQueryInterface(config) { + Tooltip.jQueryInterface = function jQueryInterface(config) { return this.each(function () { - var data = $(this).data(DATA_KEY$6); + var data = Data.getData(this, DATA_KEY$6); var _config = typeof config === 'object' && config; @@ -6102,7 +5678,6 @@ if (!data) { data = new Tooltip(this, _config); - $(this).data(DATA_KEY$6, data); } if (typeof config === 'string') { @@ -6116,11 +5691,6 @@ }; _createClass(Tooltip, null, [{ - key: "VERSION", - get: function get() { - return VERSION$6; - } - }, { key: "Default", get: function get() { return Default$4; @@ -6138,7 +5708,7 @@ }, { key: "Event", get: function get() { - return Event$6; + return Event$1; } }, { key: "EVENT_KEY", @@ -6153,21 +5723,30 @@ }]); return Tooltip; - }(); + }(BaseComponent); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ + * add .Tooltip to jQuery only if jQuery is present */ - $.fn[NAME$6] = Tooltip._jQueryInterface; - $.fn[NAME$6].Constructor = Tooltip; + onDOMContentLoaded(function () { + var $ = getjQuery(); + /* istanbul ignore if */ - $.fn[NAME$6].noConflict = function () { - $.fn[NAME$6] = JQUERY_NO_CONFLICT$6; - return Tooltip._jQueryInterface; - }; + if ($) { + var JQUERY_NO_CONFLICT = $.fn[NAME$6]; + $.fn[NAME$6] = Tooltip.jQueryInterface; + $.fn[NAME$6].Constructor = Tooltip; + + $.fn[NAME$6].noConflict = function () { + $.fn[NAME$6] = JQUERY_NO_CONFLICT; + return Tooltip.jQueryInterface; + }; + } + }); /** * ------------------------------------------------------------------------ @@ -6176,33 +5755,23 @@ */ var NAME$7 = 'popover'; - var VERSION$7 = '4.4.1'; var DATA_KEY$7 = 'bs.popover'; var EVENT_KEY$7 = "." + DATA_KEY$7; - var JQUERY_NO_CONFLICT$7 = $.fn[NAME$7]; var CLASS_PREFIX$1 = 'bs-popover'; var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g'); - var Default$5 = _objectSpread2({}, Tooltip.Default, { + var Default$5 = _extends({}, Tooltip.Default, { placement: 'right', trigger: 'click', content: '', - template: '' + template: '' }); - var DefaultType$5 = _objectSpread2({}, Tooltip.DefaultType, { + var DefaultType$5 = _extends({}, Tooltip.DefaultType, { content: '(string|element|function)' }); - var ClassName$7 = { - FADE: 'fade', - SHOW: 'show' - }; - var Selector$7 = { - TITLE: '.popover-header', - CONTENT: '.popover-body' - }; - var Event$7 = { + var Event$2 = { HIDE: "hide" + EVENT_KEY$7, HIDDEN: "hidden" + EVENT_KEY$7, SHOW: "show" + EVENT_KEY$7, @@ -6214,15 +5783,17 @@ MOUSEENTER: "mouseenter" + EVENT_KEY$7, MOUSELEAVE: "mouseleave" + EVENT_KEY$7 }; + var CLASS_NAME_FADE$2 = 'fade'; + var CLASS_NAME_SHOW$4 = 'show'; + var SELECTOR_TITLE = '.popover-header'; + var SELECTOR_CONTENT = '.popover-body'; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ - var Popover = - /*#__PURE__*/ - function (_Tooltip) { + var Popover = /*#__PURE__*/function (_Tooltip) { _inheritsLoose(Popover, _Tooltip); function Popover() { @@ -6236,48 +5807,47 @@ return this.getTitle() || this._getContent(); }; - _proto.addAttachmentClass = function addAttachmentClass(attachment) { - $(this.getTipElement()).addClass(CLASS_PREFIX$1 + "-" + attachment); - }; - - _proto.getTipElement = function getTipElement() { - this.tip = this.tip || $(this.config.template)[0]; - return this.tip; - }; - _proto.setContent = function setContent() { - var $tip = $(this.getTipElement()); // We use append for html objects to maintain js events + var tip = this.getTipElement(); // we use append for html objects to maintain js events - this.setElementContent($tip.find(Selector$7.TITLE), this.getTitle()); + this.setElementContent(SelectorEngine.findOne(SELECTOR_TITLE, tip), this.getTitle()); var content = this._getContent(); if (typeof content === 'function') { - content = content.call(this.element); + content = content.call(this._element); } - this.setElementContent($tip.find(Selector$7.CONTENT), content); - $tip.removeClass(ClassName$7.FADE + " " + ClassName$7.SHOW); + this.setElementContent(SelectorEngine.findOne(SELECTOR_CONTENT, tip), content); + tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$4); } // Private ; + _proto._addAttachmentClass = function _addAttachmentClass(attachment) { + this.getTipElement().classList.add(CLASS_PREFIX$1 + "-" + this.updateAttachment(attachment)); + }; + _proto._getContent = function _getContent() { - return this.element.getAttribute('data-content') || this.config.content; + return this._element.getAttribute('data-bs-content') || this.config.content; }; _proto._cleanTipClass = function _cleanTipClass() { - var $tip = $(this.getTipElement()); - var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX$1); + var tip = this.getTipElement(); + var tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX$1); if (tabClass !== null && tabClass.length > 0) { - $tip.removeClass(tabClass.join('')); + tabClass.map(function (token) { + return token.trim(); + }).forEach(function (tClass) { + return tip.classList.remove(tClass); + }); } } // Static ; - Popover._jQueryInterface = function _jQueryInterface(config) { + Popover.jQueryInterface = function jQueryInterface(config) { return this.each(function () { - var data = $(this).data(DATA_KEY$7); + var data = Data.getData(this, DATA_KEY$7); var _config = typeof config === 'object' ? config : null; @@ -6287,7 +5857,7 @@ if (!data) { data = new Popover(this, _config); - $(this).data(DATA_KEY$7, data); + Data.setData(this, DATA_KEY$7, data); } if (typeof config === 'string') { @@ -6301,13 +5871,8 @@ }; _createClass(Popover, null, [{ - key: "VERSION", - // Getters - get: function get() { - return VERSION$7; - } - }, { key: "Default", + // Getters get: function get() { return Default$5; } @@ -6324,7 +5889,7 @@ }, { key: "Event", get: function get() { - return Event$7; + return Event$2; } }, { key: "EVENT_KEY", @@ -6344,16 +5909,25 @@ * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ + * add .Popover to jQuery only if jQuery is present */ - $.fn[NAME$7] = Popover._jQueryInterface; - $.fn[NAME$7].Constructor = Popover; + onDOMContentLoaded(function () { + var $ = getjQuery(); + /* istanbul ignore if */ - $.fn[NAME$7].noConflict = function () { - $.fn[NAME$7] = JQUERY_NO_CONFLICT$7; - return Popover._jQueryInterface; - }; + if ($) { + var JQUERY_NO_CONFLICT = $.fn[NAME$7]; + $.fn[NAME$7] = Popover.jQueryInterface; + $.fn[NAME$7].Constructor = Popover; + + $.fn[NAME$7].noConflict = function () { + $.fn[NAME$7] = JQUERY_NO_CONFLICT; + return Popover.jQueryInterface; + }; + } + }); /** * ------------------------------------------------------------------------ @@ -6362,11 +5936,9 @@ */ var NAME$8 = 'scrollspy'; - var VERSION$8 = '4.4.1'; var DATA_KEY$8 = 'bs.scrollspy'; var EVENT_KEY$8 = "." + DATA_KEY$8; var DATA_API_KEY$6 = '.data-api'; - var JQUERY_NO_CONFLICT$8 = $.fn[NAME$8]; var Default$6 = { offset: 10, method: 'auto', @@ -6377,57 +5949,49 @@ method: 'string', target: '(string|element)' }; - var Event$8 = { - ACTIVATE: "activate" + EVENT_KEY$8, - SCROLL: "scroll" + EVENT_KEY$8, - LOAD_DATA_API: "load" + EVENT_KEY$8 + DATA_API_KEY$6 - }; - var ClassName$8 = { - DROPDOWN_ITEM: 'dropdown-item', - DROPDOWN_MENU: 'dropdown-menu', - ACTIVE: 'active' - }; - var Selector$8 = { - DATA_SPY: '[data-spy="scroll"]', - ACTIVE: '.active', - NAV_LIST_GROUP: '.nav, .list-group', - NAV_LINKS: '.nav-link', - NAV_ITEMS: '.nav-item', - LIST_ITEMS: '.list-group-item', - DROPDOWN: '.dropdown', - DROPDOWN_ITEMS: '.dropdown-item', - DROPDOWN_TOGGLE: '.dropdown-toggle' - }; - var OffsetMethod = { - OFFSET: 'offset', - POSITION: 'position' - }; + var EVENT_ACTIVATE = "activate" + EVENT_KEY$8; + var EVENT_SCROLL = "scroll" + EVENT_KEY$8; + var EVENT_LOAD_DATA_API$1 = "load" + EVENT_KEY$8 + DATA_API_KEY$6; + var CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'; + var CLASS_NAME_ACTIVE$2 = 'active'; + var SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]'; + var SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'; + var SELECTOR_NAV_LINKS = '.nav-link'; + var SELECTOR_NAV_ITEMS = '.nav-item'; + var SELECTOR_LIST_ITEMS = '.list-group-item'; + var SELECTOR_DROPDOWN = '.dropdown'; + var SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'; + var METHOD_OFFSET = 'offset'; + var METHOD_POSITION = 'position'; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ - var ScrollSpy = - /*#__PURE__*/ - function () { - function ScrollSpy(element, config) { - var _this = this; + var ScrollSpy = /*#__PURE__*/function (_BaseComponent) { + _inheritsLoose(ScrollSpy, _BaseComponent); - this._element = element; - this._scrollElement = element.tagName === 'BODY' ? window : element; - this._config = this._getConfig(config); - this._selector = this._config.target + " " + Selector$8.NAV_LINKS + "," + (this._config.target + " " + Selector$8.LIST_ITEMS + ",") + (this._config.target + " " + Selector$8.DROPDOWN_ITEMS); - this._offsets = []; - this._targets = []; - this._activeTarget = null; - this._scrollHeight = 0; - $(this._scrollElement).on(Event$8.SCROLL, function (event) { + function ScrollSpy(element, config) { + var _this; + + _this = _BaseComponent.call(this, element) || this; + _this._scrollElement = element.tagName === 'BODY' ? window : element; + _this._config = _this._getConfig(config); + _this._selector = _this._config.target + " " + SELECTOR_NAV_LINKS + ", " + _this._config.target + " " + SELECTOR_LIST_ITEMS + ", " + _this._config.target + " ." + CLASS_NAME_DROPDOWN_ITEM; + _this._offsets = []; + _this._targets = []; + _this._activeTarget = null; + _this._scrollHeight = 0; + EventHandler.on(_this._scrollElement, EVENT_SCROLL, function (event) { return _this._process(event); }); - this.refresh(); - this._process(); + _this.refresh(); + + _this._process(); + + return _this; } // Getters @@ -6437,27 +6001,22 @@ _proto.refresh = function refresh() { var _this2 = this; - var autoMethod = this._scrollElement === this._scrollElement.window ? OffsetMethod.OFFSET : OffsetMethod.POSITION; + var autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION; var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method; - var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0; + var offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0; this._offsets = []; this._targets = []; this._scrollHeight = this._getScrollHeight(); - var targets = [].slice.call(document.querySelectorAll(this._selector)); + var targets = SelectorEngine.find(this._selector); targets.map(function (element) { - var target; - var targetSelector = Util.getSelectorFromElement(element); - - if (targetSelector) { - target = document.querySelector(targetSelector); - } + var targetSelector = getSelectorFromElement(element); + var target = targetSelector ? SelectorEngine.findOne(targetSelector) : null; if (target) { var targetBCR = target.getBoundingClientRect(); if (targetBCR.width || targetBCR.height) { - // TODO (fat): remove sketch reliance on jQuery position/offset - return [$(target)[offsetMethod]().top + offsetBase, targetSelector]; + return [Manipulator[offsetMethod](target).top + offsetBase, targetSelector]; } } @@ -6474,9 +6033,9 @@ }; _proto.dispose = function dispose() { - $.removeData(this._element, DATA_KEY$8); - $(this._scrollElement).off(EVENT_KEY$8); - this._element = null; + _BaseComponent.prototype.dispose.call(this); + + EventHandler.off(this._scrollElement, EVENT_KEY$8); this._scrollElement = null; this._config = null; this._selector = null; @@ -6488,20 +6047,20 @@ ; _proto._getConfig = function _getConfig(config) { - config = _objectSpread2({}, Default$6, {}, typeof config === 'object' && config ? config : {}); + config = _extends({}, Default$6, typeof config === 'object' && config ? config : {}); - if (typeof config.target !== 'string') { - var id = $(config.target).attr('id'); + if (typeof config.target !== 'string' && isElement(config.target)) { + var id = config.target.id; if (!id) { - id = Util.getUID(NAME$8); - $(config.target).attr('id', id); + id = getUID(NAME$8); + config.target.id = id; } config.target = "#" + id; } - Util.typeCheckConfig(NAME$8, config, DefaultType$6); + typeCheckConfig(NAME$8, config, DefaultType$6); return config; }; @@ -6546,9 +6105,7 @@ return; } - var offsetLength = this._offsets.length; - - for (var i = offsetLength; i--;) { + for (var i = this._offsets.length; i--;) { var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]); if (isActiveTarget) { @@ -6563,47 +6120,54 @@ this._clear(); var queries = this._selector.split(',').map(function (selector) { - return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]"; + return selector + "[data-bs-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]"; }); - var $link = $([].slice.call(document.querySelectorAll(queries.join(',')))); + var link = SelectorEngine.findOne(queries.join(',')); - if ($link.hasClass(ClassName$8.DROPDOWN_ITEM)) { - $link.closest(Selector$8.DROPDOWN).find(Selector$8.DROPDOWN_TOGGLE).addClass(ClassName$8.ACTIVE); - $link.addClass(ClassName$8.ACTIVE); + if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) { + SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, link.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$2); + link.classList.add(CLASS_NAME_ACTIVE$2); } else { // Set triggered link as active - $link.addClass(ClassName$8.ACTIVE); // Set triggered links parents as active - // With both