diff --git a/js/src/carousel.js b/js/src/carousel.js
index a5451538cd..93f896e535 100644
--- a/js/src/carousel.js
+++ b/js/src/carousel.js
@@ -33,8 +33,8 @@ const DATA_KEY = 'bs.carousel'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
-const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key
-const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key
+const ARROW_LEFT_KEY = 'ArrowLeft'
+const ARROW_RIGHT_KEY = 'ArrowRight'
const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch
const SWIPE_THRESHOLD = 40
@@ -342,12 +342,12 @@ class Carousel {
return
}
- switch (event.which) {
- case ARROW_LEFT_KEYCODE:
+ switch (event.key) {
+ case ARROW_LEFT_KEY:
event.preventDefault()
this.prev()
break
- case ARROW_RIGHT_KEYCODE:
+ case ARROW_RIGHT_KEY:
event.preventDefault()
this.next()
break
diff --git a/js/src/dom/event-handler.js b/js/src/dom/event-handler.js
index 7fdeaa4f8e..e43edd6ee2 100644
--- a/js/src/dom/event-handler.js
+++ b/js/src/dom/event-handler.js
@@ -17,7 +17,6 @@ import { defaultPreventedPreservedOnDispatch } from './polyfill'
const $ = getjQuery()
const namespaceRegex = /[^.]*(?=\..*)\.|.*/
const stripNameRegex = /\..*/
-const keyEventRegex = /^key/
const stripUidRegex = /::\d+$/
const eventRegistry = {} // Events storage
let uidEvent = 1
@@ -94,11 +93,6 @@ function getEvent(element) {
}
function fixEvent(event, element) {
- // Add which for key events
- if (event.which === null && keyEventRegex.test(event.type)) {
- event.which = event.charCode === null ? event.keyCode : event.charCode
- }
-
event.delegateTarget = element
}
diff --git a/js/src/dropdown.js b/js/src/dropdown.js
index aab1d6bd2a..b1aa6d8496 100644
--- a/js/src/dropdown.js
+++ b/js/src/dropdown.js
@@ -31,14 +31,14 @@ const DATA_KEY = 'bs.dropdown'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
-const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
-const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key
-const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key
-const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key
-const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key
-const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)
+const ESCAPE_KEY = 'Escape'
+const SPACE_KEY = 'Space'
+const TAB_KEY = 'Tab'
+const ARROW_UP_KEY = 'ArrowUp'
+const ARROW_DOWN_KEY = 'ArrowDown'
+const RIGHT_MOUSE_BUTTON = 2 // MouseEvent.button value for the secondary button, usually the right button
-const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`)
+const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEY}|${ARROW_DOWN_KEY}|${ESCAPE_KEY}`)
const EVENT_HIDE = `hide${EVENT_KEY}`
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
@@ -372,8 +372,8 @@ class Dropdown {
}
static clearMenus(event) {
- if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH ||
- (event.type === 'keyup' && event.which !== TAB_KEYCODE))) {
+ if (event && (event.button === RIGHT_MOUSE_BUTTON ||
+ (event.type === 'keyup' && event.key !== TAB_KEY))) {
return
}
@@ -401,7 +401,7 @@ class Dropdown {
if (event && ((event.type === 'click' &&
/input|textarea/i.test(event.target.tagName)) ||
- (event.type === 'keyup' && event.which === TAB_KEYCODE)) &&
+ (event.type === 'keyup' && event.key === TAB_KEY)) &&
dropdownMenu.contains(event.target)) {
continue
}
@@ -443,10 +443,10 @@ class Dropdown {
// - If key is not up or down => not a dropdown command
// - If trigger inside the menu => not a dropdown command
if (/input|textarea/i.test(event.target.tagName) ?
- event.which === SPACE_KEYCODE || (event.which !== ESCAPE_KEYCODE &&
- ((event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE) ||
+ event.key === SPACE_KEY || (event.key !== ESCAPE_KEY &&
+ ((event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY) ||
SelectorEngine.closest(event.target, SELECTOR_MENU))) :
- !REGEXP_KEYDOWN.test(event.which)) {
+ !REGEXP_KEYDOWN.test(event.key)) {
return
}
@@ -460,14 +460,14 @@ class Dropdown {
const parent = Dropdown.getParentFromElement(this)
const isActive = this.classList.contains(CLASS_NAME_SHOW)
- if (event.which === ESCAPE_KEYCODE) {
+ if (event.key === ESCAPE_KEY) {
const button = this.matches(SELECTOR_DATA_TOGGLE) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0]
button.focus()
Dropdown.clearMenus()
return
}
- if (!isActive || event.which === SPACE_KEYCODE) {
+ if (!isActive || event.key === SPACE_KEY) {
Dropdown.clearMenus()
return
}
@@ -481,11 +481,11 @@ class Dropdown {
let index = items.indexOf(event.target) || 0
- if (event.which === ARROW_UP_KEYCODE && index > 0) { // Up
+ if (event.key === ARROW_UP_KEY && index > 0) { // Up
index--
}
- if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // Down
+ if (event.key === ARROW_DOWN_KEY && index < items.length - 1) { // Down
index++
}
diff --git a/js/src/modal.js b/js/src/modal.js
index d5f1c8c9ae..0daa428a8d 100644
--- a/js/src/modal.js
+++ b/js/src/modal.js
@@ -31,7 +31,7 @@ const VERSION = '4.3.1'
const DATA_KEY = 'bs.modal'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
-const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
+const ESCAPE_KEY = 'Escape'
const Default = {
backdrop: true,
@@ -299,10 +299,10 @@ class Modal {
_setEscapeEvent() {
if (this._isShown) {
EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
- if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {
+ if (this._config.keyboard && event.key === ESCAPE_KEY) {
event.preventDefault()
this.hide()
- } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {
+ } else if (!this._config.keyboard && event.key === ESCAPE_KEY) {
this._triggerBackdropTransition()
}
})
diff --git a/js/tests/unit/carousel.spec.js b/js/tests/unit/carousel.spec.js
index be32d19d9b..46659a032a 100644
--- a/js/tests/unit/carousel.spec.js
+++ b/js/tests/unit/carousel.spec.js
@@ -70,10 +70,10 @@ describe('Carousel', () => {
done()
})
- const keyDown = createEvent('keydown')
- keyDown.which = 39
+ const keydown = createEvent('keydown')
+ keydown.key = 'ArrowRight'
- carouselEl.dispatchEvent(keyDown)
+ carouselEl.dispatchEvent(keydown)
})
it('should go to previous item if left arrow key is pressed', done => {
@@ -100,10 +100,10 @@ describe('Carousel', () => {
done()
})
- const keyDown = createEvent('keydown')
- keyDown.which = 37
+ const keydown = createEvent('keydown')
+ keydown.key = 'ArrowLeft'
- carouselEl.dispatchEvent(keyDown)
+ carouselEl.dispatchEvent(keydown)
})
it('should not prevent keydown if key is not ARROW_LEFT or ARROW_RIGHT', done => {
@@ -130,10 +130,10 @@ describe('Carousel', () => {
done()
})
- const keyDown = createEvent('keydown')
- keyDown.which = 40
+ const keydown = createEvent('keydown')
+ keydown.key = 'ArrowDown'
- carouselEl.dispatchEvent(keyDown)
+ carouselEl.dispatchEvent(keydown)
})
it('should ignore keyboard events within s and