2023-10-23 18:05:06 +03:00
|
|
|
<script>
|
|
|
|
|
|
|
|
|
|
// https://codesandbox.io/s/codemirror-remark-editor-4m4z9?file=/src/CodeEditor.js:374-387
|
2024-09-07 15:31:56 +03:00
|
|
|
import {onDestroy, onMount} from "svelte";
|
2023-10-23 18:05:06 +03:00
|
|
|
import {basicSetup, EditorView} from "codemirror";
|
2024-09-07 15:31:56 +03:00
|
|
|
import {autocompletion, completionKeymap} from "@codemirror/autocomplete";
|
|
|
|
|
import {Compartment, EditorState} from "@codemirror/state";
|
2023-10-23 18:05:06 +03:00
|
|
|
import {keymap} from "@codemirror/view";
|
|
|
|
|
import {indentWithTab} from "@codemirror/commands";
|
|
|
|
|
import {markdown} from "@codemirror/lang-markdown";
|
|
|
|
|
import {lintKeymap} from "@codemirror/lint";
|
|
|
|
|
|
|
|
|
|
let parentElement;
|
|
|
|
|
let codeMirrorView;
|
|
|
|
|
export let value;
|
|
|
|
|
export let editable = true;
|
|
|
|
|
|
2024-09-07 15:31:56 +03:00
|
|
|
export function insertMedia(info) {
|
|
|
|
|
let insertText = "";
|
|
|
|
|
if (info.record._file.width > 0) {
|
|
|
|
|
insertText = ``;
|
|
|
|
|
} else {
|
|
|
|
|
insertText = `[${info.record._file.originalName}](${info.originalUrl})`;
|
|
|
|
|
}
|
|
|
|
|
const cursor = codeMirrorView.state.selection.main.head;
|
|
|
|
|
const transaction = codeMirrorView.state.update({
|
|
|
|
|
changes: {
|
|
|
|
|
from: cursor,
|
|
|
|
|
insert: insertText,
|
|
|
|
|
},
|
|
|
|
|
// the next 2 lines will set the appropriate cursor position after inserting the new text.
|
|
|
|
|
selection: {anchor: cursor + 1},
|
|
|
|
|
scrollIntoView: true,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (transaction) {
|
|
|
|
|
codeMirrorView.dispatch(transaction);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-23 18:05:06 +03:00
|
|
|
onMount(() => {
|
|
|
|
|
let language = new Compartment();
|
|
|
|
|
let tabSize = new Compartment();
|
|
|
|
|
|
|
|
|
|
let state = EditorState.create({
|
|
|
|
|
doc: value,
|
|
|
|
|
extensions: [
|
|
|
|
|
basicSetup,
|
|
|
|
|
keymap.of([
|
|
|
|
|
indentWithTab,
|
|
|
|
|
...lintKeymap,
|
|
|
|
|
...completionKeymap
|
|
|
|
|
]),
|
|
|
|
|
language.of(markdown()),
|
|
|
|
|
markdown(),
|
|
|
|
|
autocompletion(),
|
|
|
|
|
tabSize.of(EditorState.tabSize.of(4)),
|
|
|
|
|
basicSetup,
|
|
|
|
|
EditorView.editable.of(editable),
|
|
|
|
|
EditorView.updateListener.of(function (e) {
|
|
|
|
|
if (e.docChanged) {
|
|
|
|
|
value = e.state.doc.toString();
|
|
|
|
|
}
|
|
|
|
|
}),
|
2023-10-23 22:12:17 +03:00
|
|
|
EditorView.lineWrapping,
|
|
|
|
|
EditorView.contentAttributes.of({spellcheck: "true"})
|
2023-10-23 18:05:06 +03:00
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
codeMirrorView = new EditorView({
|
|
|
|
|
state,
|
|
|
|
|
parent: parentElement,
|
|
|
|
|
});
|
2023-10-23 22:12:17 +03:00
|
|
|
|
|
|
|
|
|
2023-10-23 18:05:06 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onDestroy(() => {
|
|
|
|
|
if (codeMirrorView) {
|
|
|
|
|
codeMirrorView.destroy();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<div class="is-editable-{editable}" bind:this={parentElement}/>
|