@witchcraft/spellcraft 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +579 -0
- package/dist/core/EmulatedEvent.d.ts +10 -0
- package/dist/core/EmulatedEvent.js +19 -0
- package/dist/core/Emulator.d.ts +74 -0
- package/dist/core/Emulator.js +153 -0
- package/dist/core/ShortcutManagerManager.d.ts +103 -0
- package/dist/core/ShortcutManagerManager.js +267 -0
- package/dist/core/addCommand.d.ts +7 -0
- package/dist/core/addCommand.js +7 -0
- package/dist/core/addKey.d.ts +7 -0
- package/dist/core/addKey.js +7 -0
- package/dist/core/addShortcut.d.ts +7 -0
- package/dist/core/addShortcut.js +7 -0
- package/dist/core/attach.d.ts +10 -0
- package/dist/core/attach.js +13 -0
- package/dist/core/createCommand.d.ts +4 -0
- package/dist/core/createCommand.js +11 -0
- package/dist/core/createCommands.d.ts +11 -0
- package/dist/core/createCommands.js +20 -0
- package/dist/core/createCondition.d.ts +7 -0
- package/dist/core/createCondition.js +11 -0
- package/dist/core/createContext.d.ts +2 -0
- package/dist/core/createContext.js +8 -0
- package/dist/core/createKey.d.ts +10 -0
- package/dist/core/createKey.js +35 -0
- package/dist/core/createKeys.d.ts +5 -0
- package/dist/core/createKeys.js +36 -0
- package/dist/core/createManager.d.ts +81 -0
- package/dist/core/createManager.js +83 -0
- package/dist/core/createManagerEventListeners.d.ts +4 -0
- package/dist/core/createManagerEventListeners.js +130 -0
- package/dist/core/createManagerOptions.d.ts +8 -0
- package/dist/core/createManagerOptions.js +17 -0
- package/dist/core/createShortcut.d.ts +8 -0
- package/dist/core/createShortcut.js +24 -0
- package/dist/core/createShortcuts.d.ts +13 -0
- package/dist/core/createShortcuts.js +20 -0
- package/dist/core/detach.d.ts +10 -0
- package/dist/core/detach.js +6 -0
- package/dist/core/index.d.ts +32 -0
- package/dist/core/index.js +32 -0
- package/dist/core/removeCommand.d.ts +7 -0
- package/dist/core/removeCommand.js +7 -0
- package/dist/core/removeKey.d.ts +7 -0
- package/dist/core/removeKey.js +7 -0
- package/dist/core/removeShortcut.d.ts +7 -0
- package/dist/core/removeShortcut.js +7 -0
- package/dist/core/setCommandProp.d.ts +17 -0
- package/dist/core/setCommandProp.js +96 -0
- package/dist/core/setCommandsProp.d.ts +15 -0
- package/dist/core/setCommandsProp.js +94 -0
- package/dist/core/setKeyProp.d.ts +16 -0
- package/dist/core/setKeyProp.js +47 -0
- package/dist/core/setKeysProp.d.ts +10 -0
- package/dist/core/setKeysProp.js +166 -0
- package/dist/core/setManagerProp.d.ts +34 -0
- package/dist/core/setManagerProp.js +54 -0
- package/dist/core/setShortcutProp.d.ts +9 -0
- package/dist/core/setShortcutProp.js +50 -0
- package/dist/core/setShortcutsProp.d.ts +12 -0
- package/dist/core/setShortcutsProp.js +93 -0
- package/dist/defaults/KeysSorter.d.ts +35 -0
- package/dist/defaults/KeysSorter.js +20 -0
- package/dist/defaults/Stringifier.d.ts +66 -0
- package/dist/defaults/Stringifier.js +119 -0
- package/dist/defaults/defaultConditionEquals.d.ts +19 -0
- package/dist/defaults/defaultConditionEquals.js +5 -0
- package/dist/defaults/defaultManagerCallback.d.ts +7 -0
- package/dist/defaults/defaultManagerCallback.js +5 -0
- package/dist/helpers/KnownError.d.ts +8 -0
- package/dist/helpers/KnownError.js +3 -0
- package/dist/helpers/calculateAndSetPositionAndWidth.d.ts +13 -0
- package/dist/helpers/calculateAndSetPositionAndWidth.js +18 -0
- package/dist/helpers/calculateLayoutSize.d.ts +9 -0
- package/dist/helpers/calculateLayoutSize.js +13 -0
- package/dist/helpers/doesShortcutConflict.d.ts +18 -0
- package/dist/helpers/doesShortcutConflict.js +42 -0
- package/dist/helpers/equalsCommand.d.ts +7 -0
- package/dist/helpers/equalsCommand.js +4 -0
- package/dist/helpers/equalsContext.d.ts +7 -0
- package/dist/helpers/equalsContext.js +19 -0
- package/dist/helpers/equalsShortcut.d.ts +9 -0
- package/dist/helpers/equalsShortcut.js +7 -0
- package/dist/helpers/forceClear.d.ts +12 -0
- package/dist/helpers/forceClear.js +16 -0
- package/dist/helpers/forceUpdateNativeKeysState.d.ts +5 -0
- package/dist/helpers/forceUpdateNativeKeysState.js +4 -0
- package/dist/helpers/generateKeyShortcutMap.d.ts +23 -0
- package/dist/helpers/generateKeyShortcutMap.js +64 -0
- package/dist/helpers/getKeyFromEventCode.d.ts +15 -0
- package/dist/helpers/getKeyFromEventCode.js +36 -0
- package/dist/helpers/getKeyFromIdOrVariant.d.ts +4 -0
- package/dist/helpers/getKeyFromIdOrVariant.js +26 -0
- package/dist/helpers/getKeyboardLayoutMap.d.ts +5 -0
- package/dist/helpers/getKeyboardLayoutMap.js +7 -0
- package/dist/helpers/getLabel.d.ts +9 -0
- package/dist/helpers/getLabel.js +6 -0
- package/dist/helpers/getTriggerableShortcut.d.ts +6 -0
- package/dist/helpers/getTriggerableShortcut.js +25 -0
- package/dist/helpers/index.d.ts +28 -0
- package/dist/helpers/index.js +28 -0
- package/dist/helpers/isValidManager.d.ts +3 -0
- package/dist/helpers/isValidManager.js +20 -0
- package/dist/helpers/isValidShortcut.d.ts +3 -0
- package/dist/helpers/isValidShortcut.js +10 -0
- package/dist/helpers/labelWithEvent.d.ts +13 -0
- package/dist/helpers/labelWithEvent.js +20 -0
- package/dist/helpers/labelWithKeyboardMap.d.ts +15 -0
- package/dist/helpers/labelWithKeyboardMap.js +17 -0
- package/dist/helpers/managerToStorableClone.d.ts +12 -0
- package/dist/helpers/managerToStorableClone.js +13 -0
- package/dist/helpers/onKeyboardLayoutChange.d.ts +10 -0
- package/dist/helpers/onKeyboardLayoutChange.js +7 -0
- package/dist/helpers/safeSetManagerChain.d.ts +20 -0
- package/dist/helpers/safeSetManagerChain.js +37 -0
- package/dist/helpers/shortcutCanExecuteIn.d.ts +4 -0
- package/dist/helpers/shortcutCanExecuteIn.js +9 -0
- package/dist/helpers/shortcutIsTriggerableBy.d.ts +2 -0
- package/dist/helpers/shortcutIsTriggerableBy.js +5 -0
- package/dist/helpers/shortcutSwapChords.d.ts +75 -0
- package/dist/helpers/shortcutSwapChords.js +118 -0
- package/dist/helpers/virtualPress.d.ts +13 -0
- package/dist/helpers/virtualPress.js +15 -0
- package/dist/helpers/virtualRelease.d.ts +5 -0
- package/dist/helpers/virtualRelease.js +15 -0
- package/dist/helpers/virtualToggle.d.ts +7 -0
- package/dist/helpers/virtualToggle.js +16 -0
- package/dist/internal/addToChain.d.ts +3 -0
- package/dist/internal/addToChain.js +27 -0
- package/dist/internal/areValidKeys.d.ts +7 -0
- package/dist/internal/areValidKeys.js +28 -0
- package/dist/internal/areValidVariants.d.ts +4 -0
- package/dist/internal/areValidVariants.js +45 -0
- package/dist/internal/checkTrigger.d.ts +2 -0
- package/dist/internal/checkTrigger.js +47 -0
- package/dist/internal/checkUntrigger.d.ts +2 -0
- package/dist/internal/checkUntrigger.js +18 -0
- package/dist/internal/cloneLastChord.d.ts +4 -0
- package/dist/internal/cloneLastChord.js +5 -0
- package/dist/internal/containsPossibleToggleChords.d.ts +13 -0
- package/dist/internal/containsPossibleToggleChords.js +65 -0
- package/dist/internal/errorTextAdd.d.ts +1 -0
- package/dist/internal/errorTextAdd.js +11 -0
- package/dist/internal/errorTextInUse.d.ts +1 -0
- package/dist/internal/errorTextInUse.js +8 -0
- package/dist/internal/errorTextRemove.d.ts +1 -0
- package/dist/internal/errorTextRemove.js +8 -0
- package/dist/internal/getModifierState.d.ts +2 -0
- package/dist/internal/getModifierState.js +7 -0
- package/dist/internal/getPressedKeys.d.ts +7 -0
- package/dist/internal/getPressedKeys.js +18 -0
- package/dist/internal/getPressedModifierKeys.d.ts +2 -0
- package/dist/internal/getPressedModifierKeys.js +10 -0
- package/dist/internal/getPressedNonModifierKeys.d.ts +7 -0
- package/dist/internal/getPressedNonModifierKeys.js +11 -0
- package/dist/internal/inChain.d.ts +5 -0
- package/dist/internal/inChain.js +14 -0
- package/dist/internal/isValidChain.d.ts +10 -0
- package/dist/internal/isValidChain.js +22 -0
- package/dist/internal/isValidChord.d.ts +11 -0
- package/dist/internal/isValidChord.js +59 -0
- package/dist/internal/isValidCommand.d.ts +12 -0
- package/dist/internal/isValidCommand.js +20 -0
- package/dist/internal/keyOrder.d.ts +6 -0
- package/dist/internal/keyOrder.js +14 -0
- package/dist/internal/removeFromChain.d.ts +3 -0
- package/dist/internal/removeFromChain.js +32 -0
- package/dist/internal/safeSetEmulatedToggleState.d.ts +4 -0
- package/dist/internal/safeSetEmulatedToggleState.js +13 -0
- package/dist/internal/setKeysState.d.ts +8 -0
- package/dist/internal/setKeysState.js +42 -0
- package/dist/internal/updateNativeKeysState.d.ts +14 -0
- package/dist/internal/updateNativeKeysState.js +58 -0
- package/dist/layouts/createLayout.d.ts +25 -0
- package/dist/layouts/createLayout.js +221 -0
- package/dist/module.d.mts +13 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +40 -0
- package/dist/runtime/composables/useLabeledByKeyboardLayoutMap.d.ts +9 -0
- package/dist/runtime/composables/useLabeledByKeyboardLayoutMap.js +19 -0
- package/dist/runtime/composables/usePointerCoords.d.ts +32 -0
- package/dist/runtime/composables/usePointerCoords.js +17 -0
- package/dist/runtime/composables/useShortcutManagerContextCount.d.ts +14 -0
- package/dist/runtime/composables/useShortcutManagerContextCount.js +61 -0
- package/dist/runtime/composables/useShortcutManagerKeysLayout.d.ts +18 -0
- package/dist/runtime/composables/useShortcutManagerKeysLayout.js +22 -0
- package/dist/runtime/composables/useShortcutManagerVirtualPress.d.ts +6 -0
- package/dist/runtime/composables/useShortcutManagerVirtualPress.js +24 -0
- package/dist/runtime/types.d.ts +10 -0
- package/dist/runtime/types.js +1 -0
- package/dist/runtime/utils/shortcutToId.d.ts +5 -0
- package/dist/runtime/utils/shortcutToId.js +6 -0
- package/dist/types/commands.d.ts +113 -0
- package/dist/types/commands.js +0 -0
- package/dist/types/condition.d.ts +29 -0
- package/dist/types/condition.js +0 -0
- package/dist/types/context.d.ts +18 -0
- package/dist/types/context.js +0 -0
- package/dist/types/enums.d.ts +186 -0
- package/dist/types/enums.js +70 -0
- package/dist/types/general.d.ts +92 -0
- package/dist/types/general.js +0 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.js +8 -0
- package/dist/types/keys.d.ts +332 -0
- package/dist/types/keys.js +0 -0
- package/dist/types/manager.d.ts +249 -0
- package/dist/types/manager.js +0 -0
- package/dist/types/plugins.d.ts +1 -0
- package/dist/types/plugins.js +0 -0
- package/dist/types/shortcuts.d.ts +144 -0
- package/dist/types/shortcuts.js +0 -0
- package/dist/types/utils.d.ts +1 -0
- package/dist/types/utils.js +0 -0
- package/dist/types.d.mts +3 -0
- package/dist/utils/chainContainsSubset.d.ts +27 -0
- package/dist/utils/chainContainsSubset.js +45 -0
- package/dist/utils/cloneChain.d.ts +2 -0
- package/dist/utils/cloneChain.js +11 -0
- package/dist/utils/cloneKey.d.ts +3 -0
- package/dist/utils/cloneKey.js +26 -0
- package/dist/utils/containsKey.d.ts +7 -0
- package/dist/utils/containsKey.js +4 -0
- package/dist/utils/dedupeKeys.d.ts +9 -0
- package/dist/utils/dedupeKeys.js +9 -0
- package/dist/utils/equalsKey.d.ts +12 -0
- package/dist/utils/equalsKey.js +13 -0
- package/dist/utils/equalsKeys.d.ts +24 -0
- package/dist/utils/equalsKeys.js +15 -0
- package/dist/utils/index.d.ts +14 -0
- package/dist/utils/index.js +14 -0
- package/dist/utils/isAnyKey.d.ts +5 -0
- package/dist/utils/isAnyKey.js +5 -0
- package/dist/utils/isMouseKey.d.ts +5 -0
- package/dist/utils/isMouseKey.js +20 -0
- package/dist/utils/isNormalKey.d.ts +5 -0
- package/dist/utils/isNormalKey.js +5 -0
- package/dist/utils/isTriggerKey.d.ts +5 -0
- package/dist/utils/isTriggerKey.js +3 -0
- package/dist/utils/isWheelKey.d.ts +5 -0
- package/dist/utils/isWheelKey.js +11 -0
- package/dist/utils/mapKeys.d.ts +8 -0
- package/dist/utils/mapKeys.js +5 -0
- package/dist/utils/removeKeys.d.ts +7 -0
- package/dist/utils/removeKeys.js +4 -0
- package/package.json +156 -0
- package/src/core/EmulatedEvent.ts +29 -0
- package/src/core/Emulator.ts +185 -0
- package/src/core/ShortcutManagerManager.ts +380 -0
- package/src/core/addCommand.ts +24 -0
- package/src/core/addKey.ts +25 -0
- package/src/core/addShortcut.ts +24 -0
- package/src/core/attach.ts +27 -0
- package/src/core/createCommand.ts +24 -0
- package/src/core/createCommands.ts +45 -0
- package/src/core/createCondition.ts +21 -0
- package/src/core/createContext.ts +14 -0
- package/src/core/createKey.ts +59 -0
- package/src/core/createKeys.ts +68 -0
- package/src/core/createManager.ts +209 -0
- package/src/core/createManagerEventListeners.ts +139 -0
- package/src/core/createManagerOptions.ts +29 -0
- package/src/core/createShortcut.ts +49 -0
- package/src/core/createShortcuts.ts +51 -0
- package/src/core/detach.ts +21 -0
- package/src/core/index.ts +35 -0
- package/src/core/removeCommand.ts +25 -0
- package/src/core/removeKey.ts +25 -0
- package/src/core/removeShortcut.ts +24 -0
- package/src/core/setCommandProp.ts +140 -0
- package/src/core/setCommandsProp.ts +128 -0
- package/src/core/setKeyProp.ts +80 -0
- package/src/core/setKeysProp.ts +205 -0
- package/src/core/setManagerProp.ts +111 -0
- package/src/core/setShortcutProp.ts +89 -0
- package/src/core/setShortcutsProp.ts +124 -0
- package/src/defaults/KeysSorter.ts +55 -0
- package/src/defaults/Stringifier.ts +234 -0
- package/src/defaults/defaultConditionEquals.ts +29 -0
- package/src/defaults/defaultManagerCallback.ts +14 -0
- package/src/helpers/KnownError.ts +13 -0
- package/src/helpers/calculateAndSetPositionAndWidth.ts +30 -0
- package/src/helpers/calculateLayoutSize.ts +22 -0
- package/src/helpers/doesShortcutConflict.ts +72 -0
- package/src/helpers/equalsCommand.ts +18 -0
- package/src/helpers/equalsContext.ts +29 -0
- package/src/helpers/equalsShortcut.ts +34 -0
- package/src/helpers/forceClear.ts +31 -0
- package/src/helpers/forceUpdateNativeKeysState.ts +9 -0
- package/src/helpers/generateKeyShortcutMap.ts +113 -0
- package/src/helpers/getKeyFromEventCode.ts +67 -0
- package/src/helpers/getKeyFromIdOrVariant.ts +33 -0
- package/src/helpers/getKeyboardLayoutMap.ts +13 -0
- package/src/helpers/getLabel.ts +15 -0
- package/src/helpers/getTriggerableShortcut.ts +37 -0
- package/src/helpers/index.ts +30 -0
- package/src/helpers/isValidManager.ts +29 -0
- package/src/helpers/isValidShortcut.ts +20 -0
- package/src/helpers/labelWithEvent.ts +41 -0
- package/src/helpers/labelWithKeyboardMap.ts +37 -0
- package/src/helpers/managerToStorableClone.ts +26 -0
- package/src/helpers/onKeyboardLayoutChange.ts +17 -0
- package/src/helpers/safeSetManagerChain.ts +66 -0
- package/src/helpers/shortcutCanExecuteIn.ts +24 -0
- package/src/helpers/shortcutIsTriggerableBy.ts +15 -0
- package/src/helpers/shortcutSwapChords.ts +240 -0
- package/src/helpers/virtualPress.ts +34 -0
- package/src/helpers/virtualRelease.ts +25 -0
- package/src/helpers/virtualToggle.ts +28 -0
- package/src/internal/addToChain.ts +40 -0
- package/src/internal/areValidKeys.ts +40 -0
- package/src/internal/areValidVariants.ts +59 -0
- package/src/internal/checkTrigger.ts +55 -0
- package/src/internal/checkUntrigger.ts +26 -0
- package/src/internal/cloneLastChord.ts +10 -0
- package/src/internal/containsPossibleToggleChords.ts +91 -0
- package/src/internal/errorTextAdd.ts +18 -0
- package/src/internal/errorTextInUse.ts +10 -0
- package/src/internal/errorTextRemove.ts +10 -0
- package/src/internal/getModifierState.ts +15 -0
- package/src/internal/getPressedKeys.ts +26 -0
- package/src/internal/getPressedModifierKeys.ts +14 -0
- package/src/internal/getPressedNonModifierKeys.ts +19 -0
- package/src/internal/inChain.ts +25 -0
- package/src/internal/isValidChain.ts +42 -0
- package/src/internal/isValidChord.ts +87 -0
- package/src/internal/isValidCommand.ts +35 -0
- package/src/internal/keyOrder.ts +24 -0
- package/src/internal/removeFromChain.ts +46 -0
- package/src/internal/safeSetEmulatedToggleState.ts +23 -0
- package/src/internal/setKeysState.ts +71 -0
- package/src/internal/updateNativeKeysState.ts +84 -0
- package/src/layouts/createLayout.ts +328 -0
- package/src/module.ts +62 -0
- package/src/runtime/composables/useLabeledByKeyboardLayoutMap.ts +28 -0
- package/src/runtime/composables/usePointerCoords.ts +40 -0
- package/src/runtime/composables/useShortcutManagerContextCount.ts +81 -0
- package/src/runtime/composables/useShortcutManagerKeysLayout.ts +42 -0
- package/src/runtime/composables/useShortcutManagerVirtualPress.ts +30 -0
- package/src/runtime/types.ts +10 -0
- package/src/runtime/utils/shortcutToId.ts +14 -0
- package/src/types/commands.ts +148 -0
- package/src/types/condition.ts +35 -0
- package/src/types/context.ts +19 -0
- package/src/types/enums.ts +236 -0
- package/src/types/general.ts +117 -0
- package/src/types/index.ts +10 -0
- package/src/types/keys.ts +385 -0
- package/src/types/manager.ts +374 -0
- package/src/types/plugins.ts +32 -0
- package/src/types/shortcuts.ts +204 -0
- package/src/types/utils.ts +40 -0
- package/src/utils/chainContainsSubset.ts +97 -0
- package/src/utils/cloneChain.ts +13 -0
- package/src/utils/cloneKey.ts +33 -0
- package/src/utils/containsKey.ts +17 -0
- package/src/utils/dedupeKeys.ts +23 -0
- package/src/utils/equalsKey.ts +32 -0
- package/src/utils/equalsKeys.ts +50 -0
- package/src/utils/index.ts +16 -0
- package/src/utils/isAnyKey.ts +12 -0
- package/src/utils/isMouseKey.ts +27 -0
- package/src/utils/isNormalKey.ts +15 -0
- package/src/utils/isTriggerKey.ts +7 -0
- package/src/utils/isWheelKey.ts +18 -0
- package/src/utils/mapKeys.ts +21 -0
- package/src/utils/removeKeys.ts +16 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { last } from "@alanscodelog/utils/last";
|
|
2
|
+
import { getKeyFromIdOrVariant } from "./getKeyFromIdOrVariant.js";
|
|
3
|
+
import { chainContainsSubset } from "../utils/chainContainsSubset.js";
|
|
4
|
+
import { equalsKeys } from "../utils/equalsKeys.js";
|
|
5
|
+
import { removeKeys } from "../utils/removeKeys.js";
|
|
6
|
+
export function generateKeyShortcutMap(chain, shortcutsList, manager, postFilter) {
|
|
7
|
+
const obj = {};
|
|
8
|
+
const nextIsChord = manager.state.nextIsChord;
|
|
9
|
+
const isEmpty = chain.length === 0 || chain.length === 1 && chain?.[0].length === 0;
|
|
10
|
+
const index = isEmpty ? 0 : nextIsChord ? chain.length : chain.length - 1;
|
|
11
|
+
for (const shortcut of shortcutsList) {
|
|
12
|
+
const containsSubset = chainContainsSubset(shortcut.chain, chain, manager.keys, { onlySubset: true, onlyPressable: false });
|
|
13
|
+
const isPressed = equalsKeys(shortcut.chain, chain, manager.keys);
|
|
14
|
+
if (!containsSubset && !isPressed) continue;
|
|
15
|
+
const keysLeftInChord = removeKeys(shortcut.chain[index] ?? [], chain[index] ?? [], manager.keys).map((_) => getKeyFromIdOrVariant(_, manager.keys).unwrap()[0]);
|
|
16
|
+
const isPressableChord = keysLeftInChord.length === 1;
|
|
17
|
+
const isPressable = isPressableChord && shortcut.chain.length - 1 === index;
|
|
18
|
+
const isPressableChain = isPressableChord && shortcut.chain.length - 1 > index;
|
|
19
|
+
const unpressedModifiers = keysLeftInChord.length > 1 ? keysLeftInChord.filter((_) => _.isModifier) : [];
|
|
20
|
+
const hasUnpressedModifiers = unpressedModifiers.length > 0;
|
|
21
|
+
if (!isPressable && !isPressableChain && !isPressed && unpressedModifiers.length <= 0) continue;
|
|
22
|
+
const pressableKeys = isPressed ? (last(shortcut.chain) ?? []).map((_) => getKeyFromIdOrVariant(_, manager.keys).unwrap()[0]) : unpressedModifiers.length === 0 ? keysLeftInChord : [];
|
|
23
|
+
const entry = {
|
|
24
|
+
shortcut,
|
|
25
|
+
isPressed,
|
|
26
|
+
isPressable,
|
|
27
|
+
isPressableChain,
|
|
28
|
+
hasUnpressedModifiers
|
|
29
|
+
};
|
|
30
|
+
if (postFilter !== void 0 && !postFilter(entry, { unpressedModifiers, pressableKeys, isPressed, containsSubset })) continue;
|
|
31
|
+
if (!hasUnpressedModifiers || isPressed) {
|
|
32
|
+
for (const k of pressableKeys) {
|
|
33
|
+
if (k.render) {
|
|
34
|
+
obj[k.id] ??= {
|
|
35
|
+
pressableEntries: [],
|
|
36
|
+
modifierEntries: [],
|
|
37
|
+
containsConflicting: false,
|
|
38
|
+
isModifierHint: false
|
|
39
|
+
};
|
|
40
|
+
if (!obj[k.id].containsConflicting) {
|
|
41
|
+
const containsConflicting = obj[k.id].pressableEntries.some((_) => _.isPressable || _.isPressableChain);
|
|
42
|
+
obj[k.id].containsConflicting = containsConflicting;
|
|
43
|
+
}
|
|
44
|
+
obj[k.id].pressableEntries.push({ ...entry });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (!isPressed && !isPressable && !isPressableChain) {
|
|
49
|
+
for (const k of unpressedModifiers) {
|
|
50
|
+
if (k.render) {
|
|
51
|
+
obj[k.id] ??= {
|
|
52
|
+
pressableEntries: [],
|
|
53
|
+
modifierEntries: [],
|
|
54
|
+
containsConflicting: false,
|
|
55
|
+
isModifierHint: false
|
|
56
|
+
};
|
|
57
|
+
obj[k.id].modifierEntries.push({ ...entry });
|
|
58
|
+
obj[k.id].isModifierHint ||= true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return obj;
|
|
64
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Result } from "@alanscodelog/utils/Result";
|
|
2
|
+
import { KnownError } from "./KnownError.js";
|
|
3
|
+
import { type Key, SHORTCUT_ERROR } from "../types/index.js";
|
|
4
|
+
export declare function getKeyFromEventCode(code: string, e: {
|
|
5
|
+
code: string;
|
|
6
|
+
} | {
|
|
7
|
+
key: string;
|
|
8
|
+
} | {
|
|
9
|
+
button: number;
|
|
10
|
+
} | {
|
|
11
|
+
deltaY: number;
|
|
12
|
+
}, keys: Record<string, Key>, { pressedState: pressState, includeDisabled }?: {
|
|
13
|
+
includeDisabled?: boolean;
|
|
14
|
+
pressedState?: boolean;
|
|
15
|
+
}): Result<string[], KnownError<typeof SHORTCUT_ERROR.UNKNOWN_KEY_EVENT>>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Err, Ok } from "@alanscodelog/utils/Result";
|
|
2
|
+
import { KnownError } from "./KnownError.js";
|
|
3
|
+
import { SHORTCUT_ERROR } from "../types/index.js";
|
|
4
|
+
export function getKeyFromEventCode(code, e, keys, {
|
|
5
|
+
pressedState: pressState,
|
|
6
|
+
includeDisabled = false
|
|
7
|
+
} = {}) {
|
|
8
|
+
const keyIds = [];
|
|
9
|
+
const disabledIds = [];
|
|
10
|
+
for (const key of Object.values(keys)) {
|
|
11
|
+
if ((pressState === void 0 ? true : key.pressed === pressState) && (key.id === code || key.variants?.includes(code))) {
|
|
12
|
+
if (key.enabled) {
|
|
13
|
+
keyIds.push(key.id);
|
|
14
|
+
} else if (!key.enabled) {
|
|
15
|
+
if (includeDisabled) {
|
|
16
|
+
keyIds.push(key.id);
|
|
17
|
+
} else {
|
|
18
|
+
disabledIds.push(key.id);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (keyIds.length === 0 && disabledIds.length === 0) {
|
|
24
|
+
const withCode = "code" in e && e.code !== void 0 ? `code: ${e.code}` : void 0;
|
|
25
|
+
const withKey = "key" in e && e.key !== void 0 ? `key: ${e.key}` : void 0;
|
|
26
|
+
const withButton = "button" in e && e.button !== void 0 ? `button: ${e.button}` : void 0;
|
|
27
|
+
const withDeltaY = "deltaY" in e && e.deltaY !== void 0 ? `deltaY: ${e.deltaY}` : void 0;
|
|
28
|
+
const info = [withCode, withKey, withButton, withDeltaY].filter((_) => _ !== "undefined").join(", ");
|
|
29
|
+
return Err(new KnownError(
|
|
30
|
+
SHORTCUT_ERROR.UNKNOWN_KEY_EVENT,
|
|
31
|
+
`An unknown key (${info}) was pressed.`,
|
|
32
|
+
{ e, button: withButton, code: withCode, key: withKey, deltaY: withDeltaY }
|
|
33
|
+
));
|
|
34
|
+
}
|
|
35
|
+
return Ok(keyIds);
|
|
36
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type Result } from "@alanscodelog/utils/Result";
|
|
2
|
+
import { KnownError } from "./KnownError.js";
|
|
3
|
+
import { type Key, type Keys, SHORTCUT_ERROR } from "../types/index.js";
|
|
4
|
+
export declare function getKeyFromIdOrVariant(id: string, keys: Keys): Result<Key[], KnownError<typeof SHORTCUT_ERROR.UNKNOWN_KEY_ID>>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { isArray } from "@alanscodelog/utils/isArray";
|
|
2
|
+
import { Err, Ok } from "@alanscodelog/utils/Result";
|
|
3
|
+
import { KnownError } from "./KnownError.js";
|
|
4
|
+
import { SHORTCUT_ERROR } from "../types/index.js";
|
|
5
|
+
export function getKeyFromIdOrVariant(id, keys) {
|
|
6
|
+
let k = keys.entries[id] ?? keys.toggles[id];
|
|
7
|
+
if (k === void 0) {
|
|
8
|
+
if (keys.variants[id]) {
|
|
9
|
+
const variants = [];
|
|
10
|
+
for (const variant of keys.variants[id]) {
|
|
11
|
+
const v = keys.entries[variant] ?? keys.toggles[variant];
|
|
12
|
+
if (v !== void 0) variants.push(v);
|
|
13
|
+
}
|
|
14
|
+
if (variants.length > 0) k = variants;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (!isArray(k) && k !== void 0) k = [k];
|
|
18
|
+
if (k === void 0) {
|
|
19
|
+
return Err(new KnownError(
|
|
20
|
+
SHORTCUT_ERROR.UNKNOWN_KEY_ID,
|
|
21
|
+
`Tried to get unknown key (${id}).`,
|
|
22
|
+
{ id }
|
|
23
|
+
));
|
|
24
|
+
}
|
|
25
|
+
return Ok(k);
|
|
26
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { KeyboardLayoutMap } from "../types/general.js";
|
|
2
|
+
/**
|
|
3
|
+
* Safely get the [KeyboardLayoutMap](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardLayoutMap) with [navigator.getLayoutMap](https://developer.mozilla.org/en-US/docs/Web/API/Keyboard/navigator.getLayoutMap).
|
|
4
|
+
*/
|
|
5
|
+
export declare function getKeyboardLayoutMap(): Promise<KeyboardLayoutMap | undefined>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Key } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the label, adding an `(On)` or `(Off)` suffix to any toggle keys.
|
|
4
|
+
*
|
|
5
|
+
* If the key has not label, uses the id
|
|
6
|
+
*
|
|
7
|
+
* Used by the {@link defaultStringifier}
|
|
8
|
+
*/
|
|
9
|
+
export declare function getLabel(id: string | undefined, key: Key): string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Result } from "@alanscodelog/utils/Result";
|
|
2
|
+
import { KnownError } from "./KnownError.js";
|
|
3
|
+
import type { Manager, PickManager, TriggerableShortcut } from "../types/index.js";
|
|
4
|
+
import { SHORTCUT_ERROR } from "../types/index.js";
|
|
5
|
+
/** Gets all triggerable shortcuts in a manager. */
|
|
6
|
+
export declare function getTriggerableShortcut(manager: Pick<Manager, "shortcuts" | "keys" | "context" | "commands"> & PickManager<"options", "stringifier" | "evaluateCondition"> & PickManager<"state", "chain" | "isRecording">): Result<false | TriggerableShortcut, KnownError<typeof SHORTCUT_ERROR.MULTIPLE_MATCHING_SHORTCUTS>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { crop } from "@alanscodelog/utils/crop";
|
|
2
|
+
import { indent } from "@alanscodelog/utils/indent";
|
|
3
|
+
import { Err, Ok } from "@alanscodelog/utils/Result";
|
|
4
|
+
import { KnownError } from "./KnownError.js";
|
|
5
|
+
import { shortcutIsTriggerableBy } from "./shortcutIsTriggerableBy.js";
|
|
6
|
+
import { SHORTCUT_ERROR } from "../types/index.js";
|
|
7
|
+
export function getTriggerableShortcut(manager) {
|
|
8
|
+
const s = manager.options.stringifier;
|
|
9
|
+
if (manager.state.isRecording) return Ok(false);
|
|
10
|
+
const shortcuts = manager.shortcuts.entries.filter((shortcut) => shortcutIsTriggerableBy(manager.state.chain, shortcut, manager));
|
|
11
|
+
if (shortcuts.length === 0) return Ok(false);
|
|
12
|
+
if (shortcuts.length > 1) {
|
|
13
|
+
return Err(new KnownError(
|
|
14
|
+
SHORTCUT_ERROR.MULTIPLE_MATCHING_SHORTCUTS,
|
|
15
|
+
crop`
|
|
16
|
+
Multiple commands are assigned to the key combination ${s.stringify(manager.state.chain, manager)}:
|
|
17
|
+
|
|
18
|
+
${indent(s.stringifyList("shortcuts", shortcuts, manager), 4)}
|
|
19
|
+
`,
|
|
20
|
+
{ shortcuts }
|
|
21
|
+
));
|
|
22
|
+
} else {
|
|
23
|
+
return Ok(shortcuts[0]);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export { calculateAndSetPositionAndSize } from "./calculateAndSetPositionAndWidth.js";
|
|
2
|
+
export { calculateLayoutSize } from "./calculateLayoutSize.js";
|
|
3
|
+
export { doesShortcutConflict } from "./doesShortcutConflict.js";
|
|
4
|
+
export { equalsCommand } from "./equalsCommand.js";
|
|
5
|
+
export { equalsContext } from "./equalsContext.js";
|
|
6
|
+
export { equalsShortcut } from "./equalsShortcut.js";
|
|
7
|
+
export { forceClear } from "./forceClear.js";
|
|
8
|
+
export { forceUpdateNativeKeysState } from "./forceUpdateNativeKeysState.js";
|
|
9
|
+
export { generateKeyShortcutMap } from "./generateKeyShortcutMap.js";
|
|
10
|
+
export { getKeyboardLayoutMap } from "./getKeyboardLayoutMap.js";
|
|
11
|
+
export { getKeyFromEventCode } from "./getKeyFromEventCode.js";
|
|
12
|
+
export { getKeyFromIdOrVariant } from "./getKeyFromIdOrVariant.js";
|
|
13
|
+
export { getLabel } from "./getLabel.js";
|
|
14
|
+
export { getTriggerableShortcut } from "./getTriggerableShortcut.js";
|
|
15
|
+
export { isValidManager } from "./isValidManager.js";
|
|
16
|
+
export { isValidShortcut } from "./isValidShortcut.js";
|
|
17
|
+
export { KnownError } from "./KnownError.js";
|
|
18
|
+
export { labelWithEvent } from "./labelWithEvent.js";
|
|
19
|
+
export { labelWithKeyboardMap } from "./labelWithKeyboardMap.js";
|
|
20
|
+
export { managerToStorableClone } from "./managerToStorableClone.js";
|
|
21
|
+
export { onKeyboardLayoutChange } from "./onKeyboardLayoutChange.js";
|
|
22
|
+
export { safeSetManagerChain } from "./safeSetManagerChain.js";
|
|
23
|
+
export { shortcutCanExecuteIn } from "./shortcutCanExecuteIn.js";
|
|
24
|
+
export { shortcutIsTriggerableBy } from "./shortcutIsTriggerableBy.js";
|
|
25
|
+
export { shortcutSwapChords } from "./shortcutSwapChords.js";
|
|
26
|
+
export { virtualPress } from "./virtualPress.js";
|
|
27
|
+
export { virtualRelease } from "./virtualRelease.js";
|
|
28
|
+
export { virtualToggle } from "./virtualToggle.js";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export { calculateAndSetPositionAndSize } from "./calculateAndSetPositionAndWidth.js";
|
|
2
|
+
export { calculateLayoutSize } from "./calculateLayoutSize.js";
|
|
3
|
+
export { doesShortcutConflict } from "./doesShortcutConflict.js";
|
|
4
|
+
export { equalsCommand } from "./equalsCommand.js";
|
|
5
|
+
export { equalsContext } from "./equalsContext.js";
|
|
6
|
+
export { equalsShortcut } from "./equalsShortcut.js";
|
|
7
|
+
export { forceClear } from "./forceClear.js";
|
|
8
|
+
export { forceUpdateNativeKeysState } from "./forceUpdateNativeKeysState.js";
|
|
9
|
+
export { generateKeyShortcutMap } from "./generateKeyShortcutMap.js";
|
|
10
|
+
export { getKeyboardLayoutMap } from "./getKeyboardLayoutMap.js";
|
|
11
|
+
export { getKeyFromEventCode } from "./getKeyFromEventCode.js";
|
|
12
|
+
export { getKeyFromIdOrVariant } from "./getKeyFromIdOrVariant.js";
|
|
13
|
+
export { getLabel } from "./getLabel.js";
|
|
14
|
+
export { getTriggerableShortcut } from "./getTriggerableShortcut.js";
|
|
15
|
+
export { isValidManager } from "./isValidManager.js";
|
|
16
|
+
export { isValidShortcut } from "./isValidShortcut.js";
|
|
17
|
+
export { KnownError } from "./KnownError.js";
|
|
18
|
+
export { labelWithEvent } from "./labelWithEvent.js";
|
|
19
|
+
export { labelWithKeyboardMap } from "./labelWithKeyboardMap.js";
|
|
20
|
+
export { managerToStorableClone } from "./managerToStorableClone.js";
|
|
21
|
+
export { onKeyboardLayoutChange } from "./onKeyboardLayoutChange.js";
|
|
22
|
+
export { safeSetManagerChain } from "./safeSetManagerChain.js";
|
|
23
|
+
export { shortcutCanExecuteIn } from "./shortcutCanExecuteIn.js";
|
|
24
|
+
export { shortcutIsTriggerableBy } from "./shortcutIsTriggerableBy.js";
|
|
25
|
+
export { shortcutSwapChords } from "./shortcutSwapChords.js";
|
|
26
|
+
export { virtualPress } from "./virtualPress.js";
|
|
27
|
+
export { virtualRelease } from "./virtualRelease.js";
|
|
28
|
+
export { virtualToggle } from "./virtualToggle.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type Result } from "@alanscodelog/utils/Result";
|
|
2
|
+
import { type ChainError, type Manager, type MultipleErrors, SHORTCUT_ERROR } from "../types/index.js";
|
|
3
|
+
export declare function isValidManager(manager: Manager): Result<true, MultipleErrors<ChainError | typeof SHORTCUT_ERROR.INVALID_MANAGER | typeof SHORTCUT_ERROR.UNKNOWN_COMMAND>>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Err, Ok } from "@alanscodelog/utils/Result";
|
|
2
|
+
import { isValidShortcut } from "./isValidShortcut.js";
|
|
3
|
+
import { KnownError } from "./KnownError.js";
|
|
4
|
+
import { SHORTCUT_ERROR } from "../types/index.js";
|
|
5
|
+
export function isValidManager(manager) {
|
|
6
|
+
const required = ["shortcuts", "keys", "commands"];
|
|
7
|
+
if (required.some((key) => manager[key] === void 0)) {
|
|
8
|
+
return Err(new KnownError(
|
|
9
|
+
SHORTCUT_ERROR.INVALID_MANAGER,
|
|
10
|
+
"Manager is missing required properties.",
|
|
11
|
+
{ keys: Object.keys(manager) }
|
|
12
|
+
));
|
|
13
|
+
}
|
|
14
|
+
let res;
|
|
15
|
+
for (const shortcut of manager.shortcuts.entries) {
|
|
16
|
+
res = isValidShortcut(shortcut, manager);
|
|
17
|
+
if (res.isError) return res;
|
|
18
|
+
}
|
|
19
|
+
return Ok(true);
|
|
20
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type Result } from "@alanscodelog/utils/Result";
|
|
2
|
+
import type { ChainError, Manager, MultipleErrors, PickManager, Shortcut, SHORTCUT_ERROR } from "../types/index.js";
|
|
3
|
+
export declare function isValidShortcut(shortcut: Shortcut, manager: Pick<Manager, "keys" | "commands"> & PickManager<"options", "stringifier" | "sorter">): Result<true, MultipleErrors<ChainError | typeof SHORTCUT_ERROR.UNKNOWN_COMMAND>>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Ok } from "@alanscodelog/utils/Result";
|
|
2
|
+
import { isValidChain } from "../internal/isValidChain.js";
|
|
3
|
+
import { isValidCommand } from "../internal/isValidCommand.js";
|
|
4
|
+
export function isValidShortcut(shortcut, manager) {
|
|
5
|
+
const resCommandsValid = isValidCommand(shortcut.command, manager, shortcut);
|
|
6
|
+
if (resCommandsValid.isError) return resCommandsValid;
|
|
7
|
+
const resChainValid = isValidChain(shortcut.chain, manager);
|
|
8
|
+
if (resChainValid.isError) return resChainValid;
|
|
9
|
+
return Ok(true);
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AnyInputEvent, KeySetEntries, LabelOptions, Manager, MinimalInputEvent, PickManager } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Labels keys using events.
|
|
4
|
+
*
|
|
5
|
+
* For keys uses `KeyboardEvent.key`. For mouse buttons it will label them `Button x` where x is `MouseEvent.button`, and for the mouse wheel, `WheelEvent.deltaY` is used to label them `Wheel Up`/`Wheel Down`.
|
|
6
|
+
*
|
|
7
|
+
* This is intended to be used for labeling keys as they are pressed or as a fallback to {@link labelWithKeyboardMap}. See it for the recommended labeling strategy.
|
|
8
|
+
*
|
|
9
|
+
* A filter can be provided to avoid labeling some keys.
|
|
10
|
+
*/
|
|
11
|
+
export declare function labelWithEvent<T extends MinimalInputEvent | AnyInputEvent = MinimalInputEvent | AnyInputEvent, THooks extends KeySetEntries["label"]["hooks"] = KeySetEntries["label"]["hooks"]>(e: T, keyIds: string[], manager: Pick<Manager, "keys"> & PickManager<"options", "stringifier"> & {
|
|
12
|
+
hooks?: THooks;
|
|
13
|
+
}, options?: Partial<Omit<LabelOptions, "map">>): string[];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { setKeyProp } from "../core/setKeyProp.js";
|
|
2
|
+
export function labelWithEvent(e, keyIds, manager, options = {}) {
|
|
3
|
+
const set = [];
|
|
4
|
+
for (const id of keyIds) {
|
|
5
|
+
let label = "";
|
|
6
|
+
if ("deltaY" in e) {
|
|
7
|
+
label = e.deltaY < 0 ? "Wheel Up" : "Wheel Down";
|
|
8
|
+
} else if ("button" in e) {
|
|
9
|
+
label = `Button ${e.button}`;
|
|
10
|
+
} else if ("key" in e) {
|
|
11
|
+
label = e.key;
|
|
12
|
+
}
|
|
13
|
+
if (!options.labelFilter || options.labelFilter(e, id, label, manager.keys)) {
|
|
14
|
+
const key = manager.keys.entries[id];
|
|
15
|
+
set.push(key.id);
|
|
16
|
+
setKeyProp(key, "label", label, manager);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return set;
|
|
20
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { KeySetEntries, LabelOptions, Manager } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Labels keys using the experimental navigator keyboard [map](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardLayoutMap) (you can get it using {@link getKeyboardLayoutMap} which safely gets it if it's available, otherwise you can use [navigator.getLayoutMap](https://developer.mozilla.org/en-US/docs/Web/API/Keyboard/navigator.getLayoutMap)).
|
|
4
|
+
*
|
|
5
|
+
* It will check for the key in the map first by the id, then by their variants.
|
|
6
|
+
*
|
|
7
|
+
*It returns a list of key ids that were set.
|
|
8
|
+
*
|
|
9
|
+
* Note that not all keys can be auto labeled with the navigator. Modifier keys and some other keys are not available.
|
|
10
|
+
*
|
|
11
|
+
* You can use {@link labelWithEvent} as a fallback, by using it with a filter and only labeling the keys that were not set by this function.
|
|
12
|
+
*/
|
|
13
|
+
export declare function labelWithKeyboardMap<THooks extends KeySetEntries["label"]["hooks"]>(manager: Pick<Manager, "keys"> & {
|
|
14
|
+
hooks?: THooks;
|
|
15
|
+
}, opts: LabelOptions): string[];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { setKeyProp } from "../core/setKeyProp.js";
|
|
2
|
+
export function labelWithKeyboardMap(manager, opts) {
|
|
3
|
+
const set = [];
|
|
4
|
+
for (const key of Object.values(manager.keys.entries)) {
|
|
5
|
+
const codes = [key.id, ...key.variants ?? []];
|
|
6
|
+
for (const code of codes) {
|
|
7
|
+
const label = opts.map.get(code);
|
|
8
|
+
if (label) {
|
|
9
|
+
if (!opts.labelFilter || opts.labelFilter({ key: label }, key.id, label, manager.keys)) {
|
|
10
|
+
setKeyProp(key, "label", label, manager);
|
|
11
|
+
set.push(key.id);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return set;
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DeepPartial } from "@alanscodelog/utils/types";
|
|
2
|
+
import type { Manager } from "../types/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Strips the manager of properties that should not be saved such as `hooks`, `listener`, `state`, and the following function options:
|
|
5
|
+
*
|
|
6
|
+
* - `evaluateCondition`
|
|
7
|
+
* - `cb`
|
|
8
|
+
* - `sorter`
|
|
9
|
+
* - `stringifier`
|
|
10
|
+
* - `conditionEquals`
|
|
11
|
+
*/
|
|
12
|
+
export declare function managerToStorableClone(m: Manager): DeepPartial<Manager>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { walk } from "@alanscodelog/utils/walk";
|
|
2
|
+
export function managerToStorableClone(m) {
|
|
3
|
+
const clone = walk(m, void 0, { save: true });
|
|
4
|
+
delete clone.hooks;
|
|
5
|
+
delete clone.listener;
|
|
6
|
+
delete clone.state;
|
|
7
|
+
delete clone.options.evaluateCondition;
|
|
8
|
+
delete clone.options.cb;
|
|
9
|
+
delete clone.options.sorter;
|
|
10
|
+
delete clone.options.stringifier;
|
|
11
|
+
delete clone.options.conditionEquals;
|
|
12
|
+
return clone;
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The spec describes a ["layoutchange" event](https://wicg.github.io/keyboard-map/#layoutchange-event) that can be added to the navigator.keyboard.
|
|
3
|
+
*
|
|
4
|
+
* I have not found a browser that implements it.
|
|
5
|
+
*
|
|
6
|
+
* But this should safely attach to the event if it exists and call the given callback if it does.
|
|
7
|
+
*
|
|
8
|
+
* It will return true if it managed to attach.
|
|
9
|
+
*/
|
|
10
|
+
export declare function onKeyboardLayoutChange(cb: () => void | Promise<void>): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Result } from "@alanscodelog/utils/Result";
|
|
2
|
+
import type { Manager, ManagerSetEntries, MultipleErrors } from "../types/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Safely sets the manager's chain.
|
|
5
|
+
*
|
|
6
|
+
* Note that it might seem to do odd things to keep the state consistant and prevent us from getting into invalid states or triggering shorcuts when we shouldn't. Some of these include:
|
|
7
|
+
* - If the new chain would trigger a shortcut, the shortcut will be synthetically triggered with a keyup.
|
|
8
|
+
* - If the manager is {@link Manager.state.isAwaitingKeyup} to trigger anything ({@link Manager.state.untrigger}), the shortcut will be synthetically triggered with a keyup.
|
|
9
|
+
* - If there are still non-modifier keys being pressed, the manager will wait until they are all released before allowing keys to be added to the chained again.
|
|
10
|
+
* - Modifiers will stay in the first chord if they are still being pressed according to {@link Key.press}. This makes it possible for the user to trigger multiple shortcuts without releasing a modifier. This can result in potentially strange behavior for shortcuts longer than one chord, as further chords can be started without releasing the modifiers. If you don't like this, you can pass `{preserveModifiers: false}` to force the user to release the modifiers.
|
|
11
|
+
* - If there are still modifier keys being pressed, the manager will add them to the last chord, unless you pass `preserverModifiers: false`.
|
|
12
|
+
* - **If keys are currently being held ({@link Key.pressed} is true), note that the manager's state and the key state state may not match. This is usually not a problem with normal key presses, but... **
|
|
13
|
+
* - If using virtualPress/virtualToggle, the keys might remain pressed, potentially causing issues. In those cases you can use the {@link Manager.listener} to keep track of whether keys are virtually pressed or not (virtually pressed keys have no events), and unpress the ones you should.
|
|
14
|
+
* - Setting a `[]` chain is slightly different than setting a `[[]]` chain to keep the behavior of the manager consistent on the next key press.
|
|
15
|
+
* - When you set `[]`, the function will also set {@link Manager.state.nextIsChord} to `true`, so it knows to insert a chord on the next key press.
|
|
16
|
+
* - When you set `[[]]`, it will set it to `false`, since the chord already exists.
|
|
17
|
+
*/
|
|
18
|
+
export declare function safeSetManagerChain(manager: Manager, chain: string[][], { preserveModifiers }?: {
|
|
19
|
+
preserveModifiers?: boolean;
|
|
20
|
+
}): Result<string[][], MultipleErrors<ManagerSetEntries["state.chain"]["error"]>>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { pushIfNotIn } from "@alanscodelog/utils";
|
|
2
|
+
import { last } from "@alanscodelog/utils/last";
|
|
3
|
+
import { Ok } from "@alanscodelog/utils/Result";
|
|
4
|
+
import { setManagerProp } from "../core/setManagerProp.js";
|
|
5
|
+
import { checkTrigger } from "../internal/checkTrigger.js";
|
|
6
|
+
import { checkUntrigger } from "../internal/checkUntrigger.js";
|
|
7
|
+
import { getPressedModifierKeys } from "../internal/getPressedModifierKeys.js";
|
|
8
|
+
import { getPressedNonModifierKeys } from "../internal/getPressedNonModifierKeys.js";
|
|
9
|
+
import { inChain } from "../internal/inChain.js";
|
|
10
|
+
import { cloneChain } from "../utils/cloneChain.js";
|
|
11
|
+
export function safeSetManagerChain(manager, chain, { preserveModifiers = true } = {}) {
|
|
12
|
+
const newChain = cloneChain(chain);
|
|
13
|
+
if (getPressedNonModifierKeys(manager).length > 0) {
|
|
14
|
+
setManagerProp(manager, "state.isAwaitingKeyup", true, { check: false });
|
|
15
|
+
}
|
|
16
|
+
const pressedModifiers = getPressedModifierKeys(manager);
|
|
17
|
+
if (preserveModifiers && pressedModifiers.length > 0) {
|
|
18
|
+
if (newChain.length > 0) {
|
|
19
|
+
pushIfNotIn(last(newChain), pressedModifiers);
|
|
20
|
+
} else {
|
|
21
|
+
newChain.push(pressedModifiers);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const can = setManagerProp(manager, "state.chain", newChain, { check: "only" });
|
|
25
|
+
if (can.isError) return can;
|
|
26
|
+
checkUntrigger(manager);
|
|
27
|
+
setManagerProp(manager, "state.chain", newChain).unwrap();
|
|
28
|
+
const isEmpty = newChain.length === 0 || newChain.length === 1 && newChain?.[0].length === 0;
|
|
29
|
+
if (!isEmpty) {
|
|
30
|
+
setManagerProp(manager, "state.nextIsChord", inChain(manager), { check: false });
|
|
31
|
+
checkTrigger(manager);
|
|
32
|
+
checkUntrigger(manager);
|
|
33
|
+
} else {
|
|
34
|
+
setManagerProp(manager, "state.nextIsChord", newChain.length === 0, { check: false });
|
|
35
|
+
}
|
|
36
|
+
return Ok(manager.state.chain);
|
|
37
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Manager, PickManager, Shortcut } from "../types/index.js";
|
|
2
|
+
export declare function shortcutCanExecuteIn(shortcut: Shortcut, manager: Pick<Manager, "context" | "commands"> & PickManager<"options", "evaluateCondition">, { allowEmptyCommand }?: {
|
|
3
|
+
allowEmptyCommand?: boolean;
|
|
4
|
+
}): boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function shortcutCanExecuteIn(shortcut, manager, {
|
|
2
|
+
allowEmptyCommand = false
|
|
3
|
+
} = {}) {
|
|
4
|
+
const context = manager.context;
|
|
5
|
+
const commands = manager.commands;
|
|
6
|
+
const evaluateCondition = manager.options.evaluateCondition;
|
|
7
|
+
const fullCommand = shortcut.command ? commands.entries[shortcut.command] : void 0;
|
|
8
|
+
return shortcut.enabled && (allowEmptyCommand && fullCommand?.execute === void 0 || fullCommand !== void 0 && evaluateCondition(fullCommand?.condition, context)) && shortcut.condition !== void 0 && evaluateCondition(shortcut.condition, context);
|
|
9
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { shortcutCanExecuteIn } from "./shortcutCanExecuteIn.js";
|
|
2
|
+
import { equalsKeys } from "../utils/equalsKeys.js";
|
|
3
|
+
export function shortcutIsTriggerableBy(chain, shortcut, manager) {
|
|
4
|
+
return shortcutCanExecuteIn(shortcut, manager, { allowEmptyCommand: true }) && equalsKeys(shortcut.chain, chain, manager.keys, void 0, { allowVariants: true });
|
|
5
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type Result } from "@alanscodelog/utils/Result";
|
|
2
|
+
import { KnownError } from "./KnownError.js";
|
|
3
|
+
import type { Manager, PickManager, Shortcut, Shortcuts } from "../types/index.js";
|
|
4
|
+
import { SHORTCUT_ERROR } from "../types/index.js";
|
|
5
|
+
/**
|
|
6
|
+
* Swaps the given chords for all matching shortcuts.
|
|
7
|
+
*
|
|
8
|
+
* This is done by using forceUnequal for each set of matching shortcuts in turn.
|
|
9
|
+
*
|
|
10
|
+
* EXAMPLES:
|
|
11
|
+
*
|
|
12
|
+
* Given the following shortcuts:
|
|
13
|
+
*
|
|
14
|
+
* ```
|
|
15
|
+
* 1 A
|
|
16
|
+
* 1 B
|
|
17
|
+
* 2 C
|
|
18
|
+
* 2 D
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* `swapChords([[1]], [[2]])` would result in:
|
|
22
|
+
*
|
|
23
|
+
* ```
|
|
24
|
+
* 2 A
|
|
25
|
+
* 2 B
|
|
26
|
+
* 1 C
|
|
27
|
+
* 1 D
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* Multiple chords, and chords of unequal lengths can be safely swapped.
|
|
31
|
+
*
|
|
32
|
+
* ```
|
|
33
|
+
* 1 2 A
|
|
34
|
+
* 1 2 B
|
|
35
|
+
* 3 C
|
|
36
|
+
* 3 D
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* `swapChords([[1], [2]], [[3]])`:
|
|
40
|
+
* ```
|
|
41
|
+
* 3 A
|
|
42
|
+
* 3 B
|
|
43
|
+
* 1 2 C
|
|
44
|
+
* 1 2 D
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* A filter function is provided, to, for example, filter out disabled entries from the swap. Note that it might be unsafe to swap entries with a filter if the new entries can be equal to the ignored ones, hence why the `check` exists.
|
|
48
|
+
*
|
|
49
|
+
* Example of how it might be a problem:
|
|
50
|
+
* ```
|
|
51
|
+
* A
|
|
52
|
+
* B
|
|
53
|
+
* ```
|
|
54
|
+
* `shortcutSwapChords([[A]], [[B]], () => { filter that ignores A })` would result in two A shortcuts.
|
|
55
|
+
*
|
|
56
|
+
* But if, for example, you use the filter to ignore disabled shortcuts, this wouldn't be a problem because you'd get two unequal shortcuts (A and A(disabled)), though re/dis-abling one of them would trigger a conflict.
|
|
57
|
+
*
|
|
58
|
+
* Note: Certain types of chords cannot be swapped, like empty chords, or chords which share a base.
|
|
59
|
+
*
|
|
60
|
+
* If using the experimental {@link ignoreModifierConflicts Shortcuts["ignoreModifierConflicts"]}, note that you cannot use this to swap the base modifiers.
|
|
61
|
+
*
|
|
62
|
+
* For example, say you had:
|
|
63
|
+
* ```
|
|
64
|
+
* Ctrl+A
|
|
65
|
+
* Ctrl
|
|
66
|
+
* ```
|
|
67
|
+
* If you do `swapChords([Ctrl],[Shift])`, `Ctrl+A` is not considered to match the `[Ctrl]` chord and you will get:
|
|
68
|
+
* ```
|
|
69
|
+
* Ctrl+A
|
|
70
|
+
* Shift
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare function shortcutSwapChords(shortcuts: Shortcuts, chainA: string[][], chainB: string[][], manager: Pick<Manager, "keys" | "shortcuts" | "commands"> & PickManager<"options", "evaluateCondition" | "conditionEquals" | "stringifier" | "sorter">, { check }?: {
|
|
74
|
+
check?: boolean | "only";
|
|
75
|
+
}, filter?: (shortcut: Shortcut) => boolean): Result<true, KnownError<typeof SHORTCUT_ERROR.INVALID_SWAP_CHORDS | typeof SHORTCUT_ERROR.INVALID_SWAP_CHORDS | typeof SHORTCUT_ERROR.DUPLICATE_SHORTCUT> | Error>;
|