| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- import { marks } from 'prosemirror-schema-basic'
- import type { 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: {} },
- inline: true,
- group: 'inline',
- 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: [
- {
- 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]
- },
- }
- const link: MarkSpec = {
- attrs: {
- href: {},
- title: { default: null },
- target: { default: '_blank' },
- },
- inclusive: false,
- parseDOM: [
- {
- tag: 'a[href]',
- getAttrs: dom => {
- const href = (dom as HTMLElement).getAttribute('href')
- const title = (dom as HTMLElement).getAttribute('title')
- return { href, title }
- }
- },
- ],
- toDOM: node => ['a', node.attrs, 0],
- }
- const mark: MarkSpec = {
- attrs: { index: { default: null } },
- parseDOM: [
- {
- tag: 'mark',
- getAttrs: dom => {
- const index = (dom as HTMLElement).dataset.index
- return { index }
- }
- },
- ],
- toDOM: node => ['mark', { 'data-index': node.attrs.index }, 0],
- }
- // ===== 新增 marks =====
- // 通用 font-weight(如 100, 200, bold, bolder 等)
- const fontWeight: MarkSpec = {
- attrs: { fontWeight: {} },
- inline: true,
- group: 'inline',
- parseDOM: [
- {
- style: 'font-weight',
- getAttrs: value => value ? { fontWeight: value } : {}
- }
- ],
- toDOM: mark => {
- const { fontWeight } = mark.attrs
- let style = ''
- if (fontWeight) style += `font-weight: ${fontWeight};`
- return ['span', { style }, 0]
- }
- }
- // 通用 font-style(如 italic, oblique, normal)
- const fontStyle: MarkSpec = {
- attrs: { fontStyle: {} },
- inline: true,
- group: 'inline',
- parseDOM: [
- {
- style: 'font-style',
- getAttrs: value => value ? { fontStyle: value } : {}
- }
- ],
- toDOM: mark => {
- const { fontStyle } = mark.attrs
- let style = ''
- if (fontStyle) style += `font-style: ${fontStyle};`
- return ['span', { style }, 0]
- }
- }
- // 通用 text-decoration(可包含 underline, overline, line-through 等组合)
- const textDecoration: MarkSpec = {
- attrs: { textDecoration: {} },
- inline: true,
- group: 'inline',
- parseDOM: [
- {
- style: 'text-decoration',
- getAttrs: value => value ? { textDecoration: value } : {}
- },
- {
- style: 'text-decoration-line',
- getAttrs: value => value ? { textDecoration: value } : {}
- }
- ],
- toDOM: mark => {
- const { textDecoration } = mark.attrs
- let style = ''
- if (textDecoration) style += `text-decoration: ${textDecoration};`
- return ['span', { style }, 0]
- }
- }
- // 通用 vertical-align(支持 baseline, sub, super, top, middle, bottom, 长度值等)
- const verticalAlign: MarkSpec = {
- attrs: { verticalAlign: {} },
- inline: true,
- group: 'inline',
- parseDOM: [
- {
- style: 'vertical-align',
- getAttrs: value => value ? { verticalAlign: value } : {}
- }
- ],
- toDOM: mark => {
- const { verticalAlign } = mark.attrs
- let style = ''
- if (verticalAlign) style += `vertical-align: ${verticalAlign};`
- return ['span', { style }, 0]
- }
- }
- // letter-spacing
- const letterSpacing: MarkSpec = {
- attrs: { letterSpacing: {} },
- inline: true,
- group: 'inline',
- parseDOM: [
- {
- style: 'letter-spacing',
- getAttrs: value => value ? { letterSpacing: value } : {}
- }
- ],
- toDOM: mark => {
- const { letterSpacing } = mark.attrs
- let style = ''
- if (letterSpacing) style += `letter-spacing: ${letterSpacing};`
- return ['span', { style }, 0]
- }
- }
- // text-shadow
- const textShadow: MarkSpec = {
- attrs: { textShadow: {} },
- inline: true,
- group: 'inline',
- parseDOM: [
- {
- style: 'text-shadow',
- getAttrs: value => value ? { textShadow: value } : {}
- }
- ],
- toDOM: mark => {
- const { textShadow } = mark.attrs
- let style = ''
- if (textShadow) style += `text-shadow: ${textShadow};`
- return ['span', { style }, 0]
- }
- }
- // 从 prosemirror-schema-basic 获取的默认 marks
- const { em, strong, code } = marks
- export default {
- em,
- strong,
- code,
- fontsize,
- fontname,
- forecolor,
- backcolor,
- subscript,
- superscript,
- strikethrough,
- underline,
- link,
- mark,
- // 新增
- fontWeight,
- fontStyle,
- textDecoration,
- verticalAlign,
- letterSpacing,
- textShadow,
- }
|