@aquera/nile-elements 1.9.6 → 1.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (510) hide show
  1. package/README.md +3 -0
  2. package/dist/index-178e1e57.cjs.js +2 -0
  3. package/dist/index-178e1e57.cjs.js.map +1 -0
  4. package/dist/index-1faa963c.esm.js +1 -0
  5. package/dist/index-249de90a.esm.js +1 -0
  6. package/dist/index-353172ed.esm.js +1 -0
  7. package/dist/index-6f3fa4ab.esm.js +1 -0
  8. package/dist/index-89c520e9.cjs.js +5 -0
  9. package/dist/index-89c520e9.cjs.js.map +1 -0
  10. package/dist/index-920675c4.esm.js +1 -0
  11. package/dist/index-b387a9f4.cjs.js +2 -0
  12. package/dist/index-b387a9f4.cjs.js.map +1 -0
  13. package/dist/index-cc1385e0.cjs.js +2 -0
  14. package/dist/index-cc1385e0.cjs.js.map +1 -0
  15. package/dist/index-dedc38a6.esm.js +1 -0
  16. package/dist/index-df196058.cjs.js +2 -0
  17. package/dist/index-df196058.cjs.js.map +1 -0
  18. package/dist/index-f956f56d.cjs.js +7 -0
  19. package/dist/index-f956f56d.cjs.js.map +1 -0
  20. package/dist/index.cjs.js +1 -1
  21. package/dist/index.esm.js +1 -1
  22. package/dist/index.js +3595 -629
  23. package/dist/internal/glyph.cjs.js +2 -0
  24. package/dist/internal/glyph.cjs.js.map +1 -0
  25. package/dist/internal/glyph.esm.js +5 -0
  26. package/dist/nile-auto-complete/index.cjs.js +1 -1
  27. package/dist/nile-auto-complete/nile-auto-complete.cjs.js +1 -1
  28. package/dist/nile-auto-complete/portal-manager.cjs.js +1 -1
  29. package/dist/nile-auto-complete/portal-utils.cjs.js +1 -1
  30. package/dist/nile-code-editor/extensionSetup.cjs.js +7 -7
  31. package/dist/nile-code-editor/extensionSetup.cjs.js.map +1 -1
  32. package/dist/nile-code-editor/extensionSetup.esm.js +1 -1
  33. package/dist/nile-code-editor/index.cjs.js +1 -1
  34. package/dist/nile-code-editor/index.esm.js +1 -1
  35. package/dist/nile-code-editor/nile-code-editor.cjs.js +2 -2
  36. package/dist/nile-code-editor/nile-code-editor.cjs.js.map +1 -1
  37. package/dist/nile-code-editor/nile-code-editor.esm.js +1 -1
  38. package/dist/nile-color-picker/index.cjs.js +1 -1
  39. package/dist/nile-color-picker/nile-color-picker.cjs.js +1 -1
  40. package/dist/nile-combobox/index.cjs.js +1 -1
  41. package/dist/nile-combobox/index.esm.js +1 -1
  42. package/dist/nile-combobox/nile-combobox.cjs.js +1 -1
  43. package/dist/nile-combobox/nile-combobox.esm.js +1 -1
  44. package/dist/nile-combobox/portal-manager.cjs.js +1 -1
  45. package/dist/nile-context-menu/index.cjs.js +1 -1
  46. package/dist/nile-context-menu/nile-context-menu.cjs.js +1 -1
  47. package/dist/nile-context-submenu/index.cjs.js +1 -1
  48. package/dist/nile-context-submenu/nile-context-submenu.cjs.js +1 -1
  49. package/dist/nile-detail/index.cjs.js +1 -1
  50. package/dist/nile-detail/index.esm.js +1 -1
  51. package/dist/nile-detail/nile-detail.cjs.js +1 -1
  52. package/dist/nile-detail/nile-detail.esm.js +1 -1
  53. package/dist/nile-dropdown/index.cjs.js +1 -1
  54. package/dist/nile-dropdown/nile-dropdown.cjs.js +1 -1
  55. package/dist/nile-dropdown/portal-manager.cjs.js +1 -1
  56. package/dist/nile-file-upload/index.cjs.js +1 -1
  57. package/dist/nile-file-upload/nile-file-upload.cjs.js +1 -1
  58. package/dist/nile-file-upload/nile-file-upload.template.cjs.js +1 -1
  59. package/dist/nile-floating-panel/index.cjs.js +1 -1
  60. package/dist/nile-floating-panel/nile-floating-panel.cjs.js +1 -1
  61. package/dist/nile-lite-tooltip/index.cjs.js +1 -1
  62. package/dist/nile-lite-tooltip/nile-lite-tooltip.cjs.js +1 -1
  63. package/dist/nile-markdown-editor/index.cjs.js +1 -1
  64. package/dist/nile-markdown-editor/nile-markdown-editor.cjs.js +1 -1
  65. package/dist/nile-popover/index.cjs.js +1 -1
  66. package/dist/nile-popover/nile-popover.cjs.js +1 -1
  67. package/dist/nile-popover/portal-manager.cjs.js +1 -1
  68. package/dist/nile-popup/index.cjs.js +1 -1
  69. package/dist/nile-popup/nile-popup.cjs.js +1 -1
  70. package/dist/nile-select/index.cjs.js +1 -1
  71. package/dist/nile-select/nile-select.cjs.js +1 -1
  72. package/dist/nile-select/portal-manager.cjs.js +1 -1
  73. package/dist/nile-side-bar-action/index.cjs.js +1 -1
  74. package/dist/nile-side-bar-action/nile-side-bar-action.cjs.js +1 -1
  75. package/dist/nile-side-bar-action/portal-manager.cjs.js +1 -1
  76. package/dist/nile-tooltip/index.cjs.js +1 -1
  77. package/dist/nile-tooltip/nile-tooltip.cjs.js +1 -1
  78. package/dist/nile-virtual-select/index.cjs.js +1 -1
  79. package/dist/nile-virtual-select/nile-virtual-select.cjs.js +1 -1
  80. package/dist/nile-virtual-select/portal-manager.cjs.js +1 -1
  81. package/dist/nile-virtual-select/renderer.cjs.js +1 -1
  82. package/dist/nile-wysiwyg-editor/emoji.cjs.js +2 -0
  83. package/dist/nile-wysiwyg-editor/emoji.cjs.js.map +1 -0
  84. package/dist/nile-wysiwyg-editor/emoji.esm.js +1 -0
  85. package/dist/nile-wysiwyg-editor/engine/commands.cjs.js +2 -0
  86. package/dist/nile-wysiwyg-editor/engine/commands.cjs.js.map +1 -0
  87. package/dist/nile-wysiwyg-editor/engine/commands.esm.js +1 -0
  88. package/dist/nile-wysiwyg-editor/engine/create-state.cjs.js +2 -0
  89. package/dist/nile-wysiwyg-editor/engine/create-state.cjs.js.map +1 -0
  90. package/dist/nile-wysiwyg-editor/engine/create-state.esm.js +1 -0
  91. package/dist/nile-wysiwyg-editor/engine/export.cjs.js +2 -0
  92. package/dist/nile-wysiwyg-editor/engine/export.cjs.js.map +1 -0
  93. package/dist/nile-wysiwyg-editor/engine/export.esm.js +1 -0
  94. package/dist/nile-wysiwyg-editor/engine/index.cjs.js +2 -0
  95. package/dist/nile-wysiwyg-editor/engine/index.cjs.js.map +1 -0
  96. package/dist/nile-wysiwyg-editor/engine/index.esm.js +1 -0
  97. package/dist/nile-wysiwyg-editor/engine/inputrules.cjs.js +2 -0
  98. package/dist/nile-wysiwyg-editor/engine/inputrules.cjs.js.map +1 -0
  99. package/dist/nile-wysiwyg-editor/engine/inputrules.esm.js +1 -0
  100. package/dist/nile-wysiwyg-editor/engine/keymap.cjs.js +2 -0
  101. package/dist/nile-wysiwyg-editor/engine/keymap.cjs.js.map +1 -0
  102. package/dist/nile-wysiwyg-editor/engine/keymap.esm.js +1 -0
  103. package/dist/nile-wysiwyg-editor/engine/markdown-parse.cjs.js +2 -0
  104. package/dist/nile-wysiwyg-editor/engine/markdown-parse.cjs.js.map +1 -0
  105. package/dist/nile-wysiwyg-editor/engine/markdown-parse.esm.js +1 -0
  106. package/dist/nile-wysiwyg-editor/engine/markdown.cjs.js +2 -0
  107. package/dist/nile-wysiwyg-editor/engine/markdown.cjs.js.map +1 -0
  108. package/dist/nile-wysiwyg-editor/engine/markdown.esm.js +1 -0
  109. package/dist/nile-wysiwyg-editor/engine/office-paste.cjs.js +2 -0
  110. package/dist/nile-wysiwyg-editor/engine/office-paste.cjs.js.map +1 -0
  111. package/dist/nile-wysiwyg-editor/engine/office-paste.esm.js +1 -0
  112. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.cjs.js +2 -0
  113. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.cjs.js.map +1 -0
  114. package/dist/nile-wysiwyg-editor/engine/plugins/code-highlight.esm.js +1 -0
  115. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.cjs.js +2 -0
  116. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.cjs.js.map +1 -0
  117. package/dist/nile-wysiwyg-editor/engine/plugins/embed-view.esm.js +1 -0
  118. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.cjs.js +2 -0
  119. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.cjs.js.map +1 -0
  120. package/dist/nile-wysiwyg-editor/engine/plugins/embeds.esm.js +1 -0
  121. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.cjs.js +2 -0
  122. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.cjs.js.map +1 -0
  123. package/dist/nile-wysiwyg-editor/engine/plugins/find-replace.esm.js +1 -0
  124. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.cjs.js +2 -0
  125. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.cjs.js.map +1 -0
  126. package/dist/nile-wysiwyg-editor/engine/plugins/format-painter.esm.js +1 -0
  127. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.cjs.js +2 -0
  128. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.cjs.js.map +1 -0
  129. package/dist/nile-wysiwyg-editor/engine/plugins/image-view.esm.js +1 -0
  130. package/dist/nile-wysiwyg-editor/engine/plugins/image.cjs.js +2 -0
  131. package/dist/nile-wysiwyg-editor/engine/plugins/image.cjs.js.map +1 -0
  132. package/dist/nile-wysiwyg-editor/engine/plugins/image.esm.js +1 -0
  133. package/dist/nile-wysiwyg-editor/engine/plugins/link.cjs.js +2 -0
  134. package/dist/nile-wysiwyg-editor/engine/plugins/link.cjs.js.map +1 -0
  135. package/dist/nile-wysiwyg-editor/engine/plugins/link.esm.js +1 -0
  136. package/dist/nile-wysiwyg-editor/engine/plugins/math-view.cjs.js +2 -0
  137. package/dist/nile-wysiwyg-editor/engine/plugins/math-view.cjs.js.map +1 -0
  138. package/dist/nile-wysiwyg-editor/engine/plugins/math-view.esm.js +1 -0
  139. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.cjs.js +2 -0
  140. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.cjs.js.map +1 -0
  141. package/dist/nile-wysiwyg-editor/engine/plugins/max-length.esm.js +1 -0
  142. package/dist/nile-wysiwyg-editor/engine/plugins/paste.cjs.js +2 -0
  143. package/dist/nile-wysiwyg-editor/engine/plugins/paste.cjs.js.map +1 -0
  144. package/dist/nile-wysiwyg-editor/engine/plugins/paste.esm.js +1 -0
  145. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.cjs.js +2 -0
  146. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.cjs.js.map +1 -0
  147. package/dist/nile-wysiwyg-editor/engine/plugins/placeholder.esm.js +1 -0
  148. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.cjs.js +2 -0
  149. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.cjs.js.map +1 -0
  150. package/dist/nile-wysiwyg-editor/engine/plugins/single-line.esm.js +1 -0
  151. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.cjs.js +2 -0
  152. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.cjs.js.map +1 -0
  153. package/dist/nile-wysiwyg-editor/engine/plugins/suggestions.esm.js +1 -0
  154. package/dist/nile-wysiwyg-editor/engine/plugins/tables.cjs.js +2 -0
  155. package/dist/nile-wysiwyg-editor/engine/plugins/tables.cjs.js.map +1 -0
  156. package/dist/nile-wysiwyg-editor/engine/plugins/tables.esm.js +1 -0
  157. package/dist/nile-wysiwyg-editor/engine/plugins/task-list.cjs.js +2 -0
  158. package/dist/nile-wysiwyg-editor/engine/plugins/task-list.cjs.js.map +1 -0
  159. package/dist/nile-wysiwyg-editor/engine/plugins/task-list.esm.js +1 -0
  160. package/dist/nile-wysiwyg-editor/engine/sanitize.cjs.js +2 -0
  161. package/dist/nile-wysiwyg-editor/engine/sanitize.cjs.js.map +1 -0
  162. package/dist/nile-wysiwyg-editor/engine/sanitize.esm.js +1 -0
  163. package/dist/nile-wysiwyg-editor/engine/schema.cjs.js +2 -0
  164. package/dist/nile-wysiwyg-editor/engine/schema.cjs.js.map +1 -0
  165. package/dist/nile-wysiwyg-editor/engine/schema.esm.js +1 -0
  166. package/dist/nile-wysiwyg-editor/engine/selection-state.cjs.js +2 -0
  167. package/dist/nile-wysiwyg-editor/engine/selection-state.cjs.js.map +1 -0
  168. package/dist/nile-wysiwyg-editor/engine/selection-state.esm.js +1 -0
  169. package/dist/nile-wysiwyg-editor/engine/serializer.cjs.js +2 -0
  170. package/dist/nile-wysiwyg-editor/engine/serializer.cjs.js.map +1 -0
  171. package/dist/nile-wysiwyg-editor/engine/serializer.esm.js +1 -0
  172. package/dist/nile-wysiwyg-editor/index.cjs.js +2 -0
  173. package/dist/nile-wysiwyg-editor/index.cjs.js.map +1 -0
  174. package/dist/nile-wysiwyg-editor/index.esm.js +1 -0
  175. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.cjs.js +2 -0
  176. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.cjs.js.map +1 -0
  177. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.cjs.js +2 -0
  178. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.cjs.js.map +1 -0
  179. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.css.esm.js +780 -0
  180. package/dist/nile-wysiwyg-editor/nile-wysiwyg-editor.esm.js +97 -0
  181. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.cjs.js +2 -0
  182. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.cjs.js.map +1 -0
  183. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.esm.js +1 -0
  184. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.cjs.js +2 -0
  185. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.cjs.js.map +1 -0
  186. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.cjs.js +2 -0
  187. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.cjs.js.map +1 -0
  188. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.esm.js +244 -0
  189. package/dist/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.esm.js +137 -0
  190. package/dist/nile-wysiwyg-editor/types.cjs.js +2 -0
  191. package/dist/nile-wysiwyg-editor/types.cjs.js.map +1 -0
  192. package/dist/nile-wysiwyg-editor/types.esm.js +1 -0
  193. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.cjs.js +2 -0
  194. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.cjs.js.map +1 -0
  195. package/dist/nile-wysiwyg-editor/ui/bookmark-panel.esm.js +97 -0
  196. package/dist/nile-wysiwyg-editor/ui/bubble-menu.cjs.js +2 -0
  197. package/dist/nile-wysiwyg-editor/ui/bubble-menu.cjs.js.map +1 -0
  198. package/dist/nile-wysiwyg-editor/ui/bubble-menu.esm.js +67 -0
  199. package/dist/nile-wysiwyg-editor/ui/code-block-menu.cjs.js +2 -0
  200. package/dist/nile-wysiwyg-editor/ui/code-block-menu.cjs.js.map +1 -0
  201. package/dist/nile-wysiwyg-editor/ui/code-block-menu.esm.js +65 -0
  202. package/dist/nile-wysiwyg-editor/ui/embed-menu.cjs.js +2 -0
  203. package/dist/nile-wysiwyg-editor/ui/embed-menu.cjs.js.map +1 -0
  204. package/dist/nile-wysiwyg-editor/ui/embed-menu.esm.js +64 -0
  205. package/dist/nile-wysiwyg-editor/ui/embed-panel.cjs.js +2 -0
  206. package/dist/nile-wysiwyg-editor/ui/embed-panel.cjs.js.map +1 -0
  207. package/dist/nile-wysiwyg-editor/ui/embed-panel.esm.js +68 -0
  208. package/dist/nile-wysiwyg-editor/ui/emoji-picker.cjs.js +2 -0
  209. package/dist/nile-wysiwyg-editor/ui/emoji-picker.cjs.js.map +1 -0
  210. package/dist/nile-wysiwyg-editor/ui/emoji-picker.esm.js +96 -0
  211. package/dist/nile-wysiwyg-editor/ui/find-replace.cjs.js +2 -0
  212. package/dist/nile-wysiwyg-editor/ui/find-replace.cjs.js.map +1 -0
  213. package/dist/nile-wysiwyg-editor/ui/find-replace.esm.js +112 -0
  214. package/dist/nile-wysiwyg-editor/ui/image-menu.cjs.js +2 -0
  215. package/dist/nile-wysiwyg-editor/ui/image-menu.cjs.js.map +1 -0
  216. package/dist/nile-wysiwyg-editor/ui/image-menu.esm.js +64 -0
  217. package/dist/nile-wysiwyg-editor/ui/image-panel.cjs.js +2 -0
  218. package/dist/nile-wysiwyg-editor/ui/image-panel.cjs.js.map +1 -0
  219. package/dist/nile-wysiwyg-editor/ui/image-panel.esm.js +171 -0
  220. package/dist/nile-wysiwyg-editor/ui/insert-menu.cjs.js +2 -0
  221. package/dist/nile-wysiwyg-editor/ui/insert-menu.cjs.js.map +1 -0
  222. package/dist/nile-wysiwyg-editor/ui/insert-menu.esm.js +90 -0
  223. package/dist/nile-wysiwyg-editor/ui/link-editor.cjs.js +2 -0
  224. package/dist/nile-wysiwyg-editor/ui/link-editor.cjs.js.map +1 -0
  225. package/dist/nile-wysiwyg-editor/ui/link-editor.esm.js +114 -0
  226. package/dist/nile-wysiwyg-editor/ui/markdown-panel.cjs.js +2 -0
  227. package/dist/nile-wysiwyg-editor/ui/markdown-panel.cjs.js.map +1 -0
  228. package/dist/nile-wysiwyg-editor/ui/markdown-panel.esm.js +80 -0
  229. package/dist/nile-wysiwyg-editor/ui/math-panel.cjs.js +2 -0
  230. package/dist/nile-wysiwyg-editor/ui/math-panel.cjs.js.map +1 -0
  231. package/dist/nile-wysiwyg-editor/ui/math-panel.esm.js +92 -0
  232. package/dist/nile-wysiwyg-editor/ui/shortcut-help.cjs.js +2 -0
  233. package/dist/nile-wysiwyg-editor/ui/shortcut-help.cjs.js.map +1 -0
  234. package/dist/nile-wysiwyg-editor/ui/shortcut-help.esm.js +147 -0
  235. package/dist/nile-wysiwyg-editor/ui/source-view.cjs.js +2 -0
  236. package/dist/nile-wysiwyg-editor/ui/source-view.cjs.js.map +1 -0
  237. package/dist/nile-wysiwyg-editor/ui/source-view.esm.js +79 -0
  238. package/dist/nile-wysiwyg-editor/ui/special-chars.cjs.js +2 -0
  239. package/dist/nile-wysiwyg-editor/ui/special-chars.cjs.js.map +1 -0
  240. package/dist/nile-wysiwyg-editor/ui/special-chars.esm.js +96 -0
  241. package/dist/nile-wysiwyg-editor/ui/suggest-list.cjs.js +2 -0
  242. package/dist/nile-wysiwyg-editor/ui/suggest-list.cjs.js.map +1 -0
  243. package/dist/nile-wysiwyg-editor/ui/suggest-list.esm.js +67 -0
  244. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.cjs.js +2 -0
  245. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.cjs.js.map +1 -0
  246. package/dist/nile-wysiwyg-editor/ui/table-grid-picker.esm.js +100 -0
  247. package/dist/nile-wysiwyg-editor/ui/table-menu.cjs.js +2 -0
  248. package/dist/nile-wysiwyg-editor/ui/table-menu.cjs.js.map +1 -0
  249. package/dist/nile-wysiwyg-editor/ui/table-menu.esm.js +58 -0
  250. package/dist/src/index.d.ts +24 -0
  251. package/dist/src/index.js +19 -0
  252. package/dist/src/index.js.map +1 -1
  253. package/dist/src/internal/glyph.d.ts +6 -0
  254. package/dist/src/internal/glyph.js +13 -0
  255. package/dist/src/internal/glyph.js.map +1 -0
  256. package/dist/src/nile-wysiwyg-editor/emoji.d.ts +5 -0
  257. package/dist/src/nile-wysiwyg-editor/emoji.js +138 -0
  258. package/dist/src/nile-wysiwyg-editor/emoji.js.map +1 -0
  259. package/dist/src/nile-wysiwyg-editor/engine/commands.d.ts +69 -0
  260. package/dist/src/nile-wysiwyg-editor/engine/commands.js +863 -0
  261. package/dist/src/nile-wysiwyg-editor/engine/commands.js.map +1 -0
  262. package/dist/src/nile-wysiwyg-editor/engine/create-state.d.ts +35 -0
  263. package/dist/src/nile-wysiwyg-editor/engine/create-state.js +67 -0
  264. package/dist/src/nile-wysiwyg-editor/engine/create-state.js.map +1 -0
  265. package/dist/src/nile-wysiwyg-editor/engine/export.d.ts +38 -0
  266. package/dist/src/nile-wysiwyg-editor/engine/export.js +208 -0
  267. package/dist/src/nile-wysiwyg-editor/engine/export.js.map +1 -0
  268. package/dist/src/nile-wysiwyg-editor/engine/export.test.d.ts +1 -0
  269. package/dist/src/nile-wysiwyg-editor/engine/export.test.js +96 -0
  270. package/dist/src/nile-wysiwyg-editor/engine/export.test.js.map +1 -0
  271. package/dist/src/nile-wysiwyg-editor/engine/index.d.ts +37 -0
  272. package/dist/src/nile-wysiwyg-editor/engine/index.js +29 -0
  273. package/dist/src/nile-wysiwyg-editor/engine/index.js.map +1 -0
  274. package/dist/src/nile-wysiwyg-editor/engine/inputrules.d.ts +12 -0
  275. package/dist/src/nile-wysiwyg-editor/engine/inputrules.js +144 -0
  276. package/dist/src/nile-wysiwyg-editor/engine/inputrules.js.map +1 -0
  277. package/dist/src/nile-wysiwyg-editor/engine/keymap.d.ts +15 -0
  278. package/dist/src/nile-wysiwyg-editor/engine/keymap.js +94 -0
  279. package/dist/src/nile-wysiwyg-editor/engine/keymap.js.map +1 -0
  280. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.d.ts +22 -0
  281. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.js +287 -0
  282. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.js.map +1 -0
  283. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.test.d.ts +1 -0
  284. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.test.js +106 -0
  285. package/dist/src/nile-wysiwyg-editor/engine/markdown-parse.test.js.map +1 -0
  286. package/dist/src/nile-wysiwyg-editor/engine/markdown.d.ts +10 -0
  287. package/dist/src/nile-wysiwyg-editor/engine/markdown.js +162 -0
  288. package/dist/src/nile-wysiwyg-editor/engine/markdown.js.map +1 -0
  289. package/dist/src/nile-wysiwyg-editor/engine/office-paste.d.ts +13 -0
  290. package/dist/src/nile-wysiwyg-editor/engine/office-paste.js +182 -0
  291. package/dist/src/nile-wysiwyg-editor/engine/office-paste.js.map +1 -0
  292. package/dist/src/nile-wysiwyg-editor/engine/plugins/code-highlight.d.ts +10 -0
  293. package/dist/src/nile-wysiwyg-editor/engine/plugins/code-highlight.js +165 -0
  294. package/dist/src/nile-wysiwyg-editor/engine/plugins/code-highlight.js.map +1 -0
  295. package/dist/src/nile-wysiwyg-editor/engine/plugins/embed-view.d.ts +17 -0
  296. package/dist/src/nile-wysiwyg-editor/engine/plugins/embed-view.js +69 -0
  297. package/dist/src/nile-wysiwyg-editor/engine/plugins/embed-view.js.map +1 -0
  298. package/dist/src/nile-wysiwyg-editor/engine/plugins/embeds.d.ts +17 -0
  299. package/dist/src/nile-wysiwyg-editor/engine/plugins/embeds.js +96 -0
  300. package/dist/src/nile-wysiwyg-editor/engine/plugins/embeds.js.map +1 -0
  301. package/dist/src/nile-wysiwyg-editor/engine/plugins/find-replace.d.ts +26 -0
  302. package/dist/src/nile-wysiwyg-editor/engine/plugins/find-replace.js +123 -0
  303. package/dist/src/nile-wysiwyg-editor/engine/plugins/find-replace.js.map +1 -0
  304. package/dist/src/nile-wysiwyg-editor/engine/plugins/format-painter.d.ts +28 -0
  305. package/dist/src/nile-wysiwyg-editor/engine/plugins/format-painter.js +72 -0
  306. package/dist/src/nile-wysiwyg-editor/engine/plugins/format-painter.js.map +1 -0
  307. package/dist/src/nile-wysiwyg-editor/engine/plugins/image-view.d.ts +41 -0
  308. package/dist/src/nile-wysiwyg-editor/engine/plugins/image-view.js +176 -0
  309. package/dist/src/nile-wysiwyg-editor/engine/plugins/image-view.js.map +1 -0
  310. package/dist/src/nile-wysiwyg-editor/engine/plugins/image.d.ts +15 -0
  311. package/dist/src/nile-wysiwyg-editor/engine/plugins/image.js +64 -0
  312. package/dist/src/nile-wysiwyg-editor/engine/plugins/image.js.map +1 -0
  313. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.d.ts +11 -0
  314. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.js +42 -0
  315. package/dist/src/nile-wysiwyg-editor/engine/plugins/link.js.map +1 -0
  316. package/dist/src/nile-wysiwyg-editor/engine/plugins/math-view.d.ts +18 -0
  317. package/dist/src/nile-wysiwyg-editor/engine/plugins/math-view.js +46 -0
  318. package/dist/src/nile-wysiwyg-editor/engine/plugins/math-view.js.map +1 -0
  319. package/dist/src/nile-wysiwyg-editor/engine/plugins/max-length.d.ts +7 -0
  320. package/dist/src/nile-wysiwyg-editor/engine/plugins/max-length.js +26 -0
  321. package/dist/src/nile-wysiwyg-editor/engine/plugins/max-length.js.map +1 -0
  322. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.d.ts +31 -0
  323. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.js +55 -0
  324. package/dist/src/nile-wysiwyg-editor/engine/plugins/paste.js.map +1 -0
  325. package/dist/src/nile-wysiwyg-editor/engine/plugins/placeholder.d.ts +7 -0
  326. package/dist/src/nile-wysiwyg-editor/engine/plugins/placeholder.js +25 -0
  327. package/dist/src/nile-wysiwyg-editor/engine/plugins/placeholder.js.map +1 -0
  328. package/dist/src/nile-wysiwyg-editor/engine/plugins/single-line.d.ts +10 -0
  329. package/dist/src/nile-wysiwyg-editor/engine/plugins/single-line.js +48 -0
  330. package/dist/src/nile-wysiwyg-editor/engine/plugins/single-line.js.map +1 -0
  331. package/dist/src/nile-wysiwyg-editor/engine/plugins/suggestions.d.ts +29 -0
  332. package/dist/src/nile-wysiwyg-editor/engine/plugins/suggestions.js +87 -0
  333. package/dist/src/nile-wysiwyg-editor/engine/plugins/suggestions.js.map +1 -0
  334. package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.d.ts +8 -0
  335. package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.js +11 -0
  336. package/dist/src/nile-wysiwyg-editor/engine/plugins/tables.js.map +1 -0
  337. package/dist/src/nile-wysiwyg-editor/engine/plugins/task-list.d.ts +16 -0
  338. package/dist/src/nile-wysiwyg-editor/engine/plugins/task-list.js +49 -0
  339. package/dist/src/nile-wysiwyg-editor/engine/plugins/task-list.js.map +1 -0
  340. package/dist/src/nile-wysiwyg-editor/engine/pm.test.d.ts +1 -0
  341. package/dist/src/nile-wysiwyg-editor/engine/pm.test.js +883 -0
  342. package/dist/src/nile-wysiwyg-editor/engine/pm.test.js.map +1 -0
  343. package/dist/src/nile-wysiwyg-editor/engine/productivity.test.d.ts +1 -0
  344. package/dist/src/nile-wysiwyg-editor/engine/productivity.test.js +129 -0
  345. package/dist/src/nile-wysiwyg-editor/engine/productivity.test.js.map +1 -0
  346. package/dist/src/nile-wysiwyg-editor/engine/sanitize.d.ts +13 -0
  347. package/dist/src/nile-wysiwyg-editor/engine/sanitize.js +155 -0
  348. package/dist/src/nile-wysiwyg-editor/engine/sanitize.js.map +1 -0
  349. package/dist/src/nile-wysiwyg-editor/engine/schema.d.ts +20 -0
  350. package/dist/src/nile-wysiwyg-editor/engine/schema.js +823 -0
  351. package/dist/src/nile-wysiwyg-editor/engine/schema.js.map +1 -0
  352. package/dist/src/nile-wysiwyg-editor/engine/selection-state.d.ts +70 -0
  353. package/dist/src/nile-wysiwyg-editor/engine/selection-state.js +138 -0
  354. package/dist/src/nile-wysiwyg-editor/engine/selection-state.js.map +1 -0
  355. package/dist/src/nile-wysiwyg-editor/engine/serializer.d.ts +18 -0
  356. package/dist/src/nile-wysiwyg-editor/engine/serializer.js +63 -0
  357. package/dist/src/nile-wysiwyg-editor/engine/serializer.js.map +1 -0
  358. package/dist/src/nile-wysiwyg-editor/index.d.ts +3 -0
  359. package/dist/src/nile-wysiwyg-editor/index.js +3 -0
  360. package/dist/src/nile-wysiwyg-editor/index.js.map +1 -0
  361. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.d.ts +1 -0
  362. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.js +782 -0
  363. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.js.map +1 -0
  364. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.d.ts +364 -0
  365. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.js +2038 -0
  366. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.js.map +1 -0
  367. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.d.ts +1 -0
  368. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.js +636 -0
  369. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.js.map +1 -0
  370. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.d.ts +1 -0
  371. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.js +2 -0
  372. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.js.map +1 -0
  373. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.d.ts +6 -0
  374. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.js +251 -0
  375. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.js.map +1 -0
  376. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.d.ts +41 -0
  377. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.js +700 -0
  378. package/dist/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.js.map +1 -0
  379. package/dist/src/nile-wysiwyg-editor/types.d.ts +49 -0
  380. package/dist/src/nile-wysiwyg-editor/types.js +8 -0
  381. package/dist/src/nile-wysiwyg-editor/types.js.map +1 -0
  382. package/dist/src/nile-wysiwyg-editor/ui/bookmark-panel.d.ts +20 -0
  383. package/dist/src/nile-wysiwyg-editor/ui/bookmark-panel.js +159 -0
  384. package/dist/src/nile-wysiwyg-editor/ui/bookmark-panel.js.map +1 -0
  385. package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.d.ts +21 -0
  386. package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.js +125 -0
  387. package/dist/src/nile-wysiwyg-editor/ui/bubble-menu.js.map +1 -0
  388. package/dist/src/nile-wysiwyg-editor/ui/code-block-menu.d.ts +18 -0
  389. package/dist/src/nile-wysiwyg-editor/ui/code-block-menu.js +107 -0
  390. package/dist/src/nile-wysiwyg-editor/ui/code-block-menu.js.map +1 -0
  391. package/dist/src/nile-wysiwyg-editor/ui/embed-menu.d.ts +19 -0
  392. package/dist/src/nile-wysiwyg-editor/ui/embed-menu.js +123 -0
  393. package/dist/src/nile-wysiwyg-editor/ui/embed-menu.js.map +1 -0
  394. package/dist/src/nile-wysiwyg-editor/ui/embed-panel.d.ts +27 -0
  395. package/dist/src/nile-wysiwyg-editor/ui/embed-panel.js +146 -0
  396. package/dist/src/nile-wysiwyg-editor/ui/embed-panel.js.map +1 -0
  397. package/dist/src/nile-wysiwyg-editor/ui/emoji-picker.d.ts +21 -0
  398. package/dist/src/nile-wysiwyg-editor/ui/emoji-picker.js +154 -0
  399. package/dist/src/nile-wysiwyg-editor/ui/emoji-picker.js.map +1 -0
  400. package/dist/src/nile-wysiwyg-editor/ui/find-replace.d.ts +26 -0
  401. package/dist/src/nile-wysiwyg-editor/ui/find-replace.js +178 -0
  402. package/dist/src/nile-wysiwyg-editor/ui/find-replace.js.map +1 -0
  403. package/dist/src/nile-wysiwyg-editor/ui/image-menu.d.ts +18 -0
  404. package/dist/src/nile-wysiwyg-editor/ui/image-menu.js +129 -0
  405. package/dist/src/nile-wysiwyg-editor/ui/image-menu.js.map +1 -0
  406. package/dist/src/nile-wysiwyg-editor/ui/image-panel.d.ts +56 -0
  407. package/dist/src/nile-wysiwyg-editor/ui/image-panel.js +349 -0
  408. package/dist/src/nile-wysiwyg-editor/ui/image-panel.js.map +1 -0
  409. package/dist/src/nile-wysiwyg-editor/ui/insert-menu.d.ts +25 -0
  410. package/dist/src/nile-wysiwyg-editor/ui/insert-menu.js +142 -0
  411. package/dist/src/nile-wysiwyg-editor/ui/insert-menu.js.map +1 -0
  412. package/dist/src/nile-wysiwyg-editor/ui/link-editor.d.ts +30 -0
  413. package/dist/src/nile-wysiwyg-editor/ui/link-editor.js +189 -0
  414. package/dist/src/nile-wysiwyg-editor/ui/link-editor.js.map +1 -0
  415. package/dist/src/nile-wysiwyg-editor/ui/markdown-panel.d.ts +24 -0
  416. package/dist/src/nile-wysiwyg-editor/ui/markdown-panel.js +144 -0
  417. package/dist/src/nile-wysiwyg-editor/ui/markdown-panel.js.map +1 -0
  418. package/dist/src/nile-wysiwyg-editor/ui/math-panel.d.ts +31 -0
  419. package/dist/src/nile-wysiwyg-editor/ui/math-panel.js +172 -0
  420. package/dist/src/nile-wysiwyg-editor/ui/math-panel.js.map +1 -0
  421. package/dist/src/nile-wysiwyg-editor/ui/shortcut-help.d.ts +30 -0
  422. package/dist/src/nile-wysiwyg-editor/ui/shortcut-help.js +296 -0
  423. package/dist/src/nile-wysiwyg-editor/ui/shortcut-help.js.map +1 -0
  424. package/dist/src/nile-wysiwyg-editor/ui/source-view.d.ts +19 -0
  425. package/dist/src/nile-wysiwyg-editor/ui/source-view.js +120 -0
  426. package/dist/src/nile-wysiwyg-editor/ui/source-view.js.map +1 -0
  427. package/dist/src/nile-wysiwyg-editor/ui/special-chars.d.ts +20 -0
  428. package/dist/src/nile-wysiwyg-editor/ui/special-chars.js +199 -0
  429. package/dist/src/nile-wysiwyg-editor/ui/special-chars.js.map +1 -0
  430. package/dist/src/nile-wysiwyg-editor/ui/suggest-list.d.ts +31 -0
  431. package/dist/src/nile-wysiwyg-editor/ui/suggest-list.js +133 -0
  432. package/dist/src/nile-wysiwyg-editor/ui/suggest-list.js.map +1 -0
  433. package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.d.ts +23 -0
  434. package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.js +177 -0
  435. package/dist/src/nile-wysiwyg-editor/ui/table-grid-picker.js.map +1 -0
  436. package/dist/src/nile-wysiwyg-editor/ui/table-menu.d.ts +16 -0
  437. package/dist/src/nile-wysiwyg-editor/ui/table-menu.js +101 -0
  438. package/dist/src/nile-wysiwyg-editor/ui/table-menu.js.map +1 -0
  439. package/dist/src/version.js +1 -1
  440. package/dist/src/version.js.map +1 -1
  441. package/dist/tsconfig.tsbuildinfo +1 -1
  442. package/package.json +18 -2
  443. package/src/index.ts +57 -1
  444. package/src/internal/glyph.ts +13 -0
  445. package/src/nile-wysiwyg-editor/emoji.ts +137 -0
  446. package/src/nile-wysiwyg-editor/engine/commands.ts +1035 -0
  447. package/src/nile-wysiwyg-editor/engine/create-state.ts +117 -0
  448. package/src/nile-wysiwyg-editor/engine/export.test.ts +113 -0
  449. package/src/nile-wysiwyg-editor/engine/export.ts +242 -0
  450. package/src/nile-wysiwyg-editor/engine/index.ts +69 -0
  451. package/src/nile-wysiwyg-editor/engine/inputrules.ts +169 -0
  452. package/src/nile-wysiwyg-editor/engine/keymap.ts +146 -0
  453. package/src/nile-wysiwyg-editor/engine/markdown-parse.test.ts +148 -0
  454. package/src/nile-wysiwyg-editor/engine/markdown-parse.ts +337 -0
  455. package/src/nile-wysiwyg-editor/engine/markdown.ts +165 -0
  456. package/src/nile-wysiwyg-editor/engine/office-paste.ts +199 -0
  457. package/src/nile-wysiwyg-editor/engine/plugins/code-highlight.ts +173 -0
  458. package/src/nile-wysiwyg-editor/engine/plugins/embed-view.ts +85 -0
  459. package/src/nile-wysiwyg-editor/engine/plugins/embeds.ts +99 -0
  460. package/src/nile-wysiwyg-editor/engine/plugins/find-replace.ts +155 -0
  461. package/src/nile-wysiwyg-editor/engine/plugins/format-painter.ts +80 -0
  462. package/src/nile-wysiwyg-editor/engine/plugins/image-view.ts +220 -0
  463. package/src/nile-wysiwyg-editor/engine/plugins/image.ts +80 -0
  464. package/src/nile-wysiwyg-editor/engine/plugins/link.ts +42 -0
  465. package/src/nile-wysiwyg-editor/engine/plugins/math-view.ts +56 -0
  466. package/src/nile-wysiwyg-editor/engine/plugins/max-length.ts +24 -0
  467. package/src/nile-wysiwyg-editor/engine/plugins/paste.ts +74 -0
  468. package/src/nile-wysiwyg-editor/engine/plugins/placeholder.ts +24 -0
  469. package/src/nile-wysiwyg-editor/engine/plugins/single-line.ts +47 -0
  470. package/src/nile-wysiwyg-editor/engine/plugins/suggestions.ts +110 -0
  471. package/src/nile-wysiwyg-editor/engine/plugins/tables.ts +12 -0
  472. package/src/nile-wysiwyg-editor/engine/plugins/task-list.ts +65 -0
  473. package/src/nile-wysiwyg-editor/engine/pm.test.ts +1088 -0
  474. package/src/nile-wysiwyg-editor/engine/productivity.test.ts +163 -0
  475. package/src/nile-wysiwyg-editor/engine/sanitize.ts +156 -0
  476. package/src/nile-wysiwyg-editor/engine/schema.ts +859 -0
  477. package/src/nile-wysiwyg-editor/engine/selection-state.ts +210 -0
  478. package/src/nile-wysiwyg-editor/engine/serializer.ts +78 -0
  479. package/src/nile-wysiwyg-editor/index.ts +3 -0
  480. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.css.ts +782 -0
  481. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.test.ts +750 -0
  482. package/src/nile-wysiwyg-editor/nile-wysiwyg-editor.ts +2155 -0
  483. package/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/index.ts +1 -0
  484. package/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.css.ts +251 -0
  485. package/src/nile-wysiwyg-editor/nile-wysiwyg-toolbar/nile-wysiwyg-toolbar.ts +772 -0
  486. package/src/nile-wysiwyg-editor/types.ts +83 -0
  487. package/src/nile-wysiwyg-editor/ui/bookmark-panel.ts +155 -0
  488. package/src/nile-wysiwyg-editor/ui/bubble-menu.ts +135 -0
  489. package/src/nile-wysiwyg-editor/ui/code-block-menu.ts +105 -0
  490. package/src/nile-wysiwyg-editor/ui/embed-menu.ts +133 -0
  491. package/src/nile-wysiwyg-editor/ui/embed-panel.ts +143 -0
  492. package/src/nile-wysiwyg-editor/ui/emoji-picker.ts +152 -0
  493. package/src/nile-wysiwyg-editor/ui/find-replace.ts +174 -0
  494. package/src/nile-wysiwyg-editor/ui/image-menu.ts +140 -0
  495. package/src/nile-wysiwyg-editor/ui/image-panel.ts +337 -0
  496. package/src/nile-wysiwyg-editor/ui/insert-menu.ts +142 -0
  497. package/src/nile-wysiwyg-editor/ui/link-editor.ts +180 -0
  498. package/src/nile-wysiwyg-editor/ui/markdown-panel.ts +143 -0
  499. package/src/nile-wysiwyg-editor/ui/math-panel.ts +169 -0
  500. package/src/nile-wysiwyg-editor/ui/shortcut-help.ts +311 -0
  501. package/src/nile-wysiwyg-editor/ui/source-view.ts +119 -0
  502. package/src/nile-wysiwyg-editor/ui/special-chars.ts +209 -0
  503. package/src/nile-wysiwyg-editor/ui/suggest-list.ts +138 -0
  504. package/src/nile-wysiwyg-editor/ui/table-grid-picker.ts +173 -0
  505. package/src/nile-wysiwyg-editor/ui/table-menu.ts +109 -0
  506. package/vscode-html-custom-data.json +450 -0
  507. package/web-dev-server.config.mjs +6 -2
  508. package/dist/index-5fef1a0d.esm.js +0 -1
  509. package/dist/index-8f38fae3.cjs.js +0 -2
  510. package/dist/index-8f38fae3.cjs.js.map +0 -1
@@ -0,0 +1,859 @@
1
+ import { Schema, NodeSpec, MarkSpec } from 'prosemirror-model';
2
+ import { addListNodes } from 'prosemirror-schema-list';
3
+ import { tableNodes } from 'prosemirror-tables';
4
+ import OrderedMap from 'orderedmap';
5
+
6
+ export type Alignment = 'left' | 'center' | 'right' | 'justify';
7
+
8
+ const ALIGN_VALUES: Alignment[] = ['left', 'center', 'right', 'justify'];
9
+
10
+ function getAlignFromDom(dom: HTMLElement): Alignment | null {
11
+ const value = dom.style.textAlign || dom.getAttribute('align') || '';
12
+ return (ALIGN_VALUES as string[]).includes(value) ? (value as Alignment) : null;
13
+ }
14
+
15
+ function alignStyle(align: Alignment | null): string | null {
16
+ return align ? `text-align: ${align}` : null;
17
+ }
18
+
19
+ /** Indent depth in 40px steps, like CKEditor/Google Docs. */
20
+ export const INDENT_STEP_PX = 40;
21
+ export const MAX_INDENT = 8;
22
+
23
+ function getIndentFromDom(dom: HTMLElement): number {
24
+ const raw = dom.style.marginInlineStart || dom.style.marginLeft || '';
25
+ const px = parseFloat(raw);
26
+ if (!Number.isFinite(px) || px <= 0) return 0;
27
+ return Math.min(MAX_INDENT, Math.round(px / INDENT_STEP_PX));
28
+ }
29
+
30
+ /**
31
+ * Line height as a unitless multiplier string ('1.5'). Percentages are
32
+ * converted; px values pass through as-is so pasted content keeps its look.
33
+ */
34
+ function getLineHeightFromDom(dom: HTMLElement): string | null {
35
+ const raw = dom.style.lineHeight.trim();
36
+ if (!raw || raw === 'normal') return null;
37
+ const num = parseFloat(raw);
38
+ if (!Number.isFinite(num) || num <= 0) return null;
39
+ if (raw.endsWith('%')) return String(num / 100);
40
+ return raw;
41
+ }
42
+
43
+ /** Combined style string for align + indent + line-height textblock attrs. */
44
+ function blockStyle(attrs: {
45
+ align?: Alignment | null;
46
+ indent?: number;
47
+ lineHeight?: string | null;
48
+ }): string | null {
49
+ const parts: string[] = [];
50
+ const align = alignStyle(attrs.align ?? null);
51
+ if (align) parts.push(align);
52
+ if (attrs.indent) parts.push(`margin-inline-start: ${attrs.indent * INDENT_STEP_PX}px`);
53
+ if (attrs.lineHeight) parts.push(`line-height: ${attrs.lineHeight}`);
54
+ return parts.length ? parts.join('; ') : null;
55
+ }
56
+
57
+ /**
58
+ * Block nodes. `align` is modeled as an attribute on textblocks rather than a
59
+ * wrapper node so alignment survives block-type changes (heading <-> paragraph).
60
+ */
61
+ const nodes: Record<string, NodeSpec> = {
62
+ doc: {
63
+ content: 'block+',
64
+ },
65
+
66
+ paragraph: {
67
+ content: 'inline*',
68
+ group: 'block',
69
+ attrs: {
70
+ align: { default: null },
71
+ indent: { default: 0 },
72
+ lineHeight: { default: null },
73
+ },
74
+ parseDOM: [
75
+ {
76
+ tag: 'p',
77
+ getAttrs: (dom: HTMLElement) => ({
78
+ align: getAlignFromDom(dom),
79
+ indent: getIndentFromDom(dom),
80
+ lineHeight: getLineHeightFromDom(dom),
81
+ }),
82
+ },
83
+ ],
84
+ toDOM(node) {
85
+ const style = blockStyle(node.attrs);
86
+ return style ? ['p', { style }, 0] : ['p', 0];
87
+ },
88
+ },
89
+
90
+ heading: {
91
+ content: 'inline*',
92
+ group: 'block',
93
+ defining: true,
94
+ attrs: {
95
+ level: { default: 1 },
96
+ align: { default: null },
97
+ indent: { default: 0 },
98
+ lineHeight: { default: null },
99
+ },
100
+ parseDOM: [1, 2, 3, 4, 5, 6].map(level => ({
101
+ tag: `h${level}`,
102
+ getAttrs: (dom: HTMLElement) => ({
103
+ level,
104
+ align: getAlignFromDom(dom),
105
+ indent: getIndentFromDom(dom),
106
+ lineHeight: getLineHeightFromDom(dom),
107
+ }),
108
+ })),
109
+ toDOM(node) {
110
+ const style = blockStyle(node.attrs);
111
+ return style ? [`h${node.attrs.level}`, { style }, 0] : [`h${node.attrs.level}`, 0];
112
+ },
113
+ },
114
+
115
+ blockquote: {
116
+ content: 'block+',
117
+ group: 'block',
118
+ defining: true,
119
+ parseDOM: [{ tag: 'blockquote' }],
120
+ toDOM() {
121
+ return ['blockquote', 0];
122
+ },
123
+ },
124
+
125
+ horizontal_rule: {
126
+ group: 'block',
127
+ parseDOM: [{ tag: 'hr' }],
128
+ toDOM() {
129
+ return ['hr'];
130
+ },
131
+ },
132
+
133
+ text: {
134
+ group: 'inline',
135
+ },
136
+
137
+ hard_break: {
138
+ inline: true,
139
+ group: 'inline',
140
+ selectable: false,
141
+ parseDOM: [{ tag: 'br' }],
142
+ toDOM() {
143
+ return ['br'];
144
+ },
145
+ },
146
+
147
+ code_block: {
148
+ content: 'text*',
149
+ group: 'block',
150
+ marks: '',
151
+ code: true,
152
+ defining: true,
153
+ attrs: { language: { default: null } },
154
+ parseDOM: [
155
+ {
156
+ tag: 'pre',
157
+ preserveWhitespace: 'full',
158
+ getAttrs: (dom: HTMLElement) => ({
159
+ language: dom.getAttribute('data-language'),
160
+ }),
161
+ },
162
+ ],
163
+ toDOM(node) {
164
+ const attrs: Record<string, string> = { class: 'nile-wysiwyg__code-block' };
165
+ if (node.attrs.language) attrs['data-language'] = node.attrs.language;
166
+ return ['pre', attrs, ['code', 0]];
167
+ },
168
+ },
169
+
170
+ /**
171
+ * ProseMirror's canonical inline image, extended with a `width` attr (px)
172
+ * written by the drag-resize handles.
173
+ */
174
+ image: {
175
+ inline: true,
176
+ group: 'inline',
177
+ draggable: true,
178
+ attrs: {
179
+ src: {},
180
+ alt: { default: null },
181
+ title: { default: null },
182
+ width: { default: null },
183
+ },
184
+ parseDOM: [
185
+ {
186
+ tag: 'img[src]',
187
+ getAttrs: (dom: HTMLElement) => {
188
+ const styleWidth = parseFloat(dom.style.width);
189
+ const attrWidth = parseFloat(dom.getAttribute('width') ?? '');
190
+ const width = Number.isFinite(styleWidth)
191
+ ? Math.round(styleWidth)
192
+ : Number.isFinite(attrWidth)
193
+ ? Math.round(attrWidth)
194
+ : null;
195
+ return {
196
+ src: dom.getAttribute('src'),
197
+ alt: dom.getAttribute('alt'),
198
+ title: dom.getAttribute('title'),
199
+ width: width && width > 0 ? width : null,
200
+ };
201
+ },
202
+ },
203
+ ],
204
+ toDOM(node) {
205
+ const { src, alt, title, width } = node.attrs;
206
+ const attrs: Record<string, string> = { src };
207
+ if (alt) attrs.alt = alt;
208
+ if (title) attrs.title = title;
209
+ if (width) attrs.style = `width: ${width}px`;
210
+ return ['img', attrs];
211
+ },
212
+ },
213
+
214
+ /**
215
+ * Captioned image: a block figure whose inline content is the caption. The
216
+ * image itself lives in the attrs (TipTap-style), so the node stays valid
217
+ * ProseMirror content — a node can't mix an inline img child with a block
218
+ * figcaption child.
219
+ */
220
+ figure: {
221
+ group: 'block',
222
+ content: 'inline*',
223
+ defining: true,
224
+ isolating: true,
225
+ attrs: {
226
+ src: {},
227
+ alt: { default: null },
228
+ title: { default: null },
229
+ width: { default: null },
230
+ align: { default: null },
231
+ },
232
+ parseDOM: [
233
+ {
234
+ tag: 'figure',
235
+ contentElement: 'figcaption',
236
+ getAttrs: (dom: HTMLElement) => {
237
+ const img = dom.querySelector('img[src]') as HTMLElement | null;
238
+ if (!img) return false;
239
+ const styleWidth = parseFloat(img.style.width || dom.style.width);
240
+ const align = dom.getAttribute('data-align');
241
+ return {
242
+ src: img.getAttribute('src'),
243
+ alt: img.getAttribute('alt'),
244
+ title: img.getAttribute('title'),
245
+ width:
246
+ Number.isFinite(styleWidth) && styleWidth > 0
247
+ ? Math.round(styleWidth)
248
+ : null,
249
+ align: align === 'left' || align === 'center' || align === 'right' ? align : null,
250
+ };
251
+ },
252
+ },
253
+ ],
254
+ toDOM(node) {
255
+ const { src, alt, title, width, align } = node.attrs;
256
+ const figureAttrs: Record<string, string> = { class: 'nile-wysiwyg__figure' };
257
+ if (align) figureAttrs['data-align'] = align;
258
+ const styles: string[] = [];
259
+ if (width) styles.push(`width: ${width}px`);
260
+ if (align === 'center') styles.push('margin-left: auto; margin-right: auto');
261
+ else if (align === 'right') styles.push('margin-left: auto; margin-right: 0');
262
+ if (styles.length) figureAttrs.style = styles.join('; ');
263
+ const imgAttrs: Record<string, string> = { src, style: 'width: 100%' };
264
+ if (alt) imgAttrs.alt = alt;
265
+ if (title) imgAttrs.title = title;
266
+ return [
267
+ 'figure',
268
+ figureAttrs,
269
+ ['img', imgAttrs],
270
+ ['figcaption', { class: 'nile-wysiwyg__figcaption' }, 0],
271
+ ];
272
+ },
273
+ },
274
+
275
+ /**
276
+ * Checklists. Serialized as <ul data-task-list><li data-task-item
277
+ * data-checked> so they survive HTML round-trips; the live checkbox is an
278
+ * editor-only NodeView. parseDOM priority 51 beats the generic li rule.
279
+ */
280
+ task_list: {
281
+ content: 'task_item+',
282
+ group: 'block',
283
+ parseDOM: [{ tag: 'ul[data-task-list]', priority: 51 }],
284
+ toDOM() {
285
+ return ['ul', { 'data-task-list': 'true', class: 'nile-wysiwyg__task-list' }, 0];
286
+ },
287
+ },
288
+
289
+ task_item: {
290
+ content: 'paragraph block*',
291
+ defining: true,
292
+ attrs: { checked: { default: false } },
293
+ parseDOM: [
294
+ {
295
+ tag: 'li[data-task-item]',
296
+ priority: 51,
297
+ getAttrs: (dom: HTMLElement) => ({
298
+ checked: dom.getAttribute('data-checked') === 'true',
299
+ }),
300
+ },
301
+ ],
302
+ toDOM(node) {
303
+ return [
304
+ 'li',
305
+ {
306
+ 'data-task-item': 'true',
307
+ 'data-checked': String(node.attrs.checked),
308
+ class: 'nile-wysiwyg__task-item',
309
+ },
310
+ 0,
311
+ ];
312
+ },
313
+ },
314
+
315
+ /**
316
+ * Provider embeds (YouTube/Vimeo/Loom) as block atoms. The iframe sits in
317
+ * a wrapper div for aspect-ratio styling and a click-to-select overlay.
318
+ */
319
+ embed: {
320
+ group: 'block',
321
+ atom: true,
322
+ selectable: true,
323
+ draggable: true,
324
+ attrs: {
325
+ src: {},
326
+ provider: { default: null },
327
+ title: { default: null },
328
+ /** Rendered width in px (drag-resize); null = default size. */
329
+ width: { default: null },
330
+ /** Block alignment: 'left' | 'center' | 'right' | null. */
331
+ align: { default: null },
332
+ },
333
+ parseDOM: [
334
+ {
335
+ tag: 'div[data-embed-provider]',
336
+ getAttrs: (dom: HTMLElement) => {
337
+ const iframe = dom.querySelector('iframe[src]');
338
+ if (!iframe) return false;
339
+ const widthAttr =
340
+ dom.getAttribute('data-width') ?? /^(\d+)px$/.exec(dom.style.width)?.[1];
341
+ const width = widthAttr ? parseInt(widthAttr, 10) : NaN;
342
+ const align = dom.getAttribute('data-align');
343
+ return {
344
+ src: iframe.getAttribute('src'),
345
+ provider: dom.getAttribute('data-embed-provider'),
346
+ title: iframe.getAttribute('title'),
347
+ width: Number.isFinite(width) && width > 0 ? width : null,
348
+ align: align === 'left' || align === 'center' || align === 'right' ? align : null,
349
+ };
350
+ },
351
+ },
352
+ {
353
+ tag: 'iframe[src]',
354
+ getAttrs: (dom: HTMLElement) => {
355
+ const width = parseInt(dom.getAttribute('width') ?? '', 10);
356
+ return {
357
+ src: dom.getAttribute('src'),
358
+ title: dom.getAttribute('title'),
359
+ width: Number.isFinite(width) && width > 0 ? width : null,
360
+ };
361
+ },
362
+ },
363
+ ],
364
+ toDOM(node) {
365
+ const { src, provider, title, width, align } = node.attrs;
366
+ const iframeAttrs: Record<string, string> = {
367
+ src,
368
+ frameborder: '0',
369
+ allowfullscreen: 'true',
370
+ allow: 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture',
371
+ };
372
+ if (title) iframeAttrs.title = title;
373
+ const wrapperAttrs: Record<string, string> = {
374
+ class: 'nile-wysiwyg__embed',
375
+ 'data-embed-provider': provider ?? 'generic',
376
+ };
377
+ const styles: string[] = [];
378
+ if (width) {
379
+ wrapperAttrs['data-width'] = String(width);
380
+ styles.push(`width: ${width}px`, 'max-width: 100%');
381
+ }
382
+ if (align) {
383
+ wrapperAttrs['data-align'] = align;
384
+ if (align === 'center') styles.push('margin-left: auto', 'margin-right: auto');
385
+ else if (align === 'right') styles.push('margin-left: auto', 'margin-right: 0');
386
+ }
387
+ if (styles.length) wrapperAttrs.style = styles.join('; ');
388
+ return ['div', wrapperAttrs, ['iframe', iframeAttrs]];
389
+ },
390
+ },
391
+
392
+ /**
393
+ * Bookmark: a named in-text anchor (`<a id="…">`) for intra-document
394
+ * navigation. Invisible in serialized output; the editor draws a flag
395
+ * marker via CSS so it can be selected and deleted.
396
+ */
397
+ bookmark: {
398
+ inline: true,
399
+ group: 'inline',
400
+ atom: true,
401
+ selectable: true,
402
+ attrs: { id: {} },
403
+ parseDOM: [
404
+ {
405
+ tag: 'a[data-bookmark]',
406
+ priority: 60,
407
+ getAttrs: (dom: HTMLElement) => {
408
+ const id = dom.getAttribute('id') || dom.getAttribute('name');
409
+ return id ? { id } : false;
410
+ },
411
+ },
412
+ // Anchors without an href are bookmarks (`<a id>` / legacy `<a name>`).
413
+ {
414
+ tag: 'a[id]',
415
+ getAttrs: (dom: HTMLElement) =>
416
+ dom.hasAttribute('href') ? false : { id: dom.getAttribute('id') },
417
+ },
418
+ {
419
+ tag: 'a[name]',
420
+ getAttrs: (dom: HTMLElement) =>
421
+ dom.hasAttribute('href') ? false : { id: dom.getAttribute('name') },
422
+ },
423
+ ],
424
+ toDOM(node) {
425
+ return ['a', { id: node.attrs.id, 'data-bookmark': 'true' }];
426
+ },
427
+ },
428
+
429
+ /** Inline atom for @-style mentions. The label renders as `${trigger}${label}`. */
430
+ mention: {
431
+ inline: true,
432
+ group: 'inline',
433
+ atom: true,
434
+ selectable: true,
435
+ attrs: {
436
+ trigger: { default: '@' },
437
+ key: {},
438
+ label: {},
439
+ },
440
+ parseDOM: [
441
+ {
442
+ tag: 'span[data-mention-key]',
443
+ getAttrs: (dom: HTMLElement) => ({
444
+ trigger: dom.getAttribute('data-mention-trigger') || '@',
445
+ key: dom.getAttribute('data-mention-key'),
446
+ label:
447
+ dom.getAttribute('data-mention-label') || dom.textContent?.slice(1) || '',
448
+ }),
449
+ },
450
+ ],
451
+ toDOM(node) {
452
+ const { trigger, key, label } = node.attrs;
453
+ return [
454
+ 'span',
455
+ {
456
+ class: 'nile-wysiwyg__mention',
457
+ 'data-mention-trigger': trigger,
458
+ 'data-mention-key': key,
459
+ 'data-mention-label': label,
460
+ },
461
+ `${trigger}${label}`,
462
+ ];
463
+ },
464
+ },
465
+
466
+ /**
467
+ * Merge field: an inline atom placeholder for mail-merge / personalization
468
+ * (e.g. `{{first_name}}`). Stores a stable `id` and a human `label`; renders
469
+ * the label (falling back to `{{id}}`) as a non-editable chip.
470
+ */
471
+ merge_field: {
472
+ inline: true,
473
+ group: 'inline',
474
+ atom: true,
475
+ selectable: true,
476
+ attrs: { id: {}, label: { default: null } },
477
+ parseDOM: [
478
+ {
479
+ tag: 'span[data-merge-field]',
480
+ getAttrs: (dom: HTMLElement) => {
481
+ const id = dom.getAttribute('data-merge-field');
482
+ if (!id) return false;
483
+ return {
484
+ id,
485
+ label: dom.getAttribute('data-merge-label') || dom.textContent || null,
486
+ };
487
+ },
488
+ },
489
+ ],
490
+ toDOM(node) {
491
+ const { id, label } = node.attrs;
492
+ return [
493
+ 'span',
494
+ {
495
+ class: 'nile-wysiwyg__merge-field',
496
+ 'data-merge-field': id,
497
+ 'data-merge-label': label ?? '',
498
+ },
499
+ label || `{{${id}}}`,
500
+ ];
501
+ },
502
+ },
503
+
504
+ /**
505
+ * Math: an inline atom holding a LaTeX source string. Rendering is pluggable
506
+ * via the editor's `mathRenderer` (KaTeX/MathJax, or MathML). Without a
507
+ * renderer the raw LaTeX is shown in a math-styled chip. `display` chooses
508
+ * inline vs. block presentation.
509
+ */
510
+ math: {
511
+ inline: true,
512
+ group: 'inline',
513
+ atom: true,
514
+ selectable: true,
515
+ attrs: { latex: {}, display: { default: 'inline' } },
516
+ parseDOM: [
517
+ {
518
+ tag: 'span[data-math]',
519
+ getAttrs: (dom: HTMLElement) => ({
520
+ latex: dom.getAttribute('data-math') || dom.textContent || '',
521
+ display: dom.getAttribute('data-math-display') === 'block' ? 'block' : 'inline',
522
+ }),
523
+ },
524
+ ],
525
+ toDOM(node) {
526
+ const { latex, display } = node.attrs;
527
+ return [
528
+ 'span',
529
+ {
530
+ class: 'nile-wysiwyg__math',
531
+ 'data-math': latex,
532
+ 'data-math-display': display,
533
+ },
534
+ latex,
535
+ ];
536
+ },
537
+ },
538
+ };
539
+
540
+ /** Table nodes from prosemirror-tables, with cell background support. */
541
+ const tableNodeSpecs = tableNodes({
542
+ tableGroup: 'block',
543
+ cellContent: 'block+',
544
+ cellAttributes: {
545
+ background: {
546
+ default: null,
547
+ getFromDOM(dom) {
548
+ return (dom as HTMLElement).style.backgroundColor || null;
549
+ },
550
+ setDOMAttr(value, attrs) {
551
+ if (value) {
552
+ attrs.style = `${(attrs.style as string) || ''}background-color: ${value};`;
553
+ }
554
+ },
555
+ },
556
+ },
557
+ });
558
+
559
+ /**
560
+ * The table spec extended with a `layout` attr: layout tables (structured
561
+ * layouts, e.g. for email HTML) serialize as `role="presentation"` and render
562
+ * borderless, with dashed guides visible only while editing.
563
+ */
564
+ const baseTableSpec = tableNodeSpecs.table;
565
+ const tableSpec: NodeSpec = {
566
+ ...baseTableSpec,
567
+ attrs: { ...(baseTableSpec.attrs ?? {}), layout: { default: false } },
568
+ parseDOM: [
569
+ {
570
+ tag: 'table',
571
+ getAttrs: (dom: HTMLElement) => ({
572
+ layout:
573
+ dom.getAttribute('role') === 'presentation' || dom.hasAttribute('data-layout'),
574
+ }),
575
+ },
576
+ ],
577
+ toDOM(node) {
578
+ return node.attrs.layout
579
+ ? ['table', { role: 'presentation', 'data-layout': 'true' }, ['tbody', 0]]
580
+ : ['table', ['tbody', 0]];
581
+ },
582
+ };
583
+
584
+ /**
585
+ * Marks. Order matters: marks later in the map render closer to the text.
586
+ * Each styling mark parses from both semantic tags AND inline `style=`
587
+ * declarations so pasted Word/Google Docs content keeps its formatting.
588
+ */
589
+ const marks: Record<string, MarkSpec> = {
590
+ link: {
591
+ attrs: {
592
+ href: {},
593
+ title: { default: null },
594
+ target: { default: null },
595
+ },
596
+ inclusive: false,
597
+ parseDOM: [
598
+ {
599
+ tag: 'a[href]',
600
+ getAttrs: (dom: HTMLElement) => ({
601
+ href: dom.getAttribute('href'),
602
+ title: dom.getAttribute('title'),
603
+ target: dom.getAttribute('target'),
604
+ }),
605
+ },
606
+ ],
607
+ toDOM(mark) {
608
+ const { href, title, target } = mark.attrs;
609
+ const attrs: Record<string, string> = { href };
610
+ if (title) attrs.title = title;
611
+ if (target) {
612
+ attrs.target = target;
613
+ if (target === '_blank') attrs.rel = 'noopener noreferrer';
614
+ }
615
+ return ['a', attrs, 0];
616
+ },
617
+ },
618
+
619
+ bold: {
620
+ parseDOM: [
621
+ { tag: 'strong' },
622
+ // Google Docs wraps everything in <b style="font-weight: normal">
623
+ {
624
+ tag: 'b',
625
+ getAttrs: (dom: HTMLElement) => dom.style.fontWeight !== 'normal' && null,
626
+ },
627
+ {
628
+ style: 'font-weight',
629
+ getAttrs: (value: string) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null,
630
+ },
631
+ ],
632
+ toDOM() {
633
+ return ['strong', 0];
634
+ },
635
+ },
636
+
637
+ italic: {
638
+ parseDOM: [
639
+ { tag: 'i' },
640
+ { tag: 'em' },
641
+ { style: 'font-style=italic' },
642
+ ],
643
+ toDOM() {
644
+ return ['em', 0];
645
+ },
646
+ },
647
+
648
+ underline: {
649
+ parseDOM: [
650
+ { tag: 'u' },
651
+ {
652
+ style: 'text-decoration',
653
+ getAttrs: (value: string) => value.includes('underline') && null,
654
+ },
655
+ {
656
+ style: 'text-decoration-line',
657
+ getAttrs: (value: string) => value.includes('underline') && null,
658
+ },
659
+ ],
660
+ toDOM() {
661
+ return ['u', 0];
662
+ },
663
+ },
664
+
665
+ strike: {
666
+ parseDOM: [
667
+ { tag: 's' },
668
+ { tag: 'strike' },
669
+ { tag: 'del' },
670
+ {
671
+ style: 'text-decoration',
672
+ getAttrs: (value: string) => value.includes('line-through') && null,
673
+ },
674
+ {
675
+ style: 'text-decoration-line',
676
+ getAttrs: (value: string) => value.includes('line-through') && null,
677
+ },
678
+ ],
679
+ toDOM() {
680
+ return ['s', 0];
681
+ },
682
+ },
683
+
684
+ /** Mutually exclusive vertical-shift marks (formulas, footnote refs). */
685
+ subscript: {
686
+ excludes: 'subscript superscript',
687
+ parseDOM: [{ tag: 'sub' }, { style: 'vertical-align=sub' }],
688
+ toDOM() {
689
+ return ['sub', 0];
690
+ },
691
+ },
692
+
693
+ superscript: {
694
+ excludes: 'subscript superscript',
695
+ parseDOM: [{ tag: 'sup' }, { style: 'vertical-align=super' }],
696
+ toDOM() {
697
+ return ['sup', 0];
698
+ },
699
+ },
700
+
701
+ code: {
702
+ parseDOM: [{ tag: 'code' }],
703
+ toDOM() {
704
+ return ['code', { class: 'nile-wysiwyg__inline-code' }, 0];
705
+ },
706
+ },
707
+
708
+ text_color: {
709
+ attrs: { color: {} },
710
+ parseDOM: [
711
+ {
712
+ style: 'color',
713
+ getAttrs: (value: string) => (value ? { color: value } : false),
714
+ },
715
+ ],
716
+ toDOM(mark) {
717
+ return ['span', { style: `color: ${mark.attrs.color}` }, 0];
718
+ },
719
+ },
720
+
721
+ bg_color: {
722
+ attrs: { color: {} },
723
+ parseDOM: [
724
+ {
725
+ style: 'background-color',
726
+ getAttrs: (value: string) =>
727
+ value && value !== 'transparent' ? { color: value } : false,
728
+ },
729
+ ],
730
+ toDOM(mark) {
731
+ return ['span', { style: `background-color: ${mark.attrs.color}` }, 0];
732
+ },
733
+ },
734
+
735
+ font_family: {
736
+ attrs: { family: {} },
737
+ parseDOM: [
738
+ {
739
+ style: 'font-family',
740
+ getAttrs: (value: string) => (value ? { family: value } : false),
741
+ },
742
+ ],
743
+ toDOM(mark) {
744
+ return ['span', { style: `font-family: ${mark.attrs.family}` }, 0];
745
+ },
746
+ },
747
+
748
+ font_size: {
749
+ attrs: { size: {} },
750
+ parseDOM: [
751
+ {
752
+ style: 'font-size',
753
+ getAttrs: (value: string) => (value ? { size: value } : false),
754
+ },
755
+ ],
756
+ toDOM(mark) {
757
+ return ['span', { style: `font-size: ${mark.attrs.size}` }, 0];
758
+ },
759
+ },
760
+ };
761
+
762
+ /** Bullet markers CSS understands; anything else falls back to default. */
763
+ export const BULLET_STYLES = ['disc', 'circle', 'square'] as const;
764
+
765
+ /** Numbering styles, keyed by the HTML `type` attribute letter. */
766
+ export const ORDERED_STYLES: Record<string, string> = {
767
+ '1': 'decimal',
768
+ a: 'lower-alpha',
769
+ A: 'upper-alpha',
770
+ i: 'lower-roman',
771
+ I: 'upper-roman',
772
+ };
773
+
774
+ const STYLE_TO_TYPE: Record<string, string> = Object.fromEntries(
775
+ Object.entries(ORDERED_STYLES).map(([type, style]) => [style, type])
776
+ );
777
+
778
+ /**
779
+ * Legal-style continuous numbering (1, 1.1, 1.1.1). Not a CSS
780
+ * list-style-type: it serializes as `data-list-style="multilevel"` and is
781
+ * rendered with CSS counters (see the editor stylesheet). Consumers rendering
782
+ * the output need the same counter rules.
783
+ */
784
+ export const MULTILEVEL_STYLE = 'multilevel';
785
+
786
+ /** List specs from prosemirror-schema-list, extended with style attrs. */
787
+ const bulletListSpec: NodeSpec = {
788
+ content: 'list_item+',
789
+ group: 'block',
790
+ attrs: { style: { default: null } },
791
+ parseDOM: [
792
+ {
793
+ tag: 'ul',
794
+ getAttrs: (dom: HTMLElement) => {
795
+ const style = dom.style.listStyleType;
796
+ return {
797
+ style: (BULLET_STYLES as readonly string[]).includes(style) ? style : null,
798
+ };
799
+ },
800
+ },
801
+ ],
802
+ toDOM(node) {
803
+ return node.attrs.style
804
+ ? ['ul', { style: `list-style-type: ${node.attrs.style}` }, 0]
805
+ : ['ul', 0];
806
+ },
807
+ };
808
+
809
+ const orderedListSpec: NodeSpec = {
810
+ content: 'list_item+',
811
+ group: 'block',
812
+ attrs: { order: { default: 1 }, style: { default: null } },
813
+ parseDOM: [
814
+ {
815
+ tag: 'ol',
816
+ getAttrs: (dom: HTMLElement) => {
817
+ const type = dom.getAttribute('type') ?? '';
818
+ const cssStyle = dom.style.listStyleType;
819
+ const style =
820
+ dom.getAttribute('data-list-style') === MULTILEVEL_STYLE
821
+ ? MULTILEVEL_STYLE
822
+ : ORDERED_STYLES[type] ??
823
+ (Object.values(ORDERED_STYLES).includes(cssStyle) ? cssStyle : null);
824
+ const start = Number(dom.getAttribute('start'));
825
+ return {
826
+ order: Number.isFinite(start) && start > 0 ? start : 1,
827
+ style,
828
+ };
829
+ },
830
+ },
831
+ ],
832
+ toDOM(node) {
833
+ const attrs: Record<string, string> = {};
834
+ if (node.attrs.order !== 1) attrs.start = String(node.attrs.order);
835
+ if (node.attrs.style === MULTILEVEL_STYLE) {
836
+ attrs['data-list-style'] = MULTILEVEL_STYLE;
837
+ } else if (node.attrs.style && STYLE_TO_TYPE[node.attrs.style]) {
838
+ attrs.type = STYLE_TO_TYPE[node.attrs.style];
839
+ }
840
+ return ['ol', attrs, 0];
841
+ },
842
+ };
843
+
844
+ /** Builds the editor schema. List nodes are added via prosemirror-schema-list. */
845
+ export function createSchema(): Schema {
846
+ const nodeMap = addListNodes(
847
+ OrderedMap.from(nodes),
848
+ 'paragraph block*',
849
+ 'block'
850
+ )
851
+ .update('bullet_list', bulletListSpec)
852
+ .update('ordered_list', orderedListSpec)
853
+ .append(tableNodeSpecs)
854
+ .update('table', tableSpec);
855
+ return new Schema({ nodes: nodeMap, marks: OrderedMap.from(marks) });
856
+ }
857
+
858
+ /** A shared default schema instance. */
859
+ export const defaultSchema = createSchema();