UNPKG

jjb-lc-designable

Version:

基于alibaba-designable源码二次封装的表单设计器。

96 lines 2.55 kB
import { observable, define, action } from 'jjb-lc-formily/reactive'; import { KeyCode } from 'jjb-lc-designable/shared'; import { Shortcut } from './Shortcut'; const Modifiers = [['metaKey', KeyCode.Meta], ['shiftKey', KeyCode.Shift], ['ctrlKey', KeyCode.Control], ['altKey', KeyCode.Alt]]; export class Keyboard { shortcuts = []; sequence = []; keyDown = null; modifiers = {}; requestTimer = null; constructor(engine) { this.engine = engine; this.shortcuts = engine.props?.shortcuts || []; this.makeObservable(); } matchCodes(context) { for (let i = 0; i < this.shortcuts.length; i++) { const shortcut = this.shortcuts[i]; if (shortcut.match(this.sequence, context)) { return true; } } return false; } preventCodes() { return this.shortcuts.some(shortcut => { return shortcut.preventCodes(this.sequence); }); } includes(key) { return this.sequence.some(code => Shortcut.matchCode(code, key)); } excludes(key) { this.sequence = this.sequence.filter(code => !Shortcut.matchCode(key, code)); } addKeyCode(key) { if (!this.includes(key)) { this.sequence.push(key); } } removeKeyCode(key) { if (this.includes(key)) { this.excludes(key); } } isModifier(code) { return Modifiers.some(modifier => Shortcut.matchCode(modifier[1], code)); } handleModifiers(event) { Modifiers.forEach(([key, code]) => { if (event[key]) { if (!this.includes(code)) { this.sequence = [code].concat(this.sequence); } } }); } handleKeyboard(event, context) { if (event.eventType === 'keydown') { this.keyDown = event.data; this.addKeyCode(this.keyDown); this.handleModifiers(event); if (this.matchCodes(context)) { this.sequence = []; } this.requestClean(4000); if (this.preventCodes()) { event.preventDefault(); event.stopPropagation(); } } else { if (this.isModifier(event.data)) { this.sequence = []; } this.keyDown = null; } } isKeyDown(code) { return this.keyDown === code; } requestClean(duration = 320) { clearTimeout(this.requestTimer); this.requestTimer = setTimeout(() => { this.keyDown = null; this.sequence = []; clearTimeout(this.requestTimer); }, duration); } makeObservable() { define(this, { sequence: observable.shallow, keyDown: observable.ref, handleKeyboard: action }); } }