[REF] barcodes: simplify isSpecialKey method

Note that more 'non printable keys' are escaped now, like 'Home'.
This seems like a bit naive solution but it avoids having to list
every key.
The only issue we might have is if a device sends the whole value in the
'key' property directly without sending sequentially several keydown events.

As a reminder, 'ctrlKey', 'metaKey', 'altKey' properties are used
because we also want to ignore keys pressed while this modifier is
active. For example, if you press CTRL+e, we want to ignore 'CTRL'
AND 'e'.

Useful references:
https://w3c.github.io/uievents/tools/key-event-viewer.html

Part-of: odoo/odoo#93387
This commit is contained in:
Adrien Dieudonné
2022-07-04 14:07:27 +02:00
parent f7ff35dad0
commit a8312703f6
3 changed files with 12 additions and 28 deletions
+12 -26
View File
@@ -6,16 +6,6 @@ import { session } from "@web/session";
const { EventBus, whenReady } = owl;
function isSpecialKey(key) {
return (key === "ArrowLeft" || key === "ArrowRight" ||
key === "ArrowUp" || key === "ArrowDown" ||
key === "Escape" ||
key === "Backspace" || key === "Delete" ||
key === "Home" || key === "End" ||
key === "PageUp" || key === "PageDown" ||
key === "Shift" || /F\d\d?/.test(key));
}
function isEditable(element) {
return element.matches('input,textarea,[contenteditable="true"]');
}
@@ -40,8 +30,6 @@ export const barcodeService = {
start() {
const bus = new EventBus();
const endRegexp = /[\n\r\t]+/;
const barcodeRegexp = /(.{3,})[\n\r\t]*/;
let timeout = null;
let bufferedBarcode = "";
@@ -60,10 +48,8 @@ export const barcodeService = {
*/
function checkBarcode() {
const str = barcodeInput ? barcodeInput.value : bufferedBarcode;
const match = str.match(barcodeRegexp);
if (match) {
const barcode = match[1];
handleBarcode(barcode, currentTarget);
if (str.length >= 3) {
handleBarcode(str, currentTarget);
}
if (barcodeInput) {
barcodeInput.value = "";
@@ -73,12 +59,14 @@ export const barcodeService = {
}
function keydownHandler(ev) {
// Don't catch non-printable keys for which Firefox triggers a keypress
if (isSpecialKey(ev.key)) {
return;
}
// Don't catch keypresses which could have a UX purpose (like shortcuts)
if (ev.ctrlKey || ev.metaKey || ev.altKey) {
// Ignore 'Shift', 'Escape', 'Backspace', 'Insert', 'Delete', 'Home', 'End', Arrow*, F*, Page*, ...
// ctrl, meta and alt are often used for UX purpose (like shortcuts)
// Note: shiftKey is not ignored because it can be used by some barcode scanner for digits.
const isSpecialKey = ev.key.length > 1 || ev.ctrlKey || ev.metaKey || ev.altKey;
const isEndCharacter = ev.key.match(/(Enter|Tab)/);
// Don't catch non-printable keys except 'enter' and 'tab'
if (isSpecialKey && !isEndCharacter) {
return;
}
@@ -93,13 +81,11 @@ export const barcodeService = {
return;
}
if (ev.key !== "Enter" && ev.key !== "Unidentified") {
bufferedBarcode += ev.key;
}
clearTimeout(timeout);
if (String.fromCharCode(ev.which).match(endRegexp)) {
if (isEndCharacter) {
checkBarcode();
} else {
bufferedBarcode += ev.key;
timeout = setTimeout(checkBarcode, barcodeService.maxTimeBetweenKeysInMs);
}
}
@@ -23,7 +23,6 @@ odoo.define('barcodes.barcode_mobile_tests', function (require) {
triggerEvent(target, 'keydown', {
key: char,
keyCode: keycode,
which: keycode,
});
}
@@ -32,7 +32,6 @@ function simulateBarCode(chars, target = document.body) {
triggerEvent(target, 'keydown', {
key: char,
keyCode: keycode,
which: keycode,
});
}
}