[FIX/REF] barcodes: don't catch keypress if a control key is pressed
This avoids breaking shortcuts on Firefox, which rely on keypress events instead of keydown / keyup. The tradeoff is that a barcode cannot be scanned and interpreted if ctrl, alt or cmd is pressed. Also don't catch function keys.
This commit is contained in:
@@ -87,14 +87,15 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, {
|
||||
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}
|
||||
// This checks that a keypress event is either ESC, TAB, an arrow
|
||||
// key or a function 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") {
|
||||
e.key === "Escape" || e.key === "Tab" ||
|
||||
/F\d\d?/.test(e.key)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -117,24 +118,34 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, {
|
||||
},
|
||||
|
||||
handler: function(e){
|
||||
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();
|
||||
// Don't catch events we resent
|
||||
if (e.dispatched_by_barcode_reader)
|
||||
return;
|
||||
// Don't catch non-printable keys for which Firefox triggers a keypress
|
||||
if (this.is_special_key(e))
|
||||
return;
|
||||
// Don't catch keypresses which could have a UX purpose (like shortcuts)
|
||||
if (e.ctrlKey || e.metaKey || e.altKey)
|
||||
return;
|
||||
// Don't catch events targeting elements that are editable because we
|
||||
// have no way of redispatching 'genuine' key events. Resent events
|
||||
// don't 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")
|
||||
return;
|
||||
|
||||
clearTimeout(this.timeout);
|
||||
if (String.fromCharCode(e.which).match(this.suffix) !== null) {
|
||||
this.handle_buffered_keys();
|
||||
} else {
|
||||
this.timeout = setTimeout(this.handle_buffered_keys.bind(this), this.max_time_between_keys_in_ms);
|
||||
}
|
||||
}
|
||||
// Catch and buffer the event
|
||||
this.buffered_key_events.push(e);
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
|
||||
// Handle buffered keys immediately if the the keypress marks the end
|
||||
// of a barcode or after x milliseconds without a new keypress
|
||||
clearTimeout(this.timeout);
|
||||
if (String.fromCharCode(e.which).match(this.suffix)) {
|
||||
this.handle_buffered_keys();
|
||||
} else {
|
||||
this.timeout = setTimeout(this.handle_buffered_keys.bind(this), this.max_time_between_keys_in_ms);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user