/
githubmirror
/
marktext
Обзор
Документация
Войти
/
githubmirror
/
marktext
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
packages/muyajs/lib/ui/quickInsert/index.js
190 строк
5 KB
Ran Luo
chore: convert repo to pnpm monorepo (packages/desktop, muyajs, website) (#4302)
29 май 2026, 05:25
Не верифицирован
29 май 2026, 05:25
565bfcd
Код
Авторство
О чём код?
import { filter } from 'fuzzaldrin' import { patch, h } from '../../parser/render/snabbdom' import { deepCopy } from '../../utils' import BaseScrollFloat from '../baseScrollFloat' import { createQuickInsertObj } from './config' import './index.css' class QuickInsert extends BaseScrollFloat { static pluginName = 'quickInsert' constructor(muya) { const name = 'ag-quick-insert' super(muya, name) this.reference = null this.oldVnode = null this._renderObj = null this.renderArray = null this.activeItem = null this.block = null // Get the translation function from muya.options, or use the default config if absent const translateFn = muya.options && muya.options.t ? muya.options.t : null this.originalQuickInsertObj = createQuickInsertObj(translateFn) this.renderObj = this.originalQuickInsertObj this.render() this.listen() } get renderObj() { return this._renderObj } set renderObj(obj) { this._renderObj = obj const renderArray = [] Object.keys(obj).forEach((key) => { renderArray.push(...obj[key]) }) this.renderArray = renderArray if (this.renderArray.length > 0) { this.activeItem = this.renderArray[0] const activeEle = this.getItemElement(this.activeItem) this.activeEleScrollIntoView(activeEle) } } render() { const { scrollElement, activeItem, _renderObj } = this let children = Object.keys(_renderObj) .filter((key) => { return _renderObj[key].length !== 0 }) .map((key) => { const titleVnode = h('div.title', key.toUpperCase()) const items = [] for (const item of _renderObj[key]) { const { title, subTitle, label, icon, shortCut } = item const iconVnode = h( 'div.icon-container', h( 'i.icon', h( `i.icon-${label.replace(/\s/g, '-')}`, { style: { background: `url(${icon}) no-repeat`, 'background-size': '100%' } }, '' ) ) ) const description = h('div.description', [ h('div.big-title', title), h('div.sub-title', subTitle) ]) const shortCutVnode = h('div.short-cut', [h('span', shortCut)]) const selector = activeItem.label === label ? 'div.item.active' : 'div.item' items.push( h( selector, { dataset: { label }, on: { click: () => { this.selectItem(item) } } }, [iconVnode, description, shortCutVnode] ) ) } return h('section', [titleVnode, ...items]) }) if (children.length === 0) { children = h('div.no-result', 'No result') } const vnode = h('div', children) if (this.oldVnode) { patch(this.oldVnode, vnode) } else { patch(scrollElement, vnode) } this.oldVnode = vnode } listen() { super.listen() const { eventCenter } = this.muya eventCenter.subscribe('muya-quick-insert', (reference, block, status) => { if (status) { this.block = block this.show(reference) this.search(block.text.substring(1)) // remove `@` char } else { this.hide() } }) } search(text) { const { contentState } = this.muya const canInserFrontMatter = contentState.canInserFrontMatter(this.block) const obj = deepCopy(this.originalQuickInsertObj) if (!canInserFrontMatter) { // Find the basic block group containing front-matter const basicBlockKey = Object.keys(obj).find((key) => { const items = obj[key] return Array.isArray(items) && items.some((item) => item.label === 'front-matter') }) if (basicBlockKey && obj[basicBlockKey]) { // Find the index of the front-matter item and remove it const frontMatterIndex = obj[basicBlockKey].findIndex( (item) => item.label === 'front-matter' ) if (frontMatterIndex !== -1) { obj[basicBlockKey].splice(frontMatterIndex, 1) } } } let result = obj if (text !== '') { result = {} Object.keys(obj).forEach((key) => { result[key] = filter(obj[key], text, { key: 'title' }) }) } this.renderObj = result this.render() } selectItem(item) { const { contentState } = this.muya // Check that block exists to avoid a null reference error if (!this.block) { console.warn('QuickInsert: block is null, cannot select item') this.hide() return } this.block.text = '' const { key } = this.block const offset = 0 contentState.cursor = { start: { key, offset }, end: { key, offset } } switch (item.label) { case 'paragraph': contentState.partialRender() break default: contentState.updateParagraph(item.label, true) break } // delay hide to avoid dispatch enter hander setTimeout(this.hide.bind(this)) } getItemElement(item) { const { label } = item return this.scrollElement.querySelector(`[data-label="${label}"]`) } } export default QuickInsert