mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
chore: 目录结构调整
This commit is contained in:
parent
a10704c0ba
commit
b86ff7dfd3
@ -142,7 +142,6 @@ A. 设置在线字体时会下载对应的字体文件,该文件较大,需
|
||||
├── hooks // 供多个组件(模块)使用的 hooks 方法
|
||||
├── mocks // mocks 数据
|
||||
├── plugins // 自定义的 Vue 插件
|
||||
├── prosemirror // ProseMirror 富文本编辑器相关的文件
|
||||
├── types // 类型定义文件
|
||||
├── store // Vuex store,参考:https://vuex.vuejs.org/zh/guide/
|
||||
├── utils // 通用的工具方法
|
||||
|
@ -1,62 +1,62 @@
|
||||
import { Schema, Node, NodeType } from 'prosemirror-model'
|
||||
import { Transaction } from 'prosemirror-state'
|
||||
import { EditorView } from 'prosemirror-view'
|
||||
|
||||
export const setTextAlign = (tr: Transaction, schema: Schema, alignment: string) => {
|
||||
const { selection, doc } = tr
|
||||
if (!selection || !doc) return tr
|
||||
|
||||
const { from, to } = selection
|
||||
const { nodes } = schema
|
||||
|
||||
const blockquote = nodes.blockquote
|
||||
const listItem = nodes.list_item
|
||||
const paragraph = nodes.paragraph
|
||||
|
||||
interface Task {
|
||||
node: Node;
|
||||
pos: number;
|
||||
nodeType: NodeType;
|
||||
}
|
||||
|
||||
const tasks: Task[] = []
|
||||
alignment = alignment || ''
|
||||
|
||||
const allowedNodeTypes = new Set([blockquote, listItem, paragraph])
|
||||
|
||||
doc.nodesBetween(from, to, (node, pos) => {
|
||||
const nodeType = node.type
|
||||
const align = node.attrs.align || ''
|
||||
if (align !== alignment && allowedNodeTypes.has(nodeType)) {
|
||||
tasks.push({
|
||||
node,
|
||||
pos,
|
||||
nodeType,
|
||||
})
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if (!tasks.length) return tr
|
||||
|
||||
tasks.forEach(task => {
|
||||
const { node, pos, nodeType } = task
|
||||
let { attrs } = node
|
||||
if (alignment) attrs = { ...attrs, align: alignment }
|
||||
else attrs = { ...attrs, align: null }
|
||||
tr = tr.setNodeMarkup(pos, nodeType, attrs, node.marks)
|
||||
})
|
||||
|
||||
return tr
|
||||
}
|
||||
|
||||
export const alignmentCommand = (view: EditorView, alignment: string) => {
|
||||
const { state } = view
|
||||
const { schema, selection } = state
|
||||
const tr = setTextAlign(
|
||||
state.tr.setSelection(selection),
|
||||
schema,
|
||||
alignment,
|
||||
)
|
||||
view.dispatch(tr)
|
||||
import { Schema, Node, NodeType } from 'prosemirror-model'
|
||||
import { Transaction } from 'prosemirror-state'
|
||||
import { EditorView } from 'prosemirror-view'
|
||||
|
||||
export const setTextAlign = (tr: Transaction, schema: Schema, alignment: string) => {
|
||||
const { selection, doc } = tr
|
||||
if (!selection || !doc) return tr
|
||||
|
||||
const { from, to } = selection
|
||||
const { nodes } = schema
|
||||
|
||||
const blockquote = nodes.blockquote
|
||||
const listItem = nodes.list_item
|
||||
const paragraph = nodes.paragraph
|
||||
|
||||
interface Task {
|
||||
node: Node;
|
||||
pos: number;
|
||||
nodeType: NodeType;
|
||||
}
|
||||
|
||||
const tasks: Task[] = []
|
||||
alignment = alignment || ''
|
||||
|
||||
const allowedNodeTypes = new Set([blockquote, listItem, paragraph])
|
||||
|
||||
doc.nodesBetween(from, to, (node, pos) => {
|
||||
const nodeType = node.type
|
||||
const align = node.attrs.align || ''
|
||||
if (align !== alignment && allowedNodeTypes.has(nodeType)) {
|
||||
tasks.push({
|
||||
node,
|
||||
pos,
|
||||
nodeType,
|
||||
})
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if (!tasks.length) return tr
|
||||
|
||||
tasks.forEach(task => {
|
||||
const { node, pos, nodeType } = task
|
||||
let { attrs } = node
|
||||
if (alignment) attrs = { ...attrs, align: alignment }
|
||||
else attrs = { ...attrs, align: null }
|
||||
tr = tr.setNodeMarkup(pos, nodeType, attrs, node.marks)
|
||||
})
|
||||
|
||||
return tr
|
||||
}
|
||||
|
||||
export const alignmentCommand = (view: EditorView, alignment: string) => {
|
||||
const { state } = view
|
||||
const { schema, selection } = state
|
||||
const tr = setTextAlign(
|
||||
state.tr.setSelection(selection),
|
||||
schema,
|
||||
alignment,
|
||||
)
|
||||
view.dispatch(tr)
|
||||
}
|
@ -1,40 +1,40 @@
|
||||
import { wrapInList, liftListItem } from 'prosemirror-schema-list'
|
||||
import { Schema, Node, NodeType } from 'prosemirror-model'
|
||||
import { Transaction, EditorState } from 'prosemirror-state'
|
||||
import { findParentNode } from '../utils'
|
||||
|
||||
const isList = (node: Node, schema: Schema) => {
|
||||
return (
|
||||
node.type === schema.nodes.bullet_list ||
|
||||
node.type === schema.nodes.ordered_list
|
||||
)
|
||||
}
|
||||
|
||||
export const toggleList = (listType: NodeType, itemType: NodeType) => {
|
||||
return (state: EditorState, dispatch: (tr: Transaction) => void) => {
|
||||
const { schema, selection } = state
|
||||
const { $from, $to } = selection
|
||||
const range = $from.blockRange($to)
|
||||
|
||||
if (!range) return false
|
||||
|
||||
const parentList = findParentNode((node: Node) => isList(node, schema))(selection)
|
||||
|
||||
if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) {
|
||||
if (parentList.node.type === listType) {
|
||||
return liftListItem(itemType)(state, dispatch)
|
||||
}
|
||||
|
||||
if (isList(parentList.node, schema) && listType.validContent(parentList.node.content)) {
|
||||
const { tr } = state
|
||||
tr.setNodeMarkup(parentList.pos, listType)
|
||||
|
||||
if (dispatch) dispatch(tr)
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return wrapInList(listType)(state, dispatch)
|
||||
}
|
||||
}
|
||||
import { wrapInList, liftListItem } from 'prosemirror-schema-list'
|
||||
import { Schema, Node, NodeType } from 'prosemirror-model'
|
||||
import { Transaction, EditorState } from 'prosemirror-state'
|
||||
import { findParentNode } from '../utils'
|
||||
|
||||
const isList = (node: Node, schema: Schema) => {
|
||||
return (
|
||||
node.type === schema.nodes.bullet_list ||
|
||||
node.type === schema.nodes.ordered_list
|
||||
)
|
||||
}
|
||||
|
||||
export const toggleList = (listType: NodeType, itemType: NodeType) => {
|
||||
return (state: EditorState, dispatch: (tr: Transaction) => void) => {
|
||||
const { schema, selection } = state
|
||||
const { $from, $to } = selection
|
||||
const range = $from.blockRange($to)
|
||||
|
||||
if (!range) return false
|
||||
|
||||
const parentList = findParentNode((node: Node) => isList(node, schema))(selection)
|
||||
|
||||
if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) {
|
||||
if (parentList.node.type === listType) {
|
||||
return liftListItem(itemType)(state, dispatch)
|
||||
}
|
||||
|
||||
if (isList(parentList.node, schema) && listType.validContent(parentList.node.content)) {
|
||||
const { tr } = state
|
||||
tr.setNodeMarkup(parentList.pos, listType)
|
||||
|
||||
if (dispatch) dispatch(tr)
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return wrapInList(listType)(state, dispatch)
|
||||
}
|
||||
}
|
@ -1,20 +1,20 @@
|
||||
import { keymap } from 'prosemirror-keymap'
|
||||
import { Schema } from 'prosemirror-model'
|
||||
import { history } from 'prosemirror-history'
|
||||
import { baseKeymap } from 'prosemirror-commands'
|
||||
import { dropCursor } from 'prosemirror-dropcursor'
|
||||
import { gapCursor } from 'prosemirror-gapcursor'
|
||||
|
||||
import { buildKeymap } from './keymap'
|
||||
import { buildInputRules } from './inputrules'
|
||||
|
||||
export const buildPlugins = (schema: Schema) => {
|
||||
return [
|
||||
buildInputRules(schema),
|
||||
keymap(buildKeymap(schema)),
|
||||
keymap(baseKeymap),
|
||||
dropCursor(),
|
||||
gapCursor(),
|
||||
history(),
|
||||
]
|
||||
import { keymap } from 'prosemirror-keymap'
|
||||
import { Schema } from 'prosemirror-model'
|
||||
import { history } from 'prosemirror-history'
|
||||
import { baseKeymap } from 'prosemirror-commands'
|
||||
import { dropCursor } from 'prosemirror-dropcursor'
|
||||
import { gapCursor } from 'prosemirror-gapcursor'
|
||||
|
||||
import { buildKeymap } from './keymap'
|
||||
import { buildInputRules } from './inputrules'
|
||||
|
||||
export const buildPlugins = (schema: Schema) => {
|
||||
return [
|
||||
buildInputRules(schema),
|
||||
keymap(buildKeymap(schema)),
|
||||
keymap(baseKeymap),
|
||||
dropCursor(),
|
||||
gapCursor(),
|
||||
history(),
|
||||
]
|
||||
}
|
@ -1,38 +1,38 @@
|
||||
import { NodeType, Schema } from 'prosemirror-model'
|
||||
import {
|
||||
inputRules,
|
||||
wrappingInputRule,
|
||||
textblockTypeInputRule,
|
||||
smartQuotes,
|
||||
emDash,
|
||||
ellipsis,
|
||||
} from 'prosemirror-inputrules'
|
||||
|
||||
const blockQuoteRule = (nodeType: NodeType) => wrappingInputRule(/^\s*>\s$/, nodeType)
|
||||
|
||||
const orderedListRule = (nodeType: NodeType) => (
|
||||
wrappingInputRule(
|
||||
/^(\d+)\.\s$/,
|
||||
nodeType,
|
||||
match => ({order: +match[1]}),
|
||||
(match, node) => node.childCount + node.attrs.order === +match[1],
|
||||
)
|
||||
)
|
||||
|
||||
const bulletListRule = (nodeType: NodeType) => wrappingInputRule(/^\s*([-+*])\s$/, nodeType)
|
||||
|
||||
const codeBlockRule = (nodeType: NodeType) => textblockTypeInputRule(/^```$/, nodeType)
|
||||
|
||||
export const buildInputRules = (schema: Schema) => {
|
||||
const rules = [
|
||||
...smartQuotes,
|
||||
ellipsis,
|
||||
emDash,
|
||||
]
|
||||
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))
|
||||
|
||||
return inputRules({ rules })
|
||||
import { NodeType, Schema } from 'prosemirror-model'
|
||||
import {
|
||||
inputRules,
|
||||
wrappingInputRule,
|
||||
textblockTypeInputRule,
|
||||
smartQuotes,
|
||||
emDash,
|
||||
ellipsis,
|
||||
} from 'prosemirror-inputrules'
|
||||
|
||||
const blockQuoteRule = (nodeType: NodeType) => wrappingInputRule(/^\s*>\s$/, nodeType)
|
||||
|
||||
const orderedListRule = (nodeType: NodeType) => (
|
||||
wrappingInputRule(
|
||||
/^(\d+)\.\s$/,
|
||||
nodeType,
|
||||
match => ({order: +match[1]}),
|
||||
(match, node) => node.childCount + node.attrs.order === +match[1],
|
||||
)
|
||||
)
|
||||
|
||||
const bulletListRule = (nodeType: NodeType) => wrappingInputRule(/^\s*([-+*])\s$/, nodeType)
|
||||
|
||||
const codeBlockRule = (nodeType: NodeType) => textblockTypeInputRule(/^```$/, nodeType)
|
||||
|
||||
export const buildInputRules = (schema: Schema) => {
|
||||
const rules = [
|
||||
...smartQuotes,
|
||||
ellipsis,
|
||||
emDash,
|
||||
]
|
||||
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))
|
||||
|
||||
return inputRules({ rules })
|
||||
}
|
@ -1,33 +1,33 @@
|
||||
import { splitListItem, liftListItem, sinkListItem } from 'prosemirror-schema-list'
|
||||
import { Schema } from 'prosemirror-model'
|
||||
import { undo, redo } from 'prosemirror-history'
|
||||
import { undoInputRule } from 'prosemirror-inputrules'
|
||||
import {
|
||||
toggleMark,
|
||||
selectParentNode,
|
||||
joinUp,
|
||||
joinDown,
|
||||
Command,
|
||||
} from 'prosemirror-commands'
|
||||
|
||||
export const buildKeymap = (schema: Schema) => {
|
||||
const keys = {}
|
||||
const bind = (key: string, cmd: Command) => keys[key] = cmd
|
||||
|
||||
bind('Alt-ArrowUp', joinUp)
|
||||
bind('Alt-ArrowDown', joinDown)
|
||||
bind('Ctrl-z', undo)
|
||||
bind('Ctrl-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('Enter', splitListItem(schema.nodes.list_item))
|
||||
bind('Mod-[', liftListItem(schema.nodes.list_item))
|
||||
bind('Mod-]', sinkListItem(schema.nodes.list_item))
|
||||
|
||||
return keys
|
||||
import { splitListItem, liftListItem, sinkListItem } from 'prosemirror-schema-list'
|
||||
import { Schema } from 'prosemirror-model'
|
||||
import { undo, redo } from 'prosemirror-history'
|
||||
import { undoInputRule } from 'prosemirror-inputrules'
|
||||
import {
|
||||
toggleMark,
|
||||
selectParentNode,
|
||||
joinUp,
|
||||
joinDown,
|
||||
Command,
|
||||
} from 'prosemirror-commands'
|
||||
|
||||
export const buildKeymap = (schema: Schema) => {
|
||||
const keys = {}
|
||||
const bind = (key: string, cmd: Command) => keys[key] = cmd
|
||||
|
||||
bind('Alt-ArrowUp', joinUp)
|
||||
bind('Alt-ArrowDown', joinDown)
|
||||
bind('Ctrl-z', undo)
|
||||
bind('Ctrl-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('Enter', splitListItem(schema.nodes.list_item))
|
||||
bind('Mod-[', liftListItem(schema.nodes.list_item))
|
||||
bind('Mod-]', sinkListItem(schema.nodes.list_item))
|
||||
|
||||
return keys
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import nodes from './nodes'
|
||||
import marks from './marks'
|
||||
|
||||
export const schemaNodes = nodes
|
||||
export const schemaMarks = marks
|
||||
import nodes from './nodes'
|
||||
import marks from './marks'
|
||||
|
||||
export const schemaNodes = nodes
|
||||
export const schemaMarks = marks
|
@ -1,148 +1,148 @@
|
||||
import { marks } from 'prosemirror-schema-basic'
|
||||
import { MarkSpec } from 'prosemirror-model'
|
||||
|
||||
const subscript: MarkSpec = {
|
||||
excludes: 'subscript',
|
||||
parseDOM: [
|
||||
{ tag: 'sub' },
|
||||
{
|
||||
style: 'vertical-align',
|
||||
getAttrs: value => value === 'sub' && null
|
||||
},
|
||||
],
|
||||
toDOM: () => ['sub', 0],
|
||||
}
|
||||
|
||||
const superscript: MarkSpec = {
|
||||
excludes: 'superscript',
|
||||
parseDOM: [
|
||||
{ tag: 'sup' },
|
||||
{
|
||||
style: 'vertical-align',
|
||||
getAttrs: value => value === 'super' && null
|
||||
},
|
||||
],
|
||||
toDOM: () => ['sup', 0],
|
||||
}
|
||||
|
||||
const strikethrough: MarkSpec = {
|
||||
parseDOM: [
|
||||
{ tag: 'strike' },
|
||||
{
|
||||
style: 'text-decoration',
|
||||
getAttrs: value => value === 'line-through' && null
|
||||
},
|
||||
{
|
||||
style: 'text-decoration-line',
|
||||
getAttrs: value => value === 'line-through' && null
|
||||
},
|
||||
],
|
||||
toDOM: () => ['span', { style: 'text-decoration-line: line-through' }, 0],
|
||||
}
|
||||
|
||||
const underline: MarkSpec = {
|
||||
parseDOM: [
|
||||
{ tag: 'u' },
|
||||
{
|
||||
style: 'text-decoration',
|
||||
getAttrs: value => value === 'underline' && null
|
||||
},
|
||||
{
|
||||
style: 'text-decoration-line',
|
||||
getAttrs: value => value === 'underline' && null
|
||||
},
|
||||
],
|
||||
toDOM: () => ['span', { style: 'text-decoration: underline' }, 0],
|
||||
}
|
||||
|
||||
const forecolor: MarkSpec = {
|
||||
attrs: {
|
||||
color: {},
|
||||
},
|
||||
parseDOM: [
|
||||
{
|
||||
style: 'color',
|
||||
getAttrs: color => color ? { color } : {}
|
||||
},
|
||||
],
|
||||
toDOM: mark => {
|
||||
const { color } = mark.attrs
|
||||
let style = ''
|
||||
if (color) style += `color: ${color};`
|
||||
return ['span', { style }, 0]
|
||||
},
|
||||
}
|
||||
|
||||
const backcolor: MarkSpec = {
|
||||
attrs: {
|
||||
backcolor: {},
|
||||
},
|
||||
inline: true,
|
||||
group: 'inline',
|
||||
parseDOM: [
|
||||
{
|
||||
tag: 'span[style*=background-color]',
|
||||
getAttrs: backcolor => backcolor ? { backcolor } : {}
|
||||
},
|
||||
],
|
||||
toDOM: mark => {
|
||||
const { backcolor } = mark.attrs
|
||||
let style = ''
|
||||
if (backcolor) style += `background-color: ${backcolor};`
|
||||
return ['span', { style }, 0]
|
||||
},
|
||||
}
|
||||
|
||||
const fontsize: MarkSpec = {
|
||||
attrs: {
|
||||
fontsize: {},
|
||||
},
|
||||
inline: true,
|
||||
group: 'inline',
|
||||
parseDOM: [
|
||||
{
|
||||
style: 'font-size',
|
||||
getAttrs: fontsize => fontsize ? { fontsize } : {}
|
||||
},
|
||||
],
|
||||
toDOM: mark => {
|
||||
const { fontsize } = mark.attrs
|
||||
let style = ''
|
||||
if (fontsize) style += `font-size: ${fontsize}`
|
||||
return ['span', { style }, 0]
|
||||
},
|
||||
}
|
||||
|
||||
const fontname: MarkSpec = {
|
||||
attrs: {
|
||||
fontname: {},
|
||||
},
|
||||
inline: true,
|
||||
group: 'inline',
|
||||
parseDOM: [
|
||||
{
|
||||
style: 'font-family',
|
||||
getAttrs: fontname => {
|
||||
return { fontname: fontname && typeof fontname === 'string' ? fontname.replace(/[\"\']/g, '') : '' }
|
||||
}
|
||||
},
|
||||
],
|
||||
toDOM: mark => {
|
||||
const { fontname } = mark.attrs
|
||||
let style = ''
|
||||
if (fontname) style += `font-family: ${fontname}`
|
||||
return ['span', { style }, 0]
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
...marks,
|
||||
subscript,
|
||||
superscript,
|
||||
strikethrough,
|
||||
underline,
|
||||
forecolor,
|
||||
backcolor,
|
||||
fontsize,
|
||||
fontname,
|
||||
import { marks } from 'prosemirror-schema-basic'
|
||||
import { MarkSpec } from 'prosemirror-model'
|
||||
|
||||
const subscript: MarkSpec = {
|
||||
excludes: 'subscript',
|
||||
parseDOM: [
|
||||
{ tag: 'sub' },
|
||||
{
|
||||
style: 'vertical-align',
|
||||
getAttrs: value => value === 'sub' && null
|
||||
},
|
||||
],
|
||||
toDOM: () => ['sub', 0],
|
||||
}
|
||||
|
||||
const superscript: MarkSpec = {
|
||||
excludes: 'superscript',
|
||||
parseDOM: [
|
||||
{ tag: 'sup' },
|
||||
{
|
||||
style: 'vertical-align',
|
||||
getAttrs: value => value === 'super' && null
|
||||
},
|
||||
],
|
||||
toDOM: () => ['sup', 0],
|
||||
}
|
||||
|
||||
const strikethrough: MarkSpec = {
|
||||
parseDOM: [
|
||||
{ tag: 'strike' },
|
||||
{
|
||||
style: 'text-decoration',
|
||||
getAttrs: value => value === 'line-through' && null
|
||||
},
|
||||
{
|
||||
style: 'text-decoration-line',
|
||||
getAttrs: value => value === 'line-through' && null
|
||||
},
|
||||
],
|
||||
toDOM: () => ['span', { style: 'text-decoration-line: line-through' }, 0],
|
||||
}
|
||||
|
||||
const underline: MarkSpec = {
|
||||
parseDOM: [
|
||||
{ tag: 'u' },
|
||||
{
|
||||
style: 'text-decoration',
|
||||
getAttrs: value => value === 'underline' && null
|
||||
},
|
||||
{
|
||||
style: 'text-decoration-line',
|
||||
getAttrs: value => value === 'underline' && null
|
||||
},
|
||||
],
|
||||
toDOM: () => ['span', { style: 'text-decoration: underline' }, 0],
|
||||
}
|
||||
|
||||
const forecolor: MarkSpec = {
|
||||
attrs: {
|
||||
color: {},
|
||||
},
|
||||
parseDOM: [
|
||||
{
|
||||
style: 'color',
|
||||
getAttrs: color => color ? { color } : {}
|
||||
},
|
||||
],
|
||||
toDOM: mark => {
|
||||
const { color } = mark.attrs
|
||||
let style = ''
|
||||
if (color) style += `color: ${color};`
|
||||
return ['span', { style }, 0]
|
||||
},
|
||||
}
|
||||
|
||||
const backcolor: MarkSpec = {
|
||||
attrs: {
|
||||
backcolor: {},
|
||||
},
|
||||
inline: true,
|
||||
group: 'inline',
|
||||
parseDOM: [
|
||||
{
|
||||
tag: 'span[style*=background-color]',
|
||||
getAttrs: backcolor => backcolor ? { backcolor } : {}
|
||||
},
|
||||
],
|
||||
toDOM: mark => {
|
||||
const { backcolor } = mark.attrs
|
||||
let style = ''
|
||||
if (backcolor) style += `background-color: ${backcolor};`
|
||||
return ['span', { style }, 0]
|
||||
},
|
||||
}
|
||||
|
||||
const fontsize: MarkSpec = {
|
||||
attrs: {
|
||||
fontsize: {},
|
||||
},
|
||||
inline: true,
|
||||
group: 'inline',
|
||||
parseDOM: [
|
||||
{
|
||||
style: 'font-size',
|
||||
getAttrs: fontsize => fontsize ? { fontsize } : {}
|
||||
},
|
||||
],
|
||||
toDOM: mark => {
|
||||
const { fontsize } = mark.attrs
|
||||
let style = ''
|
||||
if (fontsize) style += `font-size: ${fontsize}`
|
||||
return ['span', { style }, 0]
|
||||
},
|
||||
}
|
||||
|
||||
const fontname: MarkSpec = {
|
||||
attrs: {
|
||||
fontname: {},
|
||||
},
|
||||
inline: true,
|
||||
group: 'inline',
|
||||
parseDOM: [
|
||||
{
|
||||
style: 'font-family',
|
||||
getAttrs: fontname => {
|
||||
return { fontname: fontname && typeof fontname === 'string' ? fontname.replace(/[\"\']/g, '') : '' }
|
||||
}
|
||||
},
|
||||
],
|
||||
toDOM: mark => {
|
||||
const { fontname } = mark.attrs
|
||||
let style = ''
|
||||
if (fontname) style += `font-family: ${fontname}`
|
||||
return ['span', { style }, 0]
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
...marks,
|
||||
subscript,
|
||||
superscript,
|
||||
strikethrough,
|
||||
underline,
|
||||
forecolor,
|
||||
backcolor,
|
||||
fontsize,
|
||||
fontname,
|
||||
}
|
@ -1,58 +1,58 @@
|
||||
import { nodes } from 'prosemirror-schema-basic'
|
||||
import { Node, NodeSpec } from 'prosemirror-model'
|
||||
import { orderedList, bulletList, listItem } from 'prosemirror-schema-list'
|
||||
|
||||
const _orderedList: NodeSpec = {
|
||||
...orderedList,
|
||||
content: 'list_item+',
|
||||
group: 'block',
|
||||
}
|
||||
|
||||
const _bulletList: NodeSpec = {
|
||||
...bulletList,
|
||||
content: 'list_item+',
|
||||
group: 'block',
|
||||
}
|
||||
|
||||
const _listItem: NodeSpec = {
|
||||
...listItem,
|
||||
content: 'paragraph block*',
|
||||
group: 'block',
|
||||
}
|
||||
|
||||
const paragraph: NodeSpec = {
|
||||
attrs: {
|
||||
align: {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
content: 'inline*',
|
||||
group: 'block',
|
||||
parseDOM: [
|
||||
{
|
||||
tag: 'p',
|
||||
getAttrs: dom => {
|
||||
const { textAlign } = (dom as HTMLElement).style
|
||||
let align = (dom as HTMLElement).getAttribute('align') || textAlign || ''
|
||||
align = /(left|right|center|justify)/.test(align) ? align : ''
|
||||
|
||||
return { align }
|
||||
}
|
||||
}
|
||||
],
|
||||
toDOM: (node: Node) => {
|
||||
const { align } = node.attrs
|
||||
let style = ''
|
||||
if (align && align !== 'left') style += `text-align: ${align};`
|
||||
|
||||
return ['p', { style }, 0]
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
...nodes,
|
||||
'ordered_list': _orderedList,
|
||||
'bullet_list': _bulletList,
|
||||
'list_item': _listItem,
|
||||
paragraph,
|
||||
}
|
||||
import { nodes } from 'prosemirror-schema-basic'
|
||||
import { Node, NodeSpec } from 'prosemirror-model'
|
||||
import { orderedList, bulletList, listItem } from 'prosemirror-schema-list'
|
||||
|
||||
const _orderedList: NodeSpec = {
|
||||
...orderedList,
|
||||
content: 'list_item+',
|
||||
group: 'block',
|
||||
}
|
||||
|
||||
const _bulletList: NodeSpec = {
|
||||
...bulletList,
|
||||
content: 'list_item+',
|
||||
group: 'block',
|
||||
}
|
||||
|
||||
const _listItem: NodeSpec = {
|
||||
...listItem,
|
||||
content: 'paragraph block*',
|
||||
group: 'block',
|
||||
}
|
||||
|
||||
const paragraph: NodeSpec = {
|
||||
attrs: {
|
||||
align: {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
content: 'inline*',
|
||||
group: 'block',
|
||||
parseDOM: [
|
||||
{
|
||||
tag: 'p',
|
||||
getAttrs: dom => {
|
||||
const { textAlign } = (dom as HTMLElement).style
|
||||
let align = (dom as HTMLElement).getAttribute('align') || textAlign || ''
|
||||
align = /(left|right|center|justify)/.test(align) ? align : ''
|
||||
|
||||
return { align }
|
||||
}
|
||||
}
|
||||
],
|
||||
toDOM: (node: Node) => {
|
||||
const { align } = node.attrs
|
||||
let style = ''
|
||||
if (align && align !== 'left') style += `text-align: ${align};`
|
||||
|
||||
return ['p', { style }, 0]
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
...nodes,
|
||||
'ordered_list': _orderedList,
|
||||
'bullet_list': _bulletList,
|
||||
'list_item': _listItem,
|
||||
paragraph,
|
||||
}
|
@ -222,7 +222,7 @@ import { computed, defineComponent, onUnmounted, ref, watch } from 'vue'
|
||||
import { MutationTypes, useStore } from '@/store'
|
||||
import { PPTTextElement } from '@/types/slides'
|
||||
import emitter, { EmitterEvents } from '@/utils/emitter'
|
||||
import { TextAttrs } from '@/prosemirror/utils'
|
||||
import { TextAttrs } from '@/utils/prosemirror/utils'
|
||||
import { WEB_FONTS } from '@/configs/font'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
|
@ -50,12 +50,12 @@ import { EditorView } from 'prosemirror-view'
|
||||
import { toggleMark, wrapIn, selectAll } from 'prosemirror-commands'
|
||||
import { PPTTextElement } from '@/types/slides'
|
||||
import { ContextmenuItem } from '@/components/Contextmenu/types'
|
||||
import { initProsemirrorEditor } from '@/prosemirror/'
|
||||
import { getTextAttrs } from '@/prosemirror/utils'
|
||||
import { initProsemirrorEditor } from '@/utils/prosemirror/'
|
||||
import { getTextAttrs } from '@/utils/prosemirror/utils'
|
||||
import emitter, { EmitterEvents } from '@/utils/emitter'
|
||||
import useElementShadow from '@/views/components/element/hooks/useElementShadow'
|
||||
import { alignmentCommand } from '@/prosemirror/commands/setTextAlign'
|
||||
import { toggleList } from '@/prosemirror/commands/toggleList'
|
||||
import { alignmentCommand } from '@/utils/prosemirror/commands/setTextAlign'
|
||||
import { toggleList } from '@/utils/prosemirror/commands/toggleList'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
import ElementOutline from '@/views/components/element/ElementOutline.vue'
|
||||
|
Loading…
x
Reference in New Issue
Block a user