mirror of
https://github.com/twbs/bootstrap.git
synced 2025-10-03 00:03:44 -04:00
Compare commits
5 Commits
e029f3c790
...
6c835c6ab4
Author | SHA1 | Date | |
---|---|---|---|
|
6c835c6ab4 | ||
|
4189b3075c | ||
|
8cd02aabd1 | ||
|
ad443baf3a | ||
|
9c526253b4 |
6
.github/workflows/codeql.yml
vendored
6
.github/workflows/codeql.yml
vendored
@ -29,16 +29,16 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
|
uses: github/codeql-action/init@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5
|
||||||
with:
|
with:
|
||||||
config-file: ./.github/codeql/codeql-config.yml
|
config-file: ./.github/codeql/codeql-config.yml
|
||||||
languages: "javascript"
|
languages: "javascript"
|
||||||
queries: +security-and-quality
|
queries: +security-and-quality
|
||||||
|
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
|
uses: github/codeql-action/autobuild@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
|
uses: github/codeql-action/analyze@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5
|
||||||
with:
|
with:
|
||||||
category: "/language:javascript"
|
category: "/language:javascript"
|
||||||
|
2
.github/workflows/scorecard.yml
vendored
2
.github/workflows/scorecard.yml
vendored
@ -73,6 +73,6 @@ jobs:
|
|||||||
# Upload the results to GitHub's code scanning dashboard (optional).
|
# Upload the results to GitHub's code scanning dashboard (optional).
|
||||||
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
|
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3
|
uses: github/codeql-action/upload-sarif@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
@ -12,7 +12,7 @@ import Backdrop from './util/backdrop.js'
|
|||||||
import { enableDismissTrigger } from './util/component-functions.js'
|
import { enableDismissTrigger } from './util/component-functions.js'
|
||||||
import FocusTrap from './util/focustrap.js'
|
import FocusTrap from './util/focustrap.js'
|
||||||
import {
|
import {
|
||||||
defineJQueryPlugin, isRTL, isVisible, reflow
|
defineJQueryPlugin, execute, isRTL, isVisible, reflow
|
||||||
} from './util/index.js'
|
} from './util/index.js'
|
||||||
import ScrollBarHelper from './util/scrollbar.js'
|
import ScrollBarHelper from './util/scrollbar.js'
|
||||||
|
|
||||||
@ -54,9 +54,9 @@ const Default = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DefaultType = {
|
const DefaultType = {
|
||||||
backdrop: '(boolean|string)',
|
backdrop: '(boolean|string|function)',
|
||||||
focus: 'boolean',
|
focus: '(boolean|function)',
|
||||||
keyboard: 'boolean'
|
keyboard: '(boolean|function)'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,7 +157,7 @@ class Modal extends BaseComponent {
|
|||||||
// Private
|
// Private
|
||||||
_initializeBackDrop() {
|
_initializeBackDrop() {
|
||||||
return new Backdrop({
|
return new Backdrop({
|
||||||
isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value,
|
isVisible: Boolean(this._resolvePossibleFunction(this._config.backdrop)), // 'static' option will be translated to true, and booleans will keep their value
|
||||||
isAnimated: this._isAnimated()
|
isAnimated: this._isAnimated()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ class Modal extends BaseComponent {
|
|||||||
this._element.classList.add(CLASS_NAME_SHOW)
|
this._element.classList.add(CLASS_NAME_SHOW)
|
||||||
|
|
||||||
const transitionComplete = () => {
|
const transitionComplete = () => {
|
||||||
if (this._config.focus) {
|
if (this._resolvePossibleFunction(this._config.focus)) {
|
||||||
this._focustrap.activate()
|
this._focustrap.activate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +209,7 @@ class Modal extends BaseComponent {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._config.keyboard) {
|
if (this._resolvePossibleFunction(this._config.keyboard)) {
|
||||||
this.hide()
|
this.hide()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -230,12 +230,14 @@ class Modal extends BaseComponent {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._config.backdrop === 'static') {
|
const backdrop = this._resolvePossibleFunction(this._config.backdrop)
|
||||||
|
|
||||||
|
if (backdrop === 'static') {
|
||||||
this._triggerBackdropTransition()
|
this._triggerBackdropTransition()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._config.backdrop) {
|
if (backdrop) {
|
||||||
this.hide()
|
this.hide()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -314,6 +316,10 @@ class Modal extends BaseComponent {
|
|||||||
this._element.style.paddingRight = ''
|
this._element.style.paddingRight = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_resolvePossibleFunction(arg) {
|
||||||
|
return execute(arg, [this])
|
||||||
|
}
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static jQueryInterface(config, relatedTarget) {
|
static jQueryInterface(config, relatedTarget) {
|
||||||
return this.each(function () {
|
return this.each(function () {
|
||||||
|
@ -237,6 +237,7 @@ describe('Modal', () => {
|
|||||||
modal.show()
|
modal.show()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should set is transitioning if fade class is present', () => {
|
it('should set is transitioning if fade class is present', () => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
fixtureEl.innerHTML = '<div class="modal fade"><div class="modal-dialog"></div></div>'
|
fixtureEl.innerHTML = '<div class="modal fade"><div class="modal-dialog"></div></div>'
|
||||||
@ -550,6 +551,7 @@ describe('Modal', () => {
|
|||||||
modal.show()
|
modal.show()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should close modal when escape key is pressed with keyboard = true and backdrop is static', () => {
|
it('should close modal when escape key is pressed with keyboard = true and backdrop is static', () => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||||
@ -677,6 +679,44 @@ describe('Modal', () => {
|
|||||||
modal.show()
|
modal.show()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should call .focus() when config function returns true', () => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||||
|
|
||||||
|
const modalEl = fixtureEl.querySelector('.modal')
|
||||||
|
const focusSpy = spyOn(modalEl, 'focus')
|
||||||
|
const modal = new Modal(modalEl, {
|
||||||
|
focus: () => true
|
||||||
|
})
|
||||||
|
|
||||||
|
modalEl.addEventListener('shown.bs.modal', () => {
|
||||||
|
expect(focusSpy).toHaveBeenCalled()
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
|
||||||
|
modal.show()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should NOT call .focus() when config function returns false', () => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||||
|
|
||||||
|
const modalEl = fixtureEl.querySelector('.modal')
|
||||||
|
const focusSpy = spyOn(modalEl, 'focus')
|
||||||
|
const modal = new Modal(modalEl, {
|
||||||
|
focus: () => false
|
||||||
|
})
|
||||||
|
|
||||||
|
modalEl.addEventListener('shown.bs.modal', () => {
|
||||||
|
expect(focusSpy).not.toHaveBeenCalled()
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
|
||||||
|
modal.show()
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('hide', () => {
|
describe('hide', () => {
|
||||||
@ -766,6 +806,129 @@ describe('Modal', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should not close on Escape when "keyboard" option is dynamically changed to false', () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||||
|
|
||||||
|
const config = { keyboard: 'closing' }
|
||||||
|
|
||||||
|
const modalEl = fixtureEl.querySelector('.modal')
|
||||||
|
const modal = new Modal(modalEl, {
|
||||||
|
keyboard: () => config.keyboard === 'closing'
|
||||||
|
})
|
||||||
|
|
||||||
|
modalEl.addEventListener('shown.bs.modal', () => {
|
||||||
|
config.keyboard = 'nothing'
|
||||||
|
|
||||||
|
const keydownEscape = createEvent('keydown')
|
||||||
|
keydownEscape.key = 'Escape'
|
||||||
|
modalEl.dispatchEvent(keydownEscape)
|
||||||
|
|
||||||
|
expect(modal._isShown).toBeTrue()
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
|
||||||
|
modalEl.addEventListener('hidden.bs.modal', () => {
|
||||||
|
reject(new Error('Should not hide a modal'))
|
||||||
|
})
|
||||||
|
|
||||||
|
modal.show()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should close on Escape when "keyboard" option is dynamically changed to true', () => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||||
|
|
||||||
|
const config = { keyboard: 'nothing' }
|
||||||
|
|
||||||
|
const modalEl = fixtureEl.querySelector('.modal')
|
||||||
|
const modal = new Modal(modalEl, {
|
||||||
|
keyboard: () => config.keyboard === 'closing'
|
||||||
|
})
|
||||||
|
|
||||||
|
modalEl.addEventListener('shown.bs.modal', () => {
|
||||||
|
config.keyboard = 'closing'
|
||||||
|
|
||||||
|
const keydownEscape = createEvent('keydown')
|
||||||
|
keydownEscape.key = 'Escape'
|
||||||
|
modalEl.dispatchEvent(keydownEscape)
|
||||||
|
})
|
||||||
|
|
||||||
|
modalEl.addEventListener('hidden.bs.modal', () => {
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
|
||||||
|
modal.show()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should close by backdrop click when option dynamically changed to true', () => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||||
|
|
||||||
|
const config = { backdrop: 'static' }
|
||||||
|
const modalEl = fixtureEl.querySelector('.modal')
|
||||||
|
const modal = new Modal(modalEl, {
|
||||||
|
backdrop: () => config.backdrop
|
||||||
|
})
|
||||||
|
|
||||||
|
const backdropSpy = spyOn(modal._backdrop, 'hide').and.callThrough()
|
||||||
|
EventHandler.one(modalEl, 'click', () => {
|
||||||
|
if (config.backdrop === false) {
|
||||||
|
modal.hide()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
modalEl.addEventListener('shown.bs.modal', () => {
|
||||||
|
config.backdrop = false
|
||||||
|
|
||||||
|
modalEl.click()
|
||||||
|
})
|
||||||
|
|
||||||
|
modalEl.addEventListener('hidden.bs.modal', () => {
|
||||||
|
expect(backdropSpy).toHaveBeenCalled()
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
|
||||||
|
modal.show()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should not close by backdrop click when option dynamically changed to "static"', () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||||
|
|
||||||
|
const config = { backdrop: false }
|
||||||
|
const modalEl = fixtureEl.querySelector('.modal')
|
||||||
|
const modal = new Modal(modalEl, {
|
||||||
|
backdrop: () => config.backdrop
|
||||||
|
})
|
||||||
|
|
||||||
|
const backdropSpy = spyOn(modal._backdrop, 'hide').and.callThrough()
|
||||||
|
EventHandler.one(modalEl, 'click', () => {
|
||||||
|
if (config.backdrop === false) {
|
||||||
|
modal.hide()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
modalEl.addEventListener('shown.bs.modal', () => {
|
||||||
|
config.backdrop = 'static'
|
||||||
|
|
||||||
|
modalEl.click()
|
||||||
|
|
||||||
|
expect(backdropSpy).not.toHaveBeenCalled()
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
|
||||||
|
modalEl.addEventListener('hidden.bs.modal', () => {
|
||||||
|
reject(new Error('Should not hide a modal'))
|
||||||
|
})
|
||||||
|
|
||||||
|
modal.show()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('should do nothing is the modal is not shown', () => {
|
it('should do nothing is the modal is not shown', () => {
|
||||||
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||||
|
|
||||||
@ -1077,6 +1240,7 @@ describe('Modal', () => {
|
|||||||
modal.show()
|
modal.show()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not focus the trigger if the modal is not visible', () => {
|
it('should not focus the trigger if the modal is not visible', () => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
fixtureEl.innerHTML = [
|
fixtureEl.innerHTML = [
|
||||||
@ -1109,6 +1273,7 @@ describe('Modal', () => {
|
|||||||
trigger.click()
|
trigger.click()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not focus the trigger if the modal is not shown', () => {
|
it('should not focus the trigger if the modal is not shown', () => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
fixtureEl.innerHTML = [
|
fixtureEl.innerHTML = [
|
||||||
@ -1162,6 +1327,7 @@ describe('Modal', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('jQueryInterface', () => {
|
describe('jQueryInterface', () => {
|
||||||
it('should create a modal', () => {
|
it('should create a modal', () => {
|
||||||
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
fixtureEl.innerHTML = '<div class="modal"><div class="modal-dialog"></div></div>'
|
||||||
|
107
package-lock.json
generated
107
package-lock.json
generated
@ -43,7 +43,7 @@
|
|||||||
"bundlewatch": "^0.4.1",
|
"bundlewatch": "^0.4.1",
|
||||||
"clean-css-cli": "^5.6.3",
|
"clean-css-cli": "^5.6.3",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
"cross-env": "^10.0.0",
|
"cross-env": "^10.1.0",
|
||||||
"eslint": "8.57.1",
|
"eslint": "8.57.1",
|
||||||
"eslint-config-xo": "0.45.0",
|
"eslint-config-xo": "0.45.0",
|
||||||
"eslint-plugin-html": "^8.1.3",
|
"eslint-plugin-html": "^8.1.3",
|
||||||
@ -52,7 +52,7 @@
|
|||||||
"eslint-plugin-unicorn": "56.0.1",
|
"eslint-plugin-unicorn": "56.0.1",
|
||||||
"find-unused-sass-variables": "^6.1.0",
|
"find-unused-sass-variables": "^6.1.0",
|
||||||
"github-slugger": "^2.0.0",
|
"github-slugger": "^2.0.0",
|
||||||
"globby": "^14.1.0",
|
"globby": "^15.0.0",
|
||||||
"hammer-simulator": "0.0.1",
|
"hammer-simulator": "0.0.1",
|
||||||
"htmlparser2": "^10.0.0",
|
"htmlparser2": "^10.0.0",
|
||||||
"image-size": "^2.0.2",
|
"image-size": "^2.0.2",
|
||||||
@ -2196,9 +2196,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@cacheable/memory/node_modules/keyv": {
|
"node_modules/@cacheable/memory/node_modules/keyv": {
|
||||||
"version": "5.5.2",
|
"version": "5.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.3.tgz",
|
||||||
"integrity": "sha512-TXcFHbmm/z7MGd1u9ASiCSfTS+ei6Z8B3a5JHzx3oPa/o7QzWVtPRpc4KGER5RR469IC+/nfg4U5YLIuDUua2g==",
|
"integrity": "sha512-h0Un1ieD+HUrzBH6dJXhod3ifSghk5Hw/2Y4/KHBziPlZecrFyE9YOTPU6eOs0V9pYl8gOs86fkr/KN8lUX39A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -4322,9 +4322,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@sindresorhus/merge-streams": {
|
"node_modules/@sindresorhus/merge-streams": {
|
||||||
"version": "2.3.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
|
||||||
"integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
|
"integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -4552,9 +4552,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "18.19.127",
|
"version": "18.19.128",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.127.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.128.tgz",
|
||||||
"integrity": "sha512-gSjxjrnKXML/yo0BO099uPixMqfpJU0TKYjpfLU7TrtA2WWDki412Np/RSTPRil1saKBhvVVKzVx/p/6p94nVA==",
|
"integrity": "sha512-m7wxXGpPpqxp2QDi/rpih5O772APRuBIa/6XiGqLNoM1txkjI8Sz1V4oSXJxQLTz/yP5mgy9z6UXEO6/lP70Gg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -5322,9 +5322,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "0.30.1",
|
"version": "0.30.2",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.30.1.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.30.2.tgz",
|
||||||
"integrity": "sha512-2XabsR1u0/B6OoKy57/xJmPkQiUvdoV93oW4ww+Xjee7C2er/O5U77lvqycDkT2VQDtfjYcjw8ZV8GDaoqwjHQ==",
|
"integrity": "sha512-0pE4RQ4UQi1jKY6p7u6i1Tkzqmu+d+/tHS7Q7rKunWLB9WyilBTpHHpXzPNMDj5hTbK0B0PTLSz07yqMBiF6xg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -5442,9 +5442,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/baseline-browser-mapping": {
|
"node_modules/baseline-browser-mapping": {
|
||||||
"version": "2.8.7",
|
"version": "2.8.9",
|
||||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.7.tgz",
|
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.9.tgz",
|
||||||
"integrity": "sha512-bxxN2M3a4d1CRoQC//IqsR5XrLh0IJ8TCv2x6Y9N0nckNz/rTjZB3//GGscZziZOxmjP55rzxg/ze7usFI9FqQ==",
|
"integrity": "sha512-hY/u2lxLrbecMEWSB0IpGzGyDyeoMFQhCvZd2jGFSE5I17Fh01sYUBPCJtkWERw7zrac9+cIghxm/ytJa2X8iA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
@ -5804,9 +5804,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cacheable/node_modules/keyv": {
|
"node_modules/cacheable/node_modules/keyv": {
|
||||||
"version": "5.5.2",
|
"version": "5.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.3.tgz",
|
||||||
"integrity": "sha512-TXcFHbmm/z7MGd1u9ASiCSfTS+ei6Z8B3a5JHzx3oPa/o7QzWVtPRpc4KGER5RR469IC+/nfg4U5YLIuDUua2g==",
|
"integrity": "sha512-h0Un1ieD+HUrzBH6dJXhod3ifSghk5Hw/2Y4/KHBziPlZecrFyE9YOTPU6eOs0V9pYl8gOs86fkr/KN8lUX39A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -6512,9 +6512,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cross-env": {
|
"node_modules/cross-env": {
|
||||||
"version": "10.0.0",
|
"version": "10.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
|
||||||
"integrity": "sha512-aU8qlEK/nHYtVuN4p7UQgAwVljzMg8hB4YK5ThRqD2l/ziSnryncPNn7bMLt5cFYsKVKBh8HqLqyCoTupEUu7Q==",
|
"integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -7090,9 +7090,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.224",
|
"version": "1.5.227",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.224.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.227.tgz",
|
||||||
"integrity": "sha512-kWAoUu/bwzvnhpdZSIc6KUyvkI1rbRXMT0Eq8pKReyOyaPZcctMli+EgvcN1PAvwVc7Tdo4Fxi2PsLNDU05mdg==",
|
"integrity": "sha512-ITxuoPfJu3lsNWUi2lBM2PaBPYgH3uqmxut5vmBxgYvyI4AlJ6P3Cai1O76mOrkJCBzq0IxWg/NtqOrpu/0gKA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@ -8603,6 +8603,16 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/generator-function": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-xPypGGincdfyl/AiSGa7GjXLkvld9V7GjZlowup9SHIJnQnHLFiLODCd/DqKOp0PBagbHJ68r1KJI9Mut7m4sA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gensync": {
|
"node_modules/gensync": {
|
||||||
"version": "1.0.0-beta.2",
|
"version": "1.0.0-beta.2",
|
||||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||||
@ -8836,21 +8846,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/globby": {
|
"node_modules/globby": {
|
||||||
"version": "14.1.0",
|
"version": "15.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/globby/-/globby-15.0.0.tgz",
|
||||||
"integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==",
|
"integrity": "sha512-oB4vkQGqlMl682wL1IlWd02tXCbquGWM4voPEI85QmNKCaw8zGTm1f1rubFgkg3Eli2PtKlFgrnmUqasbQWlkw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sindresorhus/merge-streams": "^2.1.0",
|
"@sindresorhus/merge-streams": "^4.0.0",
|
||||||
"fast-glob": "^3.3.3",
|
"fast-glob": "^3.3.3",
|
||||||
"ignore": "^7.0.3",
|
"ignore": "^7.0.5",
|
||||||
"path-type": "^6.0.0",
|
"path-type": "^6.0.0",
|
||||||
"slash": "^5.1.0",
|
"slash": "^5.1.0",
|
||||||
"unicorn-magic": "^0.3.0"
|
"unicorn-magic": "^0.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=20"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
@ -9915,13 +9925,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-generator-function": {
|
"node_modules/is-generator-function": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.1.tgz",
|
||||||
"integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
|
"integrity": "sha512-Gn8BWUdrTzf9XUJAvqIYP7QnSC3mKs8QjQdGdJ7HmBemzZo14wj/OVmmAwgxDX/7WhFEjboybL4VhXGIQYPlOA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"call-bound": "^1.0.3",
|
"call-bound": "^1.0.3",
|
||||||
|
"generator-function": "^2.0.0",
|
||||||
"get-proto": "^1.0.0",
|
"get-proto": "^1.0.0",
|
||||||
"has-tostringtag": "^1.0.2",
|
"has-tostringtag": "^1.0.2",
|
||||||
"safe-regex-test": "^1.1.0"
|
"safe-regex-test": "^1.1.0"
|
||||||
@ -10521,16 +10532,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jest-diff": {
|
"node_modules/jest-diff": {
|
||||||
"version": "30.1.2",
|
"version": "30.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz",
|
||||||
"integrity": "sha512-4+prq+9J61mOVXCa4Qp8ZjavdxzrWQXrI80GNxP8f4tkI2syPuPrJgdRPZRrfUTRvIoUwcmNLbqEJy9W800+NQ==",
|
"integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jest/diff-sequences": "30.0.1",
|
"@jest/diff-sequences": "30.0.1",
|
||||||
"@jest/get-type": "30.1.0",
|
"@jest/get-type": "30.1.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"pretty-format": "30.0.5"
|
"pretty-format": "30.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
|
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
|
||||||
@ -14834,9 +14845,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pretty-format": {
|
"node_modules/pretty-format": {
|
||||||
"version": "30.0.5",
|
"version": "30.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz",
|
||||||
"integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==",
|
"integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -18971,9 +18982,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vscode-css-languageservice": {
|
"node_modules/vscode-css-languageservice": {
|
||||||
"version": "6.3.7",
|
"version": "6.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-6.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-6.3.8.tgz",
|
||||||
"integrity": "sha512-5TmXHKllPzfkPhW4UE9sODV3E0bIOJPOk+EERKllf2SmAczjfTmYeq5txco+N3jpF8KIZ6loj/JptpHBQuVQRA==",
|
"integrity": "sha512-dBk/9ullEjIMbfSYAohGpDOisOVU1x2MQHOeU12ohGJQI7+r0PCimBwaa/pWpxl/vH4f7ibrBfxIZY3anGmHKQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -18984,9 +18995,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vscode-html-languageservice": {
|
"node_modules/vscode-html-languageservice": {
|
||||||
"version": "5.5.1",
|
"version": "5.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.5.2.tgz",
|
||||||
"integrity": "sha512-/ZdEtsZ3OiFSyL00kmmu7crFV9KwWR+MgpzjsxO60DQH7sIfHZM892C/E4iDd11EKocr+NYuvOA4Y7uc3QzLEA==",
|
"integrity": "sha512-QpaUhCjvb7U/qThOzo4V6grwsRE62Jk/vf8BRJZoABlMw3oplLB5uovrvcrLO9vYhkeMiSjyqLnCxbfHzzZqmw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -132,7 +132,7 @@
|
|||||||
"bundlewatch": "^0.4.1",
|
"bundlewatch": "^0.4.1",
|
||||||
"clean-css-cli": "^5.6.3",
|
"clean-css-cli": "^5.6.3",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
"cross-env": "^10.0.0",
|
"cross-env": "^10.1.0",
|
||||||
"eslint": "8.57.1",
|
"eslint": "8.57.1",
|
||||||
"eslint-config-xo": "0.45.0",
|
"eslint-config-xo": "0.45.0",
|
||||||
"eslint-plugin-html": "^8.1.3",
|
"eslint-plugin-html": "^8.1.3",
|
||||||
@ -141,7 +141,7 @@
|
|||||||
"eslint-plugin-unicorn": "56.0.1",
|
"eslint-plugin-unicorn": "56.0.1",
|
||||||
"find-unused-sass-variables": "^6.1.0",
|
"find-unused-sass-variables": "^6.1.0",
|
||||||
"github-slugger": "^2.0.0",
|
"github-slugger": "^2.0.0",
|
||||||
"globby": "^14.1.0",
|
"globby": "^15.0.0",
|
||||||
"hammer-simulator": "0.0.1",
|
"hammer-simulator": "0.0.1",
|
||||||
"htmlparser2": "^10.0.0",
|
"htmlparser2": "^10.0.0",
|
||||||
"image-size": "^2.0.2",
|
"image-size": "^2.0.2",
|
||||||
|
@ -3,3 +3,5 @@ As options can be passed via data attributes or JavaScript, you can append an op
|
|||||||
As of Bootstrap 5.2.0, all components support an **experimental** reserved data attribute `data-bs-config` that can house simple component configuration as a JSON string. When an element has `data-bs-config='{"delay":0, "title":123}'` and `data-bs-title="456"` attributes, the final `title` value will be `456` and the separate data attributes will override values given on `data-bs-config`. In addition, existing data attributes are able to house JSON values like `data-bs-delay='{"show":0,"hide":150}'`.
|
As of Bootstrap 5.2.0, all components support an **experimental** reserved data attribute `data-bs-config` that can house simple component configuration as a JSON string. When an element has `data-bs-config='{"delay":0, "title":123}'` and `data-bs-title="456"` attributes, the final `title` value will be `456` and the separate data attributes will override values given on `data-bs-config`. In addition, existing data attributes are able to house JSON values like `data-bs-delay='{"show":0,"hide":150}'`.
|
||||||
|
|
||||||
The final configuration object is the merged result of `data-bs-config`, `data-bs-`, and `js object` where the latest given key-value overrides the others.
|
The final configuration object is the merged result of `data-bs-config`, `data-bs-`, and `js object` where the latest given key-value overrides the others.
|
||||||
|
|
||||||
|
You can pass a callback function there, which undertakes to return the value type specified for the parameter. This will allow you to change the logic of the modal window in runtime mode after you have passed the configuration object.
|
||||||
|
@ -782,11 +782,44 @@ const myModalAlternative = new bootstrap.Modal('#myModal', options)
|
|||||||
<BsTable>
|
<BsTable>
|
||||||
| Name | Type | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `backdrop` | boolean, `’static'` | `true` | Includes a modal-backdrop element. Alternatively, specify `static` for a backdrop which doesn’t close the modal when clicked. |
|
| `backdrop` | true, `’static'`, <br /> function | `true` | Includes a modal-backdrop element. Alternatively, specify `static` for a backdrop which doesn’t close the modal when clicked. |
|
||||||
| `focus` | boolean | `true` | Puts the focus on the modal when initialized. |
|
| `focus` | boolean, function | `true` | Puts the focus on the modal when initialized. |
|
||||||
| `keyboard` | boolean | `true` | Closes the modal when escape key is pressed. |
|
| `keyboard` | boolean, function | `true` | Closes the modal when escape key is pressed. |
|
||||||
</BsTable>
|
</BsTable>
|
||||||
|
|
||||||
|
For example, if you want to prevent the user from closing the modal window using the Escape key to avoid accidental loss
|
||||||
|
of important data if they are entered, you can use instead:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const confirmInput = document.getElementById('confirmInput')
|
||||||
|
const modalElement = document.getElementById('confirmModal')
|
||||||
|
|
||||||
|
new bootstrap.Modal(modalElement, { keyboard: true })
|
||||||
|
|
||||||
|
const keydownBlocker = event => {
|
||||||
|
if (event.key === 'Escape' && confirmInput.value.toLowerCase() === 'save') {
|
||||||
|
event.stopPropagation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modalElement.addEventListener('show.bs.modal', () => {
|
||||||
|
document.addEventListener('keydown', keydownBlocker, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
modalElement.addEventListener('hide.bs.modal', () => {
|
||||||
|
document.removeEventListener('keydown', keydownBlocker, true)
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
The next option is to transfer the function:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const confirmInput = document.getElementById('confirmInput')
|
||||||
|
const modalElement = document.getElementById('confirmModal')
|
||||||
|
|
||||||
|
new bootstrap.Modal(modalElement, { keyboard: () => confirmInput.value.toLowerCase() !== 'save' })
|
||||||
|
```
|
||||||
|
|
||||||
### Methods
|
### Methods
|
||||||
|
|
||||||
<Callout name="danger-async-methods" type="danger" />
|
<Callout name="danger-async-methods" type="danger" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user