All files / webview saveShortcut.ts

100% Statements 28/28
90.9% Branches 10/11
100% Functions 10/10
100% Lines 23/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59          1x     4x                 3x 3x 1x 1x   2x       4x 4x 4x   3x 3x   3x 3x             4x 4x         1x 1x   1x 1x 1x 1x 1x        
import { useEffect, useRef } from 'react';
import { getVsCodeApi } from './vscodeApi';
 
type SaveContentProvider = () => string | undefined;
 
const saveContentProviders = new Set<SaveContentProvider>();
 
function isSaveShortcut(event: KeyboardEvent) {
  return (
    (event.metaKey || event.ctrlKey) &&
    !event.altKey &&
    !event.shiftKey &&
    event.key.toLowerCase() === 's'
  );
}
 
function getCurrentContentForSave() {
  const providers = Array.from(saveContentProviders);
  for (let i = providers.length - 1; i >= 0; i -= 1) {
    const content = providers[i]();
    Eif (typeof content === 'string') return content;
  }
  return undefined;
}
 
export function useSaveShortcut() {
  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (!isSaveShortcut(event)) return;
 
      event.preventDefault();
      event.stopPropagation();
 
      const content = getCurrentContentForSave();
      getVsCodeApi()?.postMessage(
        typeof content === 'string'
          ? { type: 'save', content }
          : { type: 'save' }
      );
    };
 
    document.addEventListener('keydown', handleKeyDown, true);
    return () => document.removeEventListener('keydown', handleKeyDown, true);
  }, []);
}
 
export function useSaveContentProvider(provider: SaveContentProvider) {
  const providerRef = useRef(provider);
  providerRef.current = provider;
 
  useEffect(() => {
    const wrappedProvider = () => providerRef.current();
    saveContentProviders.add(wrappedProvider);
    return () => {
      saveContentProviders.delete(wrappedProvider);
    };
  }, []);
}