marks.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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 {
  121. fontname: fontname && typeof fontname === 'string' ? fontname.replace(/[\"\']/g, '') : '',
  122. };
  123. },
  124. },
  125. ],
  126. toDOM: (mark) => {
  127. const { fontname } = mark.attrs;
  128. let style = '';
  129. if (fontname) style += `font-family: ${fontname};`;
  130. return ['span', { style }, 0];
  131. },
  132. };
  133. const link: MarkSpec = {
  134. attrs: {
  135. href: {},
  136. title: { default: null },
  137. target: { default: '_blank' },
  138. },
  139. inclusive: false,
  140. parseDOM: [
  141. {
  142. tag: 'a[href]',
  143. getAttrs: (dom) => {
  144. const href = (dom as HTMLElement).getAttribute('href');
  145. const title = (dom as HTMLElement).getAttribute('title');
  146. return { href, title };
  147. },
  148. },
  149. ],
  150. toDOM: (node) => ['a', node.attrs, 0],
  151. };
  152. const mark: MarkSpec = {
  153. attrs: {
  154. index: { default: null },
  155. },
  156. parseDOM: [
  157. {
  158. tag: 'mark',
  159. getAttrs: (dom) => {
  160. const index = (dom as HTMLElement).dataset.index;
  161. return { index };
  162. },
  163. },
  164. ],
  165. toDOM: (node) => ['mark', { 'data-index': node.attrs.index }, 0],
  166. };
  167. const { em, strong, code } = marks;
  168. const schemaMarks = {
  169. em,
  170. strong,
  171. fontsize,
  172. fontname,
  173. code,
  174. forecolor,
  175. backcolor,
  176. subscript,
  177. superscript,
  178. strikethrough,
  179. underline,
  180. link,
  181. mark,
  182. };
  183. export default schemaMarks;