mirror of
https://github.com/marktext/marktext.git
synced 2025-05-03 01:40:13 +08:00

* feat: basic use of code block by prism * opti: remove codemirror from muya * feat: add highlight to math and frontmatter * feat: import and export in math block, html block, frontmatter, code block * update: paragraph ctrl * feat: copy and paste in new math block and html block * feat: update code block style in dark theme * feat: search and replace in code block * fix: update menu item status when selection changed * opti: optimization of updateCtrl divide it into clickCtrl and inputCtrl * opti: search and replace in code block when no lang selected * opti: copy paste in code block * feat: insert paragraph before or after code block * opti: change emoji.js to emoji.json * feat: auto indent in code block * opti: auto indent in code block * opti: remove the use of snabbdom-virtualize * fix: do not show format float box in code block * opti: emoji picker * update: delete some unused codes * update: electron * use a temp prismjs2 instead of prismjs
88 lines
2.4 KiB
JavaScript
88 lines
2.4 KiB
JavaScript
import BaseScrollFloat from '../baseScrollFloat'
|
|
import { patch, h } from '../../parser/render/snabbdom'
|
|
import { search } from '../../prism/index'
|
|
import fileIcons from '../fileIcons'
|
|
|
|
import './index.css'
|
|
|
|
class CodePicker extends BaseScrollFloat {
|
|
constructor (muya) {
|
|
const name = 'ag-list-picker'
|
|
super(muya, name)
|
|
this.renderArray = []
|
|
this.oldVnode = null
|
|
this.activeItem = null
|
|
this.listen()
|
|
}
|
|
|
|
listen () {
|
|
super.listen()
|
|
const { eventCenter } = this.muya
|
|
eventCenter.subscribe('muya-code-picker', ({ reference, lang, cb }) => {
|
|
const modes = search(lang)
|
|
if (modes.length && reference) {
|
|
this.show(reference, cb)
|
|
this.renderArray = modes
|
|
this.activeItem = modes[0]
|
|
this.render()
|
|
} else {
|
|
this.hide()
|
|
}
|
|
})
|
|
}
|
|
|
|
render () {
|
|
const { renderArray, oldVnode, scrollElement, activeItem } = this
|
|
let children = renderArray.map(item => {
|
|
let iconClassNames
|
|
if (item.ext && Array.isArray(item.ext)) {
|
|
for (const ext of item.ext) {
|
|
iconClassNames = fileIcons.getClassWithColor(`fackname.${ext}`)
|
|
if (iconClassNames) break
|
|
}
|
|
} else if (item.name) {
|
|
iconClassNames = fileIcons.getClassWithColor(item.name)
|
|
}
|
|
|
|
// Because `markdown mode in Codemirror` don't have extensions.
|
|
// if still can not get the className, add a common className 'atom-icon light-cyan'
|
|
if (!iconClassNames) {
|
|
iconClassNames = item.name === 'markdown' ? fileIcons.getClassWithColor('fackname.md') : 'atom-icon light-cyan'
|
|
}
|
|
const iconSelector = 'span' + iconClassNames.split(/\s/).map(s => `.${s}`).join('')
|
|
const icon = h('div.icon-wrapper', h(iconSelector))
|
|
const text = h('div.language', item.name)
|
|
const selector = activeItem === item ? 'li.item.active' : 'li.item'
|
|
return h(selector, {
|
|
dataset: {
|
|
label: item.name
|
|
},
|
|
on: {
|
|
click: () => {
|
|
this.selectItem(item)
|
|
}
|
|
}
|
|
}, [icon, text])
|
|
})
|
|
|
|
if (children.length === 0) {
|
|
children = h('div.no-result', 'No result')
|
|
}
|
|
const vnode = h('ul', children)
|
|
|
|
if (oldVnode) {
|
|
patch(oldVnode, vnode)
|
|
} else {
|
|
patch(scrollElement, vnode)
|
|
}
|
|
this.oldVnode = vnode
|
|
}
|
|
|
|
getItemElement (item) {
|
|
const { name } = item
|
|
return this.floatBox.querySelector(`[data-label="${name}"]`)
|
|
}
|
|
}
|
|
|
|
export default CodePicker
|