UNPKG

@platform/react

Version:

React refs and helpers.

194 lines (193 loc) 8.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Keyboard = void 0; var tslib_1 = require("tslib"); var rxjs_1 = require("rxjs"); var operators_1 = require("rxjs/operators"); var events_1 = require("../events"); var ramda_1 = require("ramda"); var R = { equals: ramda_1.equals, uniq: ramda_1.uniq }; var MODIFIERS = { META: 'metaKey', CTRL: 'ctrlKey', ALT: 'altKey', SHIFT: 'shiftKey', }; var isModifierPressed = function (e) { return Object.keys(MODIFIERS) .map(function (key) { return MODIFIERS[key]; }) .some(function (prop) { return e[prop] === true; }); }; var Keyboard = (function () { function Keyboard(options) { var _this = this; this._dispose$ = new rxjs_1.Subject(); this.dispose$ = this._dispose$.pipe((0, operators_1.share)()); this.bindings = []; var bindingPress$ = new rxjs_1.Subject(); this.bindingPress$ = bindingPress$.pipe((0, operators_1.takeUntil)(this._dispose$), (0, operators_1.share)()); var keyPress$ = options.keyPress$ || events_1.events.keyPress$; this.keyPress$ = keyPress$ = keyPress$.pipe((0, operators_1.takeUntil)(this._dispose$)); this.bindings = options.bindings || []; keyPress$.subscribe(function (e) { return (_this.latest = e); }); this.monitorBindings(function (e) { return bindingPress$.next(e); }); if (options.dispose$) { options.dispose$.pipe((0, operators_1.take)(1)).subscribe(function () { return _this.dispose(); }); } } Keyboard.create = function (options) { return new Keyboard(options); }; Keyboard.isModifier = function (key) { return Object.keys(MODIFIERS).some(function (item) { return item === key; }); }; Keyboard.parse = function (pattern, defaultValue) { var EMPTY = { keys: [], modifiers: [] }; if (pattern === false) { return EMPTY; } pattern = typeof pattern === 'string' ? pattern.trim() : pattern; if ((pattern === true || !pattern) && typeof defaultValue === 'string') { pattern = defaultValue; } if (!pattern || typeof pattern !== 'string') { return EMPTY; } var parts = (pattern || '') .split('+') .map(function (key) { return key.trim(); }) .filter(function (key) { return Boolean(key); }) .map(function (key) { return Keyboard.formatKey(key); }); var modifiers = Array.from(new Set(parts.filter(Keyboard.isModifier))); var keys = parts.filter(function (key) { return !modifiers.some(function (item) { return item === key; }); }); keys = Array.from(new Set(keys)); return { keys: keys, modifiers: modifiers }; }; Keyboard.matchEvent = function (pattern, event) { var key = Keyboard.formatKey(event.key); pattern = typeof pattern === 'string' ? Keyboard.parse(pattern) : pattern; if (!pattern.keys.includes(key)) { return false; } var eventModifiers = []; eventModifiers = event.metaKey ? tslib_1.__spreadArray(tslib_1.__spreadArray([], eventModifiers, true), ['META'], false) : eventModifiers; eventModifiers = event.ctrlKey ? tslib_1.__spreadArray(tslib_1.__spreadArray([], eventModifiers, true), ['CTRL'], false) : eventModifiers; eventModifiers = event.altKey ? tslib_1.__spreadArray(tslib_1.__spreadArray([], eventModifiers, true), ['ALT'], false) : eventModifiers; eventModifiers = event.shiftKey ? tslib_1.__spreadArray(tslib_1.__spreadArray([], eventModifiers, true), ['SHIFT'], false) : eventModifiers; if (eventModifiers.length !== pattern.modifiers.length) { return false; } for (var _i = 0, eventModifiers_1 = eventModifiers; _i < eventModifiers_1.length; _i++) { var modifier = eventModifiers_1[_i]; if (!pattern.modifiers.includes(modifier)) { return false; } } return true; }; Keyboard.formatKey = function (key) { key = key || ''; var MODIFIERS = ['CMD', 'COMMAND', 'META', 'CONTROL', 'CTRL', 'ALT', 'SHIFT']; key = MODIFIERS.includes(key.toUpperCase()) ? key.toUpperCase() : key; key = key === 'CMD' ? 'META' : key; key = key === 'COMMAND' ? 'META' : key; key = key === 'CONTROL' ? 'CTRL' : key; key = key.length === 1 ? key.toUpperCase() : key; return key; }; Object.defineProperty(Keyboard.prototype, "isDisposed", { get: function () { return this._dispose$.isStopped; }, enumerable: false, configurable: true }); Keyboard.prototype.dispose = function () { this._dispose$.next(); this._dispose$.complete(); }; Keyboard.prototype.clone = function (options) { if (options === void 0) { options = {}; } var dispose$ = options.dispose$; var keyPress$ = options.keyPress$ || this.keyPress$; var bindings = options.bindings || this.bindings; return Keyboard.create({ keyPress$: keyPress$, dispose$: dispose$, bindings: bindings }); }; Keyboard.prototype.filter = function (fn) { var keyPress$ = this.keyPress$.pipe((0, operators_1.filter)(fn)); return this.clone({ keyPress$: keyPress$ }); }; Keyboard.prototype.takeUntil = function (dispose$) { return this.clone({ dispose$: dispose$ }); }; Keyboard.prototype.monitorBindings = function (fire) { var _this = this; var keyPress$ = this.keyPress$; var pressedKeys = []; keyPress$ .subscribe(function (e) { var hasModifier = isModifierPressed(e); if (e.isModifier && !e.isPressed && !hasModifier) { pressedKeys = []; } if (!e.isModifier) { var key = e.code; key = key.startsWith('Key') ? e.code.replace(/^Key/, '') : key; key = key.startsWith('Numpad') ? e.code.replace(/^Numpad/, '') : key; key = key.startsWith('Digit') ? e.code.replace(/^Digit/, '') : key; key = key.length === 1 ? key.toUpperCase() : key; pressedKeys = e.isPressed ? R.uniq(tslib_1.__spreadArray(tslib_1.__spreadArray([], pressedKeys, true), [key], false)) : []; } }); keyPress$ .pipe((0, operators_1.filter)(function (e) { return e.isPressed; }), (0, operators_1.map)(function (e) { return ({ event: e, binding: _this.matchBinding(e, pressedKeys) }); })) .subscribe(function (_a) { var event = _a.event, binding = _a.binding; if (binding) { var key = binding.key, command = binding.command; fire({ key: key, command: command, preventDefault: function () { return event.preventDefault(); }, stopPropagation: function () { return event.stopPropagation(); }, stopImmediatePropagation: function () { return event.stopImmediatePropagation(); }, cancel: function () { event.preventDefault(); event.stopImmediatePropagation(); }, }); } }); }; Keyboard.prototype.matchBinding = function (e, pressedKeys) { var hasAllModifiers = function (modifiers) { var _loop_1 = function (key) { var exists = modifiers.some(function (item) { return item === key; }); if (e[MODIFIERS[key]] !== exists) { return { value: false }; } }; for (var _i = 0, _a = Object.keys(MODIFIERS); _i < _a.length; _i++) { var key = _a[_i]; var state_1 = _loop_1(key); if (typeof state_1 === "object") return state_1.value; } return true; }; var hasAllValues = function (a, b) { return R.equals(a, b); }; var isMatch = function (parts) { return hasAllModifiers(parts.modifiers) && hasAllValues(parts.keys, pressedKeys); }; for (var _i = 0, _a = this.bindings; _i < _a.length; _i++) { var binding = _a[_i]; var parts = Keyboard.parse(binding.key); if (isMatch(parts)) { return binding; } } return undefined; }; return Keyboard; }()); exports.Keyboard = Keyboard;