130 lines
3.3 KiB
Vue
130 lines
3.3 KiB
Vue
<style>
|
|
.editor
|
|
{
|
|
white-space: pre-line;
|
|
overflow: auto;
|
|
outline: none;
|
|
box-shadow: none !important;
|
|
}
|
|
</style>
|
|
|
|
<template>
|
|
<div class="editor">
|
|
<template
|
|
v-if="model && model.length > 0">
|
|
<MarkdownRenderer
|
|
v-if="node"
|
|
:key="key"
|
|
:node="node"
|
|
:proses="{
|
|
'a': LiveA,
|
|
'h1': LiveH1,
|
|
'h2': LiveH2,
|
|
'h3': LiveH3,
|
|
'h4': LiveH4,
|
|
'h5': LiveH5,
|
|
'h6': LiveH6,
|
|
'blockquote': LiveBlockquote,
|
|
}"
|
|
></MarkdownRenderer>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import LiveA from "~/components/prose/live/LiveA.vue";
|
|
import LiveH1 from "~/components/prose/live/LiveH1.vue";
|
|
import LiveH2 from "~/components/prose/live/LiveH2.vue";
|
|
import LiveH3 from "~/components/prose/live/LiveH3.vue";
|
|
import LiveH4 from "~/components/prose/live/LiveH4.vue";
|
|
import LiveH5 from "~/components/prose/live/LiveH5.vue";
|
|
import LiveH6 from "~/components/prose/live/LiveH6.vue";
|
|
import LiveBlockquote from "~/components/prose/ProseBlockquote.vue";
|
|
|
|
import { hash } from 'ohash'
|
|
import { watch, computed } from 'vue'
|
|
import type { Root, Node } from 'hast';
|
|
/* import { diffLines as diff } from 'diff'; */
|
|
|
|
const model = defineModel<string>();
|
|
|
|
const parser = useMarkdown();
|
|
const key = computed(() => hash(model.value));
|
|
|
|
const node = ref<Root>(), changes = ref();
|
|
|
|
watch(model, update);
|
|
update(model.value, "");
|
|
|
|
async function update(value: string | undefined, old: string | undefined) {
|
|
if(value && old)
|
|
{
|
|
if(node.value)
|
|
{
|
|
/* const differences = diff(old, value, {
|
|
newlineIsToken: true,
|
|
});
|
|
|
|
let removeStart = 0, removeEnd = 0; //Character count
|
|
let addStart = 0, addEnd = 0; //Character count
|
|
|
|
const needAdd = differences.find(e => e.added) !== undefined;
|
|
const needRemove = differences.find(e => e.removed) !== undefined;
|
|
|
|
for(const difference of differences)
|
|
{
|
|
if(!difference.added && !difference.removed)
|
|
{
|
|
removeStart += difference.value.length;
|
|
addStart += difference.value.length;
|
|
}
|
|
else if(difference.added)
|
|
{
|
|
addEnd = addStart + difference.value.length;
|
|
}
|
|
else if(difference.removed)
|
|
{
|
|
removeEnd = removeStart + difference.value.length;
|
|
}
|
|
|
|
if((!needAdd || addEnd !== 0) && (!needRemove || removeEnd !== 0))
|
|
break;
|
|
}
|
|
|
|
const oldNodes = getNodes(node.value.children, removeStart - 1, removeEnd + 1);
|
|
let newNodes;
|
|
|
|
if(oldNodes.length === 0)
|
|
{
|
|
node.value = parser(value);
|
|
}
|
|
else
|
|
{
|
|
const newStart = oldNodes[0].position?.start.offset;
|
|
const newEnd = oldNodes[oldNodes.length - 1].position?.end.offset;
|
|
|
|
const lengthDiff = value.length - old.length;
|
|
|
|
newNodes = parser(value.substring(newStart ?? 0, (newEnd ?? 0) + lengthDiff));
|
|
|
|
const root = node.value;
|
|
|
|
node.value = parser(value);
|
|
} */
|
|
node.value = parser(value);
|
|
}
|
|
else
|
|
{
|
|
node.value = parser(value);
|
|
}
|
|
}
|
|
else if(value)
|
|
{
|
|
node.value = parser(value);
|
|
}
|
|
}
|
|
function getNodes(nodes: Node[], start: number, end: number)
|
|
{
|
|
return nodes.filter(e => (e.position?.start.offset ?? 0) <= end && (e.position?.end.offset ?? 0) >= start);
|
|
}
|
|
</script> |