split editor and simple editor

This commit is contained in:
Ruben Fiszel
2022-09-03 15:11:51 +02:00
parent 0d72ab9306
commit e8aec1c93a
8 changed files with 246 additions and 93 deletions
+3 -3
View File
@@ -13,7 +13,6 @@
import { Button, Tooltip } from 'flowbite-svelte'
import { createEventDispatcher } from 'svelte'
import Icon from 'svelte-awesome'
import Editor from './Editor.svelte'
import FieldHeader from './FieldHeader.svelte'
import ObjectResourceInput from './ObjectResourceInput.svelte'
import ObjectTypeNarrowing from './ObjectTypeNarrowing.svelte'
@@ -21,6 +20,7 @@
import StringTypeNarrowing from './StringTypeNarrowing.svelte'
import SchemaForm from './SchemaForm.svelte'
import type { SchemaProperty } from '$lib/common'
import SimpleEditor from './SimpleEditor.svelte'
export let label: string = ''
export let value: any
@@ -55,7 +55,7 @@
let error: string = ''
export let editor: Editor | undefined = undefined
export let editor: SimpleEditor | undefined = undefined
let rawValue: string | undefined = undefined
@@ -300,7 +300,7 @@
<input class="inline-block" type="datetime-local" bind:value />
{:else if inputCat == 'sql'}
<div class="border rounded mb-4 w-full border-gray-700">
<Editor
<SimpleEditor
on:focus={() => dispatch('focus')}
on:blur={() => dispatch('blur')}
bind:this={editor}
+13 -82
View File
@@ -1,11 +1,6 @@
<script lang="ts" context="module">
import * as monaco from 'monaco-editor'
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
target: monaco.languages.typescript.ScriptTarget.Latest,
allowNonTsExtensions: true,
noLib: true
})
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
target: monaco.languages.typescript.ScriptTarget.Latest,
allowNonTsExtensions: true,
@@ -16,13 +11,6 @@
noSuggestionDiagnostics: true,
noSyntaxValidation: true
})
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
allowComments: false,
schemas: [],
enableSchemaRequest: true
})
</script>
<script lang="ts">
@@ -31,7 +19,6 @@
import { sendUserToast } from '$lib/utils'
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
import { buildWorkerDefinition } from 'monaco-editor-workers'
@@ -46,6 +33,12 @@
import getMessageServiceOverride from 'vscode/service-override/messages'
import { StandaloneServices } from 'vscode/services'
import { DENO_INIT_CODE_CLEAR, PYTHON_INIT_CODE_CLEAR } from '$lib/script_helpers'
import {
createHash as randomHash,
editorConfig,
langToExt,
updateOptions
} from '$lib/editorUtils'
StandaloneServices.initialize({
...getMessageServiceOverride(document.body)
@@ -57,13 +50,11 @@
export let deno = false
export let lang = deno ? 'typescript' : 'python'
export let code: string = ''
export let hash: string = (Math.random() + 1).toString(36).substring(2)
export let hash: string = randomHash()
export let cmdEnterAction: (() => void) | undefined = undefined
export let formatAction: (() => void) | undefined = undefined
export let automaticLayout = true
export let websocketAlive = { pyright: false, black: false, deno: false }
export let extraLib: string = ''
export let extraLibPath: string = ''
export let shouldBindKey: boolean = true
let websockets: [MonacoLanguageClient, WebSocket][] = []
@@ -86,9 +77,7 @@
// @ts-ignore
self.MonacoEnvironment = {
getWorker: function (_moduleId: any, label: string) {
if (label === 'json') {
return new jsonWorker()
} else if (label === 'typescript' || label === 'javascript') {
if (label === 'typescript' || label === 'javascript') {
return new tsWorker()
} else {
return new editorWorker()
@@ -108,23 +97,6 @@
}
}
function langToExt(lang: string): string {
switch (lang) {
case 'typescript':
return 'ts'
case 'python':
return 'py'
case 'javascript':
return 'js'
case 'json':
return 'json'
case 'sql':
return 'sql'
default:
return 'unknown'
}
}
export function insertAtBeginning(code: string): void {
if (editor) {
const range = { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 }
@@ -387,28 +359,11 @@
async function loadMonaco() {
const model = monaco.editor.createModel(code, lang, monaco.Uri.parse(uri))
model.updateOptions({ tabSize: 2, insertSpaces: true })
editor = monaco.editor.create(divEl as HTMLDivElement, {
model: model,
value: code,
language: lang,
automaticLayout,
readOnly: false,
fixedOverflowWidgets: true,
autoDetectHighContrast: true,
//lineNumbers: 'off',
//lineDecorationsWidth: 0,
lineNumbersMinChars: 4,
lineNumbers: (ln) => '<span class="pr-4 text-gray-400">' + ln + '</span>',
folding: false,
scrollBeyondLastLine: false,
minimap: {
enabled: false
},
lightbulb: {
enabled: true
}
})
model.updateOptions(updateOptions)
editor = monaco.editor.create(
divEl as HTMLDivElement,
editorConfig(model, code, lang, automaticLayout)
)
if (shouldBindKey) {
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () {
@@ -449,15 +404,6 @@
dispatch('blur')
})
if (lang == 'javascript' && extraLib != '' && extraLibPath != '') {
monaco.languages.typescript.javascriptDefaults.setExtraLibs([
{
content: extraLib,
filePath: extraLibPath
}
])
}
if (lang == 'python' || deno) {
reloadWebsocket()
}
@@ -496,19 +442,4 @@
/* stylelint-disable-next-line unit-allowed-list */
height: 80vh;
}
.small-editor {
/* stylelint-disable-next-line unit-allowed-list */
height: 26vh;
}
.few-lines-editor {
/* stylelint-disable-next-line unit-allowed-list */
height: 80px;
}
.two-lines-editor {
/* stylelint-disable-next-line unit-allowed-list */
height: 40px;
}
</style>
@@ -44,7 +44,7 @@
{:else if name === 'slack'}
<Slack {height} {width} />
{:else if name === 'github'}
<Icon data={GithubIcon} scale={1.4} />
<GithubIcon />
{:else if name === 'gmail'}
<GmailIcon {height} {width} />
{:else if name === 'gsheets'}
@@ -6,11 +6,11 @@
import { Button, Tooltip } from 'flowbite-svelte'
import Icon from 'svelte-awesome'
import ArgInput from './ArgInput.svelte'
import Editor from './Editor.svelte'
import FieldHeader from './FieldHeader.svelte'
import DynamicInputHelpBox from './flows/DynamicInputHelpBox.svelte'
import { codeToStaticTemplate, getDefaultExpr, isCodeInjection } from './flows/utils'
import OverlayPropertyPicker from './propertyPicker/OverlayPropertyPicker.svelte'
import SimpleEditor from './SimpleEditor.svelte'
import Toggle from './Toggle.svelte'
export let schema: Schema
@@ -22,7 +22,7 @@
export let pickableProperties: Object | undefined = undefined
let overlays: { [id: string]: OverlayPropertyPicker } = {}
let monacos: { [id: string]: Editor } = {}
let monacos: { [id: string]: SimpleEditor } = {}
let inputCats: { [id: string]: InputCat } = {}
let propertyType = getPropertyType(arg)
@@ -200,7 +200,7 @@
}}
>
<div class="border rounded p-2 mt-2 border-gray-300">
<Editor
<SimpleEditor
bind:this={monacos[argName]}
on:focus={() => focusProp(argName, true)}
bind:code={arg.expr}
@@ -5,10 +5,10 @@
import { Button } from 'flowbite-svelte'
import { createEventDispatcher } from 'svelte'
import Icon from 'svelte-awesome'
import Editor from './Editor.svelte'
import SchemaEditorProperty from './SchemaEditorProperty.svelte'
import type { ModalSchemaProperty } from './SchemaModal.svelte'
import SchemaModal, { DEFAULT_PROPERTY, schemaToModal } from './SchemaModal.svelte'
import SimpleEditor from './SimpleEditor.svelte'
import TableCustom from './TableCustom.svelte'
import Toggle from './Toggle.svelte'
import Tooltip from './Tooltip.svelte'
@@ -220,7 +220,7 @@
</div>
{:else}
<div class="border rounded mt-4 p-2">
<Editor
<SimpleEditor
on:change={() => {
try {
schema = JSON.parse(schemaString)
@@ -0,0 +1,174 @@
<script lang="ts" context="module">
import * as monaco from 'monaco-editor'
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
target: monaco.languages.typescript.ScriptTarget.Latest,
allowNonTsExtensions: true,
noLib: true
})
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
allowComments: false,
schemas: [],
enableSchemaRequest: true
})
</script>
<script lang="ts">
import { browser, dev } from '$app/env'
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import { buildWorkerDefinition } from 'monaco-editor-workers'
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
import { createHash, editorConfig, langToExt, updateOptions } from '$lib/editorUtils'
let divEl: HTMLDivElement | null = null
let editor: monaco.editor.IStandaloneCodeEditor
export let lang: string
export let code: string = ''
export let hash: string = createHash()
export let cmdEnterAction: (() => void) | undefined = undefined
export let formatAction: (() => void) | undefined = undefined
export let automaticLayout = true
export let extraLib: string = ''
export let extraLibPath: string = ''
export let shouldBindKey: boolean = true
const dispatch = createEventDispatcher()
const uri = `file:///${hash}.${langToExt(lang)}`
if (browser) {
if (dev) {
buildWorkerDefinition(
'../../../node_modules/monaco-editor-workers/dist/workers',
import.meta.url,
false
)
} else {
// @ts-ignore
self.MonacoEnvironment = {
getWorker: function (_moduleId: any, label: string) {
if (label === 'json') {
return new jsonWorker()
} else {
return new editorWorker()
}
}
}
}
}
export function getCode(): string {
return editor?.getValue() ?? ''
}
export function insertAtCursor(code: string): void {
if (editor) {
editor.trigger('keyboard', 'type', { text: code })
}
}
export function setCode(ncode: string): void {
code = ncode
if (editor) {
editor.setValue(ncode)
}
}
function format() {
if (editor) {
code = getCode()
editor.getAction('editor.action.formatDocument').run()
if (formatAction) {
formatAction()
}
}
}
async function loadMonaco() {
const model = monaco.editor.createModel(code, lang, monaco.Uri.parse(uri))
model.updateOptions(updateOptions)
editor = monaco.editor.create(
divEl as HTMLDivElement,
editorConfig(model, code, lang, automaticLayout)
)
if (shouldBindKey) {
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () {
format()
})
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, function () {
if (cmdEnterAction) {
cmdEnterAction()
}
})
}
let timeoutModel: NodeJS.Timeout | undefined = undefined
editor.onDidChangeModelContent((event) => {
timeoutModel && clearTimeout(timeoutModel)
timeoutModel = setTimeout(() => {
code = getCode()
}, 500)
dispatch('change')
})
editor.onDidFocusEditorText(() => {
dispatch('focus')
})
editor.onDidBlurEditorText(() => {
dispatch('blur')
})
if (lang == 'javascript' && extraLib != '' && extraLibPath != '') {
monaco.languages.typescript.javascriptDefaults.setExtraLibs([
{
content: extraLib,
filePath: extraLibPath
}
])
}
}
onMount(() => {
if (browser) {
loadMonaco()
}
})
onDestroy(() => {
try {
editor && editor.dispose()
} catch (err) {}
})
</script>
<div bind:this={divEl} class={$$props.class} />
<style>
.editor {
@apply px-0;
/* stylelint-disable-next-line unit-allowed-list */
height: 80vh;
}
.small-editor {
/* stylelint-disable-next-line unit-allowed-list */
height: 26vh;
}
.few-lines-editor {
/* stylelint-disable-next-line unit-allowed-list */
height: 80px;
}
</style>
@@ -5,9 +5,9 @@
import Icon from 'svelte-awesome'
import Menu from '../common/menu/Menu.svelte'
import MenuItem from '../common/menu/MenuItem.svelte'
import Editor from '../Editor.svelte'
import FlowViewer from '../FlowViewer.svelte'
import Modal from '../Modal.svelte'
import SimpleEditor from '../SimpleEditor.svelte'
import CollapseLink from './../CollapseLink.svelte'
import CronInput from './../CronInput.svelte'
import FlowBox from './../flows/FlowBox.svelte'
@@ -36,7 +36,7 @@
<Modal bind:this={jsonSetter}>
<div slot="title">Import JSON</div>
<div slot="content" class="h-full">
<Editor bind:code={jsonValue} lang={'json'} class="h-full" />
<SimpleEditor bind:code={jsonValue} lang="json" class="h-full" />
</div>
<div slot="submission">
<button
+48
View File
@@ -0,0 +1,48 @@
export function editorConfig(model: any, code: string, lang: string, automaticLayout: boolean) {
return {
model,
value: code,
language: lang,
automaticLayout,
readOnly: false,
fixedOverflowWidgets: true,
autoDetectHighContrast: true,
//lineNumbers: 'off',
//lineDecorationsWidth: 0,
lineNumbersMinChars: 4,
lineNumbers: (ln) => '<span class="pr-4 text-gray-400">' + ln + '</span>',
folding: false,
scrollBeyondLastLine: false,
minimap: {
enabled: false
},
lightbulb: {
enabled: true
}
}
}
export function createHash() {
return (Math.random() + 1).toString(36).substring(2)
}
export function langToExt(lang: string): string {
switch (lang) {
case 'javascript':
return 'js'
case 'json':
return 'json'
case 'sql':
return 'sql'
case 'typescript':
return 'ts'
case 'python':
return 'py'
default:
return 'unknown'
}
}
export const updateOptions = { tabSize: 2, insertSpaces: true }