2021-02-21 19:22:03 +01:00
|
|
|
<template>
|
|
|
|
<div class="editor-wrapper">
|
|
|
|
<div
|
|
|
|
:id="`editor-${id}`"
|
|
|
|
class="editor"
|
|
|
|
:class="editorClass"
|
2024-02-04 14:38:15 +01:00
|
|
|
:style="{
|
|
|
|
height: `${height}px`,
|
|
|
|
width: width ? `${width}px` : null,
|
|
|
|
resize: resizable ? 'both' : 'none'
|
|
|
|
}"
|
2021-02-21 19:22:03 +01:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
2022-05-10 13:02:01 +02:00
|
|
|
<script setup lang="ts">
|
2023-08-18 15:57:31 +02:00
|
|
|
/* eslint-disable simple-import-sort/imports */
|
2021-02-21 19:22:03 +01:00
|
|
|
import * as ace from 'ace-builds';
|
2022-04-30 11:45:49 +02:00
|
|
|
import 'ace-builds/webpack-resolver';
|
2023-08-18 15:57:31 +02:00
|
|
|
/* eslint-enable simple-import-sort/imports */
|
|
|
|
|
|
|
|
import { uidGen } from 'common/libs/uidGen';
|
2022-05-10 13:02:01 +02:00
|
|
|
import { storeToRefs } from 'pinia';
|
2024-02-04 14:38:15 +01:00
|
|
|
import { PropType, onMounted, watch } from 'vue';
|
2023-08-18 15:57:31 +02:00
|
|
|
|
2022-04-30 00:47:37 +02:00
|
|
|
import { useSettingsStore } from '@/stores/settings';
|
2021-02-21 19:22:03 +01:00
|
|
|
|
2022-05-10 13:02:01 +02:00
|
|
|
const props = defineProps({
|
|
|
|
modelValue: String,
|
|
|
|
mode: { type: String, default: 'text' },
|
|
|
|
editorClass: { type: String, default: '' },
|
2024-02-04 14:38:15 +01:00
|
|
|
resizable: { type: Boolean, default: false },
|
2022-05-10 13:02:01 +02:00
|
|
|
autoFocus: { type: Boolean, default: false },
|
|
|
|
readOnly: { type: Boolean, default: false },
|
|
|
|
showLineNumbers: { type: Boolean, default: true },
|
2024-02-04 14:38:15 +01:00
|
|
|
height: { type: Number, default: 200 },
|
|
|
|
width: { type: [Number, Boolean] as PropType<number|false>, default: false }
|
2022-05-10 13:02:01 +02:00
|
|
|
});
|
|
|
|
const emit = defineEmits(['update:modelValue']);
|
|
|
|
const settingsStore = useSettingsStore();
|
|
|
|
|
|
|
|
const {
|
|
|
|
editorTheme,
|
|
|
|
editorFontSize,
|
|
|
|
autoComplete,
|
|
|
|
lineWrap
|
|
|
|
} = storeToRefs(settingsStore);
|
|
|
|
|
|
|
|
let editor: ace.Ace.Editor;
|
|
|
|
const id = uidGen();
|
|
|
|
|
2022-05-17 19:11:31 +02:00
|
|
|
watch(() => props.mode, () => {
|
2022-05-10 13:02:01 +02:00
|
|
|
if (editor)
|
|
|
|
editor.session.setMode(`ace/mode/${props.mode}`);
|
|
|
|
});
|
|
|
|
|
2023-05-25 18:51:56 +02:00
|
|
|
watch(() => props.modelValue, () => {
|
2023-06-01 11:42:19 +02:00
|
|
|
if (editor && props.readOnly)
|
2023-05-25 18:51:56 +02:00
|
|
|
editor.session.setValue(props.modelValue);
|
|
|
|
});
|
|
|
|
|
2022-05-10 13:02:01 +02:00
|
|
|
watch(editorTheme, () => {
|
|
|
|
if (editor)
|
|
|
|
editor.setTheme(`ace/theme/${editorTheme.value}`);
|
|
|
|
});
|
|
|
|
|
|
|
|
watch(editorFontSize, () => {
|
|
|
|
const sizes = {
|
2022-09-21 10:33:44 +02:00
|
|
|
xsmall: '10px',
|
|
|
|
small: '12px',
|
|
|
|
medium: '14px',
|
|
|
|
large: '16px',
|
|
|
|
xlarge: '18px',
|
|
|
|
xxlarge: '20px'
|
2022-05-10 13:02:01 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
if (editor) {
|
|
|
|
editor.setOptions({
|
2022-09-21 10:33:44 +02:00
|
|
|
fontSize: sizes[editorFontSize.value]
|
2021-02-21 19:22:03 +01:00
|
|
|
});
|
2022-05-10 13:02:01 +02:00
|
|
|
}
|
|
|
|
});
|
2021-02-21 19:22:03 +01:00
|
|
|
|
2022-05-10 13:02:01 +02:00
|
|
|
watch(autoComplete, () => {
|
|
|
|
if (editor) {
|
|
|
|
editor.setOptions({
|
|
|
|
enableLiveAutocompletion: autoComplete.value
|
2021-02-21 19:22:03 +01:00
|
|
|
});
|
2022-05-10 13:02:01 +02:00
|
|
|
}
|
|
|
|
});
|
2021-02-21 19:22:03 +01:00
|
|
|
|
2022-05-10 13:02:01 +02:00
|
|
|
watch(lineWrap, () => {
|
|
|
|
if (editor) {
|
|
|
|
editor.setOptions({
|
|
|
|
wrap: lineWrap.value
|
2021-02-21 19:22:03 +01:00
|
|
|
});
|
2022-05-10 13:02:01 +02:00
|
|
|
}
|
|
|
|
});
|
2021-02-21 19:22:03 +01:00
|
|
|
|
2022-05-10 13:02:01 +02:00
|
|
|
onMounted(() => {
|
|
|
|
editor = ace.edit(`editor-${id}`, {
|
2022-05-17 19:11:31 +02:00
|
|
|
mode: `ace/mode/${props.mode}`,
|
2022-05-10 13:02:01 +02:00
|
|
|
theme: `ace/theme/${editorTheme.value}`,
|
|
|
|
value: props.modelValue || '',
|
|
|
|
fontSize: 14,
|
|
|
|
printMargin: false,
|
|
|
|
readOnly: props.readOnly,
|
|
|
|
showLineNumbers: props.showLineNumbers,
|
|
|
|
showGutter: props.showLineNumbers
|
|
|
|
});
|
2021-02-21 19:22:03 +01:00
|
|
|
|
2022-05-10 13:02:01 +02:00
|
|
|
editor.setOptions({
|
|
|
|
enableBasicAutocompletion: false,
|
|
|
|
wrap: lineWrap,
|
|
|
|
enableSnippets: false,
|
|
|
|
enableLiveAutocompletion: false
|
|
|
|
});
|
|
|
|
|
2022-05-14 11:15:42 +02:00
|
|
|
(editor.session as unknown as ace.Ace.Editor).on('change', () => {
|
2022-05-10 13:02:01 +02:00
|
|
|
const content = editor.getValue();
|
|
|
|
emit('update:modelValue', content);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (props.autoFocus) {
|
2021-02-21 19:22:03 +01:00
|
|
|
setTimeout(() => {
|
2022-05-10 13:02:01 +02:00
|
|
|
editor.focus();
|
|
|
|
editor.resize();
|
2021-02-21 19:22:03 +01:00
|
|
|
}, 20);
|
|
|
|
}
|
2022-05-10 13:02:01 +02:00
|
|
|
|
2023-05-26 18:17:23 +02:00
|
|
|
editor.commands.removeCommand('showSettingsMenu');
|
|
|
|
|
2022-05-10 13:02:01 +02:00
|
|
|
setTimeout(() => {
|
|
|
|
editor.resize();
|
|
|
|
}, 20);
|
|
|
|
});
|
2021-02-21 19:22:03 +01:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.editor-wrapper {
|
2024-02-04 14:38:15 +01:00
|
|
|
.editor {
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
max-width: 90vw;
|
|
|
|
}
|
2021-02-21 19:22:03 +01:00
|
|
|
}
|
|
|
|
</style>
|