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

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,
}
}