Skip to content

Instantly share code, notes, and snippets.

@syusui-s
Last active May 28, 2022 08:27
Show Gist options
  • Save syusui-s/cd0b7dd2e2fcd49b5d64e00e6256fd5c to your computer and use it in GitHub Desktop.
Save syusui-s/cd0b7dd2e2fcd49b5d64e00e6256fd5c to your computer and use it in GitHub Desktop.
富士通(FUJITSU)のバーコードリーダー BCR-213の専用モードをWebブラウザ上で検出して使えるようにするHooks的なやつ
/*
* To the extent possible under law, Shusui Moyatani has waived all copyright and related or neighboring rights to this file.
* https://creativecommons.org/publicdomain/zero/1.0/deed.ja
*/
import { createSignal, onMount, onCleanup } from 'solid-js';
type ReadResult = {
dataType: DataType;
options: Options;
length: number;
data: string;
completed: boolean;
};
type DataType =
| 'EAN-8/JAN-8'
| 'EAN-13/JAN-13'
| 'UPC-A'
| 'UPC-E'
| 'CODE39'
| 'CODEBAR_NW-7'
| 'Standard_2_of_5'
| 'Interleaved_2_of_5'
| 'CODE93'
| 'GS1-128'
| 'GS1_DataBar'
| 'Error';
type Options = {
checkDigit: boolean;
terminator: boolean;
};
type ReaderModel = 'BCR-213';
type UseFujitsuReaderProps = {
model: ReaderModel;
onRead: (result: ReadResult) => void;
};
const DataTypeMap: Record<string, DataType> = {
'01': 'EAN-8/JAN-8',
'02': 'EAN-13/JAN-13',
'03': 'UPC-A',
'04': 'UPC-E',
'05': 'CODE39',
'06': 'CODEBAR_NW-7',
'07': 'Standard_2_of_5',
'08': 'Interleaved_2_of_5',
'09': 'CODE93',
'10': 'GS1-128',
'11': 'GS1_DataBar',
'00': 'Error',
};
const OptionsMap: Record<string, Options> = {
'0': { checkDigit: false, terminator: false },
'1': { checkDigit: false, terminator: false },
'2': { checkDigit: true, terminator: false },
'3': { checkDigit: false, terminator: true },
'4': { checkDigit: true, terminator: true },
};
const parseInputForBCR213 = (input: string): ReadResult | null => {
const match = input.match(
/^(?<dataType>[0-9]{2})(?<options>[0-4])(?<length>[0-9]{2})(?<data>.*\n?)$/,
);
if (!match) return null;
const rawDataType = match.groups?.dataType ?? '';
const rawOptions = match.groups?.options ?? '';
const rawLength = match.groups?.length ?? '';
const rawData = match.groups?.data ?? '';
const dataType: DataType = DataTypeMap[rawDataType] ?? 'Error';
const options = OptionsMap[rawOptions];
const length = parseInt(rawLength, 10);
const completed = rawData.length === length;
return {
dataType,
options,
length,
data: rawData,
completed,
};
};
const useFujitsuReader = ({ onRead }: UseFujitsuReaderProps) => {
const [reading, setReading] = createSignal(false);
const input = document.createElement('input');
Object.assign(input.style, {
position: 'fixed',
width: 0,
height: 0,
opacity: 0,
imeMode: 'inactive',
});
const parseInput = parseInputForBCR213;
input.addEventListener('keydown', (ev) => {
let result;
if (ev.key === 'Enter') {
result = parseInput(`${input.value}\n`);
} else if (input.value.length >= 5) {
result = parseInput(input.value);
}
if (result?.completed) {
console.log(result);
setReading(false);
input.value = '';
onRead(result);
}
});
const handler = (ev: KeyboardEvent) => {
if (!(ev.ctrlKey && ev.shiftKey && ev.key === 'F12')) return;
setReading(true);
input.focus();
};
onMount(() => {
document.body.appendChild(input);
window.addEventListener('keydown', handler);
});
onCleanup(() => {
document.body.removeChild(input);
});
return { reading };
};
export default useFujitsuReader;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment