@platform/react
Version:
React refs and helpers.
194 lines (193 loc) • 8.67 kB
JavaScript
;
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;