You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
1.5 KiB
78 lines
1.5 KiB
export interface VditorLike {
|
|
getValue: () => string
|
|
setValue: (value: string, render?: boolean) => void
|
|
destroy: () => void
|
|
}
|
|
|
|
export interface CreateVditorLikeOptions {
|
|
element: HTMLElement
|
|
value: string
|
|
onInput: (value: string) => void
|
|
}
|
|
|
|
export type CreateVditorLike = (options: CreateVditorLikeOptions) => VditorLike
|
|
|
|
export interface CreateBridgeOptions {
|
|
getModelValue: () => string
|
|
emitUpdate: (value: string) => void
|
|
createEditor: CreateVditorLike
|
|
}
|
|
|
|
export function createPostBodyMarkdownEditorBridge(options: CreateBridgeOptions) {
|
|
let editor: VditorLike | null = null
|
|
let syncingFromProps = false
|
|
|
|
function mount(element: HTMLElement) {
|
|
if (editor) {
|
|
return editor
|
|
}
|
|
|
|
editor = options.createEditor({
|
|
element,
|
|
value: options.getModelValue(),
|
|
onInput(value) {
|
|
if (syncingFromProps) {
|
|
return
|
|
}
|
|
if (value === options.getModelValue()) {
|
|
return
|
|
}
|
|
options.emitUpdate(value)
|
|
},
|
|
})
|
|
|
|
return editor
|
|
}
|
|
|
|
function syncFromProps() {
|
|
if (!editor) {
|
|
return
|
|
}
|
|
const nextValue = options.getModelValue()
|
|
if (editor.getValue() === nextValue) {
|
|
return
|
|
}
|
|
syncingFromProps = true
|
|
try {
|
|
editor.setValue(nextValue, true)
|
|
}
|
|
finally {
|
|
syncingFromProps = false
|
|
}
|
|
}
|
|
|
|
function unmount() {
|
|
if (!editor) {
|
|
return
|
|
}
|
|
editor.destroy()
|
|
editor = null
|
|
}
|
|
|
|
return {
|
|
mount,
|
|
syncFromProps,
|
|
unmount,
|
|
getEditor: () => editor,
|
|
}
|
|
}
|
|
|