Skip to content
Snippets Groups Projects
Commit 79713a5a authored by Erwan Rouchet's avatar Erwan Rouchet Committed by Bastien Abadie
Browse files

Custom Mousetrap keyboard event filter

parent b8932e9c
No related branches found
No related tags found
1 merge request!1473Custom Mousetrap keyboard event filter
......@@ -32,6 +32,7 @@
"@types/chai": "^4.3.3",
"@types/lodash": "^4.14.186",
"@types/mocha": "^8.2.3",
"@types/mousetrap": "^1.6.11",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"@vue/cli": "^5.0.8",
......@@ -2952,6 +2953,12 @@
"integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==",
"dev": true
},
"node_modules/@types/mousetrap": {
"version": "1.6.11",
"resolved": "https://registry.npmjs.org/@types/mousetrap/-/mousetrap-1.6.11.tgz",
"integrity": "sha512-F0oAily9Q9QQpv9JKxKn0zMKfOo36KHCW7myYsmUyf2t0g+sBTbG3UleTPoguHdE1z3GLFr3p7/wiOio52QFjQ==",
"dev": true
},
"node_modules/@types/node": {
"version": "18.6.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.4.tgz",
......@@ -21603,6 +21610,12 @@
"integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==",
"dev": true
},
"@types/mousetrap": {
"version": "1.6.11",
"resolved": "https://registry.npmjs.org/@types/mousetrap/-/mousetrap-1.6.11.tgz",
"integrity": "sha512-F0oAily9Q9QQpv9JKxKn0zMKfOo36KHCW7myYsmUyf2t0g+sBTbG3UleTPoguHdE1z3GLFr3p7/wiOio52QFjQ==",
"dev": true
},
"@types/node": {
"version": "18.6.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.4.tgz",
......@@ -71,13 +71,12 @@ export default {
modelValue: {
immediate: true,
handler (newValue, oldValue) {
if (newValue === oldValue) return
if (newValue) this.onOpen()
else this.onClose()
else if (oldValue !== undefined) this.onClose()
}
}
},
beforeUnmount () {
unmounted () {
// Ensure we activate scrolling again if the modal was opened but suddenly gets destroyed
this.onClose()
}
......
......@@ -25,6 +25,7 @@ import store from './store'
import App from '@/views/App.vue'
import axios from 'axios'
import Mousetrap from 'mousetrap'
import * as Sentry from '@sentry/vue'
import { ExtraErrorData as ExtraErrorDataIntegration } from '@sentry/integrations'
......@@ -161,4 +162,35 @@ if (SENTRY_DSN) {
})
}
/*
* Overwrite the Mousetrap.stopCallback function, which filters keyboard events to determine if they should be applied.
* The default implementation rejects all events for <input>, <select>, <textarea> and any element with `contenteditable`,
* unless they have the `mousetrap` CSS class.
* We now allow the Esc key anywhere within a Bulma modal, and allow both Esc and Enter on every element except textareas.
* Original implementation: https://github.com/ccampbell/mousetrap/blob/2f9a476ba6158ba69763e4fcf914966cc72ef433/mousetrap.js#L973
*/
Mousetrap.prototype.stopCallback = (e: Mousetrap.ExtendedKeyboardEvent, element: Element, combo: string): boolean => {
// We only need to apply special handling for <input>, <select>, <textarea>, and any element with the `contenteditable` HTML attribute.
if (
!['INPUT', 'SELECT', 'TEXTAREA'].includes(element.tagName) && (
!(element instanceof HTMLElement) ||
element.contentEditable !== 'true'
)
) return false
// Allow the `mousetrap` CSS class to force all events to be accepted, just like the original implementation
if (element.classList.contains('mousetrap')) return false
// Detect whether any parent element is a modal
if (element.matches(`.modal ${element.tagName}`)) {
// In a textarea, ignore all events except the Esc key
if (element.tagName === 'TEXTAREA') return combo !== 'esc'
// Outside a textarea, ignore all events except Esc and Enter
else return !['esc', 'enter'].includes(combo)
}
// We are not in modal, but we are in a form field, ignore everything
return true
}
app.mount('#app')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment