diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 476fddb91..c7211e689 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -18,9 +18,7 @@ the preferred channel for [bug reports](#bug-reports), [features requests](#feat 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-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** use the issue tracker for personal support requests. Stack Overflow ([`bootstrap-5`](https://stackoverflow.com/questions/tagged/bootstrap-5) tag), [our GitHub Discussions](https://github.com/twbs/bootstrap/discussions) or [IRC](/README.md#community) are better places to get help. * Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others. diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md index a4739f589..26b3be42c 100644 --- a/.github/SUPPORT.md +++ b/.github/SUPPORT.md @@ -6,6 +6,6 @@ See the [contributing guidelines](CONTRIBUTING.md) for sharing bug reports. For general troubleshooting or help getting started: -- Join [the official Slack room](https://bootstrap-slack.herokuapp.com/). +- Ask and explore [our GitHub Discussions](https://github.com/twbs/bootstrap/discussions). - Chat with fellow Bootstrappers in IRC. On the `irc.libera.chat` server, in the `#bootstrap` channel. - Ask and explore Stack Overflow with the [`bootstrap-5`](https://stackoverflow.com/questions/tagged/bootstrap-5) tag. diff --git a/README.md b/README.md index 5e557c499..a7efe9268 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,6 @@ Read the [Getting started page](https://getbootstrap.com/docs/5.2/getting-starte ## Status -[![Slack](https://bootstrap-slack.herokuapp.com/badge.svg)](https://bootstrap-slack.herokuapp.com/) [![Build Status](https://img.shields.io/github/workflow/status/twbs/bootstrap/JS%20Tests/main?label=JS%20Tests&logo=github)](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) @@ -138,7 +137,7 @@ We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified ## Bugs and feature requests -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). +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/choose). ## Documentation @@ -178,7 +177,7 @@ Get updates on Bootstrap's development and chat with the project maintainers and - Follow [@getbootstrap on Twitter](https://twitter.com/getbootstrap). - Read and subscribe to [The Official Bootstrap Blog](https://blog.getbootstrap.com/). -- Join [the official Slack room](https://bootstrap-slack.herokuapp.com/). +- Ask and explore [our GitHub Discussions](https://github.com/twbs/bootstrap/discussions). - Chat with fellow Bootstrappers in IRC. On the `irc.libera.chat` server, in the `#bootstrap` channel. - 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. diff --git a/config.yml b/config.yml index 577180957..bb71b8d0c 100644 --- a/config.yml +++ b/config.yml @@ -48,10 +48,9 @@ module: target: static/favicon.ico params: - description: "The most popular HTML, CSS, and JS library in the world." + subtitle: "The most popular HTML, CSS, and JS library in the world." + description: "Powerful, extensible, and feature-packed frontend toolkit. Build and customize with Sass, utilize prebuilt grid system and components, and bring projects to life with powerful JavaScript plugins." authors: "Mark Otto, Jacob Thornton, and Bootstrap contributors" - social_image_path: /docs/5.2/assets/brand/bootstrap-social.png - social_logo_path: /docs/5.2/assets/brand/bootstrap-social-logo.png current_version: "5.2.0" current_ruby_version: "5.2.0" @@ -60,7 +59,6 @@ params: github_org: "https://github.com/twbs" repo: "https://github.com/twbs/bootstrap" twitter: "getbootstrap" - slack: "https://bootstrap-slack.herokuapp.com/" opencollective: "https://opencollective.com/bootstrap" blog: "https://blog.getbootstrap.com/" themes: "https://themes.getbootstrap.com/" diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index 102a2e101..f4d667101 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -40,14 +40,16 @@ const Default = { offset: null, // TODO: v6 @deprecated, keep it for backwards compatibility reasons rootMargin: '0px 0px -25%', smoothScroll: false, - target: null + target: null, + threshold: [0.1, 0.5, 1] } const DefaultType = { offset: '(number|null)', // TODO v6 @deprecated, keep it for backwards compatibility reasons rootMargin: 'string', smoothScroll: 'boolean', - target: 'element' + target: 'element', + threshold: 'array' } /** @@ -110,6 +112,13 @@ class ScrollSpy extends BaseComponent { // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case config.target = getElement(config.target) || document.body + // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only + config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin + + if (typeof config.threshold === 'string') { + config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value)) + } + return config } @@ -141,8 +150,8 @@ class ScrollSpy extends BaseComponent { _getNewObserver() { const options = { root: this._rootElement, - threshold: [0.1, 0.5, 1], - rootMargin: this._getRootMargin() + threshold: this._config.threshold, + rootMargin: this._config.rootMargin } return new IntersectionObserver(entries => this._observerCallback(entries), options) @@ -187,11 +196,6 @@ class ScrollSpy extends BaseComponent { } } - // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only - _getRootMargin() { - return this._config.offset ? `${this._config.offset}px 0px -30%` : this._config.rootMargin - } - _initializeTargetsAndObservables() { this._targetLinks = new Map() this._observableSections = new Map() diff --git a/js/src/tooltip.js b/js/src/tooltip.js index 54ec0367e..2c5f03a29 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -185,6 +185,10 @@ class Tooltip extends BaseComponent { this.tip.remove() } + if (this._config.originalTitle) { + this._element.setAttribute('title', this._config.originalTitle) + } + this._disposePopper() super.dispose() } diff --git a/js/tests/unit/scrollspy.spec.js b/js/tests/unit/scrollspy.spec.js index 2bdeb5830..c7951e6ff 100644 --- a/js/tests/unit/scrollspy.spec.js +++ b/js/tests/unit/scrollspy.spec.js @@ -126,6 +126,50 @@ describe('ScrollSpy', () => { expect(scrollSpy._rootElement).toBeNull() }) + it('should respect threshold option', () => { + fixtureEl.innerHTML = [ + '', + '
', + ' ', + '
' + ].join('') + + const scrollSpy = new ScrollSpy('#content', { + target: '#navigation', + threshold: [1] + }) + + expect(scrollSpy._observer.thresholds).toEqual([1]) + }) + + it('should respect threshold option markup', () => { + fixtureEl.innerHTML = [ + '', + '
', + ' ', + '
' + ].join('') + + const scrollSpy = new ScrollSpy('#content', { + target: '#navigation' + }) + + // See https://stackoverflow.com/a/45592926 + const expectToBeCloseToArray = (actual, expected) => { + expect(actual.length).toBe(expected.length) + for (const x of actual) { + const i = actual.indexOf(x) + expect(x).withContext(`[${i}]`).toBeCloseTo(expected[i]) + } + } + + expectToBeCloseToArray(scrollSpy._observer.thresholds, [0, 0.2, 1]) + }) + it('should not take count to not visible sections', () => { fixtureEl.innerHTML = [ '