Skip to content

Commit

Permalink
Merge pull request #92 from nsftx/task/CU-86951mek8/SevenGravityGatew…
Browse files Browse the repository at this point in the history
…ay----Fix-barcode-plugin-moves-focus-out-of-input

Task/cu 86951mek8/seven gravity gateway    fix barcode plugin moves focus out of input
  • Loading branch information
dikaso authored Jul 30, 2024
2 parents 77d4af3 + d8caf78 commit dadb65f
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 10 deletions.
30 changes: 21 additions & 9 deletions src/plugin/barcode-scan.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ var difference = 0;
var inScanMode = false;
var secureTimerOff = null;

function isScanModeActive() {
return inScanMode || scanResult.code.length >= 2;
}

function processKeyEvent(e) {
var whitelistedKeys = new RegExp(config.regex.pattern, config.regex.flags); // Array of key codes whose values wont't be concat with ticketId (enter, shift, space, arrow down)
var isPrefixTriggered = isPrefixBased(e);
Expand Down Expand Up @@ -64,12 +68,13 @@ function processKeyEvent(e) {
);
return scanResult;
}

logger.out('debug', '[GGP] Plugin Barcode: Possible scan mode.');
// in case when we recive space,
// we want to strip any previous char,
// this will happen if we have scanner with hardcoded prefix (e.g. ctrl+b)

if (isPrefixTriggered) {
logger.out('debug', '[GGP] Plugin Barcode: Space triggered, reset final code.');
logger.out('debug', '[GGP] Plugin Barcode: Space triggered and scan mode marked as started.');
// in case when we recive space we want to strip any previous char,
// this will happen if we have scanner with hardcoded prefix (e.g. ctrl+b)
scanResult.code = '';
inScanMode = true;
secureTimerOff = setTimeout(function(){
Expand All @@ -95,13 +100,20 @@ function processKeyEvent(e) {
previousKey.receivedAt = 0;
}

e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
// prevent native keydown behavior if we detected space
// or we are in time based scan (at least two chars are added to final result)
if (isScanModeActive()) {
logger.out('debug', '[GGP] Plugin Barcode: Prevent keydown default behavior.');
e.preventDefault();
e.stopImmediatePropagation();
e.stopPropagation();
}

// we need moove focus out of any input to body so we don't enter
// codes from scaner but we don't know if first char is from scan so don't move focus when first code is entered
if (scanResult.code.length !== 0 && document.activeElement && document.activeElement.tagName.toLocaleLowerCase() !== 'body') {
// codes from scaner (e.g we could trigger enter on payin)
// but we don't know if first char is from scan so don't move focus when first code is entered
if (isScanModeActive() &&
document.activeElement && document.activeElement.tagName.toLocaleLowerCase() !== 'body') {
logger.out('debug', '[GGP] Plugin Barcode: Blur from active element.');
document.activeElement.blur();
}
Expand Down
133 changes: 132 additions & 1 deletion test/plugin-barcode-scan.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ var assert = require('assert'),
BarcodeScan = require('../plugin-barcode-scan'),
barcodeScanPlugin = new BarcodeScan();


describe('Barcode scan', function() {
var slaveInstance;

Expand Down Expand Up @@ -140,10 +139,142 @@ describe('Barcode scan', function() {
code: result
}
})));

document.dispatchEvent(new KeyboardEvent('keydown', {'key': 'Enter', 'code': 'Enter'}));
setTimeout(function() {
document.dispatchEvent(new KeyboardEvent('keydown', {'key': 'Enter', 'code': 'Enter'}));
assert(onKeyDownCallback.called);
done();
}, 100);
});

it('should move focus only after two chars are picked up in time based scan', function() {
const doc = window.document;
var keys = ['8', 'x'];
const input = doc.createElement("input");
input.setAttribute('id', 'focus-scan-barcode');
doc.body.appendChild(input);
input.focus();

keys.forEach(function(c) {
var key;
var code;
if( Object.prototype.toString.call(c) === '[object Object]' ) {
key = c.key;
code = c.code;
} else {
key = c;
code = `Key${c.toUpperCase()}`;
}
var event = new KeyboardEvent('keydown', { 'key': key, 'code': code });
doc.dispatchEvent(event);
});
assert.equal(doc.activeElement.id, 'focus-scan-barcode');
doc.dispatchEvent(new KeyboardEvent('keydown', { 'key': 'r', 'code': 'KeyR' }));
assert.notEqual(doc.activeElement.id, 'focus-scan-barcode');
document.dispatchEvent(new KeyboardEvent('keydown', {'key': 'Enter', 'code': 'Enter'}));
});

it('should prevent default and stop propagation only after two chars are picked up in time based scan', function() {
const doc = window.document;
var keys = ['8', 'x'];
const input = doc.createElement("input");
input.setAttribute('id', 'focus-scan-barcode');
doc.body.appendChild(input);
input.focus();

keys.forEach(function(c) {
var key;
var code;
if( Object.prototype.toString.call(c) === '[object Object]' ) {
key = c.key;
code = c.code;
} else {
key = c;
code = `Key${c.toUpperCase()}`;
}
var event = new KeyboardEvent('keydown', { 'key': key, 'code': code });
var spyPrevent = sinon.spy(event, 'preventDefault');
var spyImm = sinon.spy(event, 'stopImmediatePropagation');
var spyStopProp = sinon.spy(event, 'stopPropagation');
doc.dispatchEvent(event);
assert.notEqual(spyPrevent.called, true);
assert.notEqual(spyImm.called, true);
assert.notEqual(spyStopProp.called, true);

});
var thirdKeydown = new KeyboardEvent('keydown', { 'key': 'r', 'code': 'KeyR' });
var spyStopProp = sinon.spy(thirdKeydown, 'stopPropagation');
doc.dispatchEvent(thirdKeydown);
assert(spyStopProp.called);
document.dispatchEvent(new KeyboardEvent('keydown', {'key': 'Enter', 'code': 'Enter'}));
});

it('should move focus ouf of input if space prefix detected', function() {
const doc = window.document;
var keys = [{ 'key': ' ', 'code': 'Space' }, '8', 'x'];
const input = doc.createElement("input");
input.setAttribute('id', 'focus-scan-barcode');
doc.body.appendChild(input);
input.focus();

keys.forEach(function(c, index) {
var key;
var code;
if( Object.prototype.toString.call(c) === '[object Object]' ) {
key = c.key;
code = c.code;
} else {
key = c;
code = `Key${c.toUpperCase()}`;
}
var event = new KeyboardEvent('keydown', { 'key': key, 'code': code });
if (index === 0) {
assert.equal(doc.activeElement.id, 'focus-scan-barcode');
}

doc.dispatchEvent(event);

if (index === 0) {
assert.notEqual(doc.activeElement.id, 'focus-scan-barcode');
}
});
document.dispatchEvent(new KeyboardEvent('keydown', {'key': 'Enter', 'code': 'Enter'}));
});

it('should prevent default and stop propagation if space prefix detected', function() {
const doc = window.document;
var keys = [{ 'key': ' ', 'code': 'Space' }, '8', 'x'];
const input = doc.createElement("input");
input.setAttribute('id', 'focus-scan-barcode');
doc.body.appendChild(input);
input.focus();

keys.forEach(function(c, index) {
var key;
var code;
if( Object.prototype.toString.call(c) === '[object Object]' ) {
key = c.key;
code = c.code;
} else {
key = c;
code = `Key${c.toUpperCase()}`;
}
var event = new KeyboardEvent('keydown', { 'key': key, 'code': code });
if (index === 1) {
var spyPrevent = sinon.spy(event, 'preventDefault');
var spyImm = sinon.spy(event, 'stopImmediatePropagation');
var spyStopProp = sinon.spy(event, 'stopPropagation');
}

doc.dispatchEvent(event);

if (index === 1) {
assert(spyPrevent.called);
assert(spyImm.called);
assert(spyStopProp.called);
}
});
document.dispatchEvent(new KeyboardEvent('keydown', {'key': 'Enter', 'code': 'Enter'}));
});
});

0 comments on commit dadb65f

Please sign in to comment.