mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-26 00:01:37 +00:00
fix(vscode): improve paste support for vscode extension
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import SchemaForm from '$lib/components/SchemaForm.svelte'
|
||||
import JsonInputs from '$lib/components/JsonInputs.svelte'
|
||||
import JobLoader from '$lib/components/JobLoader.svelte'
|
||||
import { Button } from '$lib/components/common'
|
||||
import { WindmillIcon } from '$lib/components/icons'
|
||||
@@ -121,6 +122,9 @@
|
||||
// Test args input
|
||||
let args: Record<string, any> = $state({})
|
||||
let isValid: boolean = $state(true)
|
||||
let jsonView: boolean = $state(false)
|
||||
let jsonEditor: JsonInputs | undefined = $state(undefined)
|
||||
let schemaHeight = $state(0)
|
||||
|
||||
// Test
|
||||
let testIsLoading = $state(false)
|
||||
@@ -781,9 +785,38 @@
|
||||
<Splitpanes horizontal style="height: 1000px;">
|
||||
<Pane size={33}>
|
||||
<div class="px-2">
|
||||
<div class="break-words relative font-sans">
|
||||
<SchemaForm compact {schema} bind:args bind:isValid />
|
||||
<div class="flex justify-end mb-2">
|
||||
<Toggle
|
||||
bind:checked={jsonView}
|
||||
size="xs"
|
||||
options={{
|
||||
right: 'JSON',
|
||||
rightTooltip: 'Fill args from JSON'
|
||||
}}
|
||||
lightMode
|
||||
on:change={() => {
|
||||
jsonEditor?.setCode(JSON.stringify(args ?? {}, null, '\t'))
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{#if jsonView}
|
||||
<div class="py-2" style="height: {Math.max(schemaHeight, 300)}px">
|
||||
<JsonInputs
|
||||
bind:this={jsonEditor}
|
||||
on:select={(e) => {
|
||||
if (e.detail) {
|
||||
args = e.detail
|
||||
}
|
||||
}}
|
||||
updateOnBlur={false}
|
||||
placeholder={`Write args as JSON.<br/><br/>Example:<br/><br/>{<br/> "foo": "12"<br/>}`}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="break-words relative font-sans" bind:clientHeight={schemaHeight}>
|
||||
<SchemaForm compact {schema} bind:args bind:isValid />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane size={67}>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import '@codingame/monaco-vscode-standalone-languages'
|
||||
import '@codingame/monaco-vscode-standalone-json-language-features'
|
||||
import '@codingame/monaco-vscode-standalone-typescript-language-features'
|
||||
import { editor as meditor } from 'monaco-editor'
|
||||
import { editor as meditor, KeyMod, KeyCode } from 'monaco-editor'
|
||||
|
||||
import { initializeVscode } from './vscode'
|
||||
import EditorTheme from './EditorTheme.svelte'
|
||||
@@ -75,6 +75,37 @@
|
||||
scrollbar: { alwaysConsumeMouseWheel: false }
|
||||
})
|
||||
|
||||
// In VSCode webview (iframe), clipboard operations need special handling
|
||||
// because the webview has restricted clipboard API access
|
||||
if (window.parent !== window) {
|
||||
const modifiedEditor = diffEditor.getModifiedEditor()
|
||||
modifiedEditor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyC, function () {
|
||||
document.execCommand('copy')
|
||||
})
|
||||
modifiedEditor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyX, function () {
|
||||
document.execCommand('cut')
|
||||
})
|
||||
modifiedEditor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyV, async function () {
|
||||
try {
|
||||
const text = await navigator.clipboard.readText()
|
||||
if (text) {
|
||||
const selection = modifiedEditor.getSelection()
|
||||
if (selection) {
|
||||
modifiedEditor.executeEdits('paste', [
|
||||
{
|
||||
range: selection,
|
||||
text: text,
|
||||
forceMoveMarkers: true
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
document.execCommand('paste')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
console.log('defaultModified', defaultModified)
|
||||
if (defaultLang !== undefined) {
|
||||
setupModel(defaultLang, defaultOriginal, defaultModified, defaultModifiedLang)
|
||||
|
||||
@@ -1376,6 +1376,38 @@
|
||||
|
||||
keepModelAroundToAvoidDisposalOfWorkers()
|
||||
|
||||
// In VSCode webview (iframe), clipboard operations need special handling
|
||||
// because the webview has restricted clipboard API access
|
||||
if (window.parent !== window) {
|
||||
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyC, function () {
|
||||
document.execCommand('copy')
|
||||
})
|
||||
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyX, function () {
|
||||
document.execCommand('cut')
|
||||
})
|
||||
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyV, async function () {
|
||||
try {
|
||||
// Use Clipboard API to read text, then insert via Monaco's API
|
||||
const text = await navigator.clipboard.readText()
|
||||
if (text && editor) {
|
||||
const selection = editor.getSelection()
|
||||
if (selection) {
|
||||
editor.executeEdits('paste', [
|
||||
{
|
||||
range: selection,
|
||||
text: text,
|
||||
forceMoveMarkers: true
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Clipboard API failed, try execCommand as fallback
|
||||
document.execCommand('paste')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// updateEditorKeybindingsMode(editor, 'vim', undefined)
|
||||
|
||||
// Raw app lint collection: listen for marker changes and report to store
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { BROWSER } from 'esm-env'
|
||||
|
||||
import { editor as meditor } from 'monaco-editor'
|
||||
import { editor as meditor, KeyMod, KeyCode } from 'monaco-editor'
|
||||
|
||||
import { onDestroy, onMount } from 'svelte'
|
||||
|
||||
@@ -20,6 +20,14 @@
|
||||
lineNumbers: 'off',
|
||||
minimap: { enabled: false }
|
||||
})
|
||||
|
||||
// In VSCode webview (iframe), clipboard operations need to use execCommand
|
||||
// because the webview has restricted clipboard API access
|
||||
if (window.parent !== window) {
|
||||
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyC, function () {
|
||||
document.execCommand('copy')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
|
||||
@@ -4,14 +4,21 @@
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
export let updateOnBlur = true
|
||||
export let placeholder =
|
||||
'Write a JSON payload. The input schema will be inferred.<br/><br/>Example:<br/><br/>{<br/> "foo": "12"<br/>}'
|
||||
export let selected: boolean = false
|
||||
interface Props {
|
||||
updateOnBlur?: boolean
|
||||
placeholder?: string
|
||||
selected?: boolean
|
||||
}
|
||||
|
||||
let pendingJson = ''
|
||||
let simpleEditor: SimpleEditor | undefined = undefined
|
||||
let focusTrap: HTMLElement | undefined
|
||||
let {
|
||||
updateOnBlur = true,
|
||||
placeholder = 'Write a JSON payload. The input schema will be inferred.<br/><br/>Example:<br/><br/>{<br/> "foo": "12"<br/>}',
|
||||
selected = false
|
||||
}: Props = $props()
|
||||
|
||||
let pendingJson = $state('')
|
||||
let simpleEditor: SimpleEditor | undefined = $state(undefined)
|
||||
let focusTrap: HTMLElement | undefined = $state()
|
||||
|
||||
function updatePayloadFromJson(jsonInput: string) {
|
||||
if (jsonInput === undefined || jsonInput === null || jsonInput.trim() === '') {
|
||||
@@ -44,12 +51,12 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={handleKeydown} />
|
||||
<svelte:window onkeydown={handleKeydown} />
|
||||
|
||||
<!-- Add a hidden button that can receive focus -->
|
||||
<button bind:this={focusTrap} class="sr-only" tabindex="-1" aria-hidden="true">Focus trap</button>
|
||||
|
||||
<div class="h-full py-3 rounded-md border">
|
||||
<div class="h-full rounded-md border">
|
||||
<SimpleEditor
|
||||
bind:this={simpleEditor}
|
||||
on:focus={() => {
|
||||
|
||||
@@ -360,6 +360,21 @@
|
||||
}
|
||||
keepModelAroundToAvoidDisposalOfWorkers()
|
||||
|
||||
// In VSCode webview (iframe), clipboard operations need special handling
|
||||
// because the webview has restricted clipboard API access
|
||||
if (window.parent !== window) {
|
||||
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyC, function () {
|
||||
document.execCommand('copy')
|
||||
})
|
||||
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyX, function () {
|
||||
document.execCommand('cut')
|
||||
})
|
||||
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyV, async function () {
|
||||
inputEl?.focus()
|
||||
document.execCommand('paste')
|
||||
})
|
||||
}
|
||||
|
||||
let timeoutModel: number | undefined = undefined
|
||||
editor.onDidChangeModelContent((event) => {
|
||||
timeoutModel && clearTimeout(timeoutModel)
|
||||
@@ -583,8 +598,38 @@
|
||||
}
|
||||
|
||||
updatePlaceholderVisibility(code ?? '')
|
||||
|
||||
let inputEl = $state<HTMLInputElement | null>(null)
|
||||
let pasteValue = $state('')
|
||||
$effect(() => {
|
||||
if (inputEl && pasteValue) {
|
||||
untrack(() => {
|
||||
editor?.executeEdits('paste', [
|
||||
{
|
||||
range: editor?.getSelection() ?? {
|
||||
startLineNumber: 1,
|
||||
startColumn: 1,
|
||||
endLineNumber: 1,
|
||||
endColumn: 1
|
||||
},
|
||||
text: pasteValue,
|
||||
forceMoveMarkers: true
|
||||
}
|
||||
])
|
||||
pasteValue = ''
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if parent.window !== window}
|
||||
<input
|
||||
style="height: 0; width: 0; opacity: 0; position: absolute; top: 0; left: 0; z-index: -1;"
|
||||
type="text"
|
||||
bind:this={inputEl}
|
||||
bind:value={pasteValue}
|
||||
/>
|
||||
{/if}
|
||||
<EditorTheme />
|
||||
{#if !editor || suggestion}
|
||||
<FakeMonacoPlaceHolder
|
||||
|
||||
@@ -464,6 +464,36 @@
|
||||
return
|
||||
}
|
||||
|
||||
// In VSCode webview (iframe), clipboard operations need special handling
|
||||
// because the webview has restricted clipboard API access
|
||||
if (window.parent !== window) {
|
||||
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyC, function () {
|
||||
document.execCommand('copy')
|
||||
})
|
||||
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyX, function () {
|
||||
document.execCommand('cut')
|
||||
})
|
||||
editor.addCommand(KeyMod.CtrlCmd | KeyCode.KeyV, async function () {
|
||||
try {
|
||||
const text = await navigator.clipboard.readText()
|
||||
if (text && editor) {
|
||||
const selection = editor.getSelection()
|
||||
if (selection) {
|
||||
editor.executeEdits('paste', [
|
||||
{
|
||||
range: selection,
|
||||
text: text,
|
||||
forceMoveMarkers: true
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
document.execCommand('paste')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
editor.onDidFocusEditorText(() => {
|
||||
dispatch('focus')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user