mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
perf: 文本框富文本编辑优化
This commit is contained in:
parent
4f9db4781a
commit
6c1c8237b0
@ -47,6 +47,15 @@
|
||||
font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;
|
||||
}
|
||||
|
||||
sup {
|
||||
vertical-align: super;
|
||||
font-size: smaller;
|
||||
}
|
||||
sub {
|
||||
vertical-align: sub;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
overflow: hidden;
|
||||
padding-right: 1.2em;
|
||||
|
@ -35,6 +35,7 @@ export const HOTKEY_DOC = [
|
||||
{ label: '剪切', value: 'Ctrl + X' },
|
||||
{ label: '复制', value: 'Ctrl + C' },
|
||||
{ label: '粘贴', value: 'Ctrl + V' },
|
||||
{ label: '粘贴为纯文本', value: 'Ctrl + Shift + V' },
|
||||
{ label: '快速复制粘贴', value: 'Ctrl + D' },
|
||||
{ label: '全选', value: 'Ctrl + A' },
|
||||
{ label: '撤销', value: 'Ctrl + Z' },
|
||||
@ -108,7 +109,10 @@ export const HOTKEY_DOC = [
|
||||
{ label: '加粗', value: 'Ctrl + B' },
|
||||
{ label: '斜体', value: 'Ctrl + I' },
|
||||
{ label: '下划线', value: 'Ctrl + U' },
|
||||
{ label: '删除线', value: 'Ctrl + D' },
|
||||
{ label: '行内代码', value: 'Ctrl + E' },
|
||||
{ label: '上角标', value: 'Ctrl + ;' },
|
||||
{ label: '下角标', value: `Ctrl + '` },
|
||||
{ label: '选中段落', value: `ESC` },
|
||||
],
|
||||
},
|
||||
]
|
@ -2,7 +2,6 @@ import type { NodeType, Schema } from 'prosemirror-model'
|
||||
import {
|
||||
inputRules,
|
||||
wrappingInputRule,
|
||||
textblockTypeInputRule,
|
||||
smartQuotes,
|
||||
emDash,
|
||||
ellipsis,
|
||||
@ -22,7 +21,18 @@ const orderedListRule = (nodeType: NodeType) => (
|
||||
|
||||
const bulletListRule = (nodeType: NodeType) => wrappingInputRule(/^\s*([-+*])\s$/, nodeType)
|
||||
|
||||
const codeBlockRule = (nodeType: NodeType) => textblockTypeInputRule(/^```$/, nodeType)
|
||||
const codeRule = () => {
|
||||
const inputRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))$/
|
||||
|
||||
return new InputRule(inputRegex, (state, match, start, end) => {
|
||||
const { schema } = state
|
||||
|
||||
const tr = state.tr.insertText(`${match[2]} `, start, end)
|
||||
const mark = schema.marks.code.create()
|
||||
|
||||
return tr.addMark(start, start + match[2].length, mark)
|
||||
})
|
||||
}
|
||||
|
||||
const linkRule = () => {
|
||||
const urlRegEx = /(?:https?:\/\/)?[\w-]+(?:\.[\w-]+)+\.?(?:\d+)?(?:\/\S*)?$/
|
||||
@ -46,7 +56,7 @@ export const buildInputRules = (schema: Schema) => {
|
||||
rules.push(blockQuoteRule(schema.nodes.blockquote))
|
||||
rules.push(orderedListRule(schema.nodes.ordered_list))
|
||||
rules.push(bulletListRule(schema.nodes.bullet_list))
|
||||
rules.push(codeBlockRule(schema.nodes.code_block))
|
||||
rules.push(codeRule())
|
||||
rules.push(linkRule())
|
||||
|
||||
return inputRules({ rules })
|
||||
|
@ -25,14 +25,17 @@ export const buildKeymap = (schema: Schema) => {
|
||||
|
||||
bind('Alt-ArrowUp', joinUp)
|
||||
bind('Alt-ArrowDown', joinDown)
|
||||
bind('Ctrl-z', undo)
|
||||
bind('Ctrl-y', redo)
|
||||
bind('Mod-z', undo)
|
||||
bind('Mod-y', redo)
|
||||
bind('Backspace', undoInputRule)
|
||||
bind('Escape', selectParentNode)
|
||||
bind('Ctrl-b', toggleMark(schema.marks.strong))
|
||||
bind('Ctrl-i', toggleMark(schema.marks.em))
|
||||
bind('Ctrl-u', toggleMark(schema.marks.underline))
|
||||
bind('Ctrl-d', toggleMark(schema.marks.strikethrough))
|
||||
bind('Mod-b', toggleMark(schema.marks.strong))
|
||||
bind('Mod-i', toggleMark(schema.marks.em))
|
||||
bind('Mod-u', toggleMark(schema.marks.underline))
|
||||
bind('Mod-d', toggleMark(schema.marks.strikethrough))
|
||||
bind('Mod-e', toggleMark(schema.marks.code))
|
||||
bind('Mod-;', toggleMark(schema.marks.superscript))
|
||||
bind(`Mod-'`, toggleMark(schema.marks.subscript))
|
||||
bind('Enter', chainCommands(
|
||||
splitListItem(schema.nodes.list_item),
|
||||
newlineInCode,
|
||||
|
@ -157,10 +157,14 @@ const link: MarkSpec = {
|
||||
toDOM: node => ['a', node.attrs, 0],
|
||||
}
|
||||
|
||||
const { em, strong, code } = marks
|
||||
|
||||
export default {
|
||||
...marks,
|
||||
em,
|
||||
strong,
|
||||
fontsize,
|
||||
fontname,
|
||||
code,
|
||||
forecolor,
|
||||
backcolor,
|
||||
subscript,
|
||||
|
@ -137,12 +137,16 @@ const paragraph: NodeSpec = {
|
||||
},
|
||||
}
|
||||
|
||||
// https://github.com/pipipi-pikachu/PPTist/issues/134
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { hard_break, ...otherNodes } = nodes
|
||||
const {
|
||||
doc,
|
||||
blockquote,
|
||||
text,
|
||||
} = nodes
|
||||
|
||||
export default {
|
||||
...otherNodes,
|
||||
doc,
|
||||
text,
|
||||
blockquote,
|
||||
'ordered_list': orderedList,
|
||||
'bullet_list': bulletList,
|
||||
'list_item': listItem,
|
||||
|
@ -13,9 +13,9 @@ import { debounce } from 'lodash'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useMainStore } from '@/store'
|
||||
import type { EditorView } from 'prosemirror-view'
|
||||
import { toggleMark, wrapIn } from 'prosemirror-commands'
|
||||
import { toggleMark, wrapIn, lift } from 'prosemirror-commands'
|
||||
import { initProsemirrorEditor, createDocument } from '@/utils/prosemirror'
|
||||
import { findNodesWithSameMark, getTextAttrs, autoSelectAll, addMark, markActive, getFontsize } from '@/utils/prosemirror/utils'
|
||||
import { isActiveOfParentNodeType, findNodesWithSameMark, getTextAttrs, autoSelectAll, addMark, markActive, getFontsize } from '@/utils/prosemirror/utils'
|
||||
import emitter, { EmitterEvents, type RichTextAction, type RichTextCommand } from '@/utils/emitter'
|
||||
import { alignmentCommand } from '@/utils/prosemirror/commands/setTextAlign'
|
||||
import { indentCommand, textIndentCommand } from '@/utils/prosemirror/commands/setTextIndent'
|
||||
@ -164,7 +164,9 @@ const execCommand = ({ target, action }: RichTextCommand) => {
|
||||
toggleMark(editorView.state.schema.marks.superscript)(editorView.state, editorView.dispatch)
|
||||
}
|
||||
else if (item.command === 'blockquote') {
|
||||
wrapIn(editorView.state.schema.nodes.blockquote)(editorView.state, editorView.dispatch)
|
||||
const isBlockquote = isActiveOfParentNodeType('blockquote', editorView.state)
|
||||
if (isBlockquote) lift(editorView.state, editorView.dispatch)
|
||||
else wrapIn(editorView.state.schema.nodes.blockquote)(editorView.state, editorView.dispatch)
|
||||
}
|
||||
else if (item.command === 'code') {
|
||||
toggleMark(editorView.state.schema.marks.code)(editorView.state, editorView.dispatch)
|
||||
|
Loading…
x
Reference in New Issue
Block a user