marktext/src/muya/lib/ui/codePicker/index.js
Ran Luo 39e1ea8081
Prism replace codemirror (#516)
* 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
2018-10-23 21:21:58 +08:00

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