mirror of
https://github.com/marktext/marktext.git
synced 2025-05-03 14:39:19 +08:00

* feat: add underline format * update doc * add support superscript and subscript in format menu
104 lines
2.5 KiB
JavaScript
104 lines
2.5 KiB
JavaScript
import BaseFloat from '../baseFloat'
|
|
import { patch, h } from '../../parser/render/snabbdom'
|
|
import icons from './config'
|
|
|
|
import './index.css'
|
|
|
|
const defaultOptions = {
|
|
placement: 'top',
|
|
modifiers: {
|
|
offset: {
|
|
offset: '20, 5'
|
|
}
|
|
},
|
|
showArrow: false
|
|
}
|
|
|
|
class FormatPicker extends BaseFloat {
|
|
static pluginName = 'formatPicker'
|
|
constructor (muya, options = {}) {
|
|
const name = 'ag-format-picker'
|
|
const opts = Object.assign({}, defaultOptions, options)
|
|
super(muya, name, opts)
|
|
this.oldVnode = null
|
|
this.formats = null
|
|
this.options = opts
|
|
this.icons = icons
|
|
const formatContainer = this.formatContainer = document.createElement('div')
|
|
this.container.appendChild(formatContainer)
|
|
this.listen()
|
|
}
|
|
|
|
listen () {
|
|
const { eventCenter } = this.muya
|
|
super.listen()
|
|
eventCenter.subscribe('muya-format-picker', ({ reference, formats }) => {
|
|
if (reference) {
|
|
this.formats = formats
|
|
setTimeout(() => {
|
|
this.show(reference)
|
|
this.render()
|
|
}, 0)
|
|
} else {
|
|
this.hide()
|
|
}
|
|
})
|
|
}
|
|
|
|
render () {
|
|
const { icons, oldVnode, formatContainer, formats } = this
|
|
const children = icons.map(i => {
|
|
let icon
|
|
let iconWrapperSelector
|
|
if (i.icon) {
|
|
// SVG icon Asset
|
|
iconWrapperSelector = 'div.icon-wrapper'
|
|
icon = h('i.icon', h(`i.icon-inner`, {
|
|
style: {
|
|
background: `url(${i.icon}) no-repeat`,
|
|
'background-size': '100%'
|
|
}
|
|
}, ''))
|
|
}
|
|
const iconWrapper = h(iconWrapperSelector, icon)
|
|
let itemSelector = `li.item.${i.type}`
|
|
if (formats.some(f => f.type === i.type || f.type === 'html_tag' && f.tag === i.type)) {
|
|
itemSelector += '.active'
|
|
}
|
|
return h(itemSelector, {
|
|
on: {
|
|
click: event => {
|
|
this.selectItem(event, i)
|
|
}
|
|
}
|
|
}, iconWrapper)
|
|
})
|
|
|
|
const vnode = h('ul', children)
|
|
|
|
if (oldVnode) {
|
|
patch(oldVnode, vnode)
|
|
} else {
|
|
patch(formatContainer, vnode)
|
|
}
|
|
this.oldVnode = vnode
|
|
}
|
|
|
|
selectItem (event, item) {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
const { contentState } = this.muya
|
|
contentState.render()
|
|
contentState.format(item.type)
|
|
if (/link|image/.test(item.type)) {
|
|
this.hide()
|
|
} else {
|
|
const { formats } = contentState.selectionFormats()
|
|
this.formats = formats
|
|
this.render()
|
|
}
|
|
}
|
|
}
|
|
|
|
export default FormatPicker
|