diff options
Diffstat (limited to 'src/shared')
| -rw-r--r-- | src/shared/utils/keys.js | 86 | 
1 files changed, 86 insertions, 0 deletions
| diff --git a/src/shared/utils/keys.js b/src/shared/utils/keys.js new file mode 100644 index 0000000..fba8ce3 --- /dev/null +++ b/src/shared/utils/keys.js @@ -0,0 +1,86 @@ +const modifierdKeyName = (name) => { +  if (name.length === 1) { +    return name; +  } else if (name === 'Escape') { +    return 'Esc'; +  } +  return name; +}; + +const fromKeyboardEvent = (e) => { +  let key = modifierdKeyName(e.key); +  let shift = e.shiftKey; +  if (key.length === 1 && key.toUpperCase() === key.toLowerCase()) { +    // make shift false for symbols to enable key bindings by symbold keys. +    // But this limits key bindings by symbol keys with Shift (such as Shift+$>. +    shift = false; +  } + +  return { +    key: modifierdKeyName(e.key), +    shiftKey: shift, +    ctrlKey: e.ctrlKey, +    altKey: e.altKey, +    metaKey: e.metaKey, +  }; +}; + +const fromMapKey = (key) => { +  if (key.startsWith('<') && key.endsWith('>')) { +    let inner = key.slice(1, -1); +    let shift = inner.includes('S-'); +    let base = inner.slice(inner.lastIndexOf('-') + 1); +    if (shift && base.length === 1) { +      base = base.toUpperCase(); +    } else if (!shift && base.length === 1) { +      base = base.toLowerCase(); +    } +    return { +      key: base, +      shiftKey: inner.includes('S-'), +      ctrlKey: inner.includes('C-'), +      altKey: inner.includes('A-'), +      metaKey: inner.includes('M-'), +    }; +  } +  return { +    key: key, +    shiftKey: key.toLowerCase() !== key, +    ctrlKey: false, +    altKey: false, +    metaKey: false, +  }; +}; + +const fromMapKeys = (keys) => { +  const fromMapKeysRecursive = (remainings, mappedKeys) => { +    if (remainings.length === 0) { +      return mappedKeys; +    } + +    let nextPos = 1; +    if (remainings.startsWith('<')) { +      let ltPos = remainings.indexOf('>'); +      if (ltPos > 0) { +        nextPos = ltPos + 1; +      } +    } + +    return fromMapKeysRecursive( +      remainings.slice(nextPos), +      mappedKeys.concat([fromMapKey(remainings.slice(0, nextPos))]) +    ); +  }; + +  return fromMapKeysRecursive(keys, []); +}; + +const equals = (e1, e2) => { +  return e1.key === e2.key && +    e1.ctrlKey === e2.ctrlKey && +    e1.metaKey === e2.metaKey && +    e1.altKey === e2.altKey && +    e1.shiftKey === e2.shiftKey; +}; + +export { fromKeyboardEvent, fromMapKey, fromMapKeys, equals }; | 
