Skip to content

Instantly share code, notes, and snippets.

@prmichaelsen
Created October 5, 2023 04:38
Show Gist options
  • Save prmichaelsen/f6233f9ff0347cc04234316c24d501ea to your computer and use it in GitHub Desktop.
Save prmichaelsen/f6233f9ff0347cc04234316c24d501ea to your computer and use it in GitHub Desktop.
Minimal example of passing hotkey strokes between VSCode and an internal webview
// Within SPA webapp
import { useEffect } from 'react';
export default function() {
useEffect(() => {
window.addEventListener('keydown', (event) => {
if ((event.ctrlKey || event.metaKey) && event.code === "KeyC") {
document.execCommand("copy");
} else if ((event.ctrlKey || event.metaKey) && event.code === "KeyX") {
document.execCommand("cut");
} else if ((event.ctrlKey || event.metaKey) && event.code === "KeyV") {
document.execCommand("paste");
} else if (event.ctrlKey || event.metaKey || event.shiftKey) {
const {
ctrlKey,
metaKey,
shiftKey,
code,
} = event;
window.parent.postMessage({
type: 'keydown-event',
payload: {
ctrlKey,
metaKey,
shiftKey,
code,
},
}, '*');
}
});
});
return (
<span>Hello world!</span>
);
}
// within VSCode Extension
import { ViewColumn, window, env, commands } from "vscode";
export const getPanel = async () => {
const panel = window.createWebviewPanel(
'webview',
'webview',
ViewColumn.Beside,
{
retainContextWhenHidden: true,
enableScripts: true,
enableCommandUris: true,
}
);
const origin = 'https://yourwebviewhost.com';
const query = 'some-route';
const srcUrl = origin + '/' + query;
const iframeHtml = `
<html>
<script>
const vscode = acquireVsCodeApi();
<!-- https://github.com/microsoft/vscode/issues/129178 -->
window.addEventListener('message', (event) => {
if (event.origin === '${origin}') {
console.log('Received event from ${origin}');
vscode.postMessage(event.data);
} else{
console.log('Received from vscode');
const iFrame = document.querySelector('iframe');
const iFrameWindow = iFrame.contentWindow;
iFrameWindow.postMessage(event.data, '*');
}
});
</script>
<body style="margin: 0; padding: 0; height: 100vh;">
<iframe
id="webview"
allow="clipboard-read; clipboard-write;"
src="${srcUrl}"
style="outline: none; border: none; height: 100vh; width: 100vw;"></iframe>
</body>
</html>
`;
panel.webview.onDidReceiveMessage(async e => {
switch (e.type) {
case 'keydown-event': {
const {
ctrlKey,
metaKey,
shiftKey,
code,
} = e.payload;
if (!ctrlKey && metaKey && shiftKey && code === "KeyP") {
await commands.executeCommand('workbench.action.showCommands');
return;
}
if (!ctrlKey && metaKey && !shiftKey && code === "KeyP") {
await commands.executeCommand('workbench.action.quickOpen');
return;
}
if (!ctrlKey && metaKey && !shiftKey && code === "KeyW") {
await commands.executeCommand('workbench.action.closeActiveEditor');
return;
}
break;
}
case 'showInformationMessage': {
window.showInformationMessage(e.paylod);
break;
}
case 'copyToClipboard': {
await env.clipboard.writeText(e.payload);
const editor = window.visibleTextEditors[0];
const selection = editor.selection;
await editor.edit(edit => {
edit.replace(selection, e.payload);
});
}
}
});
panel.webview.html = iframeHtml;
return panel;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment