140 lines
3.7 KiB
Svelte
140 lines
3.7 KiB
Svelte
<script lang="ts">
|
|
// *** Import Svelte version 5 specific
|
|
import { browser } from '$app/environment';
|
|
|
|
// BEGIN: CodeMirror
|
|
|
|
import {basicSetup} from "codemirror";
|
|
import { EditorView, keymap, placeholder as placeholderExt } from "@codemirror/view";
|
|
|
|
import { EditorState, StateEffect, type Extension } from "@codemirror/state";
|
|
import { indentWithTab } from "@codemirror/commands";
|
|
|
|
import {
|
|
defaultHighlightStyle, syntaxHighlighting, indentOnInput,
|
|
bracketMatching, foldGutter, foldKeymap
|
|
} from "@codemirror/language";
|
|
import { indentUnit, type LanguageSupport } from "@codemirror/language";
|
|
import {languages} from "@codemirror/language-data"
|
|
import { css } from "@codemirror/lang-css";
|
|
import { html } from "@codemirror/lang-html";
|
|
import {javascript} from "@codemirror/lang-javascript";
|
|
import {markdown} from "@codemirror/lang-markdown";
|
|
import { oneDark } from "@codemirror/theme-one-dark";
|
|
|
|
// END: CodeMirror
|
|
|
|
|
|
interface Props {
|
|
log_lvl?: number;
|
|
content: string; // Actual text content to be displayed in the editor
|
|
classes: string;
|
|
basic: boolean;
|
|
useTab: boolean;
|
|
tabSize: number;
|
|
}
|
|
|
|
let {
|
|
log_lvl = 0,
|
|
content = 'TEST content for CodeMirror',
|
|
classes = '',
|
|
basic = true,
|
|
useTab = true,
|
|
tabSize = 4,
|
|
}: Props = $props();
|
|
|
|
let state_extensions = [
|
|
// ...get_base_extensions(basic, useTab, tabSize, lineWrapping, placeholder, editable, readonly, lang),
|
|
// ...get_theme(theme, styles),
|
|
basicSetup,
|
|
keymap.of([indentWithTab]),
|
|
javascript(),
|
|
markdown({codeLanguages: languages})
|
|
// ...extensions,
|
|
];
|
|
|
|
let editor_view: EditorView;
|
|
let element: HTMLElement|undefined = $state();
|
|
|
|
if (browser) {
|
|
// editor_view = create_editor_view();
|
|
|
|
|
|
let test_view = new EditorView({
|
|
doc: "Hello\n\n```javascript\nlet x = 'y'\n```",
|
|
extensions: [
|
|
basicSetup,
|
|
markdown({codeLanguages: languages})
|
|
],
|
|
parent: document.getElementById('codemirror-view') ?? element,
|
|
state: EditorState.create({
|
|
doc: "Hello\n\n```javascript\nlet x = 'y'\n```",
|
|
extensions: [
|
|
basicSetup,
|
|
markdown({codeLanguages: languages})
|
|
],
|
|
}),
|
|
})
|
|
}
|
|
|
|
function create_editor_view(): EditorView {
|
|
return new EditorView({
|
|
doc: content,
|
|
extensions: [basicSetup, javascript()],
|
|
// parent: element,
|
|
parent: document.getElementById('codemirror-view') ?? element,
|
|
state: create_editor_state(content),
|
|
});
|
|
}
|
|
|
|
function create_editor_state(value: string | null | undefined): EditorState {
|
|
return EditorState.create({
|
|
doc: value ?? undefined,
|
|
extensions: state_extensions,
|
|
});
|
|
}
|
|
|
|
function update(value: string | null | undefined): void {
|
|
if (first_update) {
|
|
first_update = false;
|
|
return;
|
|
}
|
|
|
|
if (update_from_state) {
|
|
update_from_state = false;
|
|
return;
|
|
}
|
|
|
|
update_from_prop = true;
|
|
|
|
editor_view.setState(create_editor_state(value));
|
|
|
|
update_from_prop = false;
|
|
}
|
|
|
|
|
|
function handle_change(): void {
|
|
const new_value = editor_view.state.doc.toString();
|
|
if (new_value === content) return;
|
|
|
|
update_from_state = true;
|
|
|
|
content = new_value;
|
|
}
|
|
</script>
|
|
|
|
|
|
|
|
{#if browser}
|
|
<!-- <div class="codemirror-wrapper {classes}" bind:this={element} ></div> -->
|
|
<div id="codemirror-view" class="codemirror-wrapper {classes}" ></div>
|
|
{:else}
|
|
<div class="scm-waiting {classes}">
|
|
<div class="scm-waiting__loading scm-loading">
|
|
<!-- <div class="scm-loading__spinner" /> -->
|
|
<p class="scm-loading__text">Loading editor...</p>
|
|
</div>
|
|
|
|
<pre class="scm-pre cm-editor">{content}</pre>
|
|
</div>
|
|
{/if} |