| import { nodes } from 'prosemirror-schema-basic' | |
| import type { Node, NodeSpec } from 'prosemirror-model' | |
| import { listItem as _listItem } from 'prosemirror-schema-list' | |
| interface Attr { | |
| [key: string]: number | string | |
| } | |
| const orderedList: NodeSpec = { | |
| attrs: { | |
| order: { | |
| default: 1, | |
| }, | |
| listStyleType: { | |
| default: '', | |
| }, | |
| fontsize: { | |
| default: '', | |
| }, | |
| color: { | |
| default: '', | |
| }, | |
| }, | |
| content: 'list_item+', | |
| group: 'block', | |
| parseDOM: [ | |
| { | |
| tag: 'ol', | |
| getAttrs: dom => { | |
| const order = ((dom as HTMLElement).hasAttribute('start') ? (dom as HTMLElement).getAttribute('start') : 1) || 1 | |
| const attr: Attr = { order: +order } | |
| const { listStyleType, fontSize, color } = (dom as HTMLElement).style | |
| if (listStyleType) attr['listStyleType'] = listStyleType | |
| if (fontSize) attr['fontsize'] = fontSize | |
| if (color) attr['color'] = color | |
| return attr | |
| } | |
| } | |
| ], | |
| toDOM: (node: Node) => { | |
| const { order, listStyleType, fontsize, color } = node.attrs | |
| let style = '' | |
| if (listStyleType) style += `list-style-type: ${listStyleType};` | |
| if (fontsize) style += `font-size: ${fontsize};` | |
| if (color) style += `color: ${color};` | |
| const attr: Attr = { style } | |
| if (order !== 1) attr['start'] = order | |
| return ['ol', attr, 0] | |
| }, | |
| } | |
| const bulletList: NodeSpec = { | |
| attrs: { | |
| listStyleType: { | |
| default: '', | |
| }, | |
| fontsize: { | |
| default: '', | |
| }, | |
| color: { | |
| default: '', | |
| }, | |
| }, | |
| content: 'list_item+', | |
| group: 'block', | |
| parseDOM: [ | |
| { | |
| tag: 'ul', | |
| getAttrs: dom => { | |
| const attr: Attr = {} | |
| const { listStyleType, fontSize, color } = (dom as HTMLElement).style | |
| if (listStyleType) attr['listStyleType'] = listStyleType | |
| if (fontSize) attr['fontsize'] = fontSize | |
| if (color) attr['color'] = color | |
| return attr | |
| } | |
| } | |
| ], | |
| toDOM: (node: Node) => { | |
| const { listStyleType, fontsize, color } = node.attrs | |
| let style = '' | |
| if (listStyleType) style += `list-style-type: ${listStyleType};` | |
| if (fontsize) style += `font-size: ${fontsize};` | |
| if (color) style += `color: ${color};` | |
| return ['ul', { style }, 0] | |
| }, | |
| } | |
| const listItem: NodeSpec = { | |
| ..._listItem, | |
| content: 'paragraph block*', | |
| group: 'block', | |
| } | |
| const paragraph: NodeSpec = { | |
| attrs: { | |
| align: { | |
| default: '', | |
| }, | |
| indent: { | |
| default: 0, | |
| }, | |
| textIndent: { | |
| default: 0, | |
| }, | |
| }, | |
| content: 'inline*', | |
| group: 'block', | |
| parseDOM: [ | |
| { | |
| tag: 'p', | |
| getAttrs: dom => { | |
| const { textAlign, textIndent } = (dom as HTMLElement).style | |
| let align = (dom as HTMLElement).getAttribute('align') || textAlign || '' | |
| align = /(left|right|center|justify)/.test(align) ? align : '' | |
| let textIndentLevel = 0 | |
| if (textIndent) { | |
| if (/em/.test(textIndent)) { | |
| textIndentLevel = parseInt(textIndent) | |
| } | |
| else if (/px/.test(textIndent)) { | |
| textIndentLevel = Math.floor(parseInt(textIndent) / 16) | |
| if (!textIndentLevel) textIndentLevel = 1 | |
| } | |
| } | |
| const indent = +((dom as HTMLElement).getAttribute('data-indent') || 0) | |
| return { align, indent, textIndent: textIndentLevel } | |
| } | |
| }, | |
| { | |
| tag: 'img', | |
| ignore: true, | |
| }, | |
| { | |
| tag: 'pre', | |
| skip: true, | |
| }, | |
| ], | |
| toDOM: (node: Node) => { | |
| const { align, indent, textIndent } = node.attrs | |
| let style = '' | |
| if (align && align !== 'left') style += `text-align: ${align};` | |
| if (textIndent) style += `text-indent: ${textIndent}em;` | |
| const attr: Attr = { style } | |
| if (indent) attr['data-indent'] = indent | |
| return ['p', attr, 0] | |
| }, | |
| } | |
| const { | |
| doc, | |
| blockquote, | |
| text, | |
| } = nodes | |
| export default { | |
| doc, | |
| paragraph, | |
| blockquote, | |
| text, | |
| 'ordered_list': orderedList, | |
| 'bullet_list': bulletList, | |
| 'list_item': listItem, | |
| } | |