From ddfa131e135bfed4945e6123211ade14ea902504 Mon Sep 17 00:00:00 2001
From: Joren Van Onder <jov@odoo.com>
Date: Thu, 28 May 2015 12:00:33 +0200
Subject: [PATCH] [IMP] barcode_events: deal with special keys in Firefox

Let arrow keys, tab and escape pass through. We still want users to be
able to use eg. arrow keys to be used when selecting a radio item. This
will always work in Chrom{e,ium} because they do not dispatch keypress
events for these types of keys, only keydown/keyup events. Firefox does
dispatch keypress events. This makes sure that we do not touch those
types of events in Firefox.

devices have to fire keypresses every 50ms minimum

Previously this was 100ms. This works just as well, but was mainly in
there for testing purposes.
---
 .../static/src/js/framework/barcode_events.js | 30 +++++++++++++------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/addons/web/static/src/js/framework/barcode_events.js b/addons/web/static/src/js/framework/barcode_events.js
index 5956eee08ee2..d632c9e5cd79 100644
--- a/addons/web/static/src/js/framework/barcode_events.js
+++ b/addons/web/static/src/js/framework/barcode_events.js
@@ -73,6 +73,20 @@ odoo.define('web.BarcodeEvents', function(require) {
             return $(element).is('input,textarea,[contenteditable="true"]');
         },
 
+        // This checks that a keypress event is either ESC, TAB or an
+        // arrow key. This is Firefox specific, in Chrom{e,ium}
+        // keypress events are not fired for these types of keys, only
+        // keyup/keydown.
+        is_special_key: function(e) {
+            if (e.key === "ArrowLeft" || e.key === "ArrowRight" ||
+                e.key === "ArrowUp" || e.key === "ArrowDown" ||
+                e.key === "Escape" || e.key === "Tab") {
+                return true;
+            } else {
+                return false;
+            }
+        },
+
         // The keydown and keyup handlers are here to disallow key
         // repeat. When preventDefault() is called on a keydown event
         // the keypress that normally follows is cancelled.
@@ -89,21 +103,19 @@ odoo.define('web.BarcodeEvents', function(require) {
         },
 
         handler: function(e){
-            if (! e.dispatched_by_barcode_reader) {
-                // We only stop events targeting body (meaning nothing is
-                // focused). We do not stop events targeting other elements
-                // because we have no way of redispatching 'genuine' key events
-                // that trigger native event handlers of elements. So this means
-                // that our fake events will not appear in eg. an <input>
-                // element. The addition of the contentEditable attribute in HTML5
-                // means that this is not only limited to <input>, <textarea>,...
+            if (! e.dispatched_by_barcode_reader && ! this.is_special_key(e)) {
+                // We only stop events targeting elements that are editable. We
+                // do not stop events targeting other elements because we have
+                // no way of redispatching 'genuine' key events that trigger
+                // native event handlers of elements. So this means that our
+                // fake events will not appear in eg. an <input> element.
                 if (! this.element_is_editable(e.target) || e.target.getAttribute("barcode_events") === "true") {
                     this.buffered_key_events.push(e);
                     e.preventDefault();
                     e.stopImmediatePropagation();
 
                     clearTimeout(this.timeout);
-                    this.timeout = setTimeout(this.handle_buffered_keys.bind(this), 100);
+                    this.timeout = setTimeout(this.handle_buffered_keys.bind(this), 50);
                 }
             }
         },
-- 
GitLab