diff --git a/.bundlewatch.config.json b/.bundlewatch.config.json index da47da480..074066390 100644 --- a/.bundlewatch.config.json +++ b/.bundlewatch.config.json @@ -18,11 +18,11 @@ }, { "path": "./dist/css/bootstrap-utilities.css", - "maxSize": "7.5 kB" + "maxSize": "7 kB" }, { "path": "./dist/css/bootstrap-utilities.min.css", - "maxSize": "6.75 kB" + "maxSize": "6.25 kB" }, { "path": "./dist/css/bootstrap.css", diff --git a/.eslintrc.json b/.eslintrc.json index d5a54d46b..ec6aa589c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -43,14 +43,15 @@ ], "unicorn/consistent-function-scoping": "off", "unicorn/explicit-length-check": "off", - "unicorn/no-array-callback-reference": "off", + "unicorn/import-index": "off", + "unicorn/no-fn-reference-in-iterator": "off", "unicorn/no-for-loop": "off", "unicorn/no-null": "off", "unicorn/no-unused-properties": "error", "unicorn/no-useless-undefined": "off", - "unicorn/prefer-dom-node-append": "off", - "unicorn/prefer-dom-node-dataset": "off", - "unicorn/prefer-dom-node-remove": "off", + "unicorn/prefer-dataset": "off", + "unicorn/prefer-node-append": "off", + "unicorn/prefer-node-remove": "off", "unicorn/prefer-optional-catch-binding": "off", "unicorn/prefer-query-selector": "off", "unicorn/prevent-abbreviations": "off" diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 32b30cdb3..0913b5b5b 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -101,12 +101,12 @@ Example: Sometimes bugs reported to us are actually caused by bugs in the browser(s) themselves, not bugs in Bootstrap per se. -| 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 | +| 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 @@ -134,9 +134,9 @@ 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`, 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) +**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/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 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 29135b400..31976021e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,10 +15,3 @@ updates: - 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 index e2b70e03e..ae1367c89 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -4,9 +4,6 @@ prerelease: true exclude-labels: - 'skip-changelog' categories: - - title: '❗ Breaking Changes' - labels: - - 'breaking-change' - title: '🚀 Features' labels: - 'new-feature' @@ -17,9 +14,6 @@ categories: - 'fix' - 'bugfix' - 'bug' - - title: '⚡ Performance Improvements' - labels: - - 'performance' - title: '🎨 CSS' labels: - 'css' @@ -32,19 +26,11 @@ categories: - 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' diff --git a/.github/workflows/browserstack.yml b/.github/workflows/browserstack.yml index a12bffcf7..0b4cfbdaa 100644 --- a/.github/workflows/browserstack.yml +++ b/.github/workflows/browserstack.yml @@ -4,21 +4,21 @@ on: push: env: + CI: true FORCE_COLOR: 2 - NODE: 14 + NODE: 14.x 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 + uses: actions/setup-node@v1 with: node-version: "${{ env.NODE }}" @@ -28,8 +28,8 @@ jobs: 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 }}- + ${{ 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 diff --git a/.github/workflows/bundlewatch.yml b/.github/workflows/bundlewatch.yml index b2bd5eed5..966dfbf72 100644 --- a/.github/workflows/bundlewatch.yml +++ b/.github/workflows/bundlewatch.yml @@ -7,8 +7,9 @@ on: pull_request: env: + CI: true FORCE_COLOR: 2 - NODE: 14 + NODE: 14.x jobs: bundlewatch: @@ -19,7 +20,7 @@ jobs: uses: actions/checkout@v2 - name: Set up Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v1 with: node-version: "${{ env.NODE }}" @@ -29,8 +30,8 @@ jobs: 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 }}- + ${{ 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 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 469a5a4fc..f9dccfce0 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -22,6 +22,15 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 + + # If this run was triggered by a pull request event, then checkout + # the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/css.yml b/.github/workflows/css.yml index a28059d79..a75f018c5 100644 --- a/.github/workflows/css.yml +++ b/.github/workflows/css.yml @@ -7,8 +7,9 @@ on: pull_request: env: + CI: true FORCE_COLOR: 2 - NODE: 14 + NODE: 14.x jobs: css: @@ -19,7 +20,7 @@ jobs: uses: actions/checkout@v2 - name: Set up Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v1 with: node-version: "${{ env.NODE }}" @@ -29,8 +30,8 @@ jobs: 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 }}- + ${{ 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 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 150e4d16c..58b55fc7c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -7,8 +7,9 @@ on: pull_request: env: + CI: true FORCE_COLOR: 2 - NODE: 14 + NODE: 14.x jobs: docs: @@ -19,7 +20,7 @@ jobs: uses: actions/checkout@v2 - name: Set up Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v1 with: node-version: "${{ env.NODE }}" @@ -31,8 +32,8 @@ jobs: 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 }}- + ${{ 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 diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml index c56a2dfdd..1ec0d6909 100644 --- a/.github/workflows/js.yml +++ b/.github/workflows/js.yml @@ -7,6 +7,7 @@ on: pull_request: env: + CI: true FORCE_COLOR: 2 jobs: @@ -24,7 +25,7 @@ jobs: uses: actions/checkout@v2 - name: Set up Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v1 with: node-version: ${{ matrix.node }} @@ -34,8 +35,8 @@ jobs: 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 }}- + ${{ 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 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 369aaced3..e850a1f1b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,8 +7,9 @@ on: pull_request: env: + CI: true FORCE_COLOR: 2 - NODE: 14 + NODE: 14.x jobs: lint: @@ -19,7 +20,7 @@ jobs: uses: actions/checkout@v2 - name: Set up Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v1 with: node-version: "${{ env.NODE }}" @@ -29,8 +30,8 @@ jobs: 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 }}- + ${{ 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 diff --git a/.github/workflows/node-sass.yml b/.github/workflows/node-sass.yml index ee64b2152..2db55f0ff 100644 --- a/.github/workflows/node-sass.yml +++ b/.github/workflows/node-sass.yml @@ -7,8 +7,9 @@ on: pull_request: env: + CI: true FORCE_COLOR: 2 - NODE: 14 + NODE: 14.x jobs: css: @@ -19,7 +20,7 @@ jobs: uses: actions/checkout@v2 - name: Set up Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v1 with: node-version: "${{ env.NODE }}" diff --git a/.gitignore b/.gitignore index 0a0f88d15..6208c57d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,19 @@ # Ignore docs files /_gh_pages/ +# This is the old Jekyll docs dist folder; +# keeping it here so that when we switch branches it doesn't show up +/site/docs/**/dist/ +# Jekyll's cache folder; keeping it for the same reason as above +/site/.jekyll-cache/ # Hugo resources folder /resources/ +# Ignore ruby/bundler files; +# keeping them here so that when we switch branches they don't show up +/.bundle/ +/vendor/ +/.ruby-version + # Numerous always-ignore extensions *.diff *.err diff --git a/.stylelintrc b/.stylelintrc index c068d30b5..1c9ee1811 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -3,10 +3,6 @@ "stylelint-config-twbs-bootstrap/scss" ], "rules": { - "declaration-property-value-disallowed-list": { - "border": "none", - "outline": "none" - }, "function-disallowed-list": [ "calc", "lighten", diff --git a/LICENSE b/LICENSE index 72dda234e..173a9ebbb 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ The MIT License (MIT) -Copyright (c) 2011-2021 Twitter, Inc. -Copyright (c) 2011-2021 The Bootstrap Authors +Copyright (c) 2011-2020 Twitter, Inc. +Copyright (c) 2011-2020 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 f41498691..8a470260a 100644 --- a/README.md +++ b/README.md @@ -236,4 +236,4 @@ Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com ## Copyright and license -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/). +Code and documentation copyright 2011–2020 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/build/build-plugins.js b/build/build-plugins.js index d1930b855..ea7477390 100644 --- a/build/build-plugins.js +++ b/build/build-plugins.js @@ -2,8 +2,8 @@ /*! * Script to build our plugins to use them separately. - * Copyright 2020-2021 The Bootstrap Authors - * Copyright 2020-2021 Twitter, Inc. + * Copyright 2020 The Bootstrap Authors + * Copyright 2020 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ @@ -29,7 +29,6 @@ const bsPlugins = { 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'), @@ -45,13 +44,11 @@ const bsPlugins = { const defaultPluginConfig = { external: [ bsPlugins.Data, - bsPlugins.Base, bsPlugins.EventHandler, bsPlugins.SelectorEngine ], globals: { [bsPlugins.Data]: 'Data', - [bsPlugins.Base]: 'Base', [bsPlugins.EventHandler]: 'EventHandler', [bsPlugins.SelectorEngine]: 'SelectorEngine' } @@ -76,7 +73,6 @@ const getConfigByPluginKey = pluginKey => { } if ( - pluginKey === 'Base' || pluginKey === 'Button' || pluginKey === 'Carousel' || pluginKey === 'Collapse' || @@ -116,13 +112,11 @@ const getConfigByPluginKey = pluginKey => { return { external: [ bsPlugins.Data, - bsPlugins.Base, bsPlugins.EventHandler, bsPlugins.Manipulator ], globals: { [bsPlugins.Data]: 'Data', - [bsPlugins.Base]: 'Base', [bsPlugins.EventHandler]: 'EventHandler', [bsPlugins.Manipulator]: 'Manipulator' } diff --git a/build/change-version.js b/build/change-version.js index 8086ed774..b8a640fa8 100644 --- a/build/change-version.js +++ b/build/change-version.js @@ -2,8 +2,8 @@ /*! * Script to update version number references in the project. - * Copyright 2017-2021 The Bootstrap Authors - * Copyright 2017-2021 Twitter, Inc. + * Copyright 2017-2020 The Bootstrap Authors + * Copyright 2017-2020 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ diff --git a/build/generate-sri.js b/build/generate-sri.js index 221873b8f..8a2e59360 100644 --- a/build/generate-sri.js +++ b/build/generate-sri.js @@ -5,8 +5,8 @@ * Remember to use the same vendor files as the CDN ones, * otherwise the hashes won't match! * - * Copyright 2017-2021 The Bootstrap Authors - * Copyright 2017-2021 Twitter, Inc. + * Copyright 2017-2020 The Bootstrap Authors + * Copyright 2017-2020 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ diff --git a/build/vnu-jar.js b/build/vnu-jar.js index c23b94d60..90c1a12ab 100644 --- a/build/vnu-jar.js +++ b/build/vnu-jar.js @@ -2,8 +2,8 @@ /*! * Script to run vnu-jar if Java is available. - * Copyright 2017-2021 The Bootstrap Authors - * Copyright 2017-2021 Twitter, Inc. + * Copyright 2017-2020 The Bootstrap Authors + * Copyright 2017-2020 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ diff --git a/build/zip-examples.js b/build/zip-examples.js index b2f156502..bf50a0af6 100644 --- a/build/zip-examples.js +++ b/build/zip-examples.js @@ -3,7 +3,7 @@ /*! * Script to create the built examples zip archive; * requires the `zip` command to be present! - * Copyright 2020-2021 The Bootstrap Authors + * Copyright 2020 The Bootstrap Authors * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ @@ -12,67 +12,36 @@ const path = require('path') const sh = require('shelljs') -const pkg = require('../package.json') +const { version, version_short: versionShort } = 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' -] +const folderName = `bootstrap-${version}-examples` sh.config.fatal = true -if (!sh.test('-d', rootDocsDir)) { - throw new Error(`The "${rootDocsDir}" folder does not exist, did you forget building the docs?`) +if (!sh.test('-d', '_gh_pages')) { + throw new Error('The "_gh_pages" 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`]) - +// remove any previously created folder with the same name +sh.rm('-rf', folderName) // create any folders so that `cp` works -sh.mkdir('-p', [ - distFolder, - `${distFolder}/assets/brand/`, - `${distFolder}/assets/dist/css/`, - `${distFolder}/assets/dist/js/` -]) +sh.mkdir('-p', folderName) +sh.mkdir('-p', `${folderName}/assets/brand/`) -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`) +sh.cp('-Rf', `_gh_pages/docs/${versionShort}/examples/*`, folderName) +sh.cp('-Rf', `_gh_pages/docs/${versionShort}/dist/`, `${folderName}/assets/`) +// also copy the two brand images we use in the examples +sh.cp('-f', [ + `_gh_pages/docs/${versionShort}/assets/brand/bootstrap-logo.svg`, + `_gh_pages/docs/${versionShort}/assets/brand/bootstrap-logo-white.svg` +], `${folderName}/assets/brand/`) +sh.rm(`${folderName}/index.html`) // get all examples' HTML files -sh.find(`${distFolder}/**/*.html`).forEach(file => { +sh.find(`${folderName}/**/*.html`).forEach(file => { const fileContents = sh.cat(file) .toString() .replace(new RegExp(`"/docs/${versionShort}/`, 'g'), '"../') @@ -84,7 +53,7 @@ sh.find(`${distFolder}/**/*.html`).forEach(file => { }) // create the zip file -sh.exec(`zip -r9 "${distFolder}.zip" "${distFolder}"`) +sh.exec(`zip -r9 "${folderName}.zip" "${folderName}"`, { fatal: true }) // remove the folder we created -sh.rm('-rf', distFolder) +sh.rm('-rf', folderName) diff --git a/config.yml b/config.yml index a54d5bc6c..616993e15 100644 --- a/config.yml +++ b/config.yml @@ -75,5 +75,5 @@ params: js_hash: "sha384-pQQkAEnwaBkjpqZ8RU1fF1AKtTcHJwFl3pblpTlHXybJjHpMYo79HY3hIi4NKxyj" js_bundle: "https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" js_bundle_hash: "sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" - popper: "https://cdn.jsdelivr.net/npm/@popperjs/core@2.6.0/dist/umd/popper.min.js" - popper_hash: "sha384-KsvD1yqQ1/1+IA7gi3P0tyJcT3vR+NdBTt13hSJ2lnve8agRGXTTyNaBYmCR/Nwi" + popper: "https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js" + popper_hash: "sha384-q2kxQ16AaE6UbzuKqyBE9/u/KzioAlnx2maXQHiDX9d4/zp8Ok3f+M7DPm+Ib6IU" diff --git a/js/src/alert.js b/js/src/alert.js index 96eda4c5f..e498d0324 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -7,6 +7,7 @@ import { defineJQueryPlugin, + TRANSITION_END, emulateTransitionEnd, getElementFromSelector, getTransitionDurationFromElement @@ -32,9 +33,9 @@ const EVENT_CLOSE = `close${EVENT_KEY}` const EVENT_CLOSED = `closed${EVENT_KEY}` const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` -const CLASS_NAME_ALERT = 'alert' -const CLASS_NAME_FADE = 'fade' -const CLASS_NAME_SHOW = 'show' +const CLASSNAME_ALERT = 'alert' +const CLASSNAME_FADE = 'fade' +const CLASSNAME_SHOW = 'show' /** * ------------------------------------------------------------------------ @@ -65,7 +66,7 @@ class Alert extends BaseComponent { // Private _getRootElement(element) { - return getElementFromSelector(element) || element.closest(`.${CLASS_NAME_ALERT}`) + return getElementFromSelector(element) || element.closest(`.${CLASSNAME_ALERT}`) } _triggerCloseEvent(element) { @@ -73,16 +74,16 @@ class Alert extends BaseComponent { } _removeElement(element) { - element.classList.remove(CLASS_NAME_SHOW) + element.classList.remove(CLASSNAME_SHOW) - if (!element.classList.contains(CLASS_NAME_FADE)) { + if (!element.classList.contains(CLASSNAME_FADE)) { this._destroyElement(element) return } const transitionDuration = getTransitionDurationFromElement(element) - EventHandler.one(element, 'transitionend', () => this._destroyElement(element)) + EventHandler.one(element, TRANSITION_END, () => this._destroyElement(element)) emulateTransitionEnd(element, transitionDuration) } diff --git a/js/src/carousel.js b/js/src/carousel.js index 06a391419..299aadeda 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -7,11 +7,11 @@ import { defineJQueryPlugin, + TRANSITION_END, emulateTransitionEnd, getElementFromSelector, getTransitionDurationFromElement, isVisible, - isRTL, reflow, triggerTransitionEnd, typeCheckConfig @@ -93,8 +93,10 @@ const SELECTOR_INDICATORS = '.carousel-indicators' const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]' const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]' -const POINTER_TYPE_TOUCH = 'touch' -const POINTER_TYPE_PEN = 'pen' +const PointerType = { + TOUCH: 'touch', + PEN: 'pen' +} /** * ------------------------------------------------------------------------ @@ -251,20 +253,12 @@ class Carousel extends BaseComponent { // swipe left if (direction > 0) { - if (isRTL) { - this.next() - } else { - this.prev() - } + this.prev() } // swipe right if (direction < 0) { - if (isRTL) { - this.prev() - } else { - this.next() - } + this.next() } } @@ -285,7 +279,7 @@ class Carousel extends BaseComponent { _addTouchEventListeners() { const start = event => { - if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) { + if (this._pointerEvent && PointerType[event.pointerType.toUpperCase()]) { this.touchStartX = event.clientX } else if (!this._pointerEvent) { this.touchStartX = event.touches[0].clientX @@ -302,7 +296,7 @@ class Carousel extends BaseComponent { } const end = event => { - if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) { + if (this._pointerEvent && PointerType[event.pointerType.toUpperCase()]) { this.touchDeltaX = event.clientX - this.touchStartX } @@ -346,20 +340,16 @@ class Carousel extends BaseComponent { return } - if (event.key === ARROW_LEFT_KEY) { - event.preventDefault() - if (isRTL) { - this.next() - } else { + switch (event.key) { + case ARROW_LEFT_KEY: + event.preventDefault() this.prev() - } - } else if (event.key === ARROW_RIGHT_KEY) { - event.preventDefault() - if (isRTL) { - this.prev() - } else { + break + case ARROW_RIGHT_KEY: + event.preventDefault() this.next() - } + break + default: } } @@ -446,9 +436,19 @@ class Carousel extends BaseComponent { const nextElementIndex = this._getItemIndex(nextElement) const isCycling = Boolean(this._interval) - const directionalClassName = direction === DIRECTION_NEXT ? CLASS_NAME_START : CLASS_NAME_END - const orderClassName = direction === DIRECTION_NEXT ? CLASS_NAME_NEXT : CLASS_NAME_PREV - const eventDirectionName = direction === DIRECTION_NEXT ? DIRECTION_LEFT : DIRECTION_RIGHT + let directionalClassName + let orderClassName + let eventDirectionName + + if (direction === DIRECTION_NEXT) { + directionalClassName = CLASS_NAME_START + orderClassName = CLASS_NAME_NEXT + eventDirectionName = DIRECTION_LEFT + } else { + directionalClassName = CLASS_NAME_END + orderClassName = CLASS_NAME_PREV + eventDirectionName = DIRECTION_RIGHT + } if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE)) { this._isSliding = false @@ -484,7 +484,7 @@ class Carousel extends BaseComponent { const transitionDuration = getTransitionDurationFromElement(activeElement) - EventHandler.one(activeElement, 'transitionend', () => { + EventHandler.one(activeElement, TRANSITION_END, () => { nextElement.classList.remove(directionalClassName, orderClassName) nextElement.classList.add(CLASS_NAME_ACTIVE) diff --git a/js/src/collapse.js b/js/src/collapse.js index 0d3eeed54..590615b72 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -7,6 +7,7 @@ import { defineJQueryPlugin, + TRANSITION_END, emulateTransitionEnd, getSelectorFromElement, getElementFromSelector, @@ -202,7 +203,7 @@ class Collapse extends BaseComponent { const scrollSize = `scroll${capitalizedDimension}` const transitionDuration = getTransitionDurationFromElement(this._element) - EventHandler.one(this._element, 'transitionend', complete) + EventHandler.one(this._element, TRANSITION_END, complete) emulateTransitionEnd(this._element, transitionDuration) this._element.style[dimension] = `${this._element[scrollSize]}px` @@ -252,7 +253,7 @@ class Collapse extends BaseComponent { this._element.style[dimension] = '' const transitionDuration = getTransitionDurationFromElement(this._element) - EventHandler.one(this._element, 'transitionend', complete) + EventHandler.one(this._element, TRANSITION_END, complete) emulateTransitionEnd(this._element, transitionDuration) } @@ -371,7 +372,7 @@ class Collapse extends BaseComponent { EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { // preventDefault only for elements (which change the URL) not inside the collapsible element - if (event.target.tagName === 'A' || (event.delegateTarget && event.delegateTarget.tagName === 'A')) { + if (event.target.tagName === 'A') { event.preventDefault() } diff --git a/js/src/dom/event-handler.js b/js/src/dom/event-handler.js index e3c685530..2ee13bafc 100644 --- a/js/src/dom/event-handler.js +++ b/js/src/dom/event-handler.js @@ -112,7 +112,6 @@ function bootstrapDelegationHandler(element, selector, fn) { event.delegateTarget = target if (handler.oneOff) { - // eslint-disable-next-line unicorn/consistent-destructuring EventHandler.off(element, event.type, fn) } diff --git a/js/src/dom/selector-engine.js b/js/src/dom/selector-engine.js index 28287388e..727df7518 100644 --- a/js/src/dom/selector-engine.js +++ b/js/src/dom/selector-engine.js @@ -23,8 +23,9 @@ const SelectorEngine = { }, children(element, selector) { - return [].concat(...element.children) - .filter(child => child.matches(selector)) + const children = [].concat(...element.children) + + return children.filter(child => child.matches(selector)) }, parents(element, selector) { diff --git a/js/src/dropdown.js b/js/src/dropdown.js index bada537c9..4720ed1ab 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -84,7 +84,7 @@ const DefaultType = { offset: '(number|string|function)', flip: 'boolean', boundary: '(string|element)', - reference: '(string|element|object)', + reference: '(string|element)', display: 'string', popperConfig: '(null|object)' } @@ -172,8 +172,6 @@ class Dropdown extends BaseComponent { if (typeof this._config.reference.jquery !== 'undefined') { referenceElement = this._config.reference[0] } - } else if (typeof this._config.reference === 'object') { - referenceElement = this._config.reference } this._popper = Popper.createPopper(referenceElement, this._menu, this._getPopperConfig()) @@ -259,13 +257,6 @@ class Dropdown extends BaseComponent { typeCheckConfig(NAME, config, this.constructor.DefaultType) - if (typeof config.reference === 'object' && !isElement(config.reference) && - typeof config.reference.getBoundingClientRect !== 'function' - ) { - // Popper virtual elements require a getBoundingClientRect method - throw new TypeError(`${NAME.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`) - } - return config } @@ -307,12 +298,6 @@ class Dropdown extends BaseComponent { altBoundary: this._config.flip, rootBoundary: this._config.boundary } - }, - { - name: 'flip', - options: { - fallbackPlacements: ['top', 'right', 'bottom', 'left'] - } }] } diff --git a/js/src/modal.js b/js/src/modal.js index fe1b5a4c6..20fb215c6 100644 --- a/js/src/modal.js +++ b/js/src/modal.js @@ -7,6 +7,7 @@ import { defineJQueryPlugin, + TRANSITION_END, emulateTransitionEnd, getElementFromSelector, getTransitionDurationFromElement, @@ -183,7 +184,7 @@ class Modal extends BaseComponent { if (transition) { const transitionDuration = getTransitionDurationFromElement(this._element) - EventHandler.one(this._element, 'transitionend', event => this._hideModal(event)) + EventHandler.one(this._element, TRANSITION_END, event => this._hideModal(event)) emulateTransitionEnd(this._element, transitionDuration) } else { this._hideModal() @@ -271,7 +272,7 @@ class Modal extends BaseComponent { if (transition) { const transitionDuration = getTransitionDurationFromElement(this._dialog) - EventHandler.one(this._dialog, 'transitionend', transitionComplete) + EventHandler.one(this._dialog, TRANSITION_END, transitionComplete) emulateTransitionEnd(this._dialog, transitionDuration) } else { transitionComplete() @@ -376,7 +377,7 @@ class Modal extends BaseComponent { const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop) - EventHandler.one(this._backdrop, 'transitionend', callback) + EventHandler.one(this._backdrop, TRANSITION_END, callback) emulateTransitionEnd(this._backdrop, backdropTransitionDuration) } else if (!this._isShown && this._backdrop) { this._backdrop.classList.remove(CLASS_NAME_SHOW) @@ -388,7 +389,7 @@ class Modal extends BaseComponent { if (this._element.classList.contains(CLASS_NAME_FADE)) { const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop) - EventHandler.one(this._backdrop, 'transitionend', callbackRemove) + EventHandler.one(this._backdrop, TRANSITION_END, callbackRemove) emulateTransitionEnd(this._backdrop, backdropTransitionDuration) } else { callbackRemove() @@ -412,11 +413,11 @@ class Modal extends BaseComponent { this._element.classList.add(CLASS_NAME_STATIC) const modalTransitionDuration = getTransitionDurationFromElement(this._dialog) - EventHandler.off(this._element, 'transitionend') - EventHandler.one(this._element, 'transitionend', () => { + EventHandler.off(this._element, TRANSITION_END) + EventHandler.one(this._element, TRANSITION_END, () => { this._element.classList.remove(CLASS_NAME_STATIC) if (!isModalOverflowing) { - EventHandler.one(this._element, 'transitionend', () => { + EventHandler.one(this._element, TRANSITION_END, () => { this._element.style.overflowY = '' }) emulateTransitionEnd(this._element, modalTransitionDuration) @@ -590,7 +591,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( data = new Modal(target, config) } - data.toggle(this) + data.show(this) }) /** diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index baea49443..a8770ef08 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -76,7 +76,7 @@ class ScrollSpy extends BaseComponent { this._activeTarget = null this._scrollHeight = 0 - EventHandler.on(this._scrollElement, EVENT_SCROLL, () => this._process()) + EventHandler.on(this._scrollElement, EVENT_SCROLL, event => this._process(event)) this.refresh() this._process() diff --git a/js/src/tab.js b/js/src/tab.js index f1b17ac79..3a48986c4 100644 --- a/js/src/tab.js +++ b/js/src/tab.js @@ -7,6 +7,7 @@ import { defineJQueryPlugin, + TRANSITION_END, emulateTransitionEnd, getElementFromSelector, getTransitionDurationFromElement, @@ -81,11 +82,13 @@ class Tab extends BaseComponent { previous = previous[previous.length - 1] } - const hideEvent = previous ? - EventHandler.trigger(previous, EVENT_HIDE, { + let hideEvent = null + + if (previous) { + hideEvent = EventHandler.trigger(previous, EVENT_HIDE, { relatedTarget: this._element - }) : - null + }) + } const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, { relatedTarget: previous @@ -129,7 +132,7 @@ class Tab extends BaseComponent { const transitionDuration = getTransitionDurationFromElement(active) active.classList.remove(CLASS_NAME_SHOW) - EventHandler.one(active, 'transitionend', complete) + EventHandler.one(active, TRANSITION_END, complete) emulateTransitionEnd(active, transitionDuration) } else { complete() diff --git a/js/src/toast.js b/js/src/toast.js index e277cdc06..bda152af6 100644 --- a/js/src/toast.js +++ b/js/src/toast.js @@ -7,6 +7,7 @@ import { defineJQueryPlugin, + TRANSITION_END, emulateTransitionEnd, getTransitionDurationFromElement, reflow, @@ -115,7 +116,7 @@ class Toast extends BaseComponent { if (this._config.animation) { const transitionDuration = getTransitionDurationFromElement(this._element) - EventHandler.one(this._element, 'transitionend', complete) + EventHandler.one(this._element, TRANSITION_END, complete) emulateTransitionEnd(this._element, transitionDuration) } else { complete() @@ -142,7 +143,7 @@ class Toast extends BaseComponent { if (this._config.animation) { const transitionDuration = getTransitionDurationFromElement(this._element) - EventHandler.one(this._element, 'transitionend', complete) + EventHandler.one(this._element, TRANSITION_END, complete) emulateTransitionEnd(this._element, transitionDuration) } else { complete() diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 63a30cf2f..df0f0c19c 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -9,6 +9,7 @@ import * as Popper from '@popperjs/core' import { defineJQueryPlugin, + TRANSITION_END, emulateTransitionEnd, findShadowRoot, getTransitionDurationFromElement, @@ -51,7 +52,7 @@ const DefaultType = { selector: '(string|boolean)', placement: '(string|function)', container: '(string|element|boolean)', - fallbackPlacements: 'array', + fallbackPlacements: '(null|array)', boundary: '(string|element)', customClass: '(string|function)', sanitize: 'boolean', @@ -81,7 +82,7 @@ const Default = { selector: false, placement: 'top', container: false, - fallbackPlacements: ['top', 'right', 'bottom', 'left'], + fallbackPlacements: null, boundary: 'clippingParents', customClass: '', sanitize: true, @@ -222,7 +223,7 @@ class Tooltip extends BaseComponent { 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.parentNode) { + if (this.tip) { this.tip.parentNode.removeChild(this.tip) } @@ -316,7 +317,7 @@ class Tooltip extends BaseComponent { if (this.tip.classList.contains(CLASS_NAME_FADE)) { const transitionDuration = getTransitionDurationFromElement(this.tip) - EventHandler.one(this.tip, 'transitionend', complete) + EventHandler.one(this.tip, TRANSITION_END, complete) emulateTransitionEnd(this.tip, transitionDuration) } else { complete() @@ -366,7 +367,7 @@ class Tooltip extends BaseComponent { if (this.tip.classList.contains(CLASS_NAME_FADE)) { const transitionDuration = getTransitionDurationFromElement(tip) - EventHandler.one(tip, 'transitionend', complete) + EventHandler.one(tip, TRANSITION_END, complete) emulateTransitionEnd(tip, transitionDuration) } else { complete() @@ -466,16 +467,21 @@ class Tooltip extends BaseComponent { // Private _getPopperConfig(attachment) { + const flipModifier = { + name: 'flip', + options: { + altBoundary: true + } + } + + if (this.config.fallbackPlacements) { + flipModifier.options.fallbackPlacements = this.config.fallbackPlacements + } + const defaultBsConfig = { placement: attachment, modifiers: [ - { - name: 'flip', - options: { - altBoundary: true, - fallbackPlacements: this.config.fallbackPlacements - } - }, + flipModifier, { name: 'preventOverflow', options: { diff --git a/js/src/util/index.js b/js/src/util/index.js index 22d0a578b..1bf9fe954 100644 --- a/js/src/util/index.js +++ b/js/src/util/index.js @@ -111,14 +111,15 @@ const typeCheckConfig = (componentName, config, configTypes) => { Object.keys(configTypes).forEach(property => { const expectedTypes = configTypes[property] const value = config[property] - const valueType = value && isElement(value) ? 'element' : toType(value) + const valueType = value && isElement(value) ? + 'element' : + toType(value) if (!new RegExp(expectedTypes).test(valueType)) { - throw new TypeError( + throw new Error( `${componentName.toUpperCase()}: ` + `Option "${property}" provided type "${valueType}" ` + - `but expected type "${expectedTypes}".` - ) + `but expected type "${expectedTypes}".`) } }) } @@ -204,6 +205,7 @@ const defineJQueryPlugin = (name, plugin) => { } export { + TRANSITION_END, getUID, getSelectorFromElement, getElementFromSelector, diff --git a/js/src/util/sanitizer.js b/js/src/util/sanitizer.js index ce3d455a6..d908dd661 100644 --- a/js/src/util/sanitizer.js +++ b/js/src/util/sanitizer.js @@ -37,7 +37,7 @@ const allowedAttribute = (attr, allowedAttributeList) => { if (allowedAttributeList.includes(attrName)) { if (uriAttrs.has(attrName)) { - return Boolean(SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue)) + return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)) } return true @@ -47,7 +47,7 @@ const allowedAttribute = (attr, allowedAttributeList) => { // Check if a regular expression validates the attribute. for (let i = 0, len = regExp.length; i < len; i++) { - if (regExp[i].test(attrName)) { + if (attrName.match(regExp[i])) { return true } } diff --git a/js/tests/browsers.js b/js/tests/browsers.js index 2e1bd3a80..8df94cc53 100644 --- a/js/tests/browsers.js +++ b/js/tests/browsers.js @@ -5,21 +5,21 @@ const browsers = { safariMac: { base: 'BrowserStack', os: 'OS X', - os_version: 'Catalina', + os_version: 'High Sierra', browser: 'Safari', browser_version: 'latest' }, chromeMac: { base: 'BrowserStack', os: 'OS X', - os_version: 'Catalina', + os_version: 'High Sierra', browser: 'Chrome', browser_version: 'latest' }, firefoxMac: { base: 'BrowserStack', os: 'OS X', - os_version: 'Catalina', + os_version: 'High Sierra', browser: 'Firefox', browser_version: 'latest' }, diff --git a/js/tests/karma.conf.js b/js/tests/karma.conf.js index cd4946525..d0dd8bdd9 100644 --- a/js/tests/karma.conf.js +++ b/js/tests/karma.conf.js @@ -1,7 +1,5 @@ /* eslint-env node */ -'use strict' - const path = require('path') const ip = require('ip') const { babel } = require('@rollup/plugin-babel') @@ -14,11 +12,10 @@ const { browsersKeys } = require('./browsers') -const ENV = process.env -const BROWSERSTACK = Boolean(ENV.BROWSERSTACK) -const DEBUG = Boolean(ENV.DEBUG) -const JQUERY_TEST = Boolean(ENV.JQUERY) - +const { env } = process +const browserStack = env.BROWSER === 'true' +const debug = env.DEBUG === 'true' +const jQueryTest = env.JQUERY === 'true' const frameworks = [ 'jasmine' ] @@ -33,16 +30,16 @@ const reporters = ['dots'] const detectBrowsers = { usePhantomJS: false, postDetection(availableBrowser) { - if (ENV.CI === true || availableBrowser.includes('Chrome')) { - return DEBUG ? ['Chrome'] : ['ChromeHeadless'] + if (env.CI === true || availableBrowser.includes('Chrome')) { + return debug ? ['Chrome'] : ['ChromeHeadless'] } if (availableBrowser.includes('Chromium')) { - return DEBUG ? ['Chromium'] : ['ChromiumHeadless'] + return debug ? ['Chromium'] : ['ChromiumHeadless'] } if (availableBrowser.includes('Firefox')) { - return DEBUG ? ['Firefox'] : ['FirefoxHeadless'] + return debug ? ['Firefox'] : ['FirefoxHeadless'] } throw new Error('Please install Chrome, Chromium or Firefox') @@ -62,7 +59,7 @@ const conf = { colors: true, autoWatch: false, singleRun: true, - concurrency: Number.POSITIVE_INFINITY, + concurrency: Infinity, client: { clearContext: false }, @@ -70,7 +67,7 @@ const conf = { 'node_modules/hammer-simulator/index.js', { pattern: 'js/tests/unit/**/!(jquery).spec.js', - watched: !BROWSERSTACK + watched: !browserStack } ], preprocessors: { @@ -104,11 +101,11 @@ const conf = { } } -if (BROWSERSTACK) { +if (browserStack) { conf.hostname = ip.address() conf.browserStack = { - username: ENV.BROWSER_STACK_USERNAME, - accessKey: ENV.BROWSER_STACK_ACCESS_KEY, + username: env.BROWSER_STACK_USERNAME, + accessKey: env.BROWSER_STACK_ACCESS_KEY, build: `bootstrap-${new Date().toISOString()}`, project: 'Bootstrap', retryLimit: 2 @@ -117,7 +114,7 @@ if (BROWSERSTACK) { conf.customLaunchers = browsers conf.browsers = browsersKeys reporters.push('BrowserStack', 'kjhtml') -} else if (JQUERY_TEST) { +} else if (jQueryTest) { frameworks.push('detectBrowsers') plugins.push( 'karma-chrome-launcher', @@ -158,7 +155,7 @@ if (BROWSERSTACK) { } } - if (DEBUG) { + if (debug) { conf.hostname = ip.address() plugins.push('karma-jasmine-html-reporter') reporters.push('kjhtml') @@ -172,6 +169,7 @@ conf.plugins = plugins conf.reporters = reporters module.exports = karmaConfig => { - conf.logLevel = karmaConfig.LOG_ERROR + // possible values: karmaConfig.LOG_DISABLE || karmaConfig.LOG_ERROR || karmaConfig.LOG_WARN || karmaConfig.LOG_INFO || karmaConfig.LOG_DEBUG + conf.logLevel = karmaConfig.LOG_ERROR || karmaConfig.LOG_WARN karmaConfig.set(conf) } diff --git a/js/tests/unit/carousel.spec.js b/js/tests/unit/carousel.spec.js index 787a276de..07b8fc311 100644 --- a/js/tests/unit/carousel.spec.js +++ b/js/tests/unit/carousel.spec.js @@ -905,7 +905,7 @@ describe('Carousel', () => { }) describe('to', () => { - it('should go directly to the provided index', done => { + it('should go directement to the provided index', done => { fixtureEl.innerHTML = [ ' @@ -206,34 +206,6 @@ Add `data-bs-interval=""` to a `.carousel-item` to change the amount of time to {{< /example >}} -### Disable touch swiping - -Carousels support swiping left/right on touchscreen devices to move between slides. This can be disabled using the `data-bs-touch` attribute. The example below also does not include the `data-bs-ride` attribute and has `data-bs-interval="false"` so it doesn't autoplay. - -{{< example >}} - -{{< /example >}} - ## Dark variant Add `.carousel-dark` to the `.carousel` for darker controls, indicators, and captions. Controls have been inverted from their default white fill with the `filter` CSS property. Captions and controls have additional Sass variables that customize the `color` and `background-color`. @@ -250,21 +222,21 @@ Add `.carousel-dark` to the `.carousel` for darker controls, indicators, and cap {{< placeholder width="800" height="400" class="bd-placeholder-img-lg d-block w-100" color="#aaa" background="#f5f5f5" text="First slide" >}} @@ -314,7 +286,7 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap interval number 5000 - The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle. + The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle. keyboard @@ -325,15 +297,15 @@ Options can be passed via data attributes or JavaScript. For data attributes, ap pause string | boolean - 'hover' -

If set to 'hover', pauses the cycling of the carousel on mouseenter and resumes the cycling of the carousel on mouseleave. If set to false, hovering over the carousel won't pause it.

-

On touch-enabled devices, when set to 'hover', cycling will pause on touchend (once the user finished interacting with the carousel) for two intervals, before automatically resuming. Note that this is in addition to the above mouse behavior.

+ "hover" +

If set to "hover", pauses the cycling of the carousel on mouseenter and resumes the cycling of the carousel on mouseleave. If set to false, hovering over the carousel won't pause it.

+

On touch-enabled devices, when set to "hover", cycling will pause on touchend (once the user finished interacting with the carousel) for two intervals, before automatically resuming. Note that this is in addition to the above mouse behavior.

- ride + slide string | boolean false - Autoplays the carousel after the user manually cycles the first item. If set to 'carousel', autoplays the carousel on load. + Autoplays the carousel after the user manually cycles the first item. If "carousel", autoplays the carousel on load. wrap diff --git a/site/content/docs/5.0/components/collapse.md b/site/content/docs/5.0/components/collapse.md index 8546aaeb5..0c23133b6 100644 --- a/site/content/docs/5.0/components/collapse.md +++ b/site/content/docs/5.0/components/collapse.md @@ -22,7 +22,7 @@ Click the buttons below to show and hide another element via class changes: - `.collapsing` is applied during transitions - `.collapse.show` shows content -Generally, we recommend using a button with the `data-bs-target` attribute. While not recommended from a semantic point of view, you can also use a link with the `href` attribute (and a `role="button"`). In both cases, the `data-bs-toggle="collapse"` is required. +You can use a link with the `href` attribute, or a button with the `data-bs-target` attribute. In both cases, the `data-bs-toggle="collapse"` is required. {{< example >}}

@@ -35,7 +35,7 @@ Generally, we recommend using a button with the `data-bs-target` attribute. Whil

- Some placeholder content for the collapse component. This panel is hidden by default but revealed when the user activates the relevant trigger. + Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
{{< /example >}} @@ -55,14 +55,14 @@ Multiple ` - - - - + + + + {{< /example >}} @@ -86,11 +86,11 @@ Add `.list-group-flush` to remove some borders and rounded corners to render lis {{< example >}} {{< /example >}} @@ -104,9 +104,9 @@ Add `.list-group-horizontal` to change the layout of list group items from verti {{< list-group.inline >}} {{- range $.Site.Data.breakpoints }} {{- end -}} {{< /list-group.inline >}} @@ -118,7 +118,7 @@ Use contextual classes to style list items with a stateful background and color. {{< example >}}
-

Placeholder content for the tab panel. This one relates to the home tab. Takes you miles high, so high, 'cause she’s got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. ‘Cause I, I’m capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.

+

Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.

-

Placeholder content for the tab panel. This one relates to the profile tab. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.

+

Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit. Keytar helvetica VHS salvia yr, vero magna velit sapiente labore stumptown. Vegan fanny pack odio cillum wes anderson 8-bit, sustainable jean shorts beard ut DIY ethical culpa terry richardson biodiesel. Art party scenester stumptown, tumblr butcher vero sint qui sapiente accusamus tattooed echo park.

-

Placeholder content for the tab panel. This one relates to the contact tab. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.

+

Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.

@@ -368,13 +368,13 @@ To help fit your needs, this works with `
-

Placeholder content for the tab panel. This one relates to the home tab. Takes you miles high, so high, 'cause she’s got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. ‘Cause I, I’m capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.

+

Consequat occaecat ullamco amet non eiusmod nostrud dolore irure incididunt est duis anim sunt officia. Fugiat velit proident aliquip nisi incididunt nostrud exercitation proident est nisi. Irure magna elit commodo anim ex veniam culpa eiusmod id nostrud sit cupidatat in veniam ad. Eiusmod consequat eu adipisicing minim anim aliquip cupidatat culpa excepteur quis. Occaecat sit eu exercitation irure Lorem incididunt nostrud.

-

Placeholder content for the tab panel. This one relates to the profile tab. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.

+

Ad pariatur nostrud pariatur exercitation ipsum ipsum culpa mollit commodo mollit ex. Aute sunt incididunt amet commodo est sint nisi deserunt pariatur do. Aliquip ex eiusmod voluptate exercitation cillum id incididunt elit sunt. Qui minim sit magna Lorem id et dolore velit Lorem amet exercitation duis deserunt. Anim id labore elit adipisicing ut in id occaecat pariatur ut ullamco ea tempor duis.

-

Placeholder content for the tab panel. This one relates to the contact tab. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.

+

Est quis nulla laborum officia ad nisi ex nostrud culpa Lorem excepteur aliquip dolor aliqua irure ex. Nulla ut duis ipsum nisi elit fugiat commodo sunt reprehenderit laborum veniam eu veniam. Eiusmod minim exercitation fugiat irure ex labore incididunt do fugiat commodo aliquip sit id deserunt reprehenderit aliquip nostrud. Amet ex cupidatat excepteur aute veniam incididunt mollit cupidatat esse irure officia elit do ipsum ullamco Lorem. Ullamco ut ad minim do mollit labore ipsum laboris ipsum commodo sunt tempor enim incididunt. Commodo quis sunt dolore aliquip aute tempor irure magna enim minim reprehenderit. Ullamco consectetur culpa veniam sint cillum aliqua incididunt velit ullamco sunt ullamco quis quis commodo voluptate. Mollit nulla nostrud adipisicing aliqua cupidatat aliqua pariatur mollit voluptate voluptate consequat non.

@@ -452,16 +452,16 @@ And with vertical pills.
-

Placeholder content for the tab panel. This one relates to the home tab. Saw you downtown singing the Blues. Watch you circle the drain. Why don't you let me stop by? Heavy is the head that wears the crown. Yes, we make angels cry, raining down on earth from up above. Wanna see the show in 3D, a movie. Do you ever feel, feel so paper thin. It’s a yes or no, no maybe.

+

Cillum ad ut irure tempor velit nostrud occaecat ullamco aliqua anim Lorem sint. Veniam sint duis incididunt do esse magna mollit excepteur laborum qui. Id id reprehenderit sit est eu aliqua occaecat quis et velit excepteur laborum mollit dolore eiusmod. Ipsum dolor in occaecat commodo et voluptate minim reprehenderit mollit pariatur. Deserunt non laborum enim et cillum eu deserunt excepteur ea incididunt minim occaecat.

-

Placeholder content for the tab panel. This one relates to the profile tab. Takes you miles high, so high, 'cause she’s got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. ‘Cause I, I’m capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.

+

Culpa dolor voluptate do laboris laboris irure reprehenderit id incididunt duis pariatur mollit aute magna pariatur consectetur. Eu veniam duis non ut dolor deserunt commodo et minim in quis laboris ipsum velit id veniam. Quis ut consectetur adipisicing officia excepteur non sit. Ut et elit aliquip labore Lorem enim eu. Ullamco mollit occaecat dolore ipsum id officia mollit qui esse anim eiusmod do sint minim consectetur qui.

-

Placeholder content for the tab panel. This one relates to the messages tab. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.

+

Fugiat id quis dolor culpa eiusmod anim velit excepteur proident dolor aute qui magna. Ad proident laboris ullamco esse anim Lorem Lorem veniam quis Lorem irure occaecat velit nostrud magna nulla. Velit et et proident Lorem do ea tempor officia dolor. Reprehenderit Lorem aliquip labore est magna commodo est ea veniam consectetur.

-

Placeholder content for the tab panel. This one relates to the settings tab. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.

+

Eu dolore ea ullamco dolore Lorem id cupidatat excepteur reprehenderit consectetur elit id dolor proident in cupidatat officia. Voluptate excepteur commodo labore nisi cillum duis aliqua do. Aliqua amet qui mollit consectetur nulla mollit velit aliqua veniam nisi id do Lorem deserunt amet. Culpa ullamco sit adipisicing labore officia magna elit nisi in aute tempor commodo eiusmod.

diff --git a/site/content/docs/5.0/components/popovers.md b/site/content/docs/5.0/components/popovers.md index ccaf1f63f..41b482d03 100644 --- a/site/content/docs/5.0/components/popovers.md +++ b/site/content/docs/5.0/components/popovers.md @@ -62,20 +62,40 @@ var popover = new bootstrap.Popover(document.querySelector('.example-popover'), Four options are available: top, right, bottom, and left aligned. Directions are mirrored when using Bootstrap in RTL. -{{< example >}} - + + + + + + +```html + - - - -{{< /example >}} +``` ### Dismiss on next click @@ -99,13 +119,13 @@ var popover = new bootstrap.Popover(document.querySelector('.popover-dismiss'), ### Disabled elements -Elements with the `disabled` attribute aren't interactive, meaning users cannot hover or click them to trigger a popover (or tooltip). As a workaround, you'll want to trigger the popover from a wrapper `
` or ``, ideally made keyboard-focusable using `tabindex="0"`. +Elements with the `disabled` attribute aren't interactive, meaning users cannot hover or click them to trigger a popover (or tooltip). As a workaround, you'll want to trigger the popover from a wrapper `
` or `` and override the `pointer-events` on the disabled element. -For disabled popover triggers, you may also prefer `data-bs-trigger="hover focus"` so that the popover appears as immediate visual feedback to your users as they may not expect to _click_ on a disabled element. +For disabled popover triggers, you may also prefer `data-bs-trigger="hover"` so that the popover appears as immediate visual feedback to your users as they may not expect to _click_ on a disabled element. {{< example >}} - - + + {{< /example >}} @@ -228,17 +248,23 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt How popover is triggered - click | hover | focus | manual. You may pass multiple triggers; separate them with a space. manual cannot be combined with any other trigger. - fallbackPlacements - array - ['top', 'right', 'bottom', 'left'] - Define fallback placements by providing a list of placements in array (in order of preference). For more information refer to - Popper's behavior docs + offset + number | string + 0 + Offset of the popover relative to its target. For more information refer to Popper's offset docs. + + + fallbackPlacement + string | array + 'flip' + Allow to specify which position Popper will use on fallback. For more information refer to + Popper's behavior docs boundary string | element 'scrollParent' - Overflow constraint boundary of the popover. Accepts the values of 'viewport', 'window', 'scrollParent', or an HTMLElement reference (JavaScript only). For more information refer to Popper's preventOverflow docs. + Overflow constraint boundary of the popover. Accepts the values of 'viewport', 'window', 'scrollParent', or an HTMLElement reference (JavaScript only). For more information refer to Popper's preventOverflow docs. customClass @@ -271,7 +297,7 @@ Note that for security reasons the `sanitize`, `sanitizeFn`, and `allowList` opt popperConfig null | object null - To change Bootstrap's default Popper config, see Popper's configuration + To change Bootstrap's default Popper config, see Popper's configuration diff --git a/site/content/docs/5.0/components/scrollspy.md b/site/content/docs/5.0/components/scrollspy.md index 3904990af..0d099c08c 100644 --- a/site/content/docs/5.0/components/scrollspy.md +++ b/site/content/docs/5.0/components/scrollspy.md @@ -49,16 +49,17 @@ Scroll the area below the navbar and watch the active class change. The dropdown

@fat

-

Placeholder content for the scrollspy example. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.

+

Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.

@mdo

-

Placeholder content for the scrollspy example. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk.

+

Veniam marfa mustache skateboard, adipisicing fugiat velit pitchfork beard. Freegan beard aliqua cupidatat mcsweeney's vero. Cupidatat four loko nisi, ea helvetica nulla carles. Tattooed cosby sweater food truck, mcsweeney's quis non freegan vinyl. Lo-fi wes anderson +1 sartorial. Carles non aesthetic exercitation quis gentrify. Brooklyn adipisicing craft beer vice keytar deserunt.

one

-

Placeholder content for the scrollspy example. Takes you miles high, so high, 'cause she’s got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. ‘Cause I, I’m capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.

+

Occaecat commodo aliqua delectus. Fap craft beer deserunt skateboard ea. Lomo bicycle rights adipisicing banh mi, velit ea sunt next level locavore single-origin coffee in magna veniam. High life id vinyl, echo park consequat quis aliquip banh mi pitchfork. Vero VHS est adipisicing. Consectetur nisi DIY minim messenger bag. Cred ex in, sustainable delectus consectetur fanny pack iphone.

two

-

Placeholder content for the scrollspy example. It's time to bring out the big balloons. I'm walking, I'm walking on air (tonight). Yeah, we maxed our credit cards and got kicked out of the bar. Yo, shout out to all you kids, buying bottle service, with your rent money. I'm ma get your heart racing in my skin-tight jeans. If you get the chance you better keep her. Yo, shout out to all you kids, buying bottle service, with your rent money.

+

In incididunt echo park, officia deserunt mcsweeney's proident master cleanse thundercats sapiente veniam. Excepteur VHS elit, proident shoreditch +1 biodiesel laborum craft beer. Single-origin coffee wayfarers irure four loko, cupidatat terry richardson master cleanse. Assumenda you probably haven't heard of them art party fanny pack, tattooed nulla cardigan tempor ad. Proident wolf nesciunt sartorial keffiyeh eu banh mi sustainable. Elit wolf voluptate, lo-fi ea portland before they sold out four loko. Locavore enim nostrud mlkshk brooklyn nesciunt.

three

-

Placeholder content for the scrollspy example. If you wanna dance, if you want it all, you know that I'm the girl that you should call. Walk through the storm I would. So let me get you in your birthday suit. The one that got away. Last Friday night, yeah I think we broke the law, always say we're gonna stop. 'Cause she's a little bit of Yoko, And she's a little bit of 'Oh no'. I want the jaw droppin', eye poppin', head turnin', body shockin'. Yeah, we maxed our credit cards and got kicked out of the bar.

-

And some more placeholder content, for good measure.

+

Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Cosby sweater lomo jean shorts, williamsburg hoodie minim qui you probably haven't heard of them et cardigan trust fund culpa biodiesel wes anderson aesthetic. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.

+

Keytar twee blog, culpa messenger bag marfa whatever delectus food truck. Sapiente synth id assumenda. Locavore sed helvetica cliche irony, thundercats you probably haven't heard of them consequat hoodie gluten-free lo-fi fap aliquip. Labore elit placeat before they sold out, terry richardson proident brunch nesciunt quis cosby sweater pariatur keffiyeh ut helvetica artisan. Cardigan craft beer seitan readymade velit. VHS chambray laboris tempor veniam. Anim mollit minim commodo ullamco thundercats. +

@@ -124,19 +125,19 @@ Scrollspy also works with nested `.nav`s. If a nested `.nav` is `.active`, its p

Item 1

-

Placeholder content for the scrollspy example. This one relates to item 1. Takes you miles high, so high, 'cause she’s got that one international smile. There's a stranger in my bed, there's a pounding in my head. Oh, no. In another life I would make you stay. ‘Cause I, I’m capable of anything. Suiting up for my crowning battle. Used to steal your parents' liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin' heavy. Her love is like a drug. I guess that I forgot I had a choice.

+

Ex consequat commodo adipisicing exercitation aute excepteur occaecat ullamco duis aliqua id magna ullamco eu. Do aute ipsum ipsum ullamco cillum consectetur ut et aute consectetur labore. Fugiat laborum incididunt tempor eu consequat enim dolore proident. Qui laborum do non excepteur nulla magna eiusmod consectetur in. Aliqua et aliqua officia quis et incididunt voluptate non anim reprehenderit adipisicing dolore ut consequat deserunt mollit dolore. Aliquip nulla enim veniam non fugiat id cupidatat nulla elit cupidatat commodo velit ut eiusmod cupidatat elit dolore.

Item 1-1
-

Placeholder content for the scrollspy example. This one relates to the item 1-1. You got the finest architecture. Passport stamps, she's cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I'd be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she's the one. Greetings loved ones let's take a journey. Just own the night like the 4th of July! But you'd rather get wasted.

+

Amet tempor mollit aliquip pariatur excepteur commodo do ea cillum commodo Lorem et occaecat elit qui et. Aliquip labore ex ex esse voluptate occaecat Lorem ullamco deserunt. Aliqua cillum excepteur irure consequat id quis ea. Sit proident ullamco aute magna pariatur nostrud labore. Reprehenderit aliqua commodo eiusmod aliquip est do duis amet proident magna consectetur consequat eu commodo fugiat non quis. Enim aliquip exercitation ullamco adipisicing voluptate excepteur minim exercitation minim minim commodo adipisicing exercitation officia nisi adipisicing. Anim id duis qui consequat labore adipisicing sint dolor elit cillum anim et fugiat.

Item 1-2
-

Placeholder content for the scrollspy example. This one relates to the item 1-2. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. 'Cause she's the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I'm walking, I'm walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.

+

Cillum nisi deserunt magna eiusmod qui eiusmod velit voluptate pariatur laborum sunt enim. Irure laboris mollit consequat incididunt sint et culpa culpa incididunt adipisicing magna magna occaecat. Nulla ipsum cillum eiusmod sint elit excepteur ea labore enim consectetur in labore anim. Proident ullamco ipsum esse elit ut Lorem eiusmod dolor et eiusmod. Anim occaecat nulla in non consequat eiusmod velit incididunt.

Item 2

-

Placeholder content for the scrollspy example. This one relates to item 2. Don't need apologies. There is no fear now, let go and just be free, I will love you unconditionally. Last Friday night. Don't be a shy kinda guy I'll bet it's beautiful. Summer after high school when we first met. 'Cause she's the muse and the artist. What? Wait. No, no, no, no. Thought that I was the exception.

+

Quis magna Lorem anim amet ipsum do mollit sit cillum voluptate ex nulla tempor. Laborum consequat non elit enim exercitation cillum aliqua consequat id aliqua. Esse ex consectetur mollit voluptate est in duis laboris ad sit ipsum anim Lorem. Incididunt veniam velit elit elit veniam Lorem aliqua quis ullamco deserunt sit enim elit aliqua esse irure. Laborum nisi sit est tempor laborum mollit labore officia laborum excepteur commodo non commodo dolor excepteur commodo. Ipsum fugiat ex est consectetur ipsum commodo tempor sunt in proident.

Item 3

-

Placeholder content for the scrollspy example. This one relates to item 3. Word on the street, you got somethin' to show me, me. All this money can't buy me a time machine. Make it like your birthday everyday. So we hit the boulevard. You make me feel like I'm livin' a teenage dream, the way you turn me on Skip the talk, heard it all, time to walk the walk. Word on the street, you got somethin' to show me, me. It's no big deal, it's no big deal, it's no big deal.

+

Quis anim sit do amet fugiat dolor velit sit ea ea do reprehenderit culpa duis. Nostrud aliqua ipsum fugiat minim proident occaecat excepteur aliquip culpa aute tempor reprehenderit. Deserunt tempor mollit elit ex pariatur dolore velit fugiat mollit culpa irure ullamco est ex ullamco excepteur.

Item 3-1
-

Placeholder content for the scrollspy example. This one relates to item 3-1. Baby do you dare to do this? This is no big deal. Yeah, you're lucky if you're on her plane. Just own the night like the 4th of July! Standing on the frontline when the bombs start to fall. So just be sure before you give it all to me.

+

Deserunt quis elit Lorem eiusmod amet enim enim amet minim Lorem proident nostrud. Ea id dolore anim exercitation aute fugiat labore voluptate cillum do laboris labore. Ex velit exercitation nisi enim labore reprehenderit labore nostrud ut ut. Esse officia sunt duis aliquip ullamco tempor eiusmod deserunt irure nostrud irure. Ullamco proident veniam laboris ea consectetur magna sunt ex exercitation aliquip minim enim culpa occaecat exercitation. Est tempor excepteur aliquip laborum consequat do deserunt laborum esse eiusmod irure proident ipsum esse qui.

Item 3-2
-

Placeholder content for the scrollspy example. This one relates to item 3-2. You're original, cannot be replaced. All night they're playing, your song. California girls we're undeniable. Like a bird without a cage. There is no fear now, let go and just be free, I will love you unconditionally. I can see the writing on the wall. You could travel the world but nothing comes close to the golden coast.

+

Labore sit culpa commodo elit adipisicing sit aliquip elit proident voluptate minim mollit nostrud aute reprehenderit do. Mollit excepteur eu Lorem ipsum anim commodo sint labore Lorem in exercitation velit incididunt. Occaecat consectetur nisi in occaecat proident minim enim sunt reprehenderit exercitation cupidatat et do officia. Aliquip consequat ad labore labore mollit ut amet. Sit pariatur tempor proident in veniam culpa aliqua excepteur elit magna fugiat eiusmod amet officia.

@@ -195,13 +196,13 @@ Scrollspy also works with `.list-group`s. Scroll the area next to the list group

Item 1

-

Placeholder content for the scrollspy list-group example. This one relates to item 1. Don't need apologies. There is no fear now, let go and just be free, I will love you unconditionally. Last Friday night. Don't be a shy kinda guy I'll bet it's beautiful. Summer after high school when we first met. 'Cause she's the muse and the artist. What? Wait. Thought that I was the exception.

+

Ex consequat commodo adipisicing exercitation aute excepteur occaecat ullamco duis aliqua id magna ullamco eu. Do aute ipsum ipsum ullamco cillum consectetur ut et aute consectetur labore. Fugiat laborum incididunt tempor eu consequat enim dolore proident. Qui laborum do non excepteur nulla magna eiusmod consectetur in. Aliqua et aliqua officia quis et incididunt voluptate non anim reprehenderit adipisicing dolore ut consequat deserunt mollit dolore. Aliquip nulla enim veniam non fugiat id cupidatat nulla elit cupidatat commodo velit ut eiusmod cupidatat elit dolore.

Item 2

-

Placeholder content for the scrollspy list-group example. This one relates to item 2. Yeah, she dances to her own beat. Oh, no. You could've been the greatest. 'Cause, baby, you're a firework. Maybe a reason why all the doors are closed. Open up your heart and just let it begin. So très chic, yeah, she's a classic.

+

Quis magna Lorem anim amet ipsum do mollit sit cillum voluptate ex nulla tempor. Laborum consequat non elit enim exercitation cillum aliqua consequat id aliqua. Esse ex consectetur mollit voluptate est in duis laboris ad sit ipsum anim Lorem. Incididunt veniam velit elit elit veniam Lorem aliqua quis ullamco deserunt sit enim elit aliqua esse irure. Laborum nisi sit est tempor laborum mollit labore officia laborum excepteur commodo non commodo dolor excepteur commodo. Ipsum fugiat ex est consectetur ipsum commodo tempor sunt in proident.

Item 3

-

Placeholder content for the scrollspy list-group example. This one relates to item 3. We go higher and higher. Never one without the other, we made a pact. I'm walking on air. Someone said you had your tattoo removed. Now I’m floating like a butterfly. Tone, tan fit and ready, turn it up cause its gettin' heavy. Cause once you’re mine, once you’re mine. You just gotta ignite the light and let it shine! So we hit the boulevard. Do you ever feel, feel so paper thin. I see it all, I see it now.

+

Quis anim sit do amet fugiat dolor velit sit ea ea do reprehenderit culpa duis. Nostrud aliqua ipsum fugiat minim proident occaecat excepteur aliquip culpa aute tempor reprehenderit. Deserunt tempor mollit elit ex pariatur dolore velit fugiat mollit culpa irure ullamco est ex ullamco excepteur.

Item 4

-

Placeholder content for the scrollspy list-group example. This one relates to item 4. Summer after high school when we first met. There is no fear now, let go and just be free, I will love you unconditionally. Sun-kissed skin so hot we'll melt your popsicle. This love will make you levitate.

+

Quis anim sit do amet fugiat dolor velit sit ea ea do reprehenderit culpa duis. Nostrud aliqua ipsum fugiat minim proident occaecat excepteur aliquip culpa aute tempor reprehenderit. Deserunt tempor mollit elit ex pariatur dolore velit fugiat mollit culpa irure ullamco est ex ullamco excepteur.

@@ -226,6 +227,7 @@ Scrollspy also works with `.list-group`s. Scroll the area next to the list group ``` + ## Usage ### Via data attributes diff --git a/site/content/docs/5.0/components/toasts.md b/site/content/docs/5.0/components/toasts.md index bd7bcae9c..740a926f9 100644 --- a/site/content/docs/5.0/components/toasts.md +++ b/site/content/docs/5.0/components/toasts.md @@ -43,7 +43,7 @@ Toasts are as flexible as you need and have very little required markup. At a mi ### Translucent -Toasts are slightly translucent, too, so they blend over whatever they might appear over. +Toasts are slightly translucent, too, so they blend over whatever they might appear over. For browsers that support the `backdrop-filter` CSS property, we'll also attempt to blur the elements under a toast. {{< example class="bg-dark" >}}