marks.ts 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import { marks } from 'prosemirror-schema-basic'
  2. import type { MarkSpec } from 'prosemirror-model'
  3. const subscript: MarkSpec = {
  4. excludes: 'subscript',
  5. parseDOM: [
  6. { tag: 'sub' },
  7. {
  8. style: 'vertical-align',
  9. getAttrs: value => value === 'sub' && null
  10. },
  11. ],
  12. toDOM: () => ['sub', 0],
  13. }
  14. const superscript: MarkSpec = {
  15. excludes: 'superscript',
  16. parseDOM: [
  17. { tag: 'sup' },
  18. {
  19. style: 'vertical-align',
  20. getAttrs: value => value === 'super' && null
  21. },
  22. ],
  23. toDOM: () => ['sup', 0],
  24. }
  25. const strikethrough: MarkSpec = {
  26. parseDOM: [
  27. { tag: 'strike' },
  28. {
  29. style: 'text-decoration',
  30. getAttrs: value => value === 'line-through' && null
  31. },
  32. {
  33. style: 'text-decoration-line',
  34. getAttrs: value => value === 'line-through' && null
  35. },
  36. ],
  37. toDOM: () => ['span', { style: 'text-decoration-line: line-through;' }, 0],
  38. }
  39. const underline: MarkSpec = {
  40. parseDOM: [
  41. { tag: 'u' },
  42. {
  43. style: 'text-decoration',
  44. getAttrs: value => value === 'underline' && null
  45. },
  46. {
  47. style: 'text-decoration-line',
  48. getAttrs: value => value === 'underline' && null
  49. },
  50. ],
  51. toDOM: () => ['span', { style: 'text-decoration: underline;' }, 0],
  52. }
  53. const forecolor: MarkSpec = {
  54. attrs: {
  55. color: {},
  56. },
  57. inline: true,
  58. group: 'inline',
  59. parseDOM: [
  60. {
  61. style: 'color',
  62. getAttrs: color => color ? { color } : {}
  63. },
  64. ],
  65. toDOM: mark => {
  66. const { color } = mark.attrs
  67. let style = ''
  68. if (color) style += `color: ${color};`
  69. return ['span', { style }, 0]
  70. },
  71. }
  72. const backcolor: MarkSpec = {
  73. attrs: {
  74. backcolor: {},
  75. },
  76. inline: true,
  77. group: 'inline',
  78. parseDOM: [
  79. {
  80. style: 'background-color',
  81. getAttrs: backcolor => backcolor ? { backcolor } : {}
  82. },
  83. ],
  84. toDOM: mark => {
  85. const { backcolor } = mark.attrs
  86. let style = ''
  87. if (backcolor) style += `background-color: ${backcolor};`
  88. return ['span', { style }, 0]
  89. },
  90. }
  91. const fontsize: MarkSpec = {
  92. attrs: {
  93. fontsize: {},
  94. },
  95. inline: true,
  96. group: 'inline',
  97. parseDOM: [
  98. {
  99. style: 'font-size',
  100. getAttrs: fontsize => fontsize ? { fontsize } : {}
  101. },
  102. ],
  103. toDOM: mark => {
  104. const { fontsize } = mark.attrs
  105. let style = ''
  106. if (fontsize) style += `font-size: ${fontsize};`
  107. return ['span', { style }, 0]
  108. },
  109. }
  110. const fontname: MarkSpec = {
  111. attrs: {
  112. fontname: {},
  113. },
  114. inline: true,
  115. group: 'inline',
  116. parseDOM: [
  117. {
  118. style: 'font-family',
  119. getAttrs: fontname => {
  120. return { fontname: fontname && typeof fontname === 'string' ? fontname.replace(/[\"\']/g, '') : '' }
  121. }
  122. },
  123. ],
  124. toDOM: mark => {
  125. const { fontname } = mark.attrs
  126. let style = ''
  127. if (fontname) style += `font-family: ${fontname};`
  128. return ['span', { style }, 0]
  129. },
  130. }
  131. const link: MarkSpec = {
  132. attrs: {
  133. href: {},
  134. title: { default: null },
  135. target: { default: '_blank' },
  136. },
  137. inclusive: false,
  138. parseDOM: [
  139. {
  140. tag: 'a[href]',
  141. getAttrs: dom => {
  142. const href = (dom as HTMLElement).getAttribute('href')
  143. const title = (dom as HTMLElement).getAttribute('title')
  144. return { href, title }
  145. }
  146. },
  147. ],
  148. toDOM: node => ['a', node.attrs, 0],
  149. }
  150. const mark: MarkSpec = {
  151. attrs: {
  152. index: { default: null },
  153. },
  154. parseDOM: [
  155. {
  156. tag: 'mark',
  157. getAttrs: dom => {
  158. const index = (dom as HTMLElement).dataset.index
  159. return { index }
  160. }
  161. },
  162. ],
  163. toDOM: node => ['mark', { 'data-index': node.attrs.index }, 0],
  164. }
  165. const { em, strong, code } = marks
  166. export default {
  167. em,
  168. strong,
  169. fontsize,
  170. fontname,
  171. code,
  172. forecolor,
  173. backcolor,
  174. subscript,
  175. superscript,
  176. strikethrough,
  177. underline,
  178. link,
  179. mark,
  180. }