plugin-audio
Version:
wangEditor 上传音频
122 lines (101 loc) • 3.37 kB
text/typescript
/**
* @description insert audio menu
* @author wulijie
*/
import { Range, Node } from 'slate'
import {
IModalMenu,
IDomEditor,
DomEditor,
genModalInputElems,
genModalButtonElems,
t,
} from '@wangeditor/editor'
import $, { Dom7Array, DOMElement } from '../../utils/dom'
import { genRandomStr } from '../../utils/utils'
import { AUDIO_SVG } from '../../constants/icon-svg'
import insertAudio from '../helper/insert-audio'
/**
* 生成唯一的 DOM ID
*/
function genDomID(): string {
return genRandomStr('w-e-insert-audio')
}
class InsertAudioMenu implements IModalMenu {
readonly title = t('audioModule.insertAudio')
readonly iconSvg = AUDIO_SVG
readonly tag = 'button'
readonly showModal = true // 点击 button 时显示 modal
readonly modalWidth = 320
private $content: Dom7Array | null = null
private readonly srcInputId = genDomID()
private readonly posterInputId = genDomID()
private readonly buttonId = genDomID()
getValue(editor: IDomEditor): string | boolean {
// 插入菜单,不需要 value
return ''
}
isActive(editor: IDomEditor): boolean {
// 任何时候,都不用激活 menu
return false
}
exec(editor: IDomEditor, value: string | boolean) {
// 点击菜单时,弹出 modal 之前,不需要执行其他代码
// 此处空着即可
}
isDisabled(editor: IDomEditor): boolean {
const { selection } = editor
if (selection == null) return true
if (!Range.isCollapsed(selection)) return true // 选区非折叠,禁用
const selectedElems = DomEditor.getSelectedElems(editor)
const hasVoidOrPre = selectedElems.some(elem => {
const type = DomEditor.getNodeType(elem)
if (type === 'pre') return true
if (type === 'list-item') return true
if (editor.isVoid(elem)) return true
return false
})
if (hasVoidOrPre) return true // void 或 pre ,禁用
return false
}
getModalPositionNode(editor: IDomEditor): Node | null {
return null // modal 依据选区定位
}
getModalContentElem(editor: IDomEditor): DOMElement {
const { srcInputId, posterInputId, buttonId } = this
// 获取 input button elem
const [srcContainerElem, inputSrcElem] = genModalInputElems(
t('audioModule.audioSrc'),
srcInputId,
t('audioModule.audioSrcPlaceHolder')
)
const $inputSrc = $(inputSrcElem)
const [buttonContainerElem] = genModalButtonElems(buttonId, t('audioModule.ok'))
if (this.$content == null) {
// 第一次渲染
const $content = $('<div></div>')
// 绑定事件(第一次渲染时绑定,不要重复绑定)
$content.on('click', `#${buttonId}`, async e => {
e.preventDefault()
const src = $content.find(`#${srcInputId}`).val().trim()
await insertAudio(editor, src)
editor.hidePanelOrModal() // 隐藏 modal
})
// 记录属性,重要
this.$content = $content
}
const $content = this.$content
$content.empty() // 先清空内容
// append inputs and button
$content.append(srcContainerElem)
$content.append(buttonContainerElem)
// 设置 input val
$inputSrc.val('')
// focus 一个 input(异步,此时 DOM 尚未渲染)
setTimeout(() => {
$inputSrc.focus()
})
return $content[0]
}
}
export default InsertAudioMenu